From 8a5f1db425db6a8015324b6b7f1a8e4b47c285cc Mon Sep 17 00:00:00 2001 From: Newtech66 Date: Sun, 12 May 2024 19:59:36 +0530 Subject: [PATCH 001/537] Initial commit --- src/sage/rings/burnside.py | 122 +++++++++++++++++++++++++++++++++++++ 1 file changed, 122 insertions(+) create mode 100644 src/sage/rings/burnside.py diff --git a/src/sage/rings/burnside.py b/src/sage/rings/burnside.py new file mode 100644 index 00000000000..7aa51f58940 --- /dev/null +++ b/src/sage/rings/burnside.py @@ -0,0 +1,122 @@ +from sage.structure.element import Element + +def _is_conjugate(G, H1, H2): + return gap("fail") != gap.RepresentativeAction(G, H1, H2) + +class BurnsideRingElement(Element): + def __init__(self, parent, H): + """ + Initialize an element. + + INPUT: + + * ``H`` - a formal sum of representatives of conjugacy # + classes of subgroups + + EXAMPLES:: + + sage: G = SymmetricGroup(4) + sage: B = BurnsideRing(G) + sage: B(G) + """ + Element.__init__(self, parent) + self._H = H + + def _mul_(self, right): + """ + Return the product of ``self`` and ``right``. + + For the symmetric group, this is also known as the Hadamard + or tensor product of group actions. + """ + pass + + def _add_(self, right): + """ + Return the sum of ``self`` and ``right``. + """ + pass + + +class BurnsideRing(Parent): + def __init__(self, G, base_ring=ZZ): + self._G = G + self._cache = dict() + Parent.__init__(self, base=base_ring) + + def _group_invariant(self, H): + return H.order() + + Element = BurnsideRingElement + + def _element_constructor_(self, x=None, action=None, domain=None): + """ + Construct an element of the Burnside ring. + + INPUT: + + - ``x`` - data for an element + + ``x`` can be one of the following: + + * a subgroup of `G` + * a formal sum of such subgroups `G` + + (* a group action on some set `X`) + + EXAMPLES: + + sage: S4 = SymmetricGroup(4) + sage: B = BurnsideRing(S4) + + Maybe better like: + + sage: a = lambda g, x: Set([g(e) for e in x]) + sage: B(action=a, domain=Subsets(4, 2)) + + We create a group action of `S_4` on two-element subsets:: + + sage: H = PermutationGroup(S4.gens(), action=a, domain=Subsets(4, 2)) + + # we can only trust the user that this is the homomorphic + # image of a group action of S4 + sage: B(H) + """ + def normalize(H): + p = self._group_invariant(H) + if p in self._cache: + for H0 in self._cache[p]: + if _is_conjugate(self._G, H, H0): + return H0 + else: + self._cache[p].append(H) + else: + self._cache[p] = [H] + return H + + # given a group action + if x is None: + H = PermutationGroup(self._G.gens(), action=a, domain=domain) + # decompose H into a sum F of conjugacy classes + # normalize each summand + return self.element_class(self, F) + + # if x is a single subgroup of self._G + return self.element_class(self, FormalSum([(1, normalize(x))])) + +class PolynomialSpeciesElement(Parent): + + def _mul_(self, right): + """ + Return the Cauchy product of ``self`` and ``right``. + + EXAMPLES:: + + sage: X * X + X^2 + """ + pass + +class PolynomialSpecies(Parent): + pass + From ce7c87fd8ca6b14bd586a42c7842e292eb6ec1e7 Mon Sep 17 00:00:00 2001 From: Newtech66 Date: Tue, 14 May 2024 22:47:42 +0530 Subject: [PATCH 002/537] Added _add_, _mul_, _element_constructor_ for group action input --- src/sage/rings/burnside.py | 127 ++++++++++++++++++++++++++++--------- 1 file changed, 97 insertions(+), 30 deletions(-) diff --git a/src/sage/rings/burnside.py b/src/sage/rings/burnside.py index 7aa51f58940..d48b8a55165 100644 --- a/src/sage/rings/burnside.py +++ b/src/sage/rings/burnside.py @@ -4,13 +4,13 @@ def _is_conjugate(G, H1, H2): return gap("fail") != gap.RepresentativeAction(G, H1, H2) class BurnsideRingElement(Element): - def __init__(self, parent, H): - """ + def __init__(self, parent, F): + r""" Initialize an element. INPUT: - * ``H`` - a formal sum of representatives of conjugacy # + * ``F`` - a formal sum of representatives of conjugacy # classes of subgroups EXAMPLES:: @@ -18,24 +18,74 @@ def __init__(self, parent, H): sage: G = SymmetricGroup(4) sage: B = BurnsideRing(G) sage: B(G) + Symmetric group of order 4! as a permutation group + as an element of the Burnside ring """ Element.__init__(self, parent) - self._H = H + self._F = F - def _mul_(self, right): + def _repr_(self): + r""" + Return a string representation of ``self``. + """ + return repr(self._F) + " as an element of the Burnside ring" + + def _acted_upon_(self, scalar, self_on_left): + r""" + Scalar multiplication for ``self`` by ``scalar``. + + INPUT: + + - ``scalar`` -- an element of the base ring + - ``self_on_left`` -- boolean; if ``True``, compute ``self * scalar`` + + EXAMPLES: + + sage: B = BurnsideRing(G) + sage: b = B(G) + sage: b + Symmetric group of order 4! as a permutation group + as an element of the Burnside ring + sage: 2*b + 2*Symmetric group of order 4! + as a permutation group as an element of the Burnside ring """ + B = self.parent() + F = scalar * self._F + return B.element_class(B, F) + + def _mul_(self, right): + r""" Return the product of ``self`` and ``right``. For the symmetric group, this is also known as the Hadamard or tensor product of group actions. """ - pass + #TODO: Find faster way to multiply + assert right.parent() == self.parent() + B = self.parent() + G = B._G + def mul(H1, H2): + dom1 = [frozenset(g) for g in G.cosets(H1)] + dom2 = [frozenset(g) for g in G.cosets(H2)] + domain = cartesian_product([dom1, dom2]) + def action(g, pair): + return (frozenset(g*h for h in pair[0]), + frozenset(g*h for h in pair[1])) + return B(action=action, domain=domain)._F + result = FormalSum(0) + for c1, g1 in self._F: + for c2, g2 in right._F: + result += c1*c2*mul(g1, g2) + return B.element_class(B, result) def _add_(self, right): - """ + r""" Return the sum of ``self`` and ``right``. """ - pass + P = self.parent() + F = self._F + right._F + return P.element_class(P, F) class BurnsideRing(Parent): @@ -93,30 +143,47 @@ def normalize(H): else: self._cache[p] = [H] return H + + def find_stabilizer(action, pnt): + stabilizer = [] + for g in self._G: + if action(g, pnt) == pnt: + stabilizer.append(g) + return self._G.subgroup(stabilizer) # given a group action - if x is None: - H = PermutationGroup(self._G.gens(), action=a, domain=domain) + if action is not None and domain is not None: + H = PermutationGroup(self._G.gens(), action=action, domain=domain) # decompose H into a sum F of conjugacy classes - # normalize each summand + orbit_list = H.orbits() + # find the stabilizer subgroups + # TODO: find a way to do this with GAP instead + stabilizer_list = [find_stabilizer(action, orbit[0]) for orbit in orbit_list] + # normalize each summand and collect terms + from collections import Counter + C = Counter([normalize(stabilizer) for stabilizer in stabilizer_list]) + # create formal sum + F = FormalSum([(coeff, subgroup) for subgroup, coeff in C.items()]) return self.element_class(self, F) - - # if x is a single subgroup of self._G - return self.element_class(self, FormalSum([(1, normalize(x))])) - -class PolynomialSpeciesElement(Parent): - - def _mul_(self, right): + elif action is not None and domain is None: + raise ValueError("If action is provided then domain must be provided") + elif action is None and domain is not None: + raise ValueError("If domain is provided then action must be provided") + + if isinstance(x, list) or isinstance(x,FormalSum): + # if x is a list of pairs (coeff, subgroup) or FormalSum + if not all([subgroup.is_subgroup(self._G) for coeff, subgroup in x]): + raise ValueError("All groups in list must be subgroups of " + repr(self._G)) + return self.element_class(self, FormalSum([(coeff, normalize(subgroup)) for coeff, subgroup in x])) + elif x.is_subgroup(self._G): + # if x is a single subgroup of self._G + return self.element_class(self, FormalSum([(1, normalize(x))])) + + raise ValueError(f"unable to convert {x} into {self}") + + + def _repr_(self): + r""" + Return a string representation of ``self``. """ - Return the Cauchy product of ``self`` and ``right``. - - EXAMPLES:: - - sage: X * X - X^2 - """ - pass - -class PolynomialSpecies(Parent): - pass - + return "Burnside ring of " + repr(self._G) \ No newline at end of file From 2ae54974228719b8ec624e4a76ec568ab752e59d Mon Sep 17 00:00:00 2001 From: Newtech66 Date: Wed, 15 May 2024 02:29:49 +0530 Subject: [PATCH 003/537] Fixed bugs with caching and _mul_ --- src/sage/rings/all.py | 2 + src/sage/rings/burnside.py | 141 +++++++++++++++++++++++++++++-------- 2 files changed, 113 insertions(+), 30 deletions(-) diff --git a/src/sage/rings/all.py b/src/sage/rings/all.py index e3c7167fe12..5cc1988c336 100644 --- a/src/sage/rings/all.py +++ b/src/sage/rings/all.py @@ -166,5 +166,7 @@ # asymptotic ring from sage.rings.asymptotic.all import * +lazy_import('sage.rings.burnside', ['BurnsideRing']) + # Register classes in numbers abc from sage.rings import numbers_abc diff --git a/src/sage/rings/burnside.py b/src/sage/rings/burnside.py index d48b8a55165..5f8918e3654 100644 --- a/src/sage/rings/burnside.py +++ b/src/sage/rings/burnside.py @@ -1,7 +1,23 @@ +from sage.structure.parent import Parent from sage.structure.element import Element +from sage.rings.integer_ring import ZZ +from sage.structure.formal_sum import FormalSum +from sage.categories.sets_cat import cartesian_product +from sage.groups.perm_gps.permgroup import PermutationGroup +from sage.libs.gap.libgap import libgap def _is_conjugate(G, H1, H2): - return gap("fail") != gap.RepresentativeAction(G, H1, H2) + """ + TESTS:: + + sage: G = SymmetricGroup(4) + sage: B = BurnsideRing(G) + sage: [H._F[0][1].order() for H in B] + [1, 2, 2, 3, 4, 4, 4, 6, 8, 12, 24] + sage: [(o, len(l)) for o, l in B._cache.items()] + [(1, 1), (2, 2), (3, 1), (4, 3), (6, 1), (8, 1), (12, 1), (24, 1)] + """ + return libgap.eval("fail") != libgap.RepresentativeAction(G, H1, H2) class BurnsideRingElement(Element): def __init__(self, parent, F): @@ -10,7 +26,7 @@ def __init__(self, parent, F): INPUT: - * ``F`` - a formal sum of representatives of conjugacy # + - ``F`` - a formal sum of representatives of conjugacy # classes of subgroups EXAMPLES:: @@ -20,6 +36,13 @@ def __init__(self, parent, F): sage: B(G) Symmetric group of order 4! as a permutation group as an element of the Burnside ring + + sage: X = Subsets(4, 2) + sage: a = lambda g, x: X([g(e) for e in x]) + sage: B(domain=X, action=a) + Subgroup generated by [(3,4), (1,2), (1,2)(3,4)] + of (Symmetric group of order 4! as a permutation group) + as an element of the Burnside ring """ Element.__init__(self, parent) self._F = F @@ -39,8 +62,9 @@ def _acted_upon_(self, scalar, self_on_left): - ``scalar`` -- an element of the base ring - ``self_on_left`` -- boolean; if ``True``, compute ``self * scalar`` - EXAMPLES: + EXAMPLES:: + sage: G = SymmetricGroup(4) sage: B = BurnsideRing(G) sage: b = B(G) sage: b @@ -60,23 +84,47 @@ def _mul_(self, right): For the symmetric group, this is also known as the Hadamard or tensor product of group actions. + + EXAMPLES:: + + sage: G = SymmetricGroup(3) + sage: B = BurnsideRing(G) + sage: [b * b for b in B] + [6*Subgroup generated by [()] + of (Symmetric group of order 3! as a permutation group) + as an element of the Burnside ring, + Subgroup generated by [(2,3)] + of (Symmetric group of order 3! as a permutation group) + + Subgroup generated by [()] + of (Symmetric group of order 3! as a permutation group) + as an element of the Burnside ring, + 2*Subgroup generated by [(1,2,3)] + of (Symmetric group of order 3! as a permutation group) + as an element of the Burnside ring, + Subgroup generated by [(1,2,3), (2,3)] + of (Symmetric group of order 3! as a permutation group) + as an element of the Burnside ring] """ #TODO: Find faster way to multiply assert right.parent() == self.parent() B = self.parent() G = B._G + def mul(H1, H2): - dom1 = [frozenset(g) for g in G.cosets(H1)] - dom2 = [frozenset(g) for g in G.cosets(H2)] + dom1 = [frozenset(g) for g in G.cosets(H1,side='left')] + dom2 = [frozenset(g) for g in G.cosets(H2,side='left')] domain = cartesian_product([dom1, dom2]) + def action(g, pair): - return (frozenset(g*h for h in pair[0]), - frozenset(g*h for h in pair[1])) + return (frozenset(g * h for h in pair[0]), + frozenset(g * h for h in pair[1])) return B(action=action, domain=domain)._F + result = FormalSum(0) for c1, g1 in self._F: for c2, g2 in right._F: - result += c1*c2*mul(g1, g2) + result += c1 * c2 * mul(g1, g2) + return B.element_class(B, result) def _add_(self, right): @@ -100,37 +148,46 @@ def _group_invariant(self, H): Element = BurnsideRingElement def _element_constructor_(self, x=None, action=None, domain=None): - """ + r""" Construct an element of the Burnside ring. INPUT: - ``x`` - data for an element + - ``action`` - an action on ``domain`` + - ``domain`` - a finite set - ``x`` can be one of the following: - - * a subgroup of `G` - * a formal sum of such subgroups `G` - - (* a group action on some set `X`) + ``x`` can be a subgroup of `G` or a formal sum of such + subgroups. EXAMPLES: - sage: S4 = SymmetricGroup(4) - sage: B = BurnsideRing(S4) - - Maybe better like: - - sage: a = lambda g, x: Set([g(e) for e in x]) - sage: B(action=a, domain=Subsets(4, 2)) + sage: G = SymmetricGroup(4) + sage: B = BurnsideRing(G) We create a group action of `S_4` on two-element subsets:: - sage: H = PermutationGroup(S4.gens(), action=a, domain=Subsets(4, 2)) + sage: X = Subsets(4, 2) + sage: a = lambda g, x: X([g(e) for e in x]) + sage: B(domain=X, action=a) + Subgroup generated by [(3,4), (1,2), (1,2)(3,4)] + of (Symmetric group of order 4! as a permutation group) + as an element of the Burnside ring - # we can only trust the user that this is the homomorphic - # image of a group action of S4 - sage: B(H) + sage: X = G + sage: a = lambda g, x: g*x*g.inverse() + sage: B(domain=X, action=a) + Subgroup generated by [(2,3,4), (1,2)] + of (Symmetric group of order 4! as a permutation group) + + Subgroup generated by [(2,4), (1,4)(2,3)] + of (Symmetric group of order 4! as a permutation group) + + Subgroup generated by [(2,3,4)] + of (Symmetric group of order 4! as a permutation group) + + Subgroup generated by [(3,4), (1,2), (1,2)(3,4)] + of (Symmetric group of order 4! as a permutation group) + + Subgroup generated by [(1,3,2,4)] + of (Symmetric group of order 4! as a permutation group) + as an element of the Burnside ring """ def normalize(H): p = self._group_invariant(H) @@ -143,13 +200,15 @@ def normalize(H): else: self._cache[p] = [H] return H - + def find_stabilizer(action, pnt): stabilizer = [] for g in self._G: if action(g, pnt) == pnt: stabilizer.append(g) - return self._G.subgroup(stabilizer) + H = self._G.subgroup(stabilizer) + gens = H.gens_small() + return self._G.subgroup(gens) # given a group action if action is not None and domain is not None: @@ -170,7 +229,7 @@ def find_stabilizer(action, pnt): elif action is None and domain is not None: raise ValueError("If domain is provided then action must be provided") - if isinstance(x, list) or isinstance(x,FormalSum): + if isinstance(x, list) or isinstance(x, FormalSum): # if x is a list of pairs (coeff, subgroup) or FormalSum if not all([subgroup.is_subgroup(self._G) for coeff, subgroup in x]): raise ValueError("All groups in list must be subgroups of " + repr(self._G)) @@ -181,9 +240,31 @@ def find_stabilizer(action, pnt): raise ValueError(f"unable to convert {x} into {self}") + def __iter__(self): + """ + + EXAMPLES:: + + sage: G = SymmetricGroup(3) + sage: B = BurnsideRing(G) + sage: list(B) + [Subgroup generated by [()] + of (Symmetric group of order 3! as a permutation group) + as an element of the Burnside ring, + Subgroup generated by [(2,3)] + of (Symmetric group of order 3! as a permutation group) + as an element of the Burnside ring, + Subgroup generated by [(1,2,3)] + of (Symmetric group of order 3! as a permutation group) + as an element of the Burnside ring, + Subgroup generated by [(1,2,3), (2,3)] + of (Symmetric group of order 3! as a permutation group) + as an element of the Burnside ring] + """ + return iter(self(H) for H in self._G.conjugacy_classes_subgroups()) def _repr_(self): r""" Return a string representation of ``self``. """ - return "Burnside ring of " + repr(self._G) \ No newline at end of file + return "Burnside ring of " + repr(self._G) From 663b4220a650da4c89b63bcb22bf7374e85ad369 Mon Sep 17 00:00:00 2001 From: Newtech66 Date: Wed, 15 May 2024 19:35:01 +0530 Subject: [PATCH 004/537] Improved repr output and added a way to name conjugacy classes of subgroups Also added various miscellaneous functions --- src/sage/rings/burnside.py | 181 +++++++++++++++++++++---------------- 1 file changed, 104 insertions(+), 77 deletions(-) diff --git a/src/sage/rings/burnside.py b/src/sage/rings/burnside.py index 5f8918e3654..0b6a1dc83a7 100644 --- a/src/sage/rings/burnside.py +++ b/src/sage/rings/burnside.py @@ -1,3 +1,6 @@ +from sage.misc.cachefunc import cached_method +from sage.structure.unique_representation import UniqueRepresentation +from sage.structure.richcmp import op_EQ, op_NE from sage.structure.parent import Parent from sage.structure.element import Element from sage.rings.integer_ring import ZZ @@ -5,19 +8,11 @@ from sage.categories.sets_cat import cartesian_product from sage.groups.perm_gps.permgroup import PermutationGroup from sage.libs.gap.libgap import libgap +from sage.misc.repr import repr_lincomb +from sage.categories.algebras import Algebras def _is_conjugate(G, H1, H2): - """ - TESTS:: - - sage: G = SymmetricGroup(4) - sage: B = BurnsideRing(G) - sage: [H._F[0][1].order() for H in B] - [1, 2, 2, 3, 4, 4, 4, 6, 8, 12, 24] - sage: [(o, len(l)) for o, l in B._cache.items()] - [(1, 1), (2, 2), (3, 1), (4, 3), (6, 1), (8, 1), (12, 1), (24, 1)] - """ - return libgap.eval("fail") != libgap.RepresentativeAction(G, H1, H2) + return libgap.eval('fail') != libgap.RepresentativeAction(G, H1, H2) class BurnsideRingElement(Element): def __init__(self, parent, F): @@ -34,15 +29,12 @@ def __init__(self, parent, F): sage: G = SymmetricGroup(4) sage: B = BurnsideRing(G) sage: B(G) - Symmetric group of order 4! as a permutation group - as an element of the Burnside ring + 1 sage: X = Subsets(4, 2) sage: a = lambda g, x: X([g(e) for e in x]) sage: B(domain=X, action=a) - Subgroup generated by [(3,4), (1,2), (1,2)(3,4)] - of (Symmetric group of order 4! as a permutation group) - as an element of the Burnside ring + [(3,4), (1,2), (1,2)(3,4)] """ Element.__init__(self, parent) self._F = F @@ -51,7 +43,22 @@ def _repr_(self): r""" Return a string representation of ``self``. """ - return repr(self._F) + " as an element of the Burnside ring" + return repr_lincomb(([(H.gens() if name is None else name, c) + for c, (name, H) in self._F]), + repr_monomial=lambda s: s if isinstance(s, str) else repr(list(s))) + + def _richcmp_(self, other, op): + """ + + sage: G = SymmetricGroup(4) + sage: B = BurnsideRing(G) + sage: B.zero() == 0 + True + """ + if op is op_EQ: + return not bool(self._F - other._F) + if op is op_NE: + return bool(self._F - other._F) def _acted_upon_(self, scalar, self_on_left): r""" @@ -68,11 +75,9 @@ def _acted_upon_(self, scalar, self_on_left): sage: B = BurnsideRing(G) sage: b = B(G) sage: b - Symmetric group of order 4! as a permutation group - as an element of the Burnside ring + 1 sage: 2*b - 2*Symmetric group of order 4! - as a permutation group as an element of the Burnside ring + 2*1 """ B = self.parent() F = scalar * self._F @@ -89,21 +94,11 @@ def _mul_(self, right): sage: G = SymmetricGroup(3) sage: B = BurnsideRing(G) - sage: [b * b for b in B] - [6*Subgroup generated by [()] - of (Symmetric group of order 3! as a permutation group) - as an element of the Burnside ring, - Subgroup generated by [(2,3)] - of (Symmetric group of order 3! as a permutation group) - + Subgroup generated by [()] - of (Symmetric group of order 3! as a permutation group) - as an element of the Burnside ring, - 2*Subgroup generated by [(1,2,3)] - of (Symmetric group of order 3! as a permutation group) - as an element of the Burnside ring, - Subgroup generated by [(1,2,3), (2,3)] - of (Symmetric group of order 3! as a permutation group) - as an element of the Burnside ring] + sage: matrix([[b * c for b in B] for c in B]) + [ 6*[()] 3*[()] 2*[()] [()]] + [ 3*[()] [(2,3)] + [()] [()] [(2,3)]] + [ 2*[()] [()] 2*[(1,2,3)] [(1,2,3)]] + [ [()] [(2,3)] [(1,2,3)] 1] """ #TODO: Find faster way to multiply assert right.parent() == self.parent() @@ -111,18 +106,19 @@ def _mul_(self, right): G = B._G def mul(H1, H2): - dom1 = [frozenset(g) for g in G.cosets(H1,side='left')] - dom2 = [frozenset(g) for g in G.cosets(H2,side='left')] + dom1 = [frozenset(g) for g in G.cosets(H1, side="left")] + dom2 = [frozenset(g) for g in G.cosets(H2, side="left")] domain = cartesian_product([dom1, dom2]) def action(g, pair): return (frozenset(g * h for h in pair[0]), frozenset(g * h for h in pair[1])) + return B(action=action, domain=domain)._F result = FormalSum(0) - for c1, g1 in self._F: - for c2, g2 in right._F: + for c1, (_, g1) in self._F: + for c2, (_, g2) in right._F: result += c1 * c2 * mul(g1, g2) return B.element_class(B, result) @@ -136,18 +132,36 @@ def _add_(self, right): return P.element_class(P, F) -class BurnsideRing(Parent): +class BurnsideRing(UniqueRepresentation, Parent): def __init__(self, G, base_ring=ZZ): + """ + sage: G = SymmetricGroup(4) + sage: B = BurnsideRing(G) + sage: TestSuite(B).run() + """ self._G = G - self._cache = dict() - Parent.__init__(self, base=base_ring) + self._cache = dict() # invariant to a list of pairs (name, subgroup) + category = Algebras(base_ring).Commutative() + Parent.__init__(self, base=base_ring, category=category) def _group_invariant(self, H): return H.order() + def _coerce_map_from_(self, S): + """ + Return ``True`` if a coercion from ``S`` exists. + """ + if self.base_ring().has_coerce_map_from(S): + return True + return None + + @cached_method + def _an_element_(self): + return self.one() + Element = BurnsideRingElement - def _element_constructor_(self, x=None, action=None, domain=None): + def _element_constructor_(self, x=None, action=None, domain=None, name=None): r""" Construct an element of the Burnside ring. @@ -170,36 +184,42 @@ def _element_constructor_(self, x=None, action=None, domain=None): sage: X = Subsets(4, 2) sage: a = lambda g, x: X([g(e) for e in x]) sage: B(domain=X, action=a) - Subgroup generated by [(3,4), (1,2), (1,2)(3,4)] - of (Symmetric group of order 4! as a permutation group) - as an element of the Burnside ring + [(3,4), (1,2), (1,2)(3,4)] sage: X = G sage: a = lambda g, x: g*x*g.inverse() sage: B(domain=X, action=a) - Subgroup generated by [(2,3,4), (1,2)] - of (Symmetric group of order 4! as a permutation group) - + Subgroup generated by [(2,4), (1,4)(2,3)] - of (Symmetric group of order 4! as a permutation group) - + Subgroup generated by [(2,3,4)] - of (Symmetric group of order 4! as a permutation group) - + Subgroup generated by [(3,4), (1,2), (1,2)(3,4)] - of (Symmetric group of order 4! as a permutation group) - + Subgroup generated by [(1,3,2,4)] - of (Symmetric group of order 4! as a permutation group) - as an element of the Burnside ring + 1 + [(2,4), (1,4)(2,3)] + [(2,3,4)] + [(3,4), (1,2), (1,2)(3,4)] + [(1,3,2,4)] + + TESTS:: + + sage: G = SymmetricGroup(4) + sage: B = BurnsideRing(G) + sage: [H._F[0][1][1].order() for H in B] + [1, 2, 2, 3, 4, 4, 4, 6, 8, 12, 24] + sage: sorted((o, len(l)) for o, l in B._cache.items()) + [(1, 1), (2, 2), (3, 1), (4, 3), (6, 1), (8, 1), (12, 1), (24, 1)] + + sage: G = SymmetricGroup(4) + sage: B = BurnsideRing(G) + sage: B(-3) + -3*1 """ - def normalize(H): + if action is None and domain is None and x in self.base_ring(): + return x * self.one() + + def normalize(H, name=None): p = self._group_invariant(H) if p in self._cache: - for H0 in self._cache[p]: + for name0, H0 in self._cache[p]: if _is_conjugate(self._G, H, H0): - return H0 + assert name is None or name0 == name, "the name should not change" + return name0, H0 else: - self._cache[p].append(H) + self._cache[p].append((name, H)) else: - self._cache[p] = [H] - return H + self._cache[p] = [(name, H)] + return name, H def find_stabilizer(action, pnt): stabilizer = [] @@ -212,6 +232,7 @@ def find_stabilizer(action, pnt): # given a group action if action is not None and domain is not None: + assert name is None H = PermutationGroup(self._G.gens(), action=action, domain=domain) # decompose H into a sum F of conjugacy classes orbit_list = H.orbits() @@ -230,16 +251,33 @@ def find_stabilizer(action, pnt): raise ValueError("If domain is provided then action must be provided") if isinstance(x, list) or isinstance(x, FormalSum): + assert name is None # if x is a list of pairs (coeff, subgroup) or FormalSum if not all([subgroup.is_subgroup(self._G) for coeff, subgroup in x]): raise ValueError("All groups in list must be subgroups of " + repr(self._G)) return self.element_class(self, FormalSum([(coeff, normalize(subgroup)) for coeff, subgroup in x])) elif x.is_subgroup(self._G): # if x is a single subgroup of self._G - return self.element_class(self, FormalSum([(1, normalize(x))])) + return self.element_class(self, FormalSum([(1, normalize(x, name))])) raise ValueError(f"unable to convert {x} into {self}") + @cached_method + def one(self): + return self._element_constructor_(self._G, name="1") + + @cached_method + def zero(self): + """ + EXAMPLES:: + + sage: G = SymmetricGroup(3) + sage: B = BurnsideRing(G) + sage: (0 * B.one()).is_zero() + True + """ + return self.element_class(self, FormalSum([])) + def __iter__(self): """ @@ -248,18 +286,7 @@ def __iter__(self): sage: G = SymmetricGroup(3) sage: B = BurnsideRing(G) sage: list(B) - [Subgroup generated by [()] - of (Symmetric group of order 3! as a permutation group) - as an element of the Burnside ring, - Subgroup generated by [(2,3)] - of (Symmetric group of order 3! as a permutation group) - as an element of the Burnside ring, - Subgroup generated by [(1,2,3)] - of (Symmetric group of order 3! as a permutation group) - as an element of the Burnside ring, - Subgroup generated by [(1,2,3), (2,3)] - of (Symmetric group of order 3! as a permutation group) - as an element of the Burnside ring] + [[()], [(2,3)], [(1,2,3)], 1] """ return iter(self(H) for H in self._G.conjugacy_classes_subgroups()) From 6f9cac46e9de02a9c89b9d1b2b85f0cbb33e3bf8 Mon Sep 17 00:00:00 2001 From: Mainak Roy <78967475+Newtech66@users.noreply.github.com> Date: Thu, 16 May 2024 22:56:40 +0530 Subject: [PATCH 005/537] Update src/sage/rings/burnside.py Co-authored-by: Martin Rubey --- src/sage/rings/burnside.py | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/src/sage/rings/burnside.py b/src/sage/rings/burnside.py index 0b6a1dc83a7..c28c29f3789 100644 --- a/src/sage/rings/burnside.py +++ b/src/sage/rings/burnside.py @@ -278,17 +278,35 @@ def zero(self): """ return self.element_class(self, FormalSum([])) - def __iter__(self): + def group(self): + r""" + Return the underlying group. + + EXAMPLES:: + + sage: G = DiCyclicGroup(4) + sage: B = BurnsideRing(G) + sage: B.group() + Dicyclic group of order 16 as a permutation group """ + return self._G + + @cached_method + def gens(self): + r""" + Return the generators of ``self``. + + These are the conjugacy classes of subgroups of the + underlying group :meth:`group`. EXAMPLES:: sage: G = SymmetricGroup(3) sage: B = BurnsideRing(G) - sage: list(B) - [[()], [(2,3)], [(1,2,3)], 1] + sage: B.gens() + ([()], [(2,3)], [(1,2,3)], 1) """ - return iter(self(H) for H in self._G.conjugacy_classes_subgroups()) + return tuple(self(H) for H in self._G.conjugacy_classes_subgroups()) def _repr_(self): r""" From bec9b0b72b9ebec8798be30b8ffdbaa2d793510a Mon Sep 17 00:00:00 2001 From: Newtech66 Date: Thu, 16 May 2024 23:22:54 +0530 Subject: [PATCH 006/537] Doctest updates --- src/sage/rings/burnside.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/rings/burnside.py b/src/sage/rings/burnside.py index c28c29f3789..e80e7d3b8be 100644 --- a/src/sage/rings/burnside.py +++ b/src/sage/rings/burnside.py @@ -94,7 +94,7 @@ def _mul_(self, right): sage: G = SymmetricGroup(3) sage: B = BurnsideRing(G) - sage: matrix([[b * c for b in B] for c in B]) + sage: matrix([[b * c for b in B.gens()] for c in B.gens()]) [ 6*[()] 3*[()] 2*[()] [()]] [ 3*[()] [(2,3)] + [()] [()] [(2,3)]] [ 2*[()] [()] 2*[(1,2,3)] [(1,2,3)]] @@ -195,7 +195,7 @@ def _element_constructor_(self, x=None, action=None, domain=None, name=None): sage: G = SymmetricGroup(4) sage: B = BurnsideRing(G) - sage: [H._F[0][1][1].order() for H in B] + sage: [H._F[0][1][1].order() for H in B.gens()] [1, 2, 2, 3, 4, 4, 4, 6, 8, 12, 24] sage: sorted((o, len(l)) for o, l in B._cache.items()) [(1, 1), (2, 2), (3, 1), (4, 3), (6, 1), (8, 1), (12, 1), (24, 1)] From 476218fb8140da7cb41fdbb226b3e4477c237be0 Mon Sep 17 00:00:00 2001 From: Newtech66 Date: Fri, 17 May 2024 02:15:52 +0530 Subject: [PATCH 007/537] Added ConjugacyClassesOfSubgroups --- src/sage/rings/all.py | 2 +- src/sage/rings/burnside.py | 46 ++++++++++++++++++++++++++++++++++++-- 2 files changed, 45 insertions(+), 3 deletions(-) diff --git a/src/sage/rings/all.py b/src/sage/rings/all.py index 5cc1988c336..0ee0a7ee687 100644 --- a/src/sage/rings/all.py +++ b/src/sage/rings/all.py @@ -166,7 +166,7 @@ # asymptotic ring from sage.rings.asymptotic.all import * -lazy_import('sage.rings.burnside', ['BurnsideRing']) +lazy_import('sage.rings.burnside', ['BurnsideRing', 'ConjugacyClassesOfSubgroups']) # Register classes in numbers abc from sage.rings import numbers_abc diff --git a/src/sage/rings/burnside.py b/src/sage/rings/burnside.py index e80e7d3b8be..d80e0959e23 100644 --- a/src/sage/rings/burnside.py +++ b/src/sage/rings/burnside.py @@ -5,7 +5,7 @@ from sage.structure.element import Element from sage.rings.integer_ring import ZZ from sage.structure.formal_sum import FormalSum -from sage.categories.sets_cat import cartesian_product +from sage.categories.sets_cat import cartesian_product, Sets from sage.groups.perm_gps.permgroup import PermutationGroup from sage.libs.gap.libgap import libgap from sage.misc.repr import repr_lincomb @@ -14,6 +14,49 @@ def _is_conjugate(G, H1, H2): return libgap.eval('fail') != libgap.RepresentativeAction(G, H1, H2) +class ConjugacyClassOfSubgroups(Element): + def __init__(self, parent, C): + Element.__init__(self, parent) + self._C = C + + def __hash__(self): + return hash(self._C) + + def _repr_(self): + return repr(self._C.gens()) + + def __le__(self, other): + return libgap.eval('fail') != libgap.ContainedConjugates(self.parent()._G, other._C, self._C, True) + +class ConjugacyClassesOfSubgroups(Parent): + def __init__(self, G): + self._G = G + self._cache = dict() # invariant to subgroups + Parent.__init__(self, category=Sets().Finite()) + + def _group_invariant(self, H): + return H.order() + + def _element_constructor_(self, x=None): + def normalize(H): + p = self._group_invariant(H) + if p in self._cache: + for H0 in self._cache[p]: + if _is_conjugate(self._G, H, H0): + return H0 + else: + self._cache[p].append(H) + else: + self._cache[p] = [H] + return H + + return self.element_class(self, normalize(x)) + + def __iter__(self): + return iter(self(H) for H in self._G.conjugacy_classes_subgroups()) + + Element = ConjugacyClassOfSubgroups + class BurnsideRingElement(Element): def __init__(self, parent, F): r""" @@ -131,7 +174,6 @@ def _add_(self, right): F = self._F + right._F return P.element_class(P, F) - class BurnsideRing(UniqueRepresentation, Parent): def __init__(self, G, base_ring=ZZ): """ From 3d2a73059aaba955b18f694158d3faecd2d2957b Mon Sep 17 00:00:00 2001 From: Newtech66 Date: Fri, 17 May 2024 03:21:30 +0530 Subject: [PATCH 008/537] Burnside ring now inherits from CombinatorialFreeModule Also some fixes to _element_constructor_ ConjugacyClassesOfSubgroups --- src/sage/rings/burnside.py | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/sage/rings/burnside.py b/src/sage/rings/burnside.py index d80e0959e23..cdb49e3e052 100644 --- a/src/sage/rings/burnside.py +++ b/src/sage/rings/burnside.py @@ -10,6 +10,7 @@ from sage.libs.gap.libgap import libgap from sage.misc.repr import repr_lincomb from sage.categories.algebras import Algebras +from sage.combinat.free_module import CombinatorialFreeModule def _is_conjugate(G, H1, H2): return libgap.eval('fail') != libgap.RepresentativeAction(G, H1, H2) @@ -37,7 +38,7 @@ def __init__(self, G): def _group_invariant(self, H): return H.order() - def _element_constructor_(self, x=None): + def _element_constructor_(self, x): def normalize(H): p = self._group_invariant(H) if p in self._cache: @@ -50,7 +51,12 @@ def normalize(H): self._cache[p] = [H] return H - return self.element_class(self, normalize(x)) + if x.is_subgroup(self._G): + return self.element_class(self, normalize(x)) + else: + raise ValueError("x must be a subgroup of " + repr(self._G)) + + raise ValueError(f"unable to convert {x} into {self}") def __iter__(self): return iter(self(H) for H in self._G.conjugacy_classes_subgroups()) @@ -174,7 +180,7 @@ def _add_(self, right): F = self._F + right._F return P.element_class(P, F) -class BurnsideRing(UniqueRepresentation, Parent): +class BurnsideRing(CombinatorialFreeModule): def __init__(self, G, base_ring=ZZ): """ sage: G = SymmetricGroup(4) @@ -183,8 +189,11 @@ def __init__(self, G, base_ring=ZZ): """ self._G = G self._cache = dict() # invariant to a list of pairs (name, subgroup) + basis = ConjugacyClassesOfSubgroups(G) category = Algebras(base_ring).Commutative() - Parent.__init__(self, base=base_ring, category=category) + CombinatorialFreeModule.__init__(self, base_ring, basis, + element_class=BurnsideRingElement, + category=category) def _group_invariant(self, H): return H.order() From d49eb76aa1057b25ed0357d10d7662036a1ec246 Mon Sep 17 00:00:00 2001 From: Newtech66 Date: Fri, 17 May 2024 04:03:33 +0530 Subject: [PATCH 009/537] Changed category of Burnside ring to Algebras(base_ring).Commutative().WithBasis() --- src/sage/rings/burnside.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/rings/burnside.py b/src/sage/rings/burnside.py index cdb49e3e052..f329bd3e29f 100644 --- a/src/sage/rings/burnside.py +++ b/src/sage/rings/burnside.py @@ -190,7 +190,7 @@ def __init__(self, G, base_ring=ZZ): self._G = G self._cache = dict() # invariant to a list of pairs (name, subgroup) basis = ConjugacyClassesOfSubgroups(G) - category = Algebras(base_ring).Commutative() + category = Algebras(base_ring).Commutative().WithBasis() CombinatorialFreeModule.__init__(self, base_ring, basis, element_class=BurnsideRingElement, category=category) From bf76e0d930fa50594b20466cdf0025ac8c132922 Mon Sep 17 00:00:00 2001 From: Newtech66 Date: Sat, 18 May 2024 00:52:44 +0530 Subject: [PATCH 010/537] Implemented monomial() and one_basis() Added _repr_ for ConjugacyClassesOfSubgroups I now output B[(gens or name if available)] as _repr_ for generators, for example B[1] + 2*B[(2,3,4)] --- src/sage/rings/burnside.py | 78 +++++++++++++++++++++++--------------- 1 file changed, 47 insertions(+), 31 deletions(-) diff --git a/src/sage/rings/burnside.py b/src/sage/rings/burnside.py index f329bd3e29f..418da50e506 100644 --- a/src/sage/rings/burnside.py +++ b/src/sage/rings/burnside.py @@ -38,21 +38,21 @@ def __init__(self, G): def _group_invariant(self, H): return H.order() - def _element_constructor_(self, x): - def normalize(H): - p = self._group_invariant(H) - if p in self._cache: - for H0 in self._cache[p]: - if _is_conjugate(self._G, H, H0): - return H0 - else: - self._cache[p].append(H) + def _normalize(self, H): + p = self._group_invariant(H) + if p in self._cache: + for H0 in self._cache[p]: + if _is_conjugate(self._G, H, H0): + return H0 else: - self._cache[p] = [H] - return H + self._cache[p].append(H) + else: + self._cache[p] = [H] + return H + def _element_constructor_(self, x): if x.is_subgroup(self._G): - return self.element_class(self, normalize(x)) + return self.element_class(self, self._normalize(x)) else: raise ValueError("x must be a subgroup of " + repr(self._G)) @@ -61,6 +61,12 @@ def normalize(H): def __iter__(self): return iter(self(H) for H in self._G.conjugacy_classes_subgroups()) + def _repr_(self): + r""" + Return a string representation of ``self``. + """ + return "Conjugacy classes of subgroups of " + repr(self._G) + Element = ConjugacyClassOfSubgroups class BurnsideRingElement(Element): @@ -92,7 +98,7 @@ def _repr_(self): r""" Return a string representation of ``self``. """ - return repr_lincomb(([(H.gens() if name is None else name, c) + return repr_lincomb(([(f"B[{H.gens()}]" if name is None else f"B[{name}]", c) for c, (name, H) in self._F]), repr_monomial=lambda s: s if isinstance(s, str) else repr(list(s))) @@ -198,6 +204,19 @@ def __init__(self, G, base_ring=ZZ): def _group_invariant(self, H): return H.order() + def _normalize(self, H, name=None): + p = self._group_invariant(H) + if p in self._cache: + for name0, H0 in self._cache[p]: + if _is_conjugate(self._G, H, H0): + assert name is None or name0 == name, "the name should not change" + return name0, H0 + else: + self._cache[p].append((name, H)) + else: + self._cache[p] = [(name, H)] + return name, H + def _coerce_map_from_(self, S): """ Return ``True`` if a coercion from ``S`` exists. @@ -259,19 +278,6 @@ def _element_constructor_(self, x=None, action=None, domain=None, name=None): if action is None and domain is None and x in self.base_ring(): return x * self.one() - def normalize(H, name=None): - p = self._group_invariant(H) - if p in self._cache: - for name0, H0 in self._cache[p]: - if _is_conjugate(self._G, H, H0): - assert name is None or name0 == name, "the name should not change" - return name0, H0 - else: - self._cache[p].append((name, H)) - else: - self._cache[p] = [(name, H)] - return name, H - def find_stabilizer(action, pnt): stabilizer = [] for g in self._G: @@ -292,7 +298,7 @@ def find_stabilizer(action, pnt): stabilizer_list = [find_stabilizer(action, orbit[0]) for orbit in orbit_list] # normalize each summand and collect terms from collections import Counter - C = Counter([normalize(stabilizer) for stabilizer in stabilizer_list]) + C = Counter([self._normalize(stabilizer) for stabilizer in stabilizer_list]) # create formal sum F = FormalSum([(coeff, subgroup) for subgroup, coeff in C.items()]) return self.element_class(self, F) @@ -306,16 +312,26 @@ def find_stabilizer(action, pnt): # if x is a list of pairs (coeff, subgroup) or FormalSum if not all([subgroup.is_subgroup(self._G) for coeff, subgroup in x]): raise ValueError("All groups in list must be subgroups of " + repr(self._G)) - return self.element_class(self, FormalSum([(coeff, normalize(subgroup)) for coeff, subgroup in x])) + return self.element_class(self, FormalSum([(coeff, self._normalize(subgroup)) for coeff, subgroup in x])) elif x.is_subgroup(self._G): # if x is a single subgroup of self._G - return self.element_class(self, FormalSum([(1, normalize(x, name))])) + return self.element_class(self, FormalSum([(1, self._normalize(x, name))])) raise ValueError(f"unable to convert {x} into {self}") + def monomial(self, subgroup_gens): + r""" + Return the basis element indexed by `subgroup_gens`. + """ + return self.element_class(self, FormalSum([(1, self._normalize(PermutationGroup(subgroup_gens)))])) + @cached_method - def one(self): - return self._element_constructor_(self._G, name="1") + def one_basis(self): + r""" + Returns the generators of the underlying group, which index the one + of this algebra, as per :meth:`AlgebrasWithBasis.ParentMethods.one_basis`. + """ + return self._G.gens() @cached_method def zero(self): From dc1d95d11b5bc1bcbef7027de89f52438675ed26 Mon Sep 17 00:00:00 2001 From: Newtech66 Date: Sat, 18 May 2024 01:03:59 +0530 Subject: [PATCH 011/537] Add rename_gen --- src/sage/rings/burnside.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/sage/rings/burnside.py b/src/sage/rings/burnside.py index 418da50e506..afec4fd186d 100644 --- a/src/sage/rings/burnside.py +++ b/src/sage/rings/burnside.py @@ -195,6 +195,7 @@ def __init__(self, G, base_ring=ZZ): """ self._G = G self._cache = dict() # invariant to a list of pairs (name, subgroup) + self.rename_gen(G, "1") # name unit of ring as 1 basis = ConjugacyClassesOfSubgroups(G) category = Algebras(base_ring).Commutative().WithBasis() CombinatorialFreeModule.__init__(self, base_ring, basis, @@ -319,6 +320,15 @@ def find_stabilizer(action, pnt): raise ValueError(f"unable to convert {x} into {self}") + def rename_gen(self, subgroup, name): + r""" + Rename conjugacy class of ``subgroup`` to ``name``. + Passing ``None`` to ``name`` will remove any previously assigned name. + """ + if not isinstance(name, str): + raise TypeError("name must be a string") + self._normalize(subgroup, name) + def monomial(self, subgroup_gens): r""" Return the basis element indexed by `subgroup_gens`. From c271e60d59759681c4cecc929dd3d2d8dfb8732b Mon Sep 17 00:00:00 2001 From: Newtech66 Date: Sat, 18 May 2024 01:15:26 +0530 Subject: [PATCH 012/537] Add construct_from_action --- src/sage/rings/burnside.py | 76 +++++++++++++++++++------------------- 1 file changed, 38 insertions(+), 38 deletions(-) diff --git a/src/sage/rings/burnside.py b/src/sage/rings/burnside.py index afec4fd186d..a6ab34505da 100644 --- a/src/sage/rings/burnside.py +++ b/src/sage/rings/burnside.py @@ -232,18 +232,39 @@ def _an_element_(self): Element = BurnsideRingElement - def _element_constructor_(self, x=None, action=None, domain=None, name=None): + def _element_constructor_(self, x): r""" - Construct an element of the Burnside ring. + Construct an element of the Burnside ring explicitly. INPUT: - ``x`` - data for an element - - ``action`` - an action on ``domain`` - - ``domain`` - a finite set ``x`` can be a subgroup of `G` or a formal sum of such subgroups. + """ + if x in self.base_ring(): + return x * self.one() + + if isinstance(x, list) or isinstance(x, FormalSum): + # if x is a list of pairs (coeff, subgroup) or FormalSum + if not all([subgroup.is_subgroup(self._G) for coeff, subgroup in x]): + raise ValueError("All groups in list must be subgroups of " + repr(self._G)) + return self.element_class(self, FormalSum([(coeff, self._normalize(subgroup)) for coeff, subgroup in x])) + elif x.is_subgroup(self._G): + # if x is a single subgroup of self._G + return self.element_class(self, FormalSum([(1, self._normalize(x))])) + + raise ValueError(f"unable to convert {x} into {self}") + + def construct_from_action(self, action, domain): + r""" + Construct an element of the Burnside ring from a group action. + + INPUT: + + - ``action`` - an action on ``domain`` + - ``domain`` - a finite set EXAMPLES: @@ -257,6 +278,8 @@ def _element_constructor_(self, x=None, action=None, domain=None, name=None): sage: B(domain=X, action=a) [(3,4), (1,2), (1,2)(3,4)] + Next, we create a group action of `S_4` on itself via conjugation:: + sage: X = G sage: a = lambda g, x: g*x*g.inverse() sage: B(domain=X, action=a) @@ -276,9 +299,6 @@ def _element_constructor_(self, x=None, action=None, domain=None, name=None): sage: B(-3) -3*1 """ - if action is None and domain is None and x in self.base_ring(): - return x * self.one() - def find_stabilizer(action, pnt): stabilizer = [] for g in self._G: @@ -288,37 +308,17 @@ def find_stabilizer(action, pnt): gens = H.gens_small() return self._G.subgroup(gens) - # given a group action - if action is not None and domain is not None: - assert name is None - H = PermutationGroup(self._G.gens(), action=action, domain=domain) - # decompose H into a sum F of conjugacy classes - orbit_list = H.orbits() - # find the stabilizer subgroups - # TODO: find a way to do this with GAP instead - stabilizer_list = [find_stabilizer(action, orbit[0]) for orbit in orbit_list] - # normalize each summand and collect terms - from collections import Counter - C = Counter([self._normalize(stabilizer) for stabilizer in stabilizer_list]) - # create formal sum - F = FormalSum([(coeff, subgroup) for subgroup, coeff in C.items()]) - return self.element_class(self, F) - elif action is not None and domain is None: - raise ValueError("If action is provided then domain must be provided") - elif action is None and domain is not None: - raise ValueError("If domain is provided then action must be provided") - - if isinstance(x, list) or isinstance(x, FormalSum): - assert name is None - # if x is a list of pairs (coeff, subgroup) or FormalSum - if not all([subgroup.is_subgroup(self._G) for coeff, subgroup in x]): - raise ValueError("All groups in list must be subgroups of " + repr(self._G)) - return self.element_class(self, FormalSum([(coeff, self._normalize(subgroup)) for coeff, subgroup in x])) - elif x.is_subgroup(self._G): - # if x is a single subgroup of self._G - return self.element_class(self, FormalSum([(1, self._normalize(x, name))])) - - raise ValueError(f"unable to convert {x} into {self}") + H = PermutationGroup(self._G.gens(), action=action, domain=domain) + # decompose H into orbits + orbit_list = H.orbits() + # find the stabilizer subgroups + stabilizer_list = [find_stabilizer(action, orbit[0]) for orbit in orbit_list] + # normalize each summand and collect terms + from collections import Counter + C = Counter([self._normalize(stabilizer) for stabilizer in stabilizer_list]) + # create formal sum + F = FormalSum([(coeff, subgroup) for subgroup, coeff in C.items()]) + return self.element_class(self, F) def rename_gen(self, subgroup, name): r""" From 1453c90c8ce19096251698b999b700dce38a3529 Mon Sep 17 00:00:00 2001 From: Newtech66 Date: Sat, 18 May 2024 01:54:41 +0530 Subject: [PATCH 013/537] Add _from_dict --- src/sage/rings/burnside.py | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/sage/rings/burnside.py b/src/sage/rings/burnside.py index a6ab34505da..6363fec5f86 100644 --- a/src/sage/rings/burnside.py +++ b/src/sage/rings/burnside.py @@ -257,6 +257,32 @@ def _element_constructor_(self, x): raise ValueError(f"unable to convert {x} into {self}") + def _from_dict(self, d, coerce=False, remove_zeros=True): + r""" + Construct an element of "self" from an "{index: coefficient}" + dictionary. + + INPUT: + + * "d" -- a dictionary "{index: coeff}" where each "index" is the + index of a basis element and each "coeff" belongs to the + coefficient ring "self.base_ring()" + + * "coerce" -- a boolean (default: "False"), whether to coerce the + coefficients "coeff" to the coefficient ring + + * "remove_zeros" -- a boolean (default: "True"), if some + coefficients "coeff" may be zero and should therefore be removed + """ + assert isinstance(d, dict) + if coerce: + R = self.base_ring() + d = {key: R(coeff) for key, coeff in d.items()} + if remove_zeros: + d = {key: coeff for key, coeff in d.items() if coeff} + l = [(coeff, PermutationGroup(gens)) for gens, coeff in d.items()] + return self._element_constructor_(l) + def construct_from_action(self, action, domain): r""" Construct an element of the Burnside ring from a group action. From fa8b9f5e881def165c3738eed33d214025f0b335 Mon Sep 17 00:00:00 2001 From: Newtech66 Date: Sat, 18 May 2024 11:29:47 +0530 Subject: [PATCH 014/537] Add product_on_basis and monomial_coefficients --- src/sage/rings/burnside.py | 112 ++++++++++++++++++------------------- 1 file changed, 56 insertions(+), 56 deletions(-) diff --git a/src/sage/rings/burnside.py b/src/sage/rings/burnside.py index 6363fec5f86..160cf2436b6 100644 --- a/src/sage/rings/burnside.py +++ b/src/sage/rings/burnside.py @@ -93,13 +93,14 @@ def __init__(self, parent, F): """ Element.__init__(self, parent) self._F = F + self._monomial_coefficients = {parent._indices(H): c for c, H in self._F} def _repr_(self): r""" Return a string representation of ``self``. """ - return repr_lincomb(([(f"B[{H.gens()}]" if name is None else f"B[{name}]", c) - for c, (name, H) in self._F]), + return repr_lincomb(([(f"B[{H.gens()}]" if self.parent()._names[H] is None else f"B[{self.parent()._names[H]}]", c) + for c, H in self._F]), repr_monomial=lambda s: s if isinstance(s, str) else repr(list(s))) def _richcmp_(self, other, op): @@ -138,46 +139,6 @@ def _acted_upon_(self, scalar, self_on_left): F = scalar * self._F return B.element_class(B, F) - def _mul_(self, right): - r""" - Return the product of ``self`` and ``right``. - - For the symmetric group, this is also known as the Hadamard - or tensor product of group actions. - - EXAMPLES:: - - sage: G = SymmetricGroup(3) - sage: B = BurnsideRing(G) - sage: matrix([[b * c for b in B.gens()] for c in B.gens()]) - [ 6*[()] 3*[()] 2*[()] [()]] - [ 3*[()] [(2,3)] + [()] [()] [(2,3)]] - [ 2*[()] [()] 2*[(1,2,3)] [(1,2,3)]] - [ [()] [(2,3)] [(1,2,3)] 1] - """ - #TODO: Find faster way to multiply - assert right.parent() == self.parent() - B = self.parent() - G = B._G - - def mul(H1, H2): - dom1 = [frozenset(g) for g in G.cosets(H1, side="left")] - dom2 = [frozenset(g) for g in G.cosets(H2, side="left")] - domain = cartesian_product([dom1, dom2]) - - def action(g, pair): - return (frozenset(g * h for h in pair[0]), - frozenset(g * h for h in pair[1])) - - return B(action=action, domain=domain)._F - - result = FormalSum(0) - for c1, (_, g1) in self._F: - for c2, (_, g2) in right._F: - result += c1 * c2 * mul(g1, g2) - - return B.element_class(B, result) - def _add_(self, right): r""" Return the sum of ``self`` and ``right``. @@ -186,6 +147,11 @@ def _add_(self, right): F = self._F + right._F return P.element_class(P, F) + def monomial_coefficients(self, copy=True): + if copy: + return dict(self._monomial_coefficients) + return self._monomial_coefficients + class BurnsideRing(CombinatorialFreeModule): def __init__(self, G, base_ring=ZZ): """ @@ -194,7 +160,8 @@ def __init__(self, G, base_ring=ZZ): sage: TestSuite(B).run() """ self._G = G - self._cache = dict() # invariant to a list of pairs (name, subgroup) + self._cache = dict() # invariant to subgroups + self._names = dict() # dictionary mapping subgroups to names self.rename_gen(G, "1") # name unit of ring as 1 basis = ConjugacyClassesOfSubgroups(G) category = Algebras(base_ring).Commutative().WithBasis() @@ -206,17 +173,20 @@ def _group_invariant(self, H): return H.order() def _normalize(self, H, name=None): + if name is not None: + self._names[H] = name + elif H not in self._names: + self._names[H] = None p = self._group_invariant(H) if p in self._cache: - for name0, H0 in self._cache[p]: + for H0 in self._cache[p]: if _is_conjugate(self._G, H, H0): - assert name is None or name0 == name, "the name should not change" - return name0, H0 + return H0 else: - self._cache[p].append((name, H)) + self._cache[p].append(H) else: - self._cache[p] = [(name, H)] - return name, H + self._cache[p] = [H] + return H def _coerce_map_from_(self, S): """ @@ -277,10 +247,10 @@ def _from_dict(self, d, coerce=False, remove_zeros=True): assert isinstance(d, dict) if coerce: R = self.base_ring() - d = {key: R(coeff) for key, coeff in d.items()} + d = {H._C: R(coeff) for H, coeff in d.items()} if remove_zeros: - d = {key: coeff for key, coeff in d.items() if coeff} - l = [(coeff, PermutationGroup(gens)) for gens, coeff in d.items()] + d = {H._C: coeff for H, coeff in d.items() if coeff} + l = [(coeff, H._C) for H, coeff in d.items()] return self._element_constructor_(l) def construct_from_action(self, action, domain): @@ -355,11 +325,11 @@ def rename_gen(self, subgroup, name): raise TypeError("name must be a string") self._normalize(subgroup, name) - def monomial(self, subgroup_gens): + def monomial(self, H): r""" - Return the basis element indexed by `subgroup_gens`. + Return the basis element indexed by `H`. """ - return self.element_class(self, FormalSum([(1, self._normalize(PermutationGroup(subgroup_gens)))])) + return self.element_class(self, FormalSum([(1, self._normalize(H))])) @cached_method def one_basis(self): @@ -367,7 +337,7 @@ def one_basis(self): Returns the generators of the underlying group, which index the one of this algebra, as per :meth:`AlgebrasWithBasis.ParentMethods.one_basis`. """ - return self._G.gens() + return self._indices(G) @cached_method def zero(self): @@ -381,6 +351,36 @@ def zero(self): """ return self.element_class(self, FormalSum([])) + def product_on_basis(self, g1, g2): + r""" + Return the product of ``g1`` and ``g2``. + + For the symmetric group, this is also known as the Hadamard + or tensor product of group actions. + + EXAMPLES:: + + sage: G = SymmetricGroup(3) + sage: B = BurnsideRing(G) + sage: matrix([[b * c for b in B.gens()] for c in B.gens()]) + [ 6*B[((),)] 3*B[((),)] 2*B[((),)] B[((),)]] + [ 3*B[((),)] B[((1,2),)] + B[((),)] B[((),)] B[((1,2),)]] + [ 2*B[((),)] B[((),)] 2*B[((1,2,3),)] B[((1,2,3),)]] + [ B[((),)] B[((1,2),)] B[((1,2,3),)] B[1]] + """ + #TODO: Find faster way to multiply + assert g1.parent() == g2.parent() + G = g1.parent()._G + dom1 = [frozenset(g) for g in G.cosets(g1._C, side="left")] + dom2 = [frozenset(g) for g in G.cosets(g2._C, side="left")] + domain = cartesian_product([dom1, dom2]) + + def action(g, pair): + return (frozenset(g * h for h in pair[0]), + frozenset(g * h for h in pair[1])) + + return self.construct_from_action(action, domain) + def group(self): r""" Return the underlying group. From be11997d1851abcb720d0f31e2eaa2a0f34a45b8 Mon Sep 17 00:00:00 2001 From: Newtech66 Date: Sat, 18 May 2024 11:30:31 +0530 Subject: [PATCH 015/537] Remove ConjugacyClassesOfSubgroups from import --- src/sage/rings/all.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/rings/all.py b/src/sage/rings/all.py index 0ee0a7ee687..5cc1988c336 100644 --- a/src/sage/rings/all.py +++ b/src/sage/rings/all.py @@ -166,7 +166,7 @@ # asymptotic ring from sage.rings.asymptotic.all import * -lazy_import('sage.rings.burnside', ['BurnsideRing', 'ConjugacyClassesOfSubgroups']) +lazy_import('sage.rings.burnside', ['BurnsideRing']) # Register classes in numbers abc from sage.rings import numbers_abc From f39807c5b73327ef1e265fc5bf3d085794774049 Mon Sep 17 00:00:00 2001 From: Newtech66 Date: Sat, 18 May 2024 13:16:22 +0530 Subject: [PATCH 016/537] Make indexes for generators use ConjugacyClassesOfSubgroups internally and doctest updates --- src/sage/rings/burnside.py | 67 ++++++++++++++++++++------------------ 1 file changed, 35 insertions(+), 32 deletions(-) diff --git a/src/sage/rings/burnside.py b/src/sage/rings/burnside.py index 160cf2436b6..a29ef9f5582 100644 --- a/src/sage/rings/burnside.py +++ b/src/sage/rings/burnside.py @@ -84,22 +84,22 @@ def __init__(self, parent, F): sage: G = SymmetricGroup(4) sage: B = BurnsideRing(G) sage: B(G) - 1 + B[1] sage: X = Subsets(4, 2) sage: a = lambda g, x: X([g(e) for e in x]) - sage: B(domain=X, action=a) - [(3,4), (1,2), (1,2)(3,4)] + sage: B.construct_from_action(a, X) + B[((3,4), (1,2), (1,2)(3,4))] """ Element.__init__(self, parent) self._F = F - self._monomial_coefficients = {parent._indices(H): c for c, H in self._F} + self._monomial_coefficients = {H: c for c, H in self._F} def _repr_(self): r""" Return a string representation of ``self``. """ - return repr_lincomb(([(f"B[{H.gens()}]" if self.parent()._names[H] is None else f"B[{self.parent()._names[H]}]", c) + return repr_lincomb(([(f"B[{H._C.gens()}]" if self.parent()._names[H] is None else f"B[{self.parent()._names[H]}]", c) for c, H in self._F]), repr_monomial=lambda s: s if isinstance(s, str) else repr(list(s))) @@ -131,9 +131,9 @@ def _acted_upon_(self, scalar, self_on_left): sage: B = BurnsideRing(G) sage: b = B(G) sage: b - 1 + B[1] sage: 2*b - 2*1 + 2*B[1] """ B = self.parent() F = scalar * self._F @@ -162,15 +162,15 @@ def __init__(self, G, base_ring=ZZ): self._G = G self._cache = dict() # invariant to subgroups self._names = dict() # dictionary mapping subgroups to names - self.rename_gen(G, "1") # name unit of ring as 1 basis = ConjugacyClassesOfSubgroups(G) category = Algebras(base_ring).Commutative().WithBasis() CombinatorialFreeModule.__init__(self, base_ring, basis, element_class=BurnsideRingElement, category=category) + self.rename_gen(G, "1") # name unit of ring as 1 def _group_invariant(self, H): - return H.order() + return H._C.order() def _normalize(self, H, name=None): if name is not None: @@ -180,7 +180,7 @@ def _normalize(self, H, name=None): p = self._group_invariant(H) if p in self._cache: for H0 in self._cache[p]: - if _is_conjugate(self._G, H, H0): + if _is_conjugate(self._G, H._C, H0._C): return H0 else: self._cache[p].append(H) @@ -218,12 +218,15 @@ def _element_constructor_(self, x): if isinstance(x, list) or isinstance(x, FormalSum): # if x is a list of pairs (coeff, subgroup) or FormalSum - if not all([subgroup.is_subgroup(self._G) for coeff, subgroup in x]): + # Turn all subgroups into elements of ConjugacyClassesOfSubgroups + x = [(coeff, self._indices(subgroup)) for coeff, subgroup in x] + #Check if all terms are actually subgroups of G + if not all([subgroup._C.is_subgroup(self._G) for coeff, subgroup in x]): raise ValueError("All groups in list must be subgroups of " + repr(self._G)) return self.element_class(self, FormalSum([(coeff, self._normalize(subgroup)) for coeff, subgroup in x])) - elif x.is_subgroup(self._G): + elif self._indices(x)._C.is_subgroup(self._G): # if x is a single subgroup of self._G - return self.element_class(self, FormalSum([(1, self._normalize(x))])) + return self.element_class(self, FormalSum([(1, self._normalize(self._indices(x)))])) raise ValueError(f"unable to convert {x} into {self}") @@ -247,10 +250,10 @@ def _from_dict(self, d, coerce=False, remove_zeros=True): assert isinstance(d, dict) if coerce: R = self.base_ring() - d = {H._C: R(coeff) for H, coeff in d.items()} + d = {H: R(coeff) for H, coeff in d.items()} if remove_zeros: - d = {H._C: coeff for H, coeff in d.items() if coeff} - l = [(coeff, H._C) for H, coeff in d.items()] + d = {H: coeff for H, coeff in d.items() if coeff} + l = [(coeff, H) for H, coeff in d.items()] return self._element_constructor_(l) def construct_from_action(self, action, domain): @@ -271,21 +274,21 @@ def construct_from_action(self, action, domain): sage: X = Subsets(4, 2) sage: a = lambda g, x: X([g(e) for e in x]) - sage: B(domain=X, action=a) - [(3,4), (1,2), (1,2)(3,4)] + sage: B.construct_from_action(a, X) + B[((3,4), (1,2), (1,2)(3,4))] Next, we create a group action of `S_4` on itself via conjugation:: sage: X = G sage: a = lambda g, x: g*x*g.inverse() - sage: B(domain=X, action=a) - 1 + [(2,4), (1,4)(2,3)] + [(2,3,4)] + [(3,4), (1,2), (1,2)(3,4)] + [(1,3,2,4)] + sage: B.construct_from_action(a, X) + B[1] + B[((2,4), (1,4)(2,3))] + B[((2,3,4),)] + B[((3,4), (1,2), (1,2)(3,4))] + B[((1,3,2,4),)] TESTS:: sage: G = SymmetricGroup(4) sage: B = BurnsideRing(G) - sage: [H._F[0][1][1].order() for H in B.gens()] + sage: [H._F[0][1]._C.order() for H in B.gens()] [1, 2, 2, 3, 4, 4, 4, 6, 8, 12, 24] sage: sorted((o, len(l)) for o, l in B._cache.items()) [(1, 1), (2, 2), (3, 1), (4, 3), (6, 1), (8, 1), (12, 1), (24, 1)] @@ -293,7 +296,7 @@ def construct_from_action(self, action, domain): sage: G = SymmetricGroup(4) sage: B = BurnsideRing(G) sage: B(-3) - -3*1 + -3*B[1] """ def find_stabilizer(action, pnt): stabilizer = [] @@ -311,7 +314,7 @@ def find_stabilizer(action, pnt): stabilizer_list = [find_stabilizer(action, orbit[0]) for orbit in orbit_list] # normalize each summand and collect terms from collections import Counter - C = Counter([self._normalize(stabilizer) for stabilizer in stabilizer_list]) + C = Counter([self._normalize(self._indices(stabilizer)) for stabilizer in stabilizer_list]) # create formal sum F = FormalSum([(coeff, subgroup) for subgroup, coeff in C.items()]) return self.element_class(self, F) @@ -323,21 +326,21 @@ def rename_gen(self, subgroup, name): """ if not isinstance(name, str): raise TypeError("name must be a string") - self._normalize(subgroup, name) + self._normalize(self._indices(subgroup), name) def monomial(self, H): r""" Return the basis element indexed by `H`. """ - return self.element_class(self, FormalSum([(1, self._normalize(H))])) + return self(H) @cached_method def one_basis(self): r""" - Returns the generators of the underlying group, which index the one - of this algebra, as per :meth:`AlgebrasWithBasis.ParentMethods.one_basis`. + Returns the underlying group, which indexes the one of this algebra, + as per :meth:`AlgebrasWithBasis.ParentMethods.one_basis`. """ - return self._indices(G) + return self._indices(self._G) @cached_method def zero(self): @@ -353,7 +356,7 @@ def zero(self): def product_on_basis(self, g1, g2): r""" - Return the product of ``g1`` and ``g2``. + Return the product of the basis elements indexed by ``g1`` and ``g2``. For the symmetric group, this is also known as the Hadamard or tensor product of group actions. @@ -364,9 +367,9 @@ def product_on_basis(self, g1, g2): sage: B = BurnsideRing(G) sage: matrix([[b * c for b in B.gens()] for c in B.gens()]) [ 6*B[((),)] 3*B[((),)] 2*B[((),)] B[((),)]] - [ 3*B[((),)] B[((1,2),)] + B[((),)] B[((),)] B[((1,2),)]] + [ 3*B[((),)] B[((2,3),)] + B[((),)] B[((),)] B[((2,3),)]] [ 2*B[((),)] B[((),)] 2*B[((1,2,3),)] B[((1,2,3),)]] - [ B[((),)] B[((1,2),)] B[((1,2,3),)] B[1]] + [ B[((),)] B[((2,3),)] B[((1,2,3),)] B[1]] """ #TODO: Find faster way to multiply assert g1.parent() == g2.parent() @@ -407,7 +410,7 @@ def gens(self): sage: G = SymmetricGroup(3) sage: B = BurnsideRing(G) sage: B.gens() - ([()], [(2,3)], [(1,2,3)], 1) + (B[((),)], B[((2,3),)], B[((1,2,3),)], B[1]) """ return tuple(self(H) for H in self._G.conjugacy_classes_subgroups()) From d4af3fc34fae6b088af286595ca04fd4fcf16bc8 Mon Sep 17 00:00:00 2001 From: Newtech66 Date: Sat, 18 May 2024 13:49:50 +0530 Subject: [PATCH 017/537] Add __eq__ for ConjugacyClassOfSubgroups so we can use it as dict key --- src/sage/rings/burnside.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/sage/rings/burnside.py b/src/sage/rings/burnside.py index a29ef9f5582..7b886548873 100644 --- a/src/sage/rings/burnside.py +++ b/src/sage/rings/burnside.py @@ -29,6 +29,9 @@ def _repr_(self): def __le__(self, other): return libgap.eval('fail') != libgap.ContainedConjugates(self.parent()._G, other._C, self._C, True) + def __eq__(self, other): + return _is_conjugate(self.parent()._G, self._C, other._C) + class ConjugacyClassesOfSubgroups(Parent): def __init__(self, G): self._G = G @@ -99,8 +102,8 @@ def _repr_(self): r""" Return a string representation of ``self``. """ - return repr_lincomb(([(f"B[{H._C.gens()}]" if self.parent()._names[H] is None else f"B[{self.parent()._names[H]}]", c) - for c, H in self._F]), + return repr_lincomb(([(f"B[{H._C.gens()}]" if self.parent()._names[H] is None else + f"B[{self.parent()._names[H]}]", c) for c, H in self._F]), repr_monomial=lambda s: s if isinstance(s, str) else repr(list(s))) def _richcmp_(self, other, op): From de3ccbc687dd85fade7d14c22e729fc6309d9d5c Mon Sep 17 00:00:00 2001 From: Newtech66 Date: Mon, 20 May 2024 03:29:42 +0530 Subject: [PATCH 018/537] Removed BurnsideRingElement and refactored code --- src/sage/rings/burnside.py | 218 +++++-------------------------------- 1 file changed, 29 insertions(+), 189 deletions(-) diff --git a/src/sage/rings/burnside.py b/src/sage/rings/burnside.py index 7b886548873..a2546a4eb94 100644 --- a/src/sage/rings/burnside.py +++ b/src/sage/rings/burnside.py @@ -1,6 +1,5 @@ from sage.misc.cachefunc import cached_method from sage.structure.unique_representation import UniqueRepresentation -from sage.structure.richcmp import op_EQ, op_NE from sage.structure.parent import Parent from sage.structure.element import Element from sage.rings.integer_ring import ZZ @@ -8,7 +7,6 @@ from sage.categories.sets_cat import cartesian_product, Sets from sage.groups.perm_gps.permgroup import PermutationGroup from sage.libs.gap.libgap import libgap -from sage.misc.repr import repr_lincomb from sage.categories.algebras import Algebras from sage.combinat.free_module import CombinatorialFreeModule @@ -24,7 +22,11 @@ def __hash__(self): return hash(self._C) def _repr_(self): - return repr(self._C.gens()) + name = self.parent()._names.get(self._C, None) + if name is None: + return repr(self._C.gens()) + else: + return name def __le__(self, other): return libgap.eval('fail') != libgap.ContainedConjugates(self.parent()._G, other._C, self._C, True) @@ -36,12 +38,19 @@ class ConjugacyClassesOfSubgroups(Parent): def __init__(self, G): self._G = G self._cache = dict() # invariant to subgroups + self._names = dict() # dictionary mapping subgroups to names Parent.__init__(self, category=Sets().Finite()) def _group_invariant(self, H): return H.order() - def _normalize(self, H): + def _normalize(self, H, name=None): + if not H.is_subgroup(self._G): + raise ValueError(f"{H} is not a subgroup of {self._G}") + if name is not None: + self._names[H] = name + elif H not in self._names: + self._names[H] = None p = self._group_invariant(H) if p in self._cache: for H0 in self._cache[p]: @@ -61,6 +70,15 @@ def _element_constructor_(self, x): raise ValueError(f"unable to convert {x} into {self}") + def set_name(self, H, name): + r""" + Rename conjugacy class of ``H`` to ``name``. + Passing ``None`` to ``name`` will remove any previously assigned name. + """ + if not isinstance(name, str): + raise TypeError("name must be a string") + self._normalize(H, name) + def __iter__(self): return iter(self(H) for H in self._G.conjugacy_classes_subgroups()) @@ -72,89 +90,6 @@ def _repr_(self): Element = ConjugacyClassOfSubgroups -class BurnsideRingElement(Element): - def __init__(self, parent, F): - r""" - Initialize an element. - - INPUT: - - - ``F`` - a formal sum of representatives of conjugacy # - classes of subgroups - - EXAMPLES:: - - sage: G = SymmetricGroup(4) - sage: B = BurnsideRing(G) - sage: B(G) - B[1] - - sage: X = Subsets(4, 2) - sage: a = lambda g, x: X([g(e) for e in x]) - sage: B.construct_from_action(a, X) - B[((3,4), (1,2), (1,2)(3,4))] - """ - Element.__init__(self, parent) - self._F = F - self._monomial_coefficients = {H: c for c, H in self._F} - - def _repr_(self): - r""" - Return a string representation of ``self``. - """ - return repr_lincomb(([(f"B[{H._C.gens()}]" if self.parent()._names[H] is None else - f"B[{self.parent()._names[H]}]", c) for c, H in self._F]), - repr_monomial=lambda s: s if isinstance(s, str) else repr(list(s))) - - def _richcmp_(self, other, op): - """ - - sage: G = SymmetricGroup(4) - sage: B = BurnsideRing(G) - sage: B.zero() == 0 - True - """ - if op is op_EQ: - return not bool(self._F - other._F) - if op is op_NE: - return bool(self._F - other._F) - - def _acted_upon_(self, scalar, self_on_left): - r""" - Scalar multiplication for ``self`` by ``scalar``. - - INPUT: - - - ``scalar`` -- an element of the base ring - - ``self_on_left`` -- boolean; if ``True``, compute ``self * scalar`` - - EXAMPLES:: - - sage: G = SymmetricGroup(4) - sage: B = BurnsideRing(G) - sage: b = B(G) - sage: b - B[1] - sage: 2*b - 2*B[1] - """ - B = self.parent() - F = scalar * self._F - return B.element_class(B, F) - - def _add_(self, right): - r""" - Return the sum of ``self`` and ``right``. - """ - P = self.parent() - F = self._F + right._F - return P.element_class(P, F) - - def monomial_coefficients(self, copy=True): - if copy: - return dict(self._monomial_coefficients) - return self._monomial_coefficients - class BurnsideRing(CombinatorialFreeModule): def __init__(self, G, base_ring=ZZ): """ @@ -163,47 +98,10 @@ def __init__(self, G, base_ring=ZZ): sage: TestSuite(B).run() """ self._G = G - self._cache = dict() # invariant to subgroups - self._names = dict() # dictionary mapping subgroups to names basis = ConjugacyClassesOfSubgroups(G) + basis.set_name(G, "1") category = Algebras(base_ring).Commutative().WithBasis() - CombinatorialFreeModule.__init__(self, base_ring, basis, - element_class=BurnsideRingElement, - category=category) - self.rename_gen(G, "1") # name unit of ring as 1 - - def _group_invariant(self, H): - return H._C.order() - - def _normalize(self, H, name=None): - if name is not None: - self._names[H] = name - elif H not in self._names: - self._names[H] = None - p = self._group_invariant(H) - if p in self._cache: - for H0 in self._cache[p]: - if _is_conjugate(self._G, H._C, H0._C): - return H0 - else: - self._cache[p].append(H) - else: - self._cache[p] = [H] - return H - - def _coerce_map_from_(self, S): - """ - Return ``True`` if a coercion from ``S`` exists. - """ - if self.base_ring().has_coerce_map_from(S): - return True - return None - - @cached_method - def _an_element_(self): - return self.one() - - Element = BurnsideRingElement + CombinatorialFreeModule.__init__(self, base_ring, basis, category=category) def _element_constructor_(self, x): r""" @@ -222,43 +120,14 @@ def _element_constructor_(self, x): if isinstance(x, list) or isinstance(x, FormalSum): # if x is a list of pairs (coeff, subgroup) or FormalSum # Turn all subgroups into elements of ConjugacyClassesOfSubgroups - x = [(coeff, self._indices(subgroup)) for coeff, subgroup in x] - #Check if all terms are actually subgroups of G - if not all([subgroup._C.is_subgroup(self._G) for coeff, subgroup in x]): - raise ValueError("All groups in list must be subgroups of " + repr(self._G)) - return self.element_class(self, FormalSum([(coeff, self._normalize(subgroup)) for coeff, subgroup in x])) + x = [(self._indices(subgroup), coeff) for coeff, subgroup in x] + return self._from_dict(dict(x)) elif self._indices(x)._C.is_subgroup(self._G): # if x is a single subgroup of self._G - return self.element_class(self, FormalSum([(1, self._normalize(self._indices(x)))])) + return self._from_dict(dict([(self._indices(x), 1)])) raise ValueError(f"unable to convert {x} into {self}") - def _from_dict(self, d, coerce=False, remove_zeros=True): - r""" - Construct an element of "self" from an "{index: coefficient}" - dictionary. - - INPUT: - - * "d" -- a dictionary "{index: coeff}" where each "index" is the - index of a basis element and each "coeff" belongs to the - coefficient ring "self.base_ring()" - - * "coerce" -- a boolean (default: "False"), whether to coerce the - coefficients "coeff" to the coefficient ring - - * "remove_zeros" -- a boolean (default: "True"), if some - coefficients "coeff" may be zero and should therefore be removed - """ - assert isinstance(d, dict) - if coerce: - R = self.base_ring() - d = {H: R(coeff) for H, coeff in d.items()} - if remove_zeros: - d = {H: coeff for H, coeff in d.items() if coeff} - l = [(coeff, H) for H, coeff in d.items()] - return self._element_constructor_(l) - def construct_from_action(self, action, domain): r""" Construct an element of the Burnside ring from a group action. @@ -317,25 +186,8 @@ def find_stabilizer(action, pnt): stabilizer_list = [find_stabilizer(action, orbit[0]) for orbit in orbit_list] # normalize each summand and collect terms from collections import Counter - C = Counter([self._normalize(self._indices(stabilizer)) for stabilizer in stabilizer_list]) - # create formal sum - F = FormalSum([(coeff, subgroup) for subgroup, coeff in C.items()]) - return self.element_class(self, F) - - def rename_gen(self, subgroup, name): - r""" - Rename conjugacy class of ``subgroup`` to ``name``. - Passing ``None`` to ``name`` will remove any previously assigned name. - """ - if not isinstance(name, str): - raise TypeError("name must be a string") - self._normalize(self._indices(subgroup), name) - - def monomial(self, H): - r""" - Return the basis element indexed by `H`. - """ - return self(H) + C = Counter([self._indices(stabilizer) for stabilizer in stabilizer_list]) + return self._from_dict(dict(C)) @cached_method def one_basis(self): @@ -345,18 +197,6 @@ def one_basis(self): """ return self._indices(self._G) - @cached_method - def zero(self): - """ - EXAMPLES:: - - sage: G = SymmetricGroup(3) - sage: B = BurnsideRing(G) - sage: (0 * B.one()).is_zero() - True - """ - return self.element_class(self, FormalSum([])) - def product_on_basis(self, g1, g2): r""" Return the product of the basis elements indexed by ``g1`` and ``g2``. From d9e5aab54450ab68f3584a1eaf54acc136c0ad35 Mon Sep 17 00:00:00 2001 From: Newtech66 Date: Mon, 20 May 2024 03:56:05 +0530 Subject: [PATCH 019/537] Add __getitem__, minor doctest fix --- src/sage/rings/burnside.py | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/src/sage/rings/burnside.py b/src/sage/rings/burnside.py index a2546a4eb94..c57a0f5205b 100644 --- a/src/sage/rings/burnside.py +++ b/src/sage/rings/burnside.py @@ -31,9 +31,6 @@ def _repr_(self): def __le__(self, other): return libgap.eval('fail') != libgap.ContainedConjugates(self.parent()._G, other._C, self._C, True) - def __eq__(self, other): - return _is_conjugate(self.parent()._G, self._C, other._C) - class ConjugacyClassesOfSubgroups(Parent): def __init__(self, G): self._G = G @@ -122,12 +119,21 @@ def _element_constructor_(self, x): # Turn all subgroups into elements of ConjugacyClassesOfSubgroups x = [(self._indices(subgroup), coeff) for coeff, subgroup in x] return self._from_dict(dict(x)) - elif self._indices(x)._C.is_subgroup(self._G): + elif x.is_subgroup(self._G): # if x is a single subgroup of self._G - return self._from_dict(dict([(self._indices(x), 1)])) + return self._from_dict({self._indices(x): 1}) raise ValueError(f"unable to convert {x} into {self}") + def __getitem__(self, H): + r""" + Return the basis element indexed by ``H``. ``H`` must be a subgroup of ``self._G``. + """ + if H.is_subgroup(self._G): + return self._from_dict({self._indices(H): 1}) + else: + raise ValueError(f"{H} must be a subgroup of {self._G}") + def construct_from_action(self, action, domain): r""" Construct an element of the Burnside ring from a group action. @@ -160,9 +166,9 @@ def construct_from_action(self, action, domain): sage: G = SymmetricGroup(4) sage: B = BurnsideRing(G) - sage: [H._F[0][1]._C.order() for H in B.gens()] + sage: [list(b.monomial_coefficients().keys())[0]._C.order() for b in B.gens()] [1, 2, 2, 3, 4, 4, 4, 6, 8, 12, 24] - sage: sorted((o, len(l)) for o, l in B._cache.items()) + sage: sorted((o, len(l)) for o, l in B._indices._cache.items()) [(1, 1), (2, 2), (3, 1), (4, 3), (6, 1), (8, 1), (12, 1), (24, 1)] sage: G = SymmetricGroup(4) From 1a377f5310da9ca300eac9a2240d0e03dc7703dd Mon Sep 17 00:00:00 2001 From: Newtech66 Date: Mon, 20 May 2024 04:09:56 +0530 Subject: [PATCH 020/537] Add __eq__ and minor fix in _normalize and set_name --- src/sage/rings/burnside.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/sage/rings/burnside.py b/src/sage/rings/burnside.py index c57a0f5205b..e44e61d48e8 100644 --- a/src/sage/rings/burnside.py +++ b/src/sage/rings/burnside.py @@ -31,6 +31,9 @@ def _repr_(self): def __le__(self, other): return libgap.eval('fail') != libgap.ContainedConjugates(self.parent()._G, other._C, self._C, True) + def __eq__(self, other): + return _is_conjugate(self.parent()._G, self._C, other._C) + class ConjugacyClassesOfSubgroups(Parent): def __init__(self, G): self._G = G @@ -44,19 +47,18 @@ def _group_invariant(self, H): def _normalize(self, H, name=None): if not H.is_subgroup(self._G): raise ValueError(f"{H} is not a subgroup of {self._G}") - if name is not None: - self._names[H] = name - elif H not in self._names: - self._names[H] = None p = self._group_invariant(H) if p in self._cache: for H0 in self._cache[p]: if _is_conjugate(self._G, H, H0): + if name is not None: + self._names[H0] = name return H0 else: self._cache[p].append(H) else: self._cache[p] = [H] + self._names[H] = name return H def _element_constructor_(self, x): @@ -74,7 +76,8 @@ def set_name(self, H, name): """ if not isinstance(name, str): raise TypeError("name must be a string") - self._normalize(H, name) + H_norm = self._normalize(H) + self._names[H_norm] = name def __iter__(self): return iter(self(H) for H in self._G.conjugacy_classes_subgroups()) From 45361c3a138774a52c066780247b51574358f36f Mon Sep 17 00:00:00 2001 From: Newtech66 Date: Mon, 20 May 2024 21:22:06 +0530 Subject: [PATCH 021/537] Implemented all suggested changes --- src/sage/rings/burnside.py | 60 +++++--------------------------------- 1 file changed, 8 insertions(+), 52 deletions(-) diff --git a/src/sage/rings/burnside.py b/src/sage/rings/burnside.py index e44e61d48e8..045909bcab1 100644 --- a/src/sage/rings/burnside.py +++ b/src/sage/rings/burnside.py @@ -4,7 +4,8 @@ from sage.structure.element import Element from sage.rings.integer_ring import ZZ from sage.structure.formal_sum import FormalSum -from sage.categories.sets_cat import cartesian_product, Sets +from sage.categories.sets_cat import cartesian_product +from sage.categories.finite_enumerated_sets import FiniteEnumeratedSets from sage.groups.perm_gps.permgroup import PermutationGroup from sage.libs.gap.libgap import libgap from sage.categories.algebras import Algebras @@ -23,10 +24,7 @@ def __hash__(self): def _repr_(self): name = self.parent()._names.get(self._C, None) - if name is None: - return repr(self._C.gens()) - else: - return name + return repr(self._C.gens()) if name is None else name def __le__(self, other): return libgap.eval('fail') != libgap.ContainedConjugates(self.parent()._G, other._C, self._C, True) @@ -39,7 +37,7 @@ def __init__(self, G): self._G = G self._cache = dict() # invariant to subgroups self._names = dict() # dictionary mapping subgroups to names - Parent.__init__(self, category=Sets().Finite()) + Parent.__init__(self, category=FiniteEnumeratedSets()) def _group_invariant(self, H): return H.order() @@ -64,10 +62,7 @@ def _normalize(self, H, name=None): def _element_constructor_(self, x): if x.is_subgroup(self._G): return self.element_class(self, self._normalize(x)) - else: - raise ValueError("x must be a subgroup of " + repr(self._G)) - - raise ValueError(f"unable to convert {x} into {self}") + raise ValueError(f"unable to convert {x} into {self}: not a subgroup of " + repr(self._G)) def set_name(self, H, name): r""" @@ -82,6 +77,9 @@ def set_name(self, H, name): def __iter__(self): return iter(self(H) for H in self._G.conjugacy_classes_subgroups()) + def __contains__(self, H): + return H.is_subgroup(self._G) + def _repr_(self): r""" Return a string representation of ``self``. @@ -103,31 +101,6 @@ def __init__(self, G, base_ring=ZZ): category = Algebras(base_ring).Commutative().WithBasis() CombinatorialFreeModule.__init__(self, base_ring, basis, category=category) - def _element_constructor_(self, x): - r""" - Construct an element of the Burnside ring explicitly. - - INPUT: - - - ``x`` - data for an element - - ``x`` can be a subgroup of `G` or a formal sum of such - subgroups. - """ - if x in self.base_ring(): - return x * self.one() - - if isinstance(x, list) or isinstance(x, FormalSum): - # if x is a list of pairs (coeff, subgroup) or FormalSum - # Turn all subgroups into elements of ConjugacyClassesOfSubgroups - x = [(self._indices(subgroup), coeff) for coeff, subgroup in x] - return self._from_dict(dict(x)) - elif x.is_subgroup(self._G): - # if x is a single subgroup of self._G - return self._from_dict({self._indices(x): 1}) - - raise ValueError(f"unable to convert {x} into {self}") - def __getitem__(self, H): r""" Return the basis element indexed by ``H``. ``H`` must be a subgroup of ``self._G``. @@ -249,23 +222,6 @@ def group(self): """ return self._G - @cached_method - def gens(self): - r""" - Return the generators of ``self``. - - These are the conjugacy classes of subgroups of the - underlying group :meth:`group`. - - EXAMPLES:: - - sage: G = SymmetricGroup(3) - sage: B = BurnsideRing(G) - sage: B.gens() - (B[((),)], B[((2,3),)], B[((1,2,3),)], B[1]) - """ - return tuple(self(H) for H in self._G.conjugacy_classes_subgroups()) - def _repr_(self): r""" Return a string representation of ``self``. From b8da0e6ddd99c46264e6196147d425ecde1525ce Mon Sep 17 00:00:00 2001 From: Newtech66 Date: Tue, 21 May 2024 02:07:25 +0530 Subject: [PATCH 022/537] Doctest additions --- src/sage/rings/burnside.py | 124 +++++++++++++++++++++++++++++++++---- 1 file changed, 112 insertions(+), 12 deletions(-) diff --git a/src/sage/rings/burnside.py b/src/sage/rings/burnside.py index 045909bcab1..4f5d3a6a82a 100644 --- a/src/sage/rings/burnside.py +++ b/src/sage/rings/burnside.py @@ -12,6 +12,18 @@ from sage.combinat.free_module import CombinatorialFreeModule def _is_conjugate(G, H1, H2): + r""" + Test if ``H1`` and ``H2`` are conjugate subgroups in ``G``. + + EXAMPLES: + + sage: G = SymmetricGroup(3) + sage: H1 = PermutationGroup([(1,2)]) + sage: H2 = PermutationGroup([(2,3)]) + sage: from sage.rings.burnside import _is_conjugate + sage: _is_conjugate(G, H1, H2) + True + """ return libgap.eval('fail') != libgap.RepresentativeAction(G, H1, H2) class ConjugacyClassOfSubgroups(Element): @@ -20,46 +32,77 @@ def __init__(self, parent, C): self._C = C def __hash__(self): + r""" + Return the hash of the representative of the conjugacy class. + """ return hash(self._C) def _repr_(self): + r""" + Return a string representation of ``self``. + """ name = self.parent()._names.get(self._C, None) return repr(self._C.gens()) if name is None else name def __le__(self, other): + r""" + Return if this element is less or equal to ``other``. + + ``self`` is less or equal to ``other`` if it is conjugate to + a subgroup of ``other`` in the parent group. + """ return libgap.eval('fail') != libgap.ContainedConjugates(self.parent()._G, other._C, self._C, True) def __eq__(self, other): + r""" + Return if this element is equal to ``other``. + + Two elements compare equal if they are conjugate subgroups in the parent group. + """ return _is_conjugate(self.parent()._G, self._C, other._C) class ConjugacyClassesOfSubgroups(Parent): def __init__(self, G): + r""" + INPUT: + + ``G`` -- a group. + """ self._G = G self._cache = dict() # invariant to subgroups self._names = dict() # dictionary mapping subgroups to names Parent.__init__(self, category=FiniteEnumeratedSets()) def _group_invariant(self, H): + r""" + Return the set of group invariants associated with ``H``. + """ return H.order() - def _normalize(self, H, name=None): + def _normalize(self, H): + r""" + Add ``H`` as the representative of its conjugacy class to the cache and return it. + + If a representative of the conjugacy class of ``H`` + already exists in the cache, return that. + """ if not H.is_subgroup(self._G): raise ValueError(f"{H} is not a subgroup of {self._G}") p = self._group_invariant(H) if p in self._cache: for H0 in self._cache[p]: if _is_conjugate(self._G, H, H0): - if name is not None: - self._names[H0] = name return H0 else: self._cache[p].append(H) else: self._cache[p] = [H] - self._names[H] = name return H def _element_constructor_(self, x): + r""" + Construct the conjugacy class of subgroups containing ``x``. + """ if x.is_subgroup(self._G): return self.element_class(self, self._normalize(x)) raise ValueError(f"unable to convert {x} into {self}: not a subgroup of " + repr(self._G)) @@ -67,6 +110,7 @@ def _element_constructor_(self, x): def set_name(self, H, name): r""" Rename conjugacy class of ``H`` to ``name``. + Passing ``None`` to ``name`` will remove any previously assigned name. """ if not isinstance(name, str): @@ -75,14 +119,42 @@ def set_name(self, H, name): self._names[H_norm] = name def __iter__(self): + r""" + Return iterator over conjugacy classes of subgroups of the group. + + TESTS:: + + sage: G = SymmetricGroup(3) + sage: B = BurnsideRing(G) + sage: [g for g in B._indices] + [((),), ((2,3),), ((1,2,3),), 1] + """ return iter(self(H) for H in self._G.conjugacy_classes_subgroups()) def __contains__(self, H): + r""" + Return if ``H`` is a subgroup of the group. + + TESTS:: + + sage: G = SymmetricGroup(4) + sage: B = BurnsideRing(G) + sage: Z4 = CyclicPermutationGroup(4) + sage: Z4 in B._indices + True + """ return H.is_subgroup(self._G) def _repr_(self): r""" Return a string representation of ``self``. + + TESTS:: + + sage: G = SymmetricGroup(4) + sage: B = BurnsideRing(G) + sage: B._indices + Conjugacy classes of subgroups of Symmetric group of order 4! as a permutation group """ return "Conjugacy classes of subgroups of " + repr(self._G) @@ -90,7 +162,14 @@ def _repr_(self): class BurnsideRing(CombinatorialFreeModule): def __init__(self, G, base_ring=ZZ): - """ + r""" + INPUT: + + ``G`` -- a group. + ``base_ring`` -- the ring of coefficients. Default value is ``ZZ``. + + TESTS:: + sage: G = SymmetricGroup(4) sage: B = BurnsideRing(G) sage: TestSuite(B).run() @@ -103,12 +182,19 @@ def __init__(self, G, base_ring=ZZ): def __getitem__(self, H): r""" - Return the basis element indexed by ``H``. ``H`` must be a subgroup of ``self._G``. + Return the basis element indexed by ``H``. + + ``H`` must be a subgroup of the group. + + EXAMPLES:: + + sage: G = SymmetricGroup(4) + sage: B = BurnsideRing(G) + sage: Z4 = CyclicPermutationGroup(4) + sage: B[Z4] + B[((1,3,2,4), (1,2)(3,4))] """ - if H.is_subgroup(self._G): - return self._from_dict({self._indices(H): 1}) - else: - raise ValueError(f"{H} must be a subgroup of {self._G}") + return self._from_dict({self._indices(H): 1}) def construct_from_action(self, action, domain): r""" @@ -129,14 +215,14 @@ def construct_from_action(self, action, domain): sage: X = Subsets(4, 2) sage: a = lambda g, x: X([g(e) for e in x]) sage: B.construct_from_action(a, X) - B[((3,4), (1,2), (1,2)(3,4))] + B[((3,4), (1,2)(3,4))] Next, we create a group action of `S_4` on itself via conjugation:: sage: X = G sage: a = lambda g, x: g*x*g.inverse() sage: B.construct_from_action(a, X) - B[1] + B[((2,4), (1,4)(2,3))] + B[((2,3,4),)] + B[((3,4), (1,2), (1,2)(3,4))] + B[((1,3,2,4),)] + B[1] + B[((1,4)(2,3), (1,3)(2,4), (3,4))] + B[((2,4,3),)] + B[((3,4), (1,2)(3,4))] + B[((1,3,2,4), (1,2)(3,4))] TESTS:: @@ -176,6 +262,13 @@ def one_basis(self): r""" Returns the underlying group, which indexes the one of this algebra, as per :meth:`AlgebrasWithBasis.ParentMethods.one_basis`. + + EXAMPLES:: + + sage: G = DiCyclicGroup(4) + sage: B = BurnsideRing(G) + sage: B.one_basis() + 1 """ return self._indices(self._G) @@ -225,5 +318,12 @@ def group(self): def _repr_(self): r""" Return a string representation of ``self``. + + EXAMPLES:: + + sage: G = SymmetricGroup(4) + sage: B = BurnsideRing(G) + sage: B + Burnside ring of Symmetric group of order 4! as a permutation group """ return "Burnside ring of " + repr(self._G) From ac4bb20e18e741e16e936e15c04a1e7a5251ab1f Mon Sep 17 00:00:00 2001 From: Newtech66 Date: Wed, 22 May 2024 00:47:41 +0530 Subject: [PATCH 023/537] Doctest updates --- src/sage/rings/burnside.py | 226 ++++++++++++++++++++++++++++++++++--- 1 file changed, 210 insertions(+), 16 deletions(-) diff --git a/src/sage/rings/burnside.py b/src/sage/rings/burnside.py index 4f5d3a6a82a..4a3642a95d2 100644 --- a/src/sage/rings/burnside.py +++ b/src/sage/rings/burnside.py @@ -1,21 +1,22 @@ from sage.misc.cachefunc import cached_method -from sage.structure.unique_representation import UniqueRepresentation from sage.structure.parent import Parent from sage.structure.element import Element +from sage.structure.element import parent as get_parent_of from sage.rings.integer_ring import ZZ -from sage.structure.formal_sum import FormalSum from sage.categories.sets_cat import cartesian_product from sage.categories.finite_enumerated_sets import FiniteEnumeratedSets -from sage.groups.perm_gps.permgroup import PermutationGroup +from sage.groups.perm_gps.permgroup import PermutationGroup, PermutationGroup_generic from sage.libs.gap.libgap import libgap from sage.categories.algebras import Algebras from sage.combinat.free_module import CombinatorialFreeModule +GAP_FAIL = libgap.eval('fail') + def _is_conjugate(G, H1, H2): r""" Test if ``H1`` and ``H2`` are conjugate subgroups in ``G``. - EXAMPLES: + EXAMPLES:: sage: G = SymmetricGroup(3) sage: H1 = PermutationGroup([(1,2)]) @@ -24,22 +25,55 @@ def _is_conjugate(G, H1, H2): sage: _is_conjugate(G, H1, H2) True """ - return libgap.eval('fail') != libgap.RepresentativeAction(G, H1, H2) + return GAP_FAIL != libgap.RepresentativeAction(G, H1, H2) class ConjugacyClassOfSubgroups(Element): def __init__(self, parent, C): + r""" + Initialize the conjugacy class of ``C``. + + TESTS:: + + sage: G = SymmetricGroup(4) + sage: B = BurnsideRing(G) + sage: Z4 = CyclicPermutationGroup(4) + sage: TestSuite(B(Z4)).run() + """ Element.__init__(self, parent) self._C = C def __hash__(self): r""" Return the hash of the representative of the conjugacy class. + + TESTS:: + + sage: G = SymmetricGroup(3) + sage: B = BurnsideRing(G) + sage: H1 = B(PermutationGroup([(1,2)])) + sage: H2 = B(PermutationGroup([(2,3)])) + sage: hash(H1) == hash(H2) + True """ return hash(self._C) def _repr_(self): r""" Return a string representation of ``self``. + + TESTS:: + + sage: G = SymmetricGroup(4) + sage: B = BurnsideRing(G) + sage: Z4 = CyclicPermutationGroup(4) + sage: B[Z4] + B[((1,2,3,4),)] + sage: B._indices.set_name(Z4, "Z4") + sage: B[Z4] #indirect doctest + B[Z4] + sage: B._indices.set_name(Z4, None) + sage: B[Z4] + B[((1,2,3,4),)] """ name = self.parent()._names.get(self._C, None) return repr(self._C.gens()) if name is None else name @@ -50,32 +84,108 @@ def __le__(self, other): ``self`` is less or equal to ``other`` if it is conjugate to a subgroup of ``other`` in the parent group. + + EXAMPLES: + We recreate the poset of conjugacy classes of subgroups of + `S_4`:: + + sage: G = SymmetricGroup(4) + sage: B = BurnsideRing(G) + sage: P = Poset([B.basis(), lambda b, c: b <= c]) + sage: len(P.cover_relations()) + 17 """ - return libgap.eval('fail') != libgap.ContainedConjugates(self.parent()._G, other._C, self._C, True) + return (isinstance(other, ConjugacyClassOfSubgroups) + and (GAP_FAIL != libgap.ContainedConjugates(self.parent()._G, + other._C, + self._C, + True))) def __eq__(self, other): r""" Return if this element is equal to ``other``. Two elements compare equal if they are conjugate subgroups in the parent group. + + TESTS:: + + sage: G = SymmetricGroup(4) + sage: B = BurnsideRing(G) + sage: H1 = PermutationGroup([(1,2)]) + sage: H2 = PermutationGroup([(2,3)]) + sage: B[H1] == B[H2] + True """ - return _is_conjugate(self.parent()._G, self._C, other._C) + return (isinstance(other, ConjugacyClassOfSubgroups) + and _is_conjugate(self.parent()._G, self._C, other._C)) class ConjugacyClassesOfSubgroups(Parent): def __init__(self, G): r""" + Initialize the set of conjugacy classes of ``G``. + INPUT: ``G`` -- a group. + + TESTS:: + + sage: from sage.rings.burnside import ConjugacyClassesOfSubgroups + sage: G = CyclicPermutationGroup(4) + sage: C = ConjugacyClassesOfSubgroups(G) + sage: TestSuite(C).run() """ self._G = G self._cache = dict() # invariant to subgroups self._names = dict() # dictionary mapping subgroups to names Parent.__init__(self, category=FiniteEnumeratedSets()) + def __eq__(self, other): + r""" + Return if ``self`` is equal to ``other``. + + TESTS:: + + sage: from sage.rings.burnside import ConjugacyClassesOfSubgroups + sage: Z4 = CyclicPermutationGroup(4) + sage: D4 = DiCyclicGroup(4) + sage: C1 = ConjugacyClassesOfSubgroups(Z4) + sage: C2 = ConjugacyClassesOfSubgroups(D4) + sage: C1 == C2 + False + """ + if not isinstance(other, ConjugacyClassesOfSubgroups): + return False + return self._G == other._G + + def __hash__(self): + r""" + Return the hash of the representative of the conjugacy class. + + TESTS:: + + sage: from sage.rings.burnside import ConjugacyClassesOfSubgroups + sage: Z4 = CyclicPermutationGroup(4) + sage: D4 = DiCyclicGroup(4) + sage: C1 = ConjugacyClassesOfSubgroups(Z4) + sage: C2 = ConjugacyClassesOfSubgroups(D4) + sage: hash(C1) == hash(C2) + False + """ + return hash(self._G) + def _group_invariant(self, H): r""" Return the set of group invariants associated with ``H``. + + TESTS:: + + sage: from sage.rings.burnside import ConjugacyClassesOfSubgroups + sage: G = SymmetricGroup(4) + sage: C = ConjugacyClassesOfSubgroups(G) + sage: Z4 = CyclicPermutationGroup(4) + sage: C._group_invariant(Z4) + 4 """ return H.order() @@ -85,6 +195,17 @@ def _normalize(self, H): If a representative of the conjugacy class of ``H`` already exists in the cache, return that. + + TESTS:: + + sage: G = SymmetricGroup(4) + sage: B = BurnsideRing(G) + sage: H1 = PermutationGroup([(1,2)]) + sage: H2 = PermutationGroup([(2,3)]) + sage: B[H1] + B[((3,4),)] + sage: B[H2] #indirect doctest + B[((3,4),)] """ if not H.is_subgroup(self._G): raise ValueError(f"{H} is not a subgroup of {self._G}") @@ -102,6 +223,15 @@ def _normalize(self, H): def _element_constructor_(self, x): r""" Construct the conjugacy class of subgroups containing ``x``. + + TESTS:: + + sage: from sage.rings.burnside import ConjugacyClassesOfSubgroups + sage: G = SymmetricGroup(4) + sage: C = ConjugacyClassesOfSubgroups(G) + sage: Z4 = CyclicPermutationGroup(4) + sage: C(Z4) #indirect doctest + ((1,2,3,4),) """ if x.is_subgroup(self._G): return self.element_class(self, self._normalize(x)) @@ -112,10 +242,29 @@ def set_name(self, H, name): Rename conjugacy class of ``H`` to ``name``. Passing ``None`` to ``name`` will remove any previously assigned name. + + INPUT: + + ``H`` -- a subgroup of ``G``. + ``name`` -- a string that ``H`` should be printed as. + + EXAMPLES:: + + sage: G = SymmetricGroup(4) + sage: B = BurnsideRing(G) + sage: Z4 = CyclicPermutationGroup(4) + sage: B[Z4] + B[((1,2,3,4),)] + sage: B._indices.set_name(Z4, "Z4") + sage: B[Z4] + B[Z4] + sage: B._indices.set_name(Z4, None) + sage: B[Z4] + B[((1,2,3,4),)] """ - if not isinstance(name, str): - raise TypeError("name must be a string") H_norm = self._normalize(H) + if not isinstance(name, str) and name is not None: + raise TypeError("name must be a string or None") self._names[H_norm] = name def __iter__(self): @@ -127,7 +276,7 @@ def __iter__(self): sage: G = SymmetricGroup(3) sage: B = BurnsideRing(G) sage: [g for g in B._indices] - [((),), ((2,3),), ((1,2,3),), 1] + [((),), ((1,2),), ((1,2,3),), 1] """ return iter(self(H) for H in self._G.conjugacy_classes_subgroups()) @@ -143,7 +292,11 @@ def __contains__(self, H): sage: Z4 in B._indices True """ - return H.is_subgroup(self._G) + if get_parent_of(H) == self: + return True + + return (isinstance(H, PermutationGroup_generic) + and H.is_subgroup(self._G)) def _repr_(self): r""" @@ -163,11 +316,41 @@ def _repr_(self): class BurnsideRing(CombinatorialFreeModule): def __init__(self, G, base_ring=ZZ): r""" + The Burnside ring of the group ``G``. + INPUT: ``G`` -- a group. ``base_ring`` -- the ring of coefficients. Default value is ``ZZ``. + EXAMPLES:: + + sage: G = SymmetricGroup(6) + sage: B = BurnsideRing(G) + sage: X = Subsets(6, 2) + sage: b = B.construct_from_action(lambda g, x: X([g(e) for e in x]), X) + sage: B.basis().keys()._cache + {720: [Symmetric group of order 6! as a permutation group], + 48: [Subgroup generated by [(3,5,4,6), (1,2)(4,5,6)] of (Symmetric group of order 6! as a permutation group)]} + sage: b^2 + B[((3,5,4,6), (1,2)(4,5,6))] + B[((5,6), (4,6,5))] + B[((5,6), (3,4), (1,2))] + sage: B.basis().keys()._cache + {720: [Symmetric group of order 6! as a permutation group], + 48: [Subgroup generated by [(3,5,4,6), (1,2)(4,5,6)] of (Symmetric group of order 6! as a permutation group)], + 6: [Subgroup generated by [(5,6), (4,6,5)] of (Symmetric group of order 6! as a permutation group)], + 8: [Subgroup generated by [(5,6), (3,4), (1,2)] of (Symmetric group of order 6! as a permutation group)]} + + sage: G = SymmetricGroup(4) + sage: B = BurnsideRing(G) + sage: X = Subsets(4, 2) + sage: b = B.construct_from_action(lambda g, x: X([g(e) for e in x]), X) + sage: b.tensor(b) + B[((3,4), (1,2), (1,2)(3,4))] # B[((3,4), (1,2), (1,2)(3,4))] + sage: (b.tensor(b))^2 + 4*B[((3,4), (1,2), (1,2)(3,4))] # B[((3,4), (1,2), (1,2)(3,4))] + + 2*B[((),)] # B[((3,4), (1,2), (1,2)(3,4))] + + 2*B[((3,4), (1,2), (1,2)(3,4))] # B[((),)] + B[((),)] # B[((),)] + TESTS:: sage: G = SymmetricGroup(4) @@ -192,7 +375,7 @@ def __getitem__(self, H): sage: B = BurnsideRing(G) sage: Z4 = CyclicPermutationGroup(4) sage: B[Z4] - B[((1,3,2,4), (1,2)(3,4))] + B[((1,2,3,4),)] """ return self._from_dict({self._indices(H): 1}) @@ -205,7 +388,7 @@ def construct_from_action(self, action, domain): - ``action`` - an action on ``domain`` - ``domain`` - a finite set - EXAMPLES: + EXAMPLES:: sage: G = SymmetricGroup(4) sage: B = BurnsideRing(G) @@ -222,7 +405,7 @@ def construct_from_action(self, action, domain): sage: X = G sage: a = lambda g, x: g*x*g.inverse() sage: B.construct_from_action(a, X) - B[1] + B[((1,4)(2,3), (1,3)(2,4), (3,4))] + B[((2,4,3),)] + B[((3,4), (1,2)(3,4))] + B[((1,3,2,4), (1,2)(3,4))] + B[1] + B[((1,4)(2,3), (1,3)(2,4), (3,4))] + B[((2,4,3),)] + B[((3,4), (1,2)(3,4))] + B[((1,2,3,4),)] TESTS:: @@ -285,9 +468,20 @@ def product_on_basis(self, g1, g2): sage: B = BurnsideRing(G) sage: matrix([[b * c for b in B.gens()] for c in B.gens()]) [ 6*B[((),)] 3*B[((),)] 2*B[((),)] B[((),)]] - [ 3*B[((),)] B[((2,3),)] + B[((),)] B[((),)] B[((2,3),)]] + [ 3*B[((),)] B[((1,2),)] + B[((),)] B[((),)] B[((1,2),)]] [ 2*B[((),)] B[((),)] 2*B[((1,2,3),)] B[((1,2,3),)]] - [ B[((),)] B[((2,3),)] B[((1,2,3),)] B[1]] + [ B[((),)] B[((1,2),)] B[((1,2,3),)] B[1]] + + TESTS:: + + sage: G = SymmetricGroup(3) + sage: B = BurnsideRing(G) + sage: Z3 = CyclicPermutationGroup(3) + sage: Z2 = CyclicPermutationGroup(2) + sage: from sage.rings.burnside import ConjugacyClassesOfSubgroups + sage: C = ConjugacyClassesOfSubgroups(G) + sage: B.product_on_basis(C(Z2), C(Z3)) + B[((),)] """ #TODO: Find faster way to multiply assert g1.parent() == g2.parent() From 8ecf26d7a05e9108e4de3d493336bbedcf9bdf99 Mon Sep 17 00:00:00 2001 From: Newtech66 Date: Wed, 22 May 2024 00:49:12 +0530 Subject: [PATCH 024/537] Run doctest fixer --- src/sage/rings/burnside.py | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/src/sage/rings/burnside.py b/src/sage/rings/burnside.py index 4a3642a95d2..a925a2b2024 100644 --- a/src/sage/rings/burnside.py +++ b/src/sage/rings/burnside.py @@ -330,26 +330,24 @@ def __init__(self, G, base_ring=ZZ): sage: X = Subsets(6, 2) sage: b = B.construct_from_action(lambda g, x: X([g(e) for e in x]), X) sage: B.basis().keys()._cache - {720: [Symmetric group of order 6! as a permutation group], - 48: [Subgroup generated by [(3,5,4,6), (1,2)(4,5,6)] of (Symmetric group of order 6! as a permutation group)]} + {48: [Subgroup generated by [(3,5,4,6), (1,2)(4,5,6)] of (Symmetric group of order 6! as a permutation group)], + 720: [Symmetric group of order 6! as a permutation group]} sage: b^2 B[((3,5,4,6), (1,2)(4,5,6))] + B[((5,6), (4,6,5))] + B[((5,6), (3,4), (1,2))] sage: B.basis().keys()._cache - {720: [Symmetric group of order 6! as a permutation group], - 48: [Subgroup generated by [(3,5,4,6), (1,2)(4,5,6)] of (Symmetric group of order 6! as a permutation group)], - 6: [Subgroup generated by [(5,6), (4,6,5)] of (Symmetric group of order 6! as a permutation group)], - 8: [Subgroup generated by [(5,6), (3,4), (1,2)] of (Symmetric group of order 6! as a permutation group)]} + {6: [Subgroup generated by [(5,6), (4,6,5)] of (Symmetric group of order 6! as a permutation group)], + 8: [Subgroup generated by [(5,6), (3,4), (1,2)] of (Symmetric group of order 6! as a permutation group)], + 48: [Subgroup generated by [(3,5,4,6), (1,2)(4,5,6)] of (Symmetric group of order 6! as a permutation group)], + 720: [Symmetric group of order 6! as a permutation group]} sage: G = SymmetricGroup(4) sage: B = BurnsideRing(G) sage: X = Subsets(4, 2) sage: b = B.construct_from_action(lambda g, x: X([g(e) for e in x]), X) sage: b.tensor(b) - B[((3,4), (1,2), (1,2)(3,4))] # B[((3,4), (1,2), (1,2)(3,4))] + B[((3,4), (1,2)(3,4))] # B[((3,4), (1,2)(3,4))] sage: (b.tensor(b))^2 - 4*B[((3,4), (1,2), (1,2)(3,4))] # B[((3,4), (1,2), (1,2)(3,4))] + - 2*B[((),)] # B[((3,4), (1,2), (1,2)(3,4))] + - 2*B[((3,4), (1,2), (1,2)(3,4))] # B[((),)] + B[((),)] # B[((),)] + 4*B[((3,4), (1,2)(3,4))] # B[((3,4), (1,2)(3,4))] + 2*B[((),)] # B[((3,4), (1,2)(3,4))] + 2*B[((3,4), (1,2)(3,4))] # B[((),)] + B[((),)] # B[((),)] TESTS:: @@ -468,9 +466,9 @@ def product_on_basis(self, g1, g2): sage: B = BurnsideRing(G) sage: matrix([[b * c for b in B.gens()] for c in B.gens()]) [ 6*B[((),)] 3*B[((),)] 2*B[((),)] B[((),)]] - [ 3*B[((),)] B[((1,2),)] + B[((),)] B[((),)] B[((1,2),)]] + [ 3*B[((),)] B[((2,3),)] + B[((),)] B[((),)] B[((2,3),)]] [ 2*B[((),)] B[((),)] 2*B[((1,2,3),)] B[((1,2,3),)]] - [ B[((),)] B[((1,2),)] B[((1,2,3),)] B[1]] + [ B[((),)] B[((2,3),)] B[((1,2,3),)] B[1]] TESTS:: From f617657c8fd9e79746a241fdbf641d2c713d5ba3 Mon Sep 17 00:00:00 2001 From: Newtech66 Date: Wed, 22 May 2024 00:57:46 +0530 Subject: [PATCH 025/537] Small change --- src/sage/rings/burnside.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/sage/rings/burnside.py b/src/sage/rings/burnside.py index a925a2b2024..1e34068a4e2 100644 --- a/src/sage/rings/burnside.py +++ b/src/sage/rings/burnside.py @@ -86,6 +86,7 @@ def __le__(self, other): a subgroup of ``other`` in the parent group. EXAMPLES: + We recreate the poset of conjugacy classes of subgroups of `S_4`:: From d038b951d569bd9b03c58e52565390554c3bff23 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Sun, 9 Jun 2024 17:59:09 +0100 Subject: [PATCH 026/537] Created Chow Ring Ideal Class --- src/sage/matroids/chow_ring_ideal.py | 40 ++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 src/sage/matroids/chow_ring_ideal.py diff --git a/src/sage/matroids/chow_ring_ideal.py b/src/sage/matroids/chow_ring_ideal.py new file mode 100644 index 00000000000..34fece34320 --- /dev/null +++ b/src/sage/matroids/chow_ring_ideal.py @@ -0,0 +1,40 @@ +from sage.all import * +from sage.rings.ideal import Ideal_generic +from sage.rings.polynomial.multi_polynomial_ideal import MPolynomialIdeal +from sage.matroids.matroid import Matroid +from sage.matroids.utilities import cmp_elements_key +from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing + + +class ChowRingIdeal(MPolynomialIdeal): + def __init__(self, M, R=None, augmented=False): + if R is None: + raise ValueError("Ring not given") + self.augmented = augmented + self.mat = M + flats = [X for i in range(1, self.mat.rank()) + for X in self.mat.flats(i)] + try: + self.names = ['A{}'.format(''.join(str(x) for x in sorted(F, key=cmp_elements_key))) for F in flats] + self.poly_ring = PolynomialRing(R, self.names) + except ValueError: # variables are not proper names + self.poly_ring = PolynomialRing(R, 'A', len(flats)) + self.names = self.poly_ring.variable_names() + self.gens = self.poly_ring.gens() + Ideal_generic.__init__(self, self.poly_ring, self.gens, coerce=coerce) + + + + def groebner_basis(self): + gb = [] + if self.augmented: + + else: + + + + + + + + From 16850226728172697b5ddf231eef1b8a18c56ade Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Mon, 10 Jun 2024 19:34:05 +0100 Subject: [PATCH 027/537] Created class and defined groebner_basis() method --- src/sage/matroids/chow_ring_ideal.py | 114 +++++++++++++++++++++++---- 1 file changed, 97 insertions(+), 17 deletions(-) diff --git a/src/sage/matroids/chow_ring_ideal.py b/src/sage/matroids/chow_ring_ideal.py index 34fece34320..76d5b809021 100644 --- a/src/sage/matroids/chow_ring_ideal.py +++ b/src/sage/matroids/chow_ring_ideal.py @@ -1,35 +1,115 @@ -from sage.all import * -from sage.rings.ideal import Ideal_generic +#from sage.all import * +#from sage.rings.ideal import Ideal_generic from sage.rings.polynomial.multi_polynomial_ideal import MPolynomialIdeal from sage.matroids.matroid import Matroid from sage.matroids.utilities import cmp_elements_key from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing - +from sage.sets.set import Set +from sage.rings.morphism import _tensor_product_ring class ChowRingIdeal(MPolynomialIdeal): def __init__(self, M, R=None, augmented=False): if R is None: raise ValueError("Ring not given") self.augmented = augmented - self.mat = M - flats = [X for i in range(1, self.mat.rank()) - for X in self.mat.flats(i)] - try: - self.names = ['A{}'.format(''.join(str(x) for x in sorted(F, key=cmp_elements_key))) for F in flats] - self.poly_ring = PolynomialRing(R, self.names) - except ValueError: # variables are not proper names - self.poly_ring = PolynomialRing(R, 'A', len(flats)) - self.names = self.poly_ring.variable_names() - self.gens = self.poly_ring.gens() - Ideal_generic.__init__(self, self.poly_ring, self.gens, coerce=coerce) - + self._matroid = M + self.flats = [X for i in range(1, self._matroid.rank()) + for X in self._matroid.flats(i)] + E = list(self._matroid.groundset()) + flats_containing = {x: [] for x in E} + for i,F in enumerate(self.flats): + for x in F: + flats_containing[x].append(i) + self.names = dict() - def groebner_basis(self): - gb = [] if self.augmented: + try: + P1 = PolynomialRing(R, 'A', len(E)) + names_flats = ['B{}'.format(''.join(str(x) for x in sorted(F, key=cmp_elements_key))) for F in self.flats] + P2 = PolynomialRing(R, names_flats) + self.poly_ring = _tensor_product_ring(P1, P2) + + except: + P1 = PolynomialRing(R, 'A', len(E)) + P2 = PolynomialRing(R, 'B', len(self.flats)) + self.poly_ring = _tensor_product_ring(P1, P2) + + gens = self.poly_ring.gens() + for i,x in enumerate(E): + self.names[x] = gens[i] + for i,F in enumerate(self.flats): + self.names[F] = gens[len(E) + i] + + Q =[gens[len(E)+i] * gens[len(E)+i+j+1] for i,F in enumerate(self.flats) + for j,G in enumerate(self.flats[i+1:]) if not (F < G or G < F)] + Q.append([gens[i]*gens[len(E)+j] for i,x in enumerate(E) for j,F in enumerate(self.flats) if F not in flats_containing[x]]) + L = list() + for i,x in enumerate(E): + for j,F in enumerate(self.flats): + term = 0 + if F not in flats_containing[x]: + term += gens[len(E)+j] + L.append(gens[i] - term) + print(L) + self.gens = Q + L + + + else: + try: + names = ['A{}'.format(''.join(str(x) for x in sorted(F, key=cmp_elements_key))) for F in self.flats] + self.poly_ring = PolynomialRing(R, names) + for F in self.flats: + for i in range(len(self.poly_ring.gens())): + self.names[F] = self.poly_ring.gens()[i] + except ValueError: # variables are not proper names + self.poly_ring = PolynomialRing(R, 'A', len(self.flats)) + for i in range(len(self.flats)): + self.names[self.flats[i]] = self.poly_ring.gens()[i] + + gens = self.poly_ring.gens() + Q = [gens[i] * gens[i+j+1] for i,F in enumerate(self.flats) + for j,G in enumerate(self.flats[i+1:]) if not (F < G or G < F)] + L = [sum(gens[i] for i in flats_containing[x]) + - sum(gens[i] for i in flats_containing[y]) + for j,x in enumerate(E) for y in E[j+1:]] + self.gens = Q + L + + MPolynomialIdeal.__init__(self, self.poly_ring, self.gens) + + def __repr__(self): + if self.augmented: + return "Augmented Chow ring ideal of {}".format(self._matroid) else: + return "Chow ring ideal of {}".format(self._matroid) + + def groebner_basis(self): + gb = list() + for F in self.flats: + for G in self.flats: + if not (F < G or G < F): + gb.append(self.names[F]*self.names[G]) + elif Set(F).is_empty(): + term = 0 + for H in self.flats: + if H < F: + term += self.names[H] + gb.append(term**self._matroid.rank(Set(G))) + elif F < G: + term = 0 + for H in self.flats: + if H < F: + term += self.names[H] + gb.append(term**(self._matroid.rank(Set(G))-self._matroid.rank(Set(F)))) + return gb + + + + + + + From 0ab73bb6000de362ac33b079e226d4aa810d4fa1 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Mon, 10 Jun 2024 22:29:04 +0100 Subject: [PATCH 028/537] Modified groebner_basis() method --- src/sage/matroids/chow_ring_ideal.py | 38 +++++++++++++++------------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/src/sage/matroids/chow_ring_ideal.py b/src/sage/matroids/chow_ring_ideal.py index 76d5b809021..3947471d5a1 100644 --- a/src/sage/matroids/chow_ring_ideal.py +++ b/src/sage/matroids/chow_ring_ideal.py @@ -85,23 +85,27 @@ def __repr__(self): return "Chow ring ideal of {}".format(self._matroid) def groebner_basis(self): - gb = list() - for F in self.flats: - for G in self.flats: - if not (F < G or G < F): - gb.append(self.names[F]*self.names[G]) - elif Set(F).is_empty(): - term = 0 - for H in self.flats: - if H < F: - term += self.names[H] - gb.append(term**self._matroid.rank(Set(G))) - elif F < G: - term = 0 - for H in self.flats: - if H < F: - term += self.names[H] - gb.append(term**(self._matroid.rank(Set(G))-self._matroid.rank(Set(F)))) + if self.augmented: + print("Augmented gb") + else: + gb = list() + for F in self.flats: + for G in self.flats: + if not (F < G or G < F): + gb.append(self.names[F]*self.names[G]) + elif Set(F).is_empty(): + term = 0 + for H in self.flats: + if H < F: + term += self.names[H] + gb.append(term**self._matroid.rank(Set(G))) + elif F < G: + term = 0 + for H in self.flats: + if H < F: + term += self.names[H] + gb.append(term**(self._matroid.rank(Set(G))-self._matroid.rank(Set(F)))) + return gb From 6ecbe83a5dad51e013b76d0ec56f697a8f6a5d4c Mon Sep 17 00:00:00 2001 From: Newtech66 Date: Sat, 15 Jun 2024 19:45:35 +0530 Subject: [PATCH 029/537] Draft implementation of PolynomialMolecularDecomposition + other minor changes --- src/sage/rings/burnside.py | 141 ++++++++++++++++++++++++++++++++++++- 1 file changed, 138 insertions(+), 3 deletions(-) diff --git a/src/sage/rings/burnside.py b/src/sage/rings/burnside.py index 1e34068a4e2..2e98b4ce928 100644 --- a/src/sage/rings/burnside.py +++ b/src/sage/rings/burnside.py @@ -1,14 +1,20 @@ from sage.misc.cachefunc import cached_method from sage.structure.parent import Parent from sage.structure.element import Element -from sage.structure.element import parent as get_parent_of +from sage.structure.element import parent +from sage.structure.unique_representation import UniqueRepresentation from sage.rings.integer_ring import ZZ from sage.categories.sets_cat import cartesian_product from sage.categories.finite_enumerated_sets import FiniteEnumeratedSets +from sage.categories.infinite_enumerated_sets import InfiniteEnumeratedSets from sage.groups.perm_gps.permgroup import PermutationGroup, PermutationGroup_generic +from sage.groups.perm_gps.permgroup_named import SymmetricGroup from sage.libs.gap.libgap import libgap from sage.categories.algebras import Algebras from sage.combinat.free_module import CombinatorialFreeModule +from sage.categories.graded_algebras_with_basis import GradedAlgebrasWithBasis +from sage.categories.filtered_modules_with_basis import FilteredModulesWithBasis +from sage.rings.integer import Integer GAP_FAIL = libgap.eval('fail') @@ -293,7 +299,7 @@ def __contains__(self, H): sage: Z4 in B._indices True """ - if get_parent_of(H) == self: + if parent(H) == self: return True return (isinstance(H, PermutationGroup_generic) @@ -360,7 +366,8 @@ def __init__(self, G, base_ring=ZZ): basis = ConjugacyClassesOfSubgroups(G) basis.set_name(G, "1") category = Algebras(base_ring).Commutative().WithBasis() - CombinatorialFreeModule.__init__(self, base_ring, basis, category=category) + CombinatorialFreeModule.__init__(self, base_ring, basis, + category=category, prefix="B") def __getitem__(self, H): r""" @@ -520,3 +527,131 @@ def _repr_(self): Burnside ring of Symmetric group of order 4! as a permutation group """ return "Burnside ring of " + repr(self._G) + +class ConjugacyClassOfSymmetricGroupSubgroups(ConjugacyClassOfSubgroups): + def __init__(self, n, C): + r""" + Initialize the conjugacy class of ``C`` in SymmetricGroup(n). + + TESTS:: + + sage: G = SymmetricGroup(4) + sage: B = BurnsideRing(G) + sage: Z4 = CyclicPermutationGroup(4) + sage: TestSuite(B(Z4)).run() + """ + self._n = n + self._G = SymmetricGroup(n) + ConjugacyClassOfSubgroups.__init__(self, ConjugacyClassesOfSymmetricGroupSubgroups(), C) + + def __hash__(self): + r""" + Return the hash of the representative of the conjugacy class. + """ + return hash(self._C) + + def _repr_(self): + r""" + Return a string representation of ``self``. + """ + # name = self.parent()._names.get(self._C, None) + name = None + return repr((self._n, self._C.gens())) if name is None else repr((self._n, name)) + + def __eq__(self, other): + r""" + Return if this element is equal to ``other``. + + Two elements compare equal if they are conjugate subgroups in the parent group. + """ + return (isinstance(other, ConjugacyClassOfSymmetricGroupSubgroups) + and self._n == other._n and _is_conjugate(self._G, self._C, other._C)) + +class ConjugacyClassesOfSymmetricGroupSubgroups(UniqueRepresentation, Parent): + def __init__(self): + category = InfiniteEnumeratedSets() + Parent.__init__(self, category=category) + + def _repr_(self): + return "Conjugacy classes of subgroups of symmetric groups" + + def _element_constructor_(self, x): + r""" + x is a tuple (n, H) where H is a subgroup of S_n. + """ + G = SymmetricGroup(x[0]) + if x[1].is_subgroup(G): + return self.element_class(x[0], x[1]) + raise ValueError(f"Unable to convert {x} into self: {x[1]} is not a subgroup of SymmetricGroup({x[0]})") + + def __iter__(self): + n = 0 + while True: + G = SymmetricGroup(n) + CC = ConjugacyClassesOfSubgroups(G) + yield from iter(CC) + n += 1 + + def __contains__(self, x): + r""" + x is a tuple (n, H) where H is a subgroup of S_n. + """ + if parent(x) == self: + return True + return isinstance(x[0], (int, Integer)) and x[1] in ConjugacyClassesOfSubgroups(SymmetricGroup(x[0])) + + Element = ConjugacyClassOfSymmetricGroupSubgroups + +class PolynomialMolecularDecomposition(CombinatorialFreeModule): + def __init__(self, base_ring=ZZ): + category = GradedAlgebrasWithBasis(base_ring) + CombinatorialFreeModule.__init__(self, base_ring, + basis_keys=ConjugacyClassesOfSymmetricGroupSubgroups(), + category=category, + prefix="PMD") + + # FIXME: this is currently required, because the implementation of ``basis`` + # in CombinatorialFreeModule overrides that of GradedModulesWithBasis + basis = FilteredModulesWithBasis.ParentMethods.__dict__['basis'] + + def __getitem__(self, x): + r""" + Return the basis element indexed by ``x``. + """ + return self._from_dict({self._indices(x): 1}) + + @cached_method + def one_basis(self): + r""" + Returns (0, S0), which indexes the one of this algebra, + as per :meth:`AlgebrasWithBasis.ParentMethods.one_basis`. + """ + return self._indices((0, SymmetricGroup(0))) + + def product_on_basis(self, g1, g2): + n, m = g1._n, g2._n + H, K = g1._C, g2._C + def construct_element(h, k): + element = [None for i in range(n+m)] + for i in range(n+m): + if i Date: Sun, 16 Jun 2024 17:18:42 +0530 Subject: [PATCH 030/537] Added PolynomialMolecularDecomposition to imports --- src/sage/rings/all.py | 2 +- src/sage/rings/burnside.py | 9 ++++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/sage/rings/all.py b/src/sage/rings/all.py index 5cc1988c336..8b8d98d734e 100644 --- a/src/sage/rings/all.py +++ b/src/sage/rings/all.py @@ -166,7 +166,7 @@ # asymptotic ring from sage.rings.asymptotic.all import * -lazy_import('sage.rings.burnside', ['BurnsideRing']) +lazy_import('sage.rings.burnside', ['BurnsideRing', 'PolynomialMolecularDecomposition']) # Register classes in numbers abc from sage.rings import numbers_abc diff --git a/src/sage/rings/burnside.py b/src/sage/rings/burnside.py index 2e98b4ce928..21303e4c9d3 100644 --- a/src/sage/rings/burnside.py +++ b/src/sage/rings/burnside.py @@ -628,11 +628,18 @@ def one_basis(self): """ return self._indices((0, SymmetricGroup(0))) + # Remember, a basis element here is a molecular species. + # When two basis elements are multiplied, you get another + # molecular species, ie a basis element. + # Any molecular species centered on cardinality n M_n, + # is equivalent to [S_n/H] where H is some conjugacy class + # of subgroups of S_n. + def product_on_basis(self, g1, g2): n, m = g1._n, g2._n H, K = g1._C, g2._C def construct_element(h, k): - element = [None for i in range(n+m)] + element = [None for _ in range(n+m)] for i in range(n+m): if i Date: Sun, 16 Jun 2024 23:10:56 +0530 Subject: [PATCH 031/537] Fixed __iter__ and added subset in ConjugacyClassesOfSymmetricGroupSubgroups --- src/sage/rings/burnside.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/sage/rings/burnside.py b/src/sage/rings/burnside.py index 21303e4c9d3..027b6905f1a 100644 --- a/src/sage/rings/burnside.py +++ b/src/sage/rings/burnside.py @@ -589,7 +589,8 @@ def __iter__(self): while True: G = SymmetricGroup(n) CC = ConjugacyClassesOfSubgroups(G) - yield from iter(CC) + for H in CC: + yield self((n, H._C)) n += 1 def __contains__(self, x): @@ -600,6 +601,9 @@ def __contains__(self, x): return True return isinstance(x[0], (int, Integer)) and x[1] in ConjugacyClassesOfSubgroups(SymmetricGroup(x[0])) + def subset(self, size): + return ConjugacyClassesOfSubgroups(SymmetricGroup(size)) + Element = ConjugacyClassOfSymmetricGroupSubgroups class PolynomialMolecularDecomposition(CombinatorialFreeModule): From 04ac9e9dabab1e55122cf9b4d58fbe1a1016bd46 Mon Sep 17 00:00:00 2001 From: Newtech66 Date: Tue, 18 Jun 2024 01:09:03 +0530 Subject: [PATCH 032/537] Refactor conjugacy classes of subgroups of symmetric groups, add special case in construct_element --- src/sage/rings/burnside.py | 175 +++++++++++++++++++------------------ 1 file changed, 89 insertions(+), 86 deletions(-) diff --git a/src/sage/rings/burnside.py b/src/sage/rings/burnside.py index 027b6905f1a..25cd1f4caf6 100644 --- a/src/sage/rings/burnside.py +++ b/src/sage/rings/burnside.py @@ -6,7 +6,7 @@ from sage.rings.integer_ring import ZZ from sage.categories.sets_cat import cartesian_product from sage.categories.finite_enumerated_sets import FiniteEnumeratedSets -from sage.categories.infinite_enumerated_sets import InfiniteEnumeratedSets +from sage.categories.sets_with_grading import SetsWithGrading from sage.groups.perm_gps.permgroup import PermutationGroup, PermutationGroup_generic from sage.groups.perm_gps.permgroup_named import SymmetricGroup from sage.libs.gap.libgap import libgap @@ -320,6 +320,81 @@ def _repr_(self): Element = ConjugacyClassOfSubgroups +class ConjugacyClassOfSubgroups_SymmetricGroup(ConjugacyClassOfSubgroups): + def __init__(self, parent, C): + r""" + Initialize the conjugacy class of ``C`` in SymmetricGroup(n). + + TESTS:: + + sage: G = SymmetricGroup(4) + sage: B = BurnsideRing(G) + sage: Z4 = CyclicPermutationGroup(4) + sage: TestSuite(B(Z4)).run() + """ + ConjugacyClassOfSubgroups.__init__(self, parent, C) + + def grade(self): + return self.parent()._G.degree() + + def __hash__(self): + r""" + Return the hash of the representative of the conjugacy class. + """ + return hash((hash(self.parent()._G), hash(self._C))) + + def _repr_(self): + r""" + Return a string representation of ``self``. + """ + return repr((self.grade(), super()._repr_())) + + def __eq__(self, other): + r""" + Return if this element is equal to ``other``. + + Two elements compare equal if they are conjugate subgroups in the parent group. + """ + return (isinstance(other, ConjugacyClassOfSubgroups_SymmetricGroup) + and self.grade() == other.grade() and _is_conjugate(self.parent()._G, self._C, other._C)) + +class ConjugacyClassesOfSubgroups_SymmetricGroup(ConjugacyClassesOfSubgroups): + def __init__(self, n): + ConjugacyClassesOfSubgroups.__init__(self, SymmetricGroup(n)) + + Element = ConjugacyClassOfSubgroups_SymmetricGroup + +class ConjugacyClassesOfSubgroups_SymmetricGroup_all(UniqueRepresentation, Parent): + def __init__(self): + category = SetsWithGrading().Infinite() + Parent.__init__(self, category=category) + + def _repr_(self): + return "Conjugacy classes of subgroups of symmetric groups" + + def subset(self, size): + return ConjugacyClassesOfSubgroups_SymmetricGroup(size) + + def _element_constructor_(self, H): + r""" + H is a subgroup of a symmetric group. + """ + return self.subset(H.degree())(H) + + def __iter__(self): + n = 0 + while True: + yield from self.subset(n) + n += 1 + + def __contains__(self, H): + r""" + Returns if H is a subgroup of a symmetric group. + """ + return H in self.subset(H.degree()) + + Element = ConjugacyClassOfSubgroups_SymmetricGroup + class BurnsideRing(CombinatorialFreeModule): def __init__(self, G, base_ring=ZZ): r""" @@ -528,89 +603,11 @@ def _repr_(self): """ return "Burnside ring of " + repr(self._G) -class ConjugacyClassOfSymmetricGroupSubgroups(ConjugacyClassOfSubgroups): - def __init__(self, n, C): - r""" - Initialize the conjugacy class of ``C`` in SymmetricGroup(n). - - TESTS:: - - sage: G = SymmetricGroup(4) - sage: B = BurnsideRing(G) - sage: Z4 = CyclicPermutationGroup(4) - sage: TestSuite(B(Z4)).run() - """ - self._n = n - self._G = SymmetricGroup(n) - ConjugacyClassOfSubgroups.__init__(self, ConjugacyClassesOfSymmetricGroupSubgroups(), C) - - def __hash__(self): - r""" - Return the hash of the representative of the conjugacy class. - """ - return hash(self._C) - - def _repr_(self): - r""" - Return a string representation of ``self``. - """ - # name = self.parent()._names.get(self._C, None) - name = None - return repr((self._n, self._C.gens())) if name is None else repr((self._n, name)) - - def __eq__(self, other): - r""" - Return if this element is equal to ``other``. - - Two elements compare equal if they are conjugate subgroups in the parent group. - """ - return (isinstance(other, ConjugacyClassOfSymmetricGroupSubgroups) - and self._n == other._n and _is_conjugate(self._G, self._C, other._C)) - -class ConjugacyClassesOfSymmetricGroupSubgroups(UniqueRepresentation, Parent): - def __init__(self): - category = InfiniteEnumeratedSets() - Parent.__init__(self, category=category) - - def _repr_(self): - return "Conjugacy classes of subgroups of symmetric groups" - - def _element_constructor_(self, x): - r""" - x is a tuple (n, H) where H is a subgroup of S_n. - """ - G = SymmetricGroup(x[0]) - if x[1].is_subgroup(G): - return self.element_class(x[0], x[1]) - raise ValueError(f"Unable to convert {x} into self: {x[1]} is not a subgroup of SymmetricGroup({x[0]})") - - def __iter__(self): - n = 0 - while True: - G = SymmetricGroup(n) - CC = ConjugacyClassesOfSubgroups(G) - for H in CC: - yield self((n, H._C)) - n += 1 - - def __contains__(self, x): - r""" - x is a tuple (n, H) where H is a subgroup of S_n. - """ - if parent(x) == self: - return True - return isinstance(x[0], (int, Integer)) and x[1] in ConjugacyClassesOfSubgroups(SymmetricGroup(x[0])) - - def subset(self, size): - return ConjugacyClassesOfSubgroups(SymmetricGroup(size)) - - Element = ConjugacyClassOfSymmetricGroupSubgroups - class PolynomialMolecularDecomposition(CombinatorialFreeModule): def __init__(self, base_ring=ZZ): category = GradedAlgebrasWithBasis(base_ring) CombinatorialFreeModule.__init__(self, base_ring, - basis_keys=ConjugacyClassesOfSymmetricGroupSubgroups(), + basis_keys=ConjugacyClassesOfSubgroups_SymmetricGroup_all(), category=category, prefix="PMD") @@ -630,7 +627,7 @@ def one_basis(self): Returns (0, S0), which indexes the one of this algebra, as per :meth:`AlgebrasWithBasis.ParentMethods.one_basis`. """ - return self._indices((0, SymmetricGroup(0))) + return self._indices(SymmetricGroup(0)) # Remember, a basis element here is a molecular species. # When two basis elements are multiplied, you get another @@ -640,12 +637,13 @@ def one_basis(self): # of subgroups of S_n. def product_on_basis(self, g1, g2): - n, m = g1._n, g2._n + n, m = g1.grade(), g2.grade() H, K = g1._C, g2._C + def construct_element(h, k): element = [None for _ in range(n+m)] for i in range(n+m): - if i Date: Tue, 18 Jun 2024 10:56:26 +0530 Subject: [PATCH 033/537] Added Augmented Chow Ring Ideal Class --- src/sage/matroids/chow_ring_ideal.py | 191 +++++++++++++++++---------- 1 file changed, 118 insertions(+), 73 deletions(-) diff --git a/src/sage/matroids/chow_ring_ideal.py b/src/sage/matroids/chow_ring_ideal.py index 3947471d5a1..3b5d0a16207 100644 --- a/src/sage/matroids/chow_ring_ideal.py +++ b/src/sage/matroids/chow_ring_ideal.py @@ -8,10 +8,7 @@ from sage.rings.morphism import _tensor_product_ring class ChowRingIdeal(MPolynomialIdeal): - def __init__(self, M, R=None, augmented=False): - if R is None: - raise ValueError("Ring not given") - self.augmented = augmented + def __init__(self, M, R): self._matroid = M self.flats = [X for i in range(1, self._matroid.rank()) for X in self._matroid.flats(i)] @@ -22,96 +19,144 @@ def __init__(self, M, R=None, augmented=False): for x in F: flats_containing[x].append(i) self.names = dict() + try: + names = ['A{}'.format(''.join(str(x) for x in sorted(F, key=cmp_elements_key))) for F in self.flats] + self.poly_ring = PolynomialRing(R, names) + for F in self.flats: + for i in range(len(self.poly_ring.gens())): + self.names[F] = self.poly_ring.gens()[i] + except ValueError: # variables are not proper names + self.poly_ring = PolynomialRing(R, 'A', len(self.flats)) + for i in range(len(self.flats)): + self.names[self.flats[i]] = self.poly_ring.gens()[i] + + gens = self.poly_ring.gens() + Q = [gens[i] * gens[i+j+1] for i,F in enumerate(self.flats) + for j,G in enumerate(self.flats[i+1:]) if not (F < G or G < F)] + L = [sum(gens[i] for i in flats_containing[x]) + - sum(gens[i] for i in flats_containing[y]) + for j,x in enumerate(E) for y in E[j+1:]] + self.gens = Q + L + - if self.augmented: - try: - P1 = PolynomialRing(R, 'A', len(E)) - names_flats = ['B{}'.format(''.join(str(x) for x in sorted(F, key=cmp_elements_key))) for F in self.flats] - P2 = PolynomialRing(R, names_flats) - self.poly_ring = _tensor_product_ring(P1, P2) - - except: - P1 = PolynomialRing(R, 'A', len(E)) - P2 = PolynomialRing(R, 'B', len(self.flats)) - self.poly_ring = _tensor_product_ring(P1, P2) - - gens = self.poly_ring.gens() - for i,x in enumerate(E): - self.names[x] = gens[i] - for i,F in enumerate(self.flats): - self.names[F] = gens[len(E) + i] + MPolynomialIdeal.__init__(self, self.poly_ring, self.gens) - Q =[gens[len(E)+i] * gens[len(E)+i+j+1] for i,F in enumerate(self.flats) - for j,G in enumerate(self.flats[i+1:]) if not (F < G or G < F)] - Q.append([gens[i]*gens[len(E)+j] for i,x in enumerate(E) for j,F in enumerate(self.flats) if F not in flats_containing[x]]) - L = list() - for i,x in enumerate(E): - for j,F in enumerate(self.flats): + def __repr__(self): + return "Chow ring ideal of {}".format(self._matroid) + + def groebner_basis(self): + gb = list() + for F in self.flats: + for G in self.flats: + if not (F < G or G < F): + gb.append(self.names[F]*self.names[G]) + elif Set(F).is_empty(): term = 0 - if F not in flats_containing[x]: - term += gens[len(E)+j] - L.append(gens[i] - term) - print(L) - self.gens = Q + L - + for H in self.flats: + if H < F: + term += self.names[H] + gb.append(term**self._matroid.rank(Set(G))) + elif F < G: + term = 0 + for H in self.flats: + if H < F: + term += self.names[H] + gb.append(term**(self._matroid.rank(Set(G))-self._matroid.rank(Set(F)))) - else: - try: - names = ['A{}'.format(''.join(str(x) for x in sorted(F, key=cmp_elements_key))) for F in self.flats] - self.poly_ring = PolynomialRing(R, names) - for F in self.flats: - for i in range(len(self.poly_ring.gens())): - self.names[F] = self.poly_ring.gens()[i] - except ValueError: # variables are not proper names - self.poly_ring = PolynomialRing(R, 'A', len(self.flats)) - for i in range(len(self.flats)): - self.names[self.flats[i]] = self.poly_ring.gens()[i] - - gens = self.poly_ring.gens() - Q = [gens[i] * gens[i+j+1] for i,F in enumerate(self.flats) - for j,G in enumerate(self.flats[i+1:]) if not (F < G or G < F)] - L = [sum(gens[i] for i in flats_containing[x]) - - sum(gens[i] for i in flats_containing[y]) - for j,x in enumerate(E) for y in E[j+1:]] - self.gens = Q + L - + return gb - MPolynomialIdeal.__init__(self, self.poly_ring, self.gens) +class AugmentedChowRingIdeal(MPolynomialIdeal): + def __init__(self, M, R): + self._matroid = M + self.flats = [X for i in range(1, self._matroid.rank()) + for X in self._matroid.flats(i)] + + E = list(self._matroid.groundset()) + flats_containing = {x: [] for x in E} + for i,F in enumerate(self.flats): + for x in F: + flats_containing[x].append(i) + self.names = dict() + #names_groundset = ['A{}'.format(''.join(str(x))) for x in E] + #names_flats = ['B{}'.format(''.join(str(x) for x in sorted(F, key=cmp_elements_key))) for F in self.flats] + self.poly_ring = PolynomialRing(R, 'A', len(E) + len(self.flats)) + gens = self.poly_ring.gens() + for i,x in enumerate(E): + self.names[x] = gens[i] + for i,F in enumerate(self.flats): + self.names[F] = gens[len(E) + i] + + Q =[gens[len(E)+i] * gens[len(E)+i+j+1] for i,F in enumerate(self.flats) + for j,G in enumerate(self.flats[i+1:]) if not (F < G or G < F)] + Q.append([gens[i]*gens[len(E)+j] for i,x in enumerate(E) for j,F in enumerate(self.flats) if F not in flats_containing[x]]) + L = list() + for i,x in enumerate(E): + term = 0 + for j,F in enumerate(self.flats): + if F not in flats_containing[x]: + term += gens[len(E)+j] + L.append(gens[i] - term) + self.gens = Q + L + MPolynomialIdeal.__init__(self, self.poly_ring, self.gens, coerce=False) + def __repr__(self): - if self.augmented: - return "Augmented Chow ring ideal of {}".format(self._matroid) - else: - return "Chow ring ideal of {}".format(self._matroid) + return "Augmented Chow ring ideal of {}".format(self._matroid) - def groebner_basis(self): - if self.augmented: - print("Augmented gb") - else: - gb = list() + + def groebner_basis(self, atom_free=False): + #add removal of empty flat line + #list returned or iterator returned? + gb = [] + if atom_free: for F in self.flats: for G in self.flats: - if not (F < G or G < F): + if not (F > G or G > F): gb.append(self.names[F]*self.names[G]) - elif Set(F).is_empty(): + elif F < G: term = 0 for H in self.flats: if H < F: term += self.names[H] - gb.append(term**self._matroid.rank(Set(G))) - elif F < G: + gb.append(self.names[F]*(term**self._matroid.rank(Set(G)))* + (term**(self._matroid.rank(Set(G))-self._matroid.rank(Set(F))))) + + else: + E = list(self._matroid.groundset()) + for i in E: + for F in self.flats: + for G in self.flats: term = 0 for H in self.flats: - if H < F: + if i in Set(H): term += self.names[H] - gb.append(term**(self._matroid.rank(Set(G))-self._matroid.rank(Set(F)))) - - return gb + gb.append(self.names[i] + term) + + if i in Set(F): + term = 0 + for H in self.flats: + if H < F: + term += self.names[H] + gb.append(self.names[i]*(term**self._matroid.rank(Set(G)))* + (term**(self._matroid.rank(Set(G))-self._matroid.rank(Set(F))))) + + elif not i in Set(F): + gb.append(self.names[i]*self.names[F]) + + elif not (F < G or G < F): + gb.append(self.names[F]*self.names[G]) + + elif F < G: + term = 0 + for H in self.flats: + if H < F: + term += self.names[H] + gb.append(term**(self._matroid.rank(Set(G))-self._matroid.rank(Set(F)))) + + return gb - - From 3ca886199f0d0618175cdd5dda159f1c88780327 Mon Sep 17 00:00:00 2001 From: Newtech66 Date: Wed, 19 Jun 2024 02:17:53 +0530 Subject: [PATCH 034/537] Reworked naming facility + other minor changes --- src/sage/rings/burnside.py | 177 +++++++++++++++++-------------------- 1 file changed, 81 insertions(+), 96 deletions(-) diff --git a/src/sage/rings/burnside.py b/src/sage/rings/burnside.py index 25cd1f4caf6..7269781b307 100644 --- a/src/sage/rings/burnside.py +++ b/src/sage/rings/burnside.py @@ -33,6 +33,57 @@ def _is_conjugate(G, H1, H2): """ return GAP_FAIL != libgap.RepresentativeAction(G, H1, H2) +class SubgroupNameStore(): + def __init__(self, basis_keys): + r""" + This class stores subgroup <-> name associations. + """ + self._key_constructor = basis_keys + self._cache = dict() # invariant to subgroups + self._names = dict() # dictionary mapping subgroups to names + + def _group_invariant(self, H): + return H.order() + + def _normalize(self, H): + print('Normalize was called') + key = self._key_constructor(H) + p = self._group_invariant(key._C) + if p in self._cache: + for H0 in self._cache[p]: + if _is_conjugate(key.subgroup_of(), key._C, H0): + return H0 + else: + self._cache[p].append(H) + else: + self._cache[p] = [H] + return H + + def get_name(self, H): + r""" + Takes a subgroup as input and returns its associated name, if any. + Otherwise, the generators are returned. Returns a string. + """ + G = self._normalize(H) + name = self._names.get(G, None) + return name if name else repr(G.gens()) + + def set_name(self, H, name): + r""" + Takes a subgroup as input and sets its name. + """ + if not isinstance(name, str): + raise ValueError("name must be a string") + G = self._normalize(H) + self._names[G] = name + + def unset_name(self, H): + r""" + Takes a subgroup as input and removes its name, if any. + """ + G = self._normalize(H) + self._names.pop(G, None) + class ConjugacyClassOfSubgroups(Element): def __init__(self, parent, C): r""" @@ -48,6 +99,9 @@ def __init__(self, parent, C): Element.__init__(self, parent) self._C = C + def subgroup_of(self): + return self.parent()._G + def __hash__(self): r""" Return the hash of the representative of the conjugacy class. @@ -81,8 +135,7 @@ def _repr_(self): sage: B[Z4] B[((1,2,3,4),)] """ - name = self.parent()._names.get(self._C, None) - return repr(self._C.gens()) if name is None else name + return self.parent()._namegetter(self._C) def __le__(self, other): r""" @@ -103,7 +156,7 @@ def __le__(self, other): 17 """ return (isinstance(other, ConjugacyClassOfSubgroups) - and (GAP_FAIL != libgap.ContainedConjugates(self.parent()._G, + and (GAP_FAIL != libgap.ContainedConjugates(self.subgroup_of(), other._C, self._C, True))) @@ -124,7 +177,7 @@ def __eq__(self, other): True """ return (isinstance(other, ConjugacyClassOfSubgroups) - and _is_conjugate(self.parent()._G, self._C, other._C)) + and _is_conjugate(self.subgroup_of(), self._C, other._C)) class ConjugacyClassesOfSubgroups(Parent): def __init__(self, G): @@ -143,8 +196,7 @@ def __init__(self, G): sage: TestSuite(C).run() """ self._G = G - self._cache = dict() # invariant to subgroups - self._names = dict() # dictionary mapping subgroups to names + self._namegetter = lambda H: repr(H.gens()) Parent.__init__(self, category=FiniteEnumeratedSets()) def __eq__(self, other): @@ -181,52 +233,6 @@ def __hash__(self): """ return hash(self._G) - def _group_invariant(self, H): - r""" - Return the set of group invariants associated with ``H``. - - TESTS:: - - sage: from sage.rings.burnside import ConjugacyClassesOfSubgroups - sage: G = SymmetricGroup(4) - sage: C = ConjugacyClassesOfSubgroups(G) - sage: Z4 = CyclicPermutationGroup(4) - sage: C._group_invariant(Z4) - 4 - """ - return H.order() - - def _normalize(self, H): - r""" - Add ``H`` as the representative of its conjugacy class to the cache and return it. - - If a representative of the conjugacy class of ``H`` - already exists in the cache, return that. - - TESTS:: - - sage: G = SymmetricGroup(4) - sage: B = BurnsideRing(G) - sage: H1 = PermutationGroup([(1,2)]) - sage: H2 = PermutationGroup([(2,3)]) - sage: B[H1] - B[((3,4),)] - sage: B[H2] #indirect doctest - B[((3,4),)] - """ - if not H.is_subgroup(self._G): - raise ValueError(f"{H} is not a subgroup of {self._G}") - p = self._group_invariant(H) - if p in self._cache: - for H0 in self._cache[p]: - if _is_conjugate(self._G, H, H0): - return H0 - else: - self._cache[p].append(H) - else: - self._cache[p] = [H] - return H - def _element_constructor_(self, x): r""" Construct the conjugacy class of subgroups containing ``x``. @@ -241,38 +247,8 @@ def _element_constructor_(self, x): ((1,2,3,4),) """ if x.is_subgroup(self._G): - return self.element_class(self, self._normalize(x)) - raise ValueError(f"unable to convert {x} into {self}: not a subgroup of " + repr(self._G)) - - def set_name(self, H, name): - r""" - Rename conjugacy class of ``H`` to ``name``. - - Passing ``None`` to ``name`` will remove any previously assigned name. - - INPUT: - - ``H`` -- a subgroup of ``G``. - ``name`` -- a string that ``H`` should be printed as. - - EXAMPLES:: - - sage: G = SymmetricGroup(4) - sage: B = BurnsideRing(G) - sage: Z4 = CyclicPermutationGroup(4) - sage: B[Z4] - B[((1,2,3,4),)] - sage: B._indices.set_name(Z4, "Z4") - sage: B[Z4] - B[Z4] - sage: B._indices.set_name(Z4, None) - sage: B[Z4] - B[((1,2,3,4),)] - """ - H_norm = self._normalize(H) - if not isinstance(name, str) and name is not None: - raise TypeError("name must be a string or None") - self._names[H_norm] = name + return self.element_class(self, x) + raise ValueError(f"unable to convert {x} into {self}: not a subgroup of {self._G}") def __iter__(self): r""" @@ -333,21 +309,24 @@ def __init__(self, parent, C): sage: TestSuite(B(Z4)).run() """ ConjugacyClassOfSubgroups.__init__(self, parent, C) + + def subgroup_of(self): + return SymmetricGroup(self.grade()) def grade(self): - return self.parent()._G.degree() + return self._C.degree() def __hash__(self): r""" Return the hash of the representative of the conjugacy class. """ - return hash((hash(self.parent()._G), hash(self._C))) + return hash((hash(SymmetricGroup(self.grade())), hash(self._C))) def _repr_(self): r""" Return a string representation of ``self``. """ - return repr((self.grade(), super()._repr_())) + return f"({self.grade()}, {super()._repr_()})" def __eq__(self, other): r""" @@ -356,7 +335,7 @@ def __eq__(self, other): Two elements compare equal if they are conjugate subgroups in the parent group. """ return (isinstance(other, ConjugacyClassOfSubgroups_SymmetricGroup) - and self.grade() == other.grade() and _is_conjugate(self.parent()._G, self._C, other._C)) + and self.grade() == other.grade() and _is_conjugate(SymmetricGroup(self._C), self._C, other._C)) class ConjugacyClassesOfSubgroups_SymmetricGroup(ConjugacyClassesOfSubgroups): def __init__(self, n): @@ -366,6 +345,7 @@ def __init__(self, n): class ConjugacyClassesOfSubgroups_SymmetricGroup_all(UniqueRepresentation, Parent): def __init__(self): + self._namegetter = lambda H: repr(H.gens()) category = SetsWithGrading().Infinite() Parent.__init__(self, category=category) @@ -379,7 +359,7 @@ def _element_constructor_(self, H): r""" H is a subgroup of a symmetric group. """ - return self.subset(H.degree())(H) + return self.element_class(self, H) def __iter__(self): n = 0 @@ -395,7 +375,7 @@ def __contains__(self, H): Element = ConjugacyClassOfSubgroups_SymmetricGroup -class BurnsideRing(CombinatorialFreeModule): +class BurnsideRing(CombinatorialFreeModule, SubgroupNameStore): def __init__(self, G, base_ring=ZZ): r""" The Burnside ring of the group ``G``. @@ -438,11 +418,13 @@ def __init__(self, G, base_ring=ZZ): sage: TestSuite(B).run() """ self._G = G - basis = ConjugacyClassesOfSubgroups(G) - basis.set_name(G, "1") + basis_keys = ConjugacyClassesOfSubgroups(G) category = Algebras(base_ring).Commutative().WithBasis() - CombinatorialFreeModule.__init__(self, base_ring, basis, + CombinatorialFreeModule.__init__(self, base_ring, basis_keys, category=category, prefix="B") + SubgroupNameStore.__init__(self, basis_keys) + basis_keys._namegetter = self.get_name + self.set_name(G, "1") def __getitem__(self, H): r""" @@ -566,7 +548,7 @@ def product_on_basis(self, g1, g2): """ #TODO: Find faster way to multiply assert g1.parent() == g2.parent() - G = g1.parent()._G + G = g1.subgroup_of() dom1 = [frozenset(g) for g in G.cosets(g1._C, side="left")] dom2 = [frozenset(g) for g in G.cosets(g2._C, side="left")] domain = cartesian_product([dom1, dom2]) @@ -603,13 +585,16 @@ def _repr_(self): """ return "Burnside ring of " + repr(self._G) -class PolynomialMolecularDecomposition(CombinatorialFreeModule): +class PolynomialMolecularDecomposition(CombinatorialFreeModule, SubgroupNameStore): def __init__(self, base_ring=ZZ): + basis_keys = ConjugacyClassesOfSubgroups_SymmetricGroup_all() category = GradedAlgebrasWithBasis(base_ring) CombinatorialFreeModule.__init__(self, base_ring, - basis_keys=ConjugacyClassesOfSubgroups_SymmetricGroup_all(), + basis_keys=basis_keys, category=category, prefix="PMD") + SubgroupNameStore.__init__(self, basis_keys) + basis_keys._namegetter = self.get_name # FIXME: this is currently required, because the implementation of ``basis`` # in CombinatorialFreeModule overrides that of GradedModulesWithBasis From 6dd1b871ae64abc5e167659583938969cdfb962d Mon Sep 17 00:00:00 2001 From: Newtech66 Date: Wed, 19 Jun 2024 02:39:26 +0530 Subject: [PATCH 035/537] Add default_name for fallback if no name is present --- src/sage/rings/burnside.py | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/src/sage/rings/burnside.py b/src/sage/rings/burnside.py index 7269781b307..d7fe2a81494 100644 --- a/src/sage/rings/burnside.py +++ b/src/sage/rings/burnside.py @@ -46,7 +46,6 @@ def _group_invariant(self, H): return H.order() def _normalize(self, H): - print('Normalize was called') key = self._key_constructor(H) p = self._group_invariant(key._C) if p in self._cache: @@ -64,9 +63,11 @@ def get_name(self, H): Takes a subgroup as input and returns its associated name, if any. Otherwise, the generators are returned. Returns a string. """ + # If name exists, I want to return that, otherwise I want a default name. + # But only basis_keys can provide that default name. G = self._normalize(H) name = self._names.get(G, None) - return name if name else repr(G.gens()) + return name if name else self._key_constructor(H).default_name() def set_name(self, H, name): r""" @@ -102,6 +103,9 @@ def __init__(self, parent, C): def subgroup_of(self): return self.parent()._G + def default_name(self): + return repr(self._C) + def __hash__(self): r""" Return the hash of the representative of the conjugacy class. @@ -128,14 +132,15 @@ def _repr_(self): sage: Z4 = CyclicPermutationGroup(4) sage: B[Z4] B[((1,2,3,4),)] - sage: B._indices.set_name(Z4, "Z4") + sage: B.set_name(Z4, "Z4") sage: B[Z4] #indirect doctest B[Z4] - sage: B._indices.set_name(Z4, None) + sage: B.unset_name(Z4) sage: B[Z4] B[((1,2,3,4),)] """ - return self.parent()._namegetter(self._C) + namefunc = self.parent()._namegetter + return namefunc(self._C) if namefunc else self.default_name() def __le__(self, other): r""" @@ -196,7 +201,7 @@ def __init__(self, G): sage: TestSuite(C).run() """ self._G = G - self._namegetter = lambda H: repr(H.gens()) + self._namegetter = None Parent.__init__(self, category=FiniteEnumeratedSets()) def __eq__(self, other): @@ -313,6 +318,9 @@ def __init__(self, parent, C): def subgroup_of(self): return SymmetricGroup(self.grade()) + def default_name(self): + return f"({self.grade()}, {repr(self._C)})" + def grade(self): return self._C.degree() @@ -345,7 +353,7 @@ def __init__(self, n): class ConjugacyClassesOfSubgroups_SymmetricGroup_all(UniqueRepresentation, Parent): def __init__(self): - self._namegetter = lambda H: repr(H.gens()) + self._namegetter = None category = SetsWithGrading().Infinite() Parent.__init__(self, category=category) From 77136a3194f56b5060b55789d681b9085eeec93a Mon Sep 17 00:00:00 2001 From: Newtech66 Date: Wed, 19 Jun 2024 02:42:03 +0530 Subject: [PATCH 036/537] Minor correction --- src/sage/rings/burnside.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/rings/burnside.py b/src/sage/rings/burnside.py index d7fe2a81494..2f23c7f2e44 100644 --- a/src/sage/rings/burnside.py +++ b/src/sage/rings/burnside.py @@ -104,7 +104,7 @@ def subgroup_of(self): return self.parent()._G def default_name(self): - return repr(self._C) + return repr(self._C.gens()) def __hash__(self): r""" @@ -319,7 +319,7 @@ def subgroup_of(self): return SymmetricGroup(self.grade()) def default_name(self): - return f"({self.grade()}, {repr(self._C)})" + return f"({self.grade()}, {repr(self._C.gens())})" def grade(self): return self._C.degree() From 1e0a707bd9037c59b6271a41fa7a0dc55929d927 Mon Sep 17 00:00:00 2001 From: Newtech66 Date: Wed, 19 Jun 2024 02:46:45 +0530 Subject: [PATCH 037/537] Remove _repr_ from ConjugacyClassOfSubgroups_SymmetricGroup --- src/sage/rings/burnside.py | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/sage/rings/burnside.py b/src/sage/rings/burnside.py index 2f23c7f2e44..30f9aa21c1d 100644 --- a/src/sage/rings/burnside.py +++ b/src/sage/rings/burnside.py @@ -330,12 +330,6 @@ def __hash__(self): """ return hash((hash(SymmetricGroup(self.grade())), hash(self._C))) - def _repr_(self): - r""" - Return a string representation of ``self``. - """ - return f"({self.grade()}, {super()._repr_()})" - def __eq__(self, other): r""" Return if this element is equal to ``other``. From 9ffc003c6d768708b9bceb68ea54cb83492ebb42 Mon Sep 17 00:00:00 2001 From: Newtech66 Date: Sun, 23 Jun 2024 00:10:53 +0530 Subject: [PATCH 038/537] Reworked naming system again to use CombinatorialFreeModule's naming system --- src/sage/rings/burnside.py | 95 ++++++++++++++++---------------------- 1 file changed, 39 insertions(+), 56 deletions(-) diff --git a/src/sage/rings/burnside.py b/src/sage/rings/burnside.py index 30f9aa21c1d..62d1c658641 100644 --- a/src/sage/rings/burnside.py +++ b/src/sage/rings/burnside.py @@ -14,7 +14,6 @@ from sage.combinat.free_module import CombinatorialFreeModule from sage.categories.graded_algebras_with_basis import GradedAlgebrasWithBasis from sage.categories.filtered_modules_with_basis import FilteredModulesWithBasis -from sage.rings.integer import Integer GAP_FAIL = libgap.eval('fail') @@ -33,24 +32,24 @@ def _is_conjugate(G, H1, H2): """ return GAP_FAIL != libgap.RepresentativeAction(G, H1, H2) -class SubgroupNameStore(): - def __init__(self, basis_keys): +class SubgroupStore(): + def __init__(self): r""" - This class stores subgroup <-> name associations. + This class caches subgroup information and provides + helper methods to handle subgroup <-> name associations. """ - self._key_constructor = basis_keys self._cache = dict() # invariant to subgroups - self._names = dict() # dictionary mapping subgroups to names + self._names = dict() # stores subgroup names def _group_invariant(self, H): return H.order() def _normalize(self, H): - key = self._key_constructor(H) - p = self._group_invariant(key._C) + # H is of type self.element_class + p = self._group_invariant(H._C) if p in self._cache: for H0 in self._cache[p]: - if _is_conjugate(key.subgroup_of(), key._C, H0): + if _is_conjugate(H.subgroup_of(), H._C, H0._C): return H0 else: self._cache[p].append(H) @@ -63,11 +62,10 @@ def get_name(self, H): Takes a subgroup as input and returns its associated name, if any. Otherwise, the generators are returned. Returns a string. """ - # If name exists, I want to return that, otherwise I want a default name. - # But only basis_keys can provide that default name. - G = self._normalize(H) + key = self.element_class(self, H) + G = self._normalize(key) name = self._names.get(G, None) - return name if name else self._key_constructor(H).default_name() + return name if name else repr(G) def set_name(self, H, name): r""" @@ -75,14 +73,16 @@ def set_name(self, H, name): """ if not isinstance(name, str): raise ValueError("name must be a string") - G = self._normalize(H) + key = self.element_class(self, H) + G = self._normalize(key) self._names[G] = name def unset_name(self, H): r""" Takes a subgroup as input and removes its name, if any. """ - G = self._normalize(H) + key = self.element_class(self, H) + G = self._normalize(key) self._names.pop(G, None) class ConjugacyClassOfSubgroups(Element): @@ -103,9 +103,6 @@ def __init__(self, parent, C): def subgroup_of(self): return self.parent()._G - def default_name(self): - return repr(self._C.gens()) - def __hash__(self): r""" Return the hash of the representative of the conjugacy class. @@ -120,27 +117,10 @@ def __hash__(self): True """ return hash(self._C) - + def _repr_(self): - r""" - Return a string representation of ``self``. - - TESTS:: - - sage: G = SymmetricGroup(4) - sage: B = BurnsideRing(G) - sage: Z4 = CyclicPermutationGroup(4) - sage: B[Z4] - B[((1,2,3,4),)] - sage: B.set_name(Z4, "Z4") - sage: B[Z4] #indirect doctest - B[Z4] - sage: B.unset_name(Z4) - sage: B[Z4] - B[((1,2,3,4),)] - """ - namefunc = self.parent()._namegetter - return namefunc(self._C) if namefunc else self.default_name() + name = self.parent()._names.get(self._C, None) + return name if name else repr(self._C.gens()) def __le__(self, other): r""" @@ -184,7 +164,7 @@ def __eq__(self, other): return (isinstance(other, ConjugacyClassOfSubgroups) and _is_conjugate(self.subgroup_of(), self._C, other._C)) -class ConjugacyClassesOfSubgroups(Parent): +class ConjugacyClassesOfSubgroups(Parent, SubgroupStore): def __init__(self, G): r""" Initialize the set of conjugacy classes of ``G``. @@ -201,8 +181,8 @@ def __init__(self, G): sage: TestSuite(C).run() """ self._G = G - self._namegetter = None Parent.__init__(self, category=FiniteEnumeratedSets()) + SubgroupStore.__init__(self) def __eq__(self, other): r""" @@ -252,7 +232,8 @@ def _element_constructor_(self, x): ((1,2,3,4),) """ if x.is_subgroup(self._G): - return self.element_class(self, x) + key = self.element_class(self, x) + return self._normalize(key) raise ValueError(f"unable to convert {x} into {self}: not a subgroup of {self._G}") def __iter__(self): @@ -318,8 +299,8 @@ def __init__(self, parent, C): def subgroup_of(self): return SymmetricGroup(self.grade()) - def default_name(self): - return f"({self.grade()}, {repr(self._C.gens())})" + def _repr_(self): + return f"({self.grade()}, {super()._repr_()})" def grade(self): return self._C.degree() @@ -337,7 +318,7 @@ def __eq__(self, other): Two elements compare equal if they are conjugate subgroups in the parent group. """ return (isinstance(other, ConjugacyClassOfSubgroups_SymmetricGroup) - and self.grade() == other.grade() and _is_conjugate(SymmetricGroup(self._C), self._C, other._C)) + and self.grade() == other.grade() and _is_conjugate(self.subgroup_of(), self._C, other._C)) class ConjugacyClassesOfSubgroups_SymmetricGroup(ConjugacyClassesOfSubgroups): def __init__(self, n): @@ -345,11 +326,11 @@ def __init__(self, n): Element = ConjugacyClassOfSubgroups_SymmetricGroup -class ConjugacyClassesOfSubgroups_SymmetricGroup_all(UniqueRepresentation, Parent): +class ConjugacyClassesOfSubgroups_SymmetricGroup_all(UniqueRepresentation, Parent, SubgroupStore): def __init__(self): - self._namegetter = None category = SetsWithGrading().Infinite() Parent.__init__(self, category=category) + SubgroupStore.__init__(self) def _repr_(self): return "Conjugacy classes of subgroups of symmetric groups" @@ -357,11 +338,15 @@ def _repr_(self): def subset(self, size): return ConjugacyClassesOfSubgroups_SymmetricGroup(size) - def _element_constructor_(self, H): + def _element_constructor_(self, x): r""" - H is a subgroup of a symmetric group. + x is a subgroup of a symmetric group. """ - return self.element_class(self, H) + G = SymmetricGroup(x.degree()) + if x.is_subgroup(G): + key = self.element_class(self, x) + return self._normalize(key) + raise ValueError(f"unable to convert {x} into {self}: not a subgroup of {G}") def __iter__(self): n = 0 @@ -377,7 +362,7 @@ def __contains__(self, H): Element = ConjugacyClassOfSubgroups_SymmetricGroup -class BurnsideRing(CombinatorialFreeModule, SubgroupNameStore): +class BurnsideRing(CombinatorialFreeModule): def __init__(self, G, base_ring=ZZ): r""" The Burnside ring of the group ``G``. @@ -424,9 +409,8 @@ def __init__(self, G, base_ring=ZZ): category = Algebras(base_ring).Commutative().WithBasis() CombinatorialFreeModule.__init__(self, base_ring, basis_keys, category=category, prefix="B") - SubgroupNameStore.__init__(self, basis_keys) - basis_keys._namegetter = self.get_name - self.set_name(G, "1") + self._print_options['names'] = self._indices._names + self._indices.set_name(G, "1") def __getitem__(self, H): r""" @@ -587,7 +571,7 @@ def _repr_(self): """ return "Burnside ring of " + repr(self._G) -class PolynomialMolecularDecomposition(CombinatorialFreeModule, SubgroupNameStore): +class PolynomialMolecularDecomposition(CombinatorialFreeModule): def __init__(self, base_ring=ZZ): basis_keys = ConjugacyClassesOfSubgroups_SymmetricGroup_all() category = GradedAlgebrasWithBasis(base_ring) @@ -595,8 +579,7 @@ def __init__(self, base_ring=ZZ): basis_keys=basis_keys, category=category, prefix="PMD") - SubgroupNameStore.__init__(self, basis_keys) - basis_keys._namegetter = self.get_name + self._print_options['names'] = self._indices._names # FIXME: this is currently required, because the implementation of ``basis`` # in CombinatorialFreeModule overrides that of GradedModulesWithBasis From d51bd1d663282448c8d2754e41d1b20f08030cfb Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Sun, 23 Jun 2024 14:45:48 +0530 Subject: [PATCH 039/537] Modified ChowRingIdeal class --- src/sage/matroids/chow_ring_ideal.py | 77 +++++++++++++++++++--------- 1 file changed, 54 insertions(+), 23 deletions(-) diff --git a/src/sage/matroids/chow_ring_ideal.py b/src/sage/matroids/chow_ring_ideal.py index 3b5d0a16207..4e55ca4a313 100644 --- a/src/sage/matroids/chow_ring_ideal.py +++ b/src/sage/matroids/chow_ring_ideal.py @@ -10,7 +10,7 @@ class ChowRingIdeal(MPolynomialIdeal): def __init__(self, M, R): self._matroid = M - self.flats = [X for i in range(1, self._matroid.rank()) + self.flats = [X for i in range(1, self._matroid.rank()) #_flats. NOT NEEDED AS AN ATTRIBUTE. USE NAMES for X in self._matroid.flats(i)] E = list(self._matroid.groundset()) @@ -18,17 +18,17 @@ def __init__(self, M, R): for i,F in enumerate(self.flats): for x in F: flats_containing[x].append(i) - self.names = dict() + self.flat_generator = dict() try: names = ['A{}'.format(''.join(str(x) for x in sorted(F, key=cmp_elements_key))) for F in self.flats] - self.poly_ring = PolynomialRing(R, names) + self.poly_ring = PolynomialRing(R, names) #self.ring for F in self.flats: for i in range(len(self.poly_ring.gens())): - self.names[F] = self.poly_ring.gens()[i] + self.flat_generator[F] = self.poly_ring.gens()[i] #change self.names to self.flat_generator except ValueError: # variables are not proper names self.poly_ring = PolynomialRing(R, 'A', len(self.flats)) for i in range(len(self.flats)): - self.names[self.flats[i]] = self.poly_ring.gens()[i] + self.flat_generator[self.flats[i]] = self.poly_ring.gens()[i] gens = self.poly_ring.gens() Q = [gens[i] * gens[i+j+1] for i,F in enumerate(self.flats) @@ -41,13 +41,13 @@ def __init__(self, M, R): MPolynomialIdeal.__init__(self, self.poly_ring, self.gens) - def __repr__(self): + def _repr_(self): return "Chow ring ideal of {}".format(self._matroid) def groebner_basis(self): gb = list() for F in self.flats: - for G in self.flats: + for G in self.flats: #write from F not G if not (F < G or G < F): gb.append(self.names[F]*self.names[G]) elif Set(F).is_empty(): @@ -66,6 +66,16 @@ def groebner_basis(self): return gb + def matroid(self): + return Matroid(self._matroid) + + def flat_generator(self): + return dict(self.flat_generator) + +#get matroid method, called matroid, returning the matroid +#get names + + class AugmentedChowRingIdeal(MPolynomialIdeal): def __init__(self, M, R): self._matroid = M @@ -77,19 +87,38 @@ def __init__(self, M, R): for i,F in enumerate(self.flats): for x in F: flats_containing[x].append(i) - self.names = dict() + self.flats_generator = dict() #names_groundset = ['A{}'.format(''.join(str(x))) for x in E] #names_flats = ['B{}'.format(''.join(str(x) for x in sorted(F, key=cmp_elements_key))) for F in self.flats] self.poly_ring = PolynomialRing(R, 'A', len(E) + len(self.flats)) gens = self.poly_ring.gens() for i,x in enumerate(E): - self.names[x] = gens[i] + self.flats_generator[x] = gens[i] for i,F in enumerate(self.flats): - self.names[F] = gens[len(E) + i] + self.flats_generator[F] = gens[len(E) + i] + + print(gens) - Q =[gens[len(E)+i] * gens[len(E)+i+j+1] for i,F in enumerate(self.flats) - for j,G in enumerate(self.flats[i+1:]) if not (F < G or G < F)] - Q.append([gens[i]*gens[len(E)+j] for i,x in enumerate(E) for j,F in enumerate(self.flats) if F not in flats_containing[x]]) + Q = list() + for i,F in enumerate(self.flats): + for j,G in enumerate(self.flats): + if not (F < G or G < F): + print(type(gens[len(E)+i] * gens[len(E)+i+j+1])) + Q.append(gens[len(E)+i] * gens[len(E)+i+j+1]) + + for j,F in enumerate(self.flats): + for k,x in enumerate(E): + if F not in flats_containing[x]: + print(type(gens[k]*gens[len(E)+j])) + Q.append(gens[k]*gens[len(E)+j]) + print("this is Q", Q) + + + + #debug Q and L. coerce must be true. Coerce allows you to add two different elements from two different rings + #Q =[gens[len(E)+i] * gens[len(E)+i+j+1] for i,F in enumerate(self.flats) + #for j,G in enumerate(self.flats[i+1:]) if not (F < G or G < F)] + #Q.append([gens[i]*gens[len(E)+j] for i,x in enumerate(E) for j,F in enumerate(self.flats) if F not in flats_containing[x]]) L = list() for i,x in enumerate(E): term = 0 @@ -100,17 +129,19 @@ def __init__(self, M, R): self.gens = Q + L MPolynomialIdeal.__init__(self, self.poly_ring, self.gens, coerce=False) - def __repr__(self): + def _repr_short(self): #use single underscore return "Augmented Chow ring ideal of {}".format(self._matroid) def groebner_basis(self, atom_free=False): - #add removal of empty flat line - #list returned or iterator returned? + #list returned or iterator returned? - neither - polynomial_sequence_generic object gb = [] + flats = self.flats + if Set([]) in flats: + flats.remove(Set([])) if atom_free: - for F in self.flats: - for G in self.flats: + for F in flats: + for G in flats: if not (F > G or G > F): gb.append(self.names[F]*self.names[G]) elif F < G: @@ -124,17 +155,17 @@ def groebner_basis(self, atom_free=False): else: E = list(self._matroid.groundset()) for i in E: - for F in self.flats: - for G in self.flats: + for F in flats: + for G in flats: term = 0 - for H in self.flats: + for H in flats: if i in Set(H): term += self.names[H] gb.append(self.names[i] + term) if i in Set(F): term = 0 - for H in self.flats: + for H in flats: if H < F: term += self.names[H] gb.append(self.names[i]*(term**self._matroid.rank(Set(G)))* @@ -148,7 +179,7 @@ def groebner_basis(self, atom_free=False): elif F < G: term = 0 - for H in self.flats: + for H in flats: if H < F: term += self.names[H] gb.append(term**(self._matroid.rank(Set(G))-self._matroid.rank(Set(F)))) From 462ce6c0c25d916a85dba2e54963c4bb0dc30ca6 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Sun, 23 Jun 2024 14:47:36 +0530 Subject: [PATCH 040/537] Created Chow Ring class --- src/sage/matroids/chow_ring.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 src/sage/matroids/chow_ring.py diff --git a/src/sage/matroids/chow_ring.py b/src/sage/matroids/chow_ring.py new file mode 100644 index 00000000000..0498307f491 --- /dev/null +++ b/src/sage/matroids/chow_ring.py @@ -0,0 +1,18 @@ +from sage.matroids.chow_ring_ideal import * +from sage.rings.quotient_ring import QuotientRing_nc +from sage.rings.quotient_ring_element import QuotientRingElement +from sage.categories.graded_algebras_with_basis import GradedAlgebrasWithBasis +import sage.misc.latex as latex + +class ChowRing(QuotientRing_nc, category=GradedAlgebrasWithBasis): + def __init__(self, R, M): + self._matroid = M + self._ideal = ChowRingIdeal(M, R) + self.poly_ring = self._ideal.poly_ring + QuotientRing_nc.__init__(R, self._ideal, names=self.poly_ring.variable_names, category=GradedAlgebrasWithBasis) + + def _repr_(self): + return "Chow ring of {}".format(self._matroid) + + def _latex_(self): + return "%s/%s" % (latex.latex(self.poly_ring), latex.latex(self._ideal)) \ No newline at end of file From ad4c43c1c4f7f609dfe84921966c9e183c4bd8dc Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Sun, 23 Jun 2024 14:49:08 +0530 Subject: [PATCH 041/537] Created Augmented Chow Ring class --- src/sage/matroids/chow_ring.py | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/sage/matroids/chow_ring.py b/src/sage/matroids/chow_ring.py index 0498307f491..ac59ca2d408 100644 --- a/src/sage/matroids/chow_ring.py +++ b/src/sage/matroids/chow_ring.py @@ -15,4 +15,17 @@ def _repr_(self): return "Chow ring of {}".format(self._matroid) def _latex_(self): - return "%s/%s" % (latex.latex(self.poly_ring), latex.latex(self._ideal)) \ No newline at end of file + return "%s/%s" % (latex.latex(self.poly_ring), latex.latex(self._ideal)) + +class AugmentedChowRing(QuotientRing_nc, category=GradedAlgebrasWithBasis): + def __init__(self, R, M): + self._matroid = M + self._ideal = AugmentedChowRingIdeal(M, R) + self.poly_ring = self._ideal.poly_ring + QuotientRing_nc.__init__(R, self._ideal, names=self.poly_ring.variable_names, category=GradedAlgebrasWithBasis) + + def _repr_(self): + return "Chow ring of {}".format(self._matroid) + + def _latex_(self): + return "%s/%s" % (latex.latex(self.poly_ring), latex.latex(self._ideal)) \ No newline at end of file From 4207aab4450a7efa206a70df45f29c4a40494009 Mon Sep 17 00:00:00 2001 From: Newtech66 Date: Mon, 24 Jun 2024 01:11:48 +0530 Subject: [PATCH 042/537] Minor performance improvements --- src/sage/rings/burnside.py | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/src/sage/rings/burnside.py b/src/sage/rings/burnside.py index 62d1c658641..050d327a43d 100644 --- a/src/sage/rings/burnside.py +++ b/src/sage/rings/burnside.py @@ -7,13 +7,12 @@ from sage.categories.sets_cat import cartesian_product from sage.categories.finite_enumerated_sets import FiniteEnumeratedSets from sage.categories.sets_with_grading import SetsWithGrading +from sage.categories.graded_algebras_with_basis import GradedAlgebrasWithBasis +from sage.categories.algebras import Algebras from sage.groups.perm_gps.permgroup import PermutationGroup, PermutationGroup_generic from sage.groups.perm_gps.permgroup_named import SymmetricGroup from sage.libs.gap.libgap import libgap -from sage.categories.algebras import Algebras from sage.combinat.free_module import CombinatorialFreeModule -from sage.categories.graded_algebras_with_basis import GradedAlgebrasWithBasis -from sage.categories.filtered_modules_with_basis import FilteredModulesWithBasis GAP_FAIL = libgap.eval('fail') @@ -46,10 +45,12 @@ def _group_invariant(self, H): def _normalize(self, H): # H is of type self.element_class + G = H.subgroup_of() + H._C = G.subgroup(H._C.gens_small()) p = self._group_invariant(H._C) if p in self._cache: for H0 in self._cache[p]: - if _is_conjugate(H.subgroup_of(), H._C, H0._C): + if _is_conjugate(G, H._C, H0._C): return H0 else: self._cache[p].append(H) @@ -532,13 +533,17 @@ def product_on_basis(self, g1, g2): sage: B.product_on_basis(C(Z2), C(Z3)) B[((),)] """ + def get_left_cosets(G,H): + right_transversal = libgap.List(libgap.RightTransversal(G, H)) + libgap.Apply(right_transversal, libgap.Inverse) + left_transversal = [rep.sage(G) for rep in right_transversal] + return [frozenset(rep * h for h in H) for rep in left_transversal] #TODO: Find faster way to multiply assert g1.parent() == g2.parent() G = g1.subgroup_of() - dom1 = [frozenset(g) for g in G.cosets(g1._C, side="left")] - dom2 = [frozenset(g) for g in G.cosets(g2._C, side="left")] + dom1 = get_left_cosets(G, g1._C) + dom2 = get_left_cosets(G, g2._C) domain = cartesian_product([dom1, dom2]) - def action(g, pair): return (frozenset(g * h for h in pair[0]), frozenset(g * h for h in pair[1])) @@ -581,10 +586,6 @@ def __init__(self, base_ring=ZZ): prefix="PMD") self._print_options['names'] = self._indices._names - # FIXME: this is currently required, because the implementation of ``basis`` - # in CombinatorialFreeModule overrides that of GradedModulesWithBasis - basis = FilteredModulesWithBasis.ParentMethods.__dict__['basis'] - def __getitem__(self, x): r""" Return the basis element indexed by ``x``. From 8c4b0e28539e393b926207ec3549505205efed4b Mon Sep 17 00:00:00 2001 From: Newtech66 Date: Mon, 24 Jun 2024 01:44:20 +0530 Subject: [PATCH 043/537] Major performance improvement in PolynomialMolecularDecomposition product_on_basis --- src/sage/rings/burnside.py | 22 +++++++--------------- 1 file changed, 7 insertions(+), 15 deletions(-) diff --git a/src/sage/rings/burnside.py b/src/sage/rings/burnside.py index 050d327a43d..32c75c81f2d 100644 --- a/src/sage/rings/burnside.py +++ b/src/sage/rings/burnside.py @@ -609,26 +609,18 @@ def one_basis(self): def product_on_basis(self, g1, g2): n, m = g1.grade(), g2.grade() - H, K = g1._C, g2._C - - def construct_element(h, k): - element = [None for _ in range(n+m)] - for i in range(n+m): - if i < n: - element[i] = h(i+1) - else: - element[i] = n + k(i-n+1) - return element - H_ast_K = [ - construct_element(h, k) - for h in H - for k in K - ] # There is no way to create SymmetricGroup(0) using the # PermutationGroup constructor as used here, so a special # case has to be added. if n+m == 0: return self._from_dict({self._indices(SymmetricGroup(0)): 1}) + # We only really need to multiply generators, since we are multiplying + # permutations acting on disjoint domains. + H_ast_K = [ + h*k + for h in SymmetricGroup(n).gens_small() + for k in SymmetricGroup(range(n+1,n+m+1)).gens_small() + ] G = PermutationGroup(H_ast_K) return self._from_dict({self._indices(G): 1}) From cbf6db49cb0bcedd936d758e78f1c0ce845d78f2 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Tue, 25 Jun 2024 09:52:40 +0530 Subject: [PATCH 044/537] Edited __init__ and _repr_short funcs --- src/sage/matroids/chow_ring.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/sage/matroids/chow_ring.py b/src/sage/matroids/chow_ring.py index ac59ca2d408..7af728f2c71 100644 --- a/src/sage/matroids/chow_ring.py +++ b/src/sage/matroids/chow_ring.py @@ -4,27 +4,27 @@ from sage.categories.graded_algebras_with_basis import GradedAlgebrasWithBasis import sage.misc.latex as latex -class ChowRing(QuotientRing_nc, category=GradedAlgebrasWithBasis): +class ChowRing(QuotientRing_nc): def __init__(self, R, M): self._matroid = M self._ideal = ChowRingIdeal(M, R) self.poly_ring = self._ideal.poly_ring - QuotientRing_nc.__init__(R, self._ideal, names=self.poly_ring.variable_names, category=GradedAlgebrasWithBasis) + QuotientRing_nc.__init__(self, R=R, I=self._ideal, names=self.poly_ring.variable_names, category=GradedAlgebrasWithBasis) - def _repr_(self): + def _repr_short(self): return "Chow ring of {}".format(self._matroid) def _latex_(self): return "%s/%s" % (latex.latex(self.poly_ring), latex.latex(self._ideal)) -class AugmentedChowRing(QuotientRing_nc, category=GradedAlgebrasWithBasis): +class AugmentedChowRing(QuotientRing_nc): def __init__(self, R, M): self._matroid = M self._ideal = AugmentedChowRingIdeal(M, R) self.poly_ring = self._ideal.poly_ring - QuotientRing_nc.__init__(R, self._ideal, names=self.poly_ring.variable_names, category=GradedAlgebrasWithBasis) + QuotientRing_nc.__init__(self, R, self._ideal, names=self.poly_ring.variable_names, category=GradedAlgebrasWithBasis) - def _repr_(self): + def _repr_short(self): return "Chow ring of {}".format(self._matroid) def _latex_(self): From 12a129b3cb59a032b61eb891b345a0ae47b6bb31 Mon Sep 17 00:00:00 2001 From: Newtech66 Date: Wed, 26 Jun 2024 10:29:27 +0530 Subject: [PATCH 045/537] Much faster implementation of Burnside ring product --- src/sage/rings/burnside.py | 30 ++++++++++++------------------ 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/src/sage/rings/burnside.py b/src/sage/rings/burnside.py index 32c75c81f2d..d248685bad6 100644 --- a/src/sage/rings/burnside.py +++ b/src/sage/rings/burnside.py @@ -505,9 +505,9 @@ def one_basis(self): """ return self._indices(self._G) - def product_on_basis(self, g1, g2): + def product_on_basis(self, H, K): r""" - Return the product of the basis elements indexed by ``g1`` and ``g2``. + Return the product of the basis elements indexed by ``H`` and ``K``. For the symmetric group, this is also known as the Hadamard or tensor product of group actions. @@ -533,22 +533,16 @@ def product_on_basis(self, g1, g2): sage: B.product_on_basis(C(Z2), C(Z3)) B[((),)] """ - def get_left_cosets(G,H): - right_transversal = libgap.List(libgap.RightTransversal(G, H)) - libgap.Apply(right_transversal, libgap.Inverse) - left_transversal = [rep.sage(G) for rep in right_transversal] - return [frozenset(rep * h for h in H) for rep in left_transversal] - #TODO: Find faster way to multiply - assert g1.parent() == g2.parent() - G = g1.subgroup_of() - dom1 = get_left_cosets(G, g1._C) - dom2 = get_left_cosets(G, g2._C) - domain = cartesian_product([dom1, dom2]) - def action(g, pair): - return (frozenset(g * h for h in pair[0]), - frozenset(g * h for h in pair[1])) - - return self.construct_from_action(action, domain) + #is it correct to use DoubleCosetRepsAndSizes? It may return ANY element of the double coset! + # g_reps = [rep for rep, size in libgap.DoubleCosetRepsAndSizes(self._G, H._C, K._C)] + g_reps = libgap.List(libgap.DoubleCosets(self._G, H._C, K._C), libgap.Representative) + from collections import Counter + C = Counter() + for g in g_reps: + g_sup_K = libgap.ConjugateSubgroup(K._C, g) + P = self._G.subgroup(gap_group=libgap.Intersection(H._C, g_sup_K)) + C[self._indices(P)] += 1 + return self._from_dict(dict(C)) def group(self): r""" From 873d9a705ac99e1194a8c86380d95f10ca2bd296 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Wed, 26 Jun 2024 15:12:27 +0530 Subject: [PATCH 046/537] Modified __init__() functions for both classes --- src/sage/matroids/chow_ring_ideal.py | 74 +++++++++++++++------------- 1 file changed, 41 insertions(+), 33 deletions(-) diff --git a/src/sage/matroids/chow_ring_ideal.py b/src/sage/matroids/chow_ring_ideal.py index 4e55ca4a313..12a708d196b 100644 --- a/src/sage/matroids/chow_ring_ideal.py +++ b/src/sage/matroids/chow_ring_ideal.py @@ -1,11 +1,9 @@ -#from sage.all import * -#from sage.rings.ideal import Ideal_generic from sage.rings.polynomial.multi_polynomial_ideal import MPolynomialIdeal from sage.matroids.matroid import Matroid from sage.matroids.utilities import cmp_elements_key from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing from sage.sets.set import Set -from sage.rings.morphism import _tensor_product_ring + class ChowRingIdeal(MPolynomialIdeal): def __init__(self, M, R): @@ -18,28 +16,27 @@ def __init__(self, M, R): for i,F in enumerate(self.flats): for x in F: flats_containing[x].append(i) - self.flat_generator = dict() + + names = ['A{}'.format(''.join(str(x) for x in sorted(F, key=cmp_elements_key))) for F in self.flats] + try: - names = ['A{}'.format(''.join(str(x) for x in sorted(F, key=cmp_elements_key))) for F in self.flats] - self.poly_ring = PolynomialRing(R, names) #self.ring - for F in self.flats: - for i in range(len(self.poly_ring.gens())): - self.flat_generator[F] = self.poly_ring.gens()[i] #change self.names to self.flat_generator + poly_ring = PolynomialRing(R, names) #self.ring except ValueError: # variables are not proper names - self.poly_ring = PolynomialRing(R, 'A', len(self.flats)) - for i in range(len(self.flats)): - self.flat_generator[self.flats[i]] = self.poly_ring.gens()[i] + poly_ring = PolynomialRing(R, 'A', len(self.flats)) + + + gens = poly_ring.gens() + self.flat_generator = dict(zip(self.flats, gens)) - gens = self.poly_ring.gens() + Q = [gens[i] * gens[i+j+1] for i,F in enumerate(self.flats) for j,G in enumerate(self.flats[i+1:]) if not (F < G or G < F)] L = [sum(gens[i] for i in flats_containing[x]) - sum(gens[i] for i in flats_containing[y]) for j,x in enumerate(E) for y in E[j+1:]] - self.gens = Q + L - MPolynomialIdeal.__init__(self, self.poly_ring, self.gens) + MPolynomialIdeal.__init__(self, poly_ring, Q + L) def _repr_(self): return "Chow ring ideal of {}".format(self._matroid) @@ -67,13 +64,11 @@ def groebner_basis(self): def matroid(self): - return Matroid(self._matroid) + return self._matroid def flat_generator(self): return dict(self.flat_generator) -#get matroid method, called matroid, returning the matroid -#get names class AugmentedChowRingIdeal(MPolynomialIdeal): @@ -90,28 +85,28 @@ def __init__(self, M, R): self.flats_generator = dict() #names_groundset = ['A{}'.format(''.join(str(x))) for x in E] #names_flats = ['B{}'.format(''.join(str(x) for x in sorted(F, key=cmp_elements_key))) for F in self.flats] - self.poly_ring = PolynomialRing(R, 'A', len(E) + len(self.flats)) - gens = self.poly_ring.gens() + poly_ring = PolynomialRing(R, 'A', len(E) + len(self.flats)) + gens = poly_ring.gens() for i,x in enumerate(E): self.flats_generator[x] = gens[i] for i,F in enumerate(self.flats): self.flats_generator[F] = gens[len(E) + i] - print(gens) - + + le = len(E) Q = list() for i,F in enumerate(self.flats): for j,G in enumerate(self.flats): if not (F < G or G < F): - print(type(gens[len(E)+i] * gens[len(E)+i+j+1])) - Q.append(gens[len(E)+i] * gens[len(E)+i+j+1]) + #print(type(gens[le+i] * gens[le+i+j+1])) + Q.append(gens[le+i] * gens[le+j]) for j,F in enumerate(self.flats): for k,x in enumerate(E): if F not in flats_containing[x]: - print(type(gens[k]*gens[len(E)+j])) - Q.append(gens[k]*gens[len(E)+j]) - print("this is Q", Q) + #print(type(gens[k]*gens[len(E)+j])) + Q.append(gens[k]*gens[le+j]) + #print("this is Q", Q) @@ -121,17 +116,30 @@ def __init__(self, M, R): #Q.append([gens[i]*gens[len(E)+j] for i,x in enumerate(E) for j,F in enumerate(self.flats) if F not in flats_containing[x]]) L = list() for i,x in enumerate(E): - term = 0 + term = poly_ring.zero() for j,F in enumerate(self.flats): if F not in flats_containing[x]: - term += gens[len(E)+j] - L.append(gens[i] - term) - self.gens = Q + L - MPolynomialIdeal.__init__(self, self.poly_ring, self.gens, coerce=False) + term += gens[le+j] + L.append(gens[i] - term) + + for g in Q: + print(g, g.parent()) + for g in L: + print(g, g.parent()) + MPolynomialIdeal.__init__(self, poly_ring, Q + L) - def _repr_short(self): #use single underscore + def _repr_(self): #use single underscore return "Augmented Chow ring ideal of {}".format(self._matroid) + def matroid(self): + return self._matroid + + def flat_generator(self): + return self.flat_generator + + + + def groebner_basis(self, atom_free=False): #list returned or iterator returned? - neither - polynomial_sequence_generic object From 529bb10b3554082242c4a19f7dc053a9c2031575 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Wed, 26 Jun 2024 15:21:36 +0530 Subject: [PATCH 047/537] Debugged __init__() function of Chow ring class --- src/sage/matroids/chow_ring.py | 33 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/src/sage/matroids/chow_ring.py b/src/sage/matroids/chow_ring.py index 7af728f2c71..d4b817564a2 100644 --- a/src/sage/matroids/chow_ring.py +++ b/src/sage/matroids/chow_ring.py @@ -4,28 +4,27 @@ from sage.categories.graded_algebras_with_basis import GradedAlgebrasWithBasis import sage.misc.latex as latex +#chow rings class needs to be written properly +#gens of chow ring ideal must be debugged +#gb must be a poly sequence +#commented and documented +#use is_groebner() +#matroids - try all of them + + class ChowRing(QuotientRing_nc): - def __init__(self, R, M): + def __init__(self, R, M, augmented): self._matroid = M - self._ideal = ChowRingIdeal(M, R) - self.poly_ring = self._ideal.poly_ring - QuotientRing_nc.__init__(self, R=R, I=self._ideal, names=self.poly_ring.variable_names, category=GradedAlgebrasWithBasis) + self._augmented = augmented + if augmented: + self._ideal = AugmentedChowRingIdeal(M, R) + else: + self._ideal = ChowRingIdeal(M, R) #check method to get ring + QuotientRing_nc.__init__(self, R=self._ideal.poly_ring, I=self._ideal, names=self.poly_ring.variable_names(), category=GradedAlgebrasWithBasis(R)) - def _repr_short(self): + def _repr_(self): return "Chow ring of {}".format(self._matroid) def _latex_(self): return "%s/%s" % (latex.latex(self.poly_ring), latex.latex(self._ideal)) -class AugmentedChowRing(QuotientRing_nc): - def __init__(self, R, M): - self._matroid = M - self._ideal = AugmentedChowRingIdeal(M, R) - self.poly_ring = self._ideal.poly_ring - QuotientRing_nc.__init__(self, R, self._ideal, names=self.poly_ring.variable_names, category=GradedAlgebrasWithBasis) - - def _repr_short(self): - return "Chow ring of {}".format(self._matroid) - - def _latex_(self): - return "%s/%s" % (latex.latex(self.poly_ring), latex.latex(self._ideal)) \ No newline at end of file From 6079e3d5d888594eb71d514cabffd4df9f5e5130 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Fri, 28 Jun 2024 14:17:09 +0530 Subject: [PATCH 048/537] Modified groebner_basis() method for both classes --- src/sage/matroids/chow_ring_ideal.py | 76 ++++++++++++++-------------- 1 file changed, 37 insertions(+), 39 deletions(-) diff --git a/src/sage/matroids/chow_ring_ideal.py b/src/sage/matroids/chow_ring_ideal.py index 12a708d196b..bf5f2b50a37 100644 --- a/src/sage/matroids/chow_ring_ideal.py +++ b/src/sage/matroids/chow_ring_ideal.py @@ -3,6 +3,7 @@ from sage.matroids.utilities import cmp_elements_key from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing from sage.sets.set import Set +from sage.rings.polynomial.multi_polynomial_sequence import PolynomialSequence class ChowRingIdeal(MPolynomialIdeal): @@ -20,13 +21,13 @@ def __init__(self, M, R): names = ['A{}'.format(''.join(str(x) for x in sorted(F, key=cmp_elements_key))) for F in self.flats] try: - poly_ring = PolynomialRing(R, names) #self.ring + self.poly_ring = PolynomialRing(R, names) #self.ring except ValueError: # variables are not proper names - poly_ring = PolynomialRing(R, 'A', len(self.flats)) + self.poly_ring = PolynomialRing(R, 'A', len(self.flats)) - gens = poly_ring.gens() - self.flat_generator = dict(zip(self.flats, gens)) + gens = self.poly_ring.gens() + self.flats_generator = dict(zip(self.flats, gens)) Q = [gens[i] * gens[i+j+1] for i,F in enumerate(self.flats) @@ -36,7 +37,7 @@ def __init__(self, M, R): for j,x in enumerate(E) for y in E[j+1:]] - MPolynomialIdeal.__init__(self, poly_ring, Q + L) + MPolynomialIdeal.__init__(self, self.poly_ring, Q + L) def _repr_(self): return "Chow ring ideal of {}".format(self._matroid) @@ -44,30 +45,31 @@ def _repr_(self): def groebner_basis(self): gb = list() for F in self.flats: - for G in self.flats: #write from F not G + for G in self.flats: if not (F < G or G < F): - gb.append(self.names[F]*self.names[G]) + gb.append(self.flats_generator[F]*self.flats_generator[G]) elif Set(F).is_empty(): - term = 0 + term = self.poly_ring.zero() for H in self.flats: if H < F: - term += self.names[H] + term += self.flats_generator[H] gb.append(term**self._matroid.rank(Set(G))) elif F < G: - term = 0 + term = self.poly_ring.zero() for H in self.flats: if H < F: - term += self.names[H] + term += self.flats_generator[H] gb.append(term**(self._matroid.rank(Set(G))-self._matroid.rank(Set(F)))) - return gb + g_basis = PolynomialSequence(self.poly_ring, [gb]) + return g_basis def matroid(self): return self._matroid - def flat_generator(self): - return dict(self.flat_generator) + def flats_generator(self): + return dict(self.flats_generator) @@ -85,8 +87,8 @@ def __init__(self, M, R): self.flats_generator = dict() #names_groundset = ['A{}'.format(''.join(str(x))) for x in E] #names_flats = ['B{}'.format(''.join(str(x) for x in sorted(F, key=cmp_elements_key))) for F in self.flats] - poly_ring = PolynomialRing(R, 'A', len(E) + len(self.flats)) - gens = poly_ring.gens() + self.poly_ring = PolynomialRing(R, 'A', len(E) + len(self.flats)) + gens = self.poly_ring.gens() for i,x in enumerate(E): self.flats_generator[x] = gens[i] for i,F in enumerate(self.flats): @@ -116,17 +118,13 @@ def __init__(self, M, R): #Q.append([gens[i]*gens[len(E)+j] for i,x in enumerate(E) for j,F in enumerate(self.flats) if F not in flats_containing[x]]) L = list() for i,x in enumerate(E): - term = poly_ring.zero() + term = self.poly_ring.zero() for j,F in enumerate(self.flats): if F not in flats_containing[x]: term += gens[le+j] L.append(gens[i] - term) - for g in Q: - print(g, g.parent()) - for g in L: - print(g, g.parent()) - MPolynomialIdeal.__init__(self, poly_ring, Q + L) + MPolynomialIdeal.__init__(self, self.poly_ring, Q + L) def _repr_(self): #use single underscore return "Augmented Chow ring ideal of {}".format(self._matroid) @@ -135,14 +133,13 @@ def matroid(self): return self._matroid def flat_generator(self): - return self.flat_generator + return self.flats_generator def groebner_basis(self, atom_free=False): - #list returned or iterator returned? - neither - polynomial_sequence_generic object gb = [] flats = self.flats if Set([]) in flats: @@ -151,13 +148,13 @@ def groebner_basis(self, atom_free=False): for F in flats: for G in flats: if not (F > G or G > F): - gb.append(self.names[F]*self.names[G]) + gb.append(self.flats_generator[F]*self.flats_generator[G]) elif F < G: - term = 0 + term = self.poly_ring.zero() for H in self.flats: if H < F: - term += self.names[H] - gb.append(self.names[F]*(term**self._matroid.rank(Set(G)))* + term += self.flats_generator[H] + gb.append(self.flats_generator[F]*(term**self._matroid.rank(Set(G)))* (term**(self._matroid.rank(Set(G))-self._matroid.rank(Set(F))))) else: @@ -165,34 +162,35 @@ def groebner_basis(self, atom_free=False): for i in E: for F in flats: for G in flats: - term = 0 + term = self.poly_ring.zero() for H in flats: if i in Set(H): - term += self.names[H] - gb.append(self.names[i] + term) + term += self.flats_generator[H] + gb.append(self.flats_generator[i] + term) if i in Set(F): - term = 0 + term = self.poly_ring.zero() for H in flats: if H < F: - term += self.names[H] - gb.append(self.names[i]*(term**self._matroid.rank(Set(G)))* + term += self.flats_generator[H] + gb.append(self.flats_generator[i]*(term**self._matroid.rank(Set(G)))* (term**(self._matroid.rank(Set(G))-self._matroid.rank(Set(F))))) elif not i in Set(F): - gb.append(self.names[i]*self.names[F]) + gb.append(self.flats_generator[i]*self.flats_generator[F]) elif not (F < G or G < F): - gb.append(self.names[F]*self.names[G]) + gb.append(self.flats_generator[F]*self.flats_generator[G]) elif F < G: - term = 0 + term = self.poly_ring.zero() for H in flats: if H < F: - term += self.names[H] + term += self.flats_generator[H] gb.append(term**(self._matroid.rank(Set(G))-self._matroid.rank(Set(F)))) - return gb + g_basis = PolynomialSequence(self.poly_ring, [gb]) + return g_basis From 053346c0d34562eefa820903c108e3343e63ef01 Mon Sep 17 00:00:00 2001 From: Newtech66 Date: Sun, 30 Jun 2024 16:28:02 +0530 Subject: [PATCH 049/537] Improvements and corrections --- src/sage/rings/burnside.py | 66 ++++++++++++++++++++++++++++++-------- 1 file changed, 52 insertions(+), 14 deletions(-) diff --git a/src/sage/rings/burnside.py b/src/sage/rings/burnside.py index d248685bad6..40279df058f 100644 --- a/src/sage/rings/burnside.py +++ b/src/sage/rings/burnside.py @@ -46,15 +46,18 @@ def _group_invariant(self, H): def _normalize(self, H): # H is of type self.element_class G = H.subgroup_of() - H._C = G.subgroup(H._C.gens_small()) p = self._group_invariant(H._C) if p in self._cache: for H0 in self._cache[p]: if _is_conjugate(G, H._C, H0._C): return H0 else: + g = H._C.gens_small() + H._C = G.subgroup(g) self._cache[p].append(H) else: + g = H._C.gens_small() + H._C = G.subgroup(g) self._cache[p] = [H] return H @@ -165,6 +168,21 @@ def __eq__(self, other): return (isinstance(other, ConjugacyClassOfSubgroups) and _is_conjugate(self.subgroup_of(), self._C, other._C)) + def __lt__(self, other): + r""" + Return if this element is less than ``other``. + """ + return (isinstance(other, ConjugacyClassOfSubgroups_SymmetricGroup) + and self.grade() < other.grade() + and (GAP_FAIL != libgap.ContainedConjugates( + self.subgroup_of(), other._C, self._C, True))) + + def __le__(self, other): + r""" + Return if this element is less than or equal to ``other``. + """ + return self == other or self < other + class ConjugacyClassesOfSubgroups(Parent, SubgroupStore): def __init__(self, G): r""" @@ -319,7 +337,23 @@ def __eq__(self, other): Two elements compare equal if they are conjugate subgroups in the parent group. """ return (isinstance(other, ConjugacyClassOfSubgroups_SymmetricGroup) - and self.grade() == other.grade() and _is_conjugate(self.subgroup_of(), self._C, other._C)) + and self.grade() == other.grade() + and _is_conjugate(self.subgroup_of(), self._C, other._C)) + + def __lt__(self, other): + r""" + Return if this element is less than ``other``. + """ + return (isinstance(other, ConjugacyClassOfSubgroups_SymmetricGroup) + and self.grade() < other.grade() + and (GAP_FAIL != libgap.ContainedConjugates( + self.subgroup_of(), other._C, self._C, True))) + + def __le__(self, other): + r""" + Return if this element is less than or equal to ``other``. + """ + return self == other or self < other class ConjugacyClassesOfSubgroups_SymmetricGroup(ConjugacyClassesOfSubgroups): def __init__(self, n): @@ -333,6 +367,9 @@ def __init__(self): Parent.__init__(self, category=category) SubgroupStore.__init__(self) + def _group_invariant(self, H): + return (H.order(), H.degree()) + def _repr_(self): return "Conjugacy classes of subgroups of symmetric groups" @@ -533,9 +570,7 @@ def product_on_basis(self, H, K): sage: B.product_on_basis(C(Z2), C(Z3)) B[((),)] """ - #is it correct to use DoubleCosetRepsAndSizes? It may return ANY element of the double coset! - # g_reps = [rep for rep, size in libgap.DoubleCosetRepsAndSizes(self._G, H._C, K._C)] - g_reps = libgap.List(libgap.DoubleCosets(self._G, H._C, K._C), libgap.Representative) + g_reps = [rep for rep, size in libgap.DoubleCosetRepsAndSizes(self._G, H._C, K._C)] from collections import Counter C = Counter() for g in g_reps: @@ -573,7 +608,7 @@ def _repr_(self): class PolynomialMolecularDecomposition(CombinatorialFreeModule): def __init__(self, base_ring=ZZ): basis_keys = ConjugacyClassesOfSubgroups_SymmetricGroup_all() - category = GradedAlgebrasWithBasis(base_ring) + category = GradedAlgebrasWithBasis(base_ring).Commutative() CombinatorialFreeModule.__init__(self, base_ring, basis_keys=basis_keys, category=category, @@ -601,8 +636,8 @@ def one_basis(self): # is equivalent to [S_n/H] where H is some conjugacy class # of subgroups of S_n. - def product_on_basis(self, g1, g2): - n, m = g1.grade(), g2.grade() + def product_on_basis(self, H, K): + n, m = H.grade(), K.grade() # There is no way to create SymmetricGroup(0) using the # PermutationGroup constructor as used here, so a special # case has to be added. @@ -610,12 +645,15 @@ def product_on_basis(self, g1, g2): return self._from_dict({self._indices(SymmetricGroup(0)): 1}) # We only really need to multiply generators, since we are multiplying # permutations acting on disjoint domains. - H_ast_K = [ - h*k - for h in SymmetricGroup(n).gens_small() - for k in SymmetricGroup(range(n+1,n+m+1)).gens_small() - ] - G = PermutationGroup(H_ast_K) + H_action = lambda g, e: g(e) if e<=n else e + H_extend = PermutationGroup(H._C.gens_small(), action=H_action, domain=range(1,n+m+1)) + K_action = lambda g, e: n + g(e-n) if e>n else e + K_restrict = PermutationGroup(K._C.gens_small(), action=K_action, domain=range(1,n+m+1)) + # We need to add the identity elements to the generating sets + # to obtain a generating set for H*K. + G = PermutationGroup(H_extend.gens_small() + + K_restrict.gens_small() + + [H_extend.identity()], domain=range(1,n+m+1)) return self._from_dict({self._indices(G): 1}) def degree_on_basis(self, x): From 91490233c643e9c34968c573261ccc9f0b410c40 Mon Sep 17 00:00:00 2001 From: Newtech66 Date: Sun, 30 Jun 2024 17:33:54 +0530 Subject: [PATCH 050/537] Doctest fixes --- src/sage/rings/burnside.py | 78 +++++++++++++++++++++++--------------- 1 file changed, 48 insertions(+), 30 deletions(-) diff --git a/src/sage/rings/burnside.py b/src/sage/rings/burnside.py index 40279df058f..a1473770b5f 100644 --- a/src/sage/rings/burnside.py +++ b/src/sage/rings/burnside.py @@ -36,11 +36,32 @@ def __init__(self): r""" This class caches subgroup information and provides helper methods to handle subgroup <-> name associations. + + TESTS:: + + sage: P = PolynomialMolecularDecomposition() + sage: Z3 = CyclicPermutationGroup(3) + sage: P[Z3] + PMD[(3, ((1,2,3),))] + sage: P._indices.set_name(Z3, "C3") + sage: P[Z3] + C3 + sage: P._indices.get_name(Z3) + 'C3' + sage: P._indices.unset_name(Z3) + sage: P[Z3] + PMD[(3, ((1,2,3),))] + sage: P._indices.get_name(Z3) + '(3, ((1,2,3),))' """ self._cache = dict() # invariant to subgroups self._names = dict() # stores subgroup names def _group_invariant(self, H): + r""" + Returns the set of computed group invariants + associated with a subgroup H. + """ return H.order() def _normalize(self, H): @@ -168,20 +189,19 @@ def __eq__(self, other): return (isinstance(other, ConjugacyClassOfSubgroups) and _is_conjugate(self.subgroup_of(), self._C, other._C)) - def __lt__(self, other): + def __le__(self, other): r""" - Return if this element is less than ``other``. + Return if this element is less than or equal to ``other``. """ - return (isinstance(other, ConjugacyClassOfSubgroups_SymmetricGroup) - and self.grade() < other.grade() + return (isinstance(other, ConjugacyClassOfSubgroups) and (GAP_FAIL != libgap.ContainedConjugates( self.subgroup_of(), other._C, self._C, True))) - def __le__(self, other): + def __lt__(self, other): r""" - Return if this element is less than or equal to ``other``. + Return if this element is less than ``other``. """ - return self == other or self < other + return self <= other and self != other class ConjugacyClassesOfSubgroups(Parent, SubgroupStore): def __init__(self, G): @@ -264,7 +284,7 @@ def __iter__(self): sage: G = SymmetricGroup(3) sage: B = BurnsideRing(G) sage: [g for g in B._indices] - [((),), ((1,2),), ((1,2,3),), 1] + [((),), ((1,2),), ((1,2,3),), ((1,2,3), (1,2))] """ return iter(self(H) for H in self._G.conjugacy_classes_subgroups()) @@ -340,20 +360,18 @@ def __eq__(self, other): and self.grade() == other.grade() and _is_conjugate(self.subgroup_of(), self._C, other._C)) - def __lt__(self, other): + def __le__(self, other): r""" - Return if this element is less than ``other``. + Return if this element is less than or equal to ``other``. """ return (isinstance(other, ConjugacyClassOfSubgroups_SymmetricGroup) - and self.grade() < other.grade() - and (GAP_FAIL != libgap.ContainedConjugates( - self.subgroup_of(), other._C, self._C, True))) + and (self.grade() < other.grade() or self == other)) - def __le__(self, other): + def __lt__(self, other): r""" - Return if this element is less than or equal to ``other``. + Return if this element is less than ``other``. """ - return self == other or self < other + return self != other and self <= other class ConjugacyClassesOfSubgroups_SymmetricGroup(ConjugacyClassesOfSubgroups): def __init__(self, n): @@ -417,15 +435,14 @@ def __init__(self, G, base_ring=ZZ): sage: X = Subsets(6, 2) sage: b = B.construct_from_action(lambda g, x: X([g(e) for e in x]), X) sage: B.basis().keys()._cache - {48: [Subgroup generated by [(3,5,4,6), (1,2)(4,5,6)] of (Symmetric group of order 6! as a permutation group)], - 720: [Symmetric group of order 6! as a permutation group]} + {48: [((1,2)(4,5,6), (3,5,4,6))], 720: [((1,2,3,4,5,6), (1,2))]} sage: b^2 - B[((3,5,4,6), (1,2)(4,5,6))] + B[((5,6), (4,6,5))] + B[((5,6), (3,4), (1,2))] + B[((4,5), (4,6))] + B[((5,6), (3,4), (1,2))] + B[((1,2)(4,5,6), (3,5,4,6))] sage: B.basis().keys()._cache - {6: [Subgroup generated by [(5,6), (4,6,5)] of (Symmetric group of order 6! as a permutation group)], - 8: [Subgroup generated by [(5,6), (3,4), (1,2)] of (Symmetric group of order 6! as a permutation group)], - 48: [Subgroup generated by [(3,5,4,6), (1,2)(4,5,6)] of (Symmetric group of order 6! as a permutation group)], - 720: [Symmetric group of order 6! as a permutation group]} + {6: [((4,5), (4,6))], + 8: [((5,6), (3,4), (1,2))], + 48: [((1,2)(4,5,6), (3,5,4,6))], + 720: [((1,2,3,4,5,6), (1,2))]} sage: G = SymmetricGroup(4) sage: B = BurnsideRing(G) @@ -434,7 +451,8 @@ def __init__(self, G, base_ring=ZZ): sage: b.tensor(b) B[((3,4), (1,2)(3,4))] # B[((3,4), (1,2)(3,4))] sage: (b.tensor(b))^2 - 4*B[((3,4), (1,2)(3,4))] # B[((3,4), (1,2)(3,4))] + 2*B[((),)] # B[((3,4), (1,2)(3,4))] + 2*B[((3,4), (1,2)(3,4))] # B[((),)] + B[((),)] # B[((),)] + B[((),)] # B[((),)] + 2*B[((),)] # B[((3,4), (1,2)(3,4))] + + 2*B[((3,4), (1,2)(3,4))] # B[((),)] + 4*B[((3,4), (1,2)(3,4))] # B[((3,4), (1,2)(3,4))] TESTS:: @@ -492,13 +510,13 @@ def construct_from_action(self, action, domain): sage: X = G sage: a = lambda g, x: g*x*g.inverse() sage: B.construct_from_action(a, X) - B[1] + B[((1,4)(2,3), (1,3)(2,4), (3,4))] + B[((2,4,3),)] + B[((3,4), (1,2)(3,4))] + B[((1,2,3,4),)] + B[((3,4), (1,3)(2,4), (1,4)(2,3))] + B[((2,4,3),)] + B[((3,4), (1,2)(3,4))] + B[((1,2,3,4),)] + 1 TESTS:: sage: G = SymmetricGroup(4) sage: B = BurnsideRing(G) - sage: [list(b.monomial_coefficients().keys())[0]._C.order() for b in B.gens()] + sage: [b.support()[0]._C.order() for b in B.gens()] [1, 2, 2, 3, 4, 4, 4, 6, 8, 12, 24] sage: sorted((o, len(l)) for o, l in B._indices._cache.items()) [(1, 1), (2, 2), (3, 1), (4, 3), (6, 1), (8, 1), (12, 1), (24, 1)] @@ -506,7 +524,7 @@ def construct_from_action(self, action, domain): sage: G = SymmetricGroup(4) sage: B = BurnsideRing(G) sage: B(-3) - -3*B[1] + -3 """ def find_stabilizer(action, pnt): stabilizer = [] @@ -538,7 +556,7 @@ def one_basis(self): sage: G = DiCyclicGroup(4) sage: B = BurnsideRing(G) sage: B.one_basis() - 1 + ((1,2,3,4,5,6,7,8)(9,10,11,12,13,14,15,16), (1,9,5,13)(2,16,6,12)(3,15,7,11)(4,14,8,10)) """ return self._indices(self._G) @@ -555,9 +573,9 @@ def product_on_basis(self, H, K): sage: B = BurnsideRing(G) sage: matrix([[b * c for b in B.gens()] for c in B.gens()]) [ 6*B[((),)] 3*B[((),)] 2*B[((),)] B[((),)]] - [ 3*B[((),)] B[((2,3),)] + B[((),)] B[((),)] B[((2,3),)]] + [ 3*B[((),)] B[((),)] + B[((1,2),)] B[((),)] B[((1,2),)]] [ 2*B[((),)] B[((),)] 2*B[((1,2,3),)] B[((1,2,3),)]] - [ B[((),)] B[((2,3),)] B[((1,2,3),)] B[1]] + [ B[((),)] B[((1,2),)] B[((1,2,3),)] 1] TESTS:: From 3f466b945bc3a83124a218bf26c2b7aad16aec8b Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Tue, 2 Jul 2024 10:23:54 +0530 Subject: [PATCH 051/537] Added Documentation to both classes --- src/sage/matroids/chow_ring_ideal.py | 243 +++++++++++++++++++++------ 1 file changed, 189 insertions(+), 54 deletions(-) diff --git a/src/sage/matroids/chow_ring_ideal.py b/src/sage/matroids/chow_ring_ideal.py index bf5f2b50a37..5c3ebabb9d6 100644 --- a/src/sage/matroids/chow_ring_ideal.py +++ b/src/sage/matroids/chow_ring_ideal.py @@ -5,20 +5,79 @@ from sage.sets.set import Set from sage.rings.polynomial.multi_polynomial_sequence import PolynomialSequence +r""" +Chow ring ideals of matroids + +AUTHORS: + +- Travis Scrimshaw +- Shriya M + +These are the classes of Chow ring ideals for matroids. There are two classes +created - Chow ring ideal and augmented Chow ring ideal. The augmented +Chow ring ideal has two different presentations implemented - the Feitchner- +Yuzvinsky presentation and atom-free presentation. Both classes have +``grobner_basis()`` methods as well, as an explicit Groebner basis is known +in each case. + +REFERENCES + +- :arxiv:`2309.14312` +- :arxiv:`2111.00393` +""" +#***************************************************************************** +# Copyright (C) 2024 Travis Scrimshaw +# 2024 Shriya M +# +# 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/ +#***************************************************************************** class ChowRingIdeal(MPolynomialIdeal): + r""" + The class of Chow ring ideal, a multi-polynomial ideal. + Base class - ``MPolynomialIdeal``. + + INPUT: + + + - `M` -- a matroid. + - `R` -- a ring. + + OUTPUT: Chow ring ideal of matroid `M`. + + EXAMPLES:: + + Chow ring ideal of uniform matroid of rank 3 on 6 elements:: + + sage: ch = ChowRingIdeal(M=matroids.Uniform(3,6), R=QQ) + sage: ch + Chow ring ideal of U(3, 6): Matroid of rank 3 on 6 elements with circuit-closures + {3: {{0, 1, 2, 3, 4, 5}}} + sage: ch = ChowRingIdeal(M=matroids.catalog.Fano(), R=QQ) + Chow ring ideal of Fano: Binary matroid of rank 3 on 7 elements, type (3, 0) + """ + def __init__(self, M, R): self._matroid = M - self.flats = [X for i in range(1, self._matroid.rank()) #_flats. NOT NEEDED AS AN ATTRIBUTE. USE NAMES + flats = [X for i in range(1, self._matroid.rank()) for X in self._matroid.flats(i)] E = list(self._matroid.groundset()) flats_containing = {x: [] for x in E} - for i,F in enumerate(self.flats): + for i,F in enumerate(flats): for x in F: flats_containing[x].append(i) - names = ['A{}'.format(''.join(str(x) for x in sorted(F, key=cmp_elements_key))) for F in self.flats] + names = ['A{}'.format(''.join(str(x) for x in sorted(F, key=cmp_elements_key))) for F in flats] try: self.poly_ring = PolynomialRing(R, names) #self.ring @@ -27,11 +86,11 @@ def __init__(self, M, R): gens = self.poly_ring.gens() - self.flats_generator = dict(zip(self.flats, gens)) + self.flats_generator = dict(zip(flats, gens)) - Q = [gens[i] * gens[i+j+1] for i,F in enumerate(self.flats) - for j,G in enumerate(self.flats[i+1:]) if not (F < G or G < F)] + Q = [gens[i] * gens[i+j+1] for i,F in enumerate(flats) + for j,G in enumerate(flats[i+1:]) if not (F < G or G < F)] L = [sum(gens[i] for i in flats_containing[x]) - sum(gens[i] for i in flats_containing[y]) for j,x in enumerate(E) for y in E[j+1:]] @@ -39,24 +98,45 @@ def __init__(self, M, R): MPolynomialIdeal.__init__(self, self.poly_ring, Q + L) - def _repr_(self): + def __repr__(self): return "Chow ring ideal of {}".format(self._matroid) - def groebner_basis(self): + def groebner_basis(self): + r""" + Returns the Groebner basis of the Chow ring ideal of consideration. + Return type - ``PolynomialSequence``. + + EXAMPLES:: + + sage: ch = ChowRingIdeal(M=BasisMatroid(groundset='abc', bases=['ab', 'ac']), R=QQ) + sage: ch.groebner_basis() + [Aa^2, Aa*Abc, Aa*Abc, Abc^2] + sage: ch.groebner_basis().is_groebner() + True + + Another example would be the Groebner basis of the Chow ring ideal of + the Non-Fano matroid:: + + sage: ch = ChowRingIdeal(M=matroids.catalog.NonFano(), R=QQ) + sage: ch.groebner.basis() + Polynomial Sequence with 592 Polynomials in 16 Variables + """ + + flats = list(self.flats_generator.keys()) gb = list() - for F in self.flats: - for G in self.flats: + for F in flats: + for G in flats: if not (F < G or G < F): gb.append(self.flats_generator[F]*self.flats_generator[G]) elif Set(F).is_empty(): term = self.poly_ring.zero() - for H in self.flats: + for H in flats: if H < F: term += self.flats_generator[H] gb.append(term**self._matroid.rank(Set(G))) elif F < G: term = self.poly_ring.zero() - for H in self.flats: + for H in flats: if H < F: term += self.flats_generator[H] gb.append(term**(self._matroid.rank(Set(G))-self._matroid.rank(Set(F)))) @@ -74,84 +154,139 @@ def flats_generator(self): class AugmentedChowRingIdeal(MPolynomialIdeal): - def __init__(self, M, R): + r""" + The class of Chow ring ideal, a multi-polynomial ideal. + Base class - ``MPolynomialIdeal``. + + INPUT: + + + - `M` -- a matroid. + - `R` -- a ring. + - ``atom_free`` -- a Boolean value, default value set to ``False``. When + ``True``, it returns the atom-free presentation of the augmented Chow + ring. If ``False``, it returns the Feitchner-Yuzvinsky presentation of the + augmented Chow ring. + + OUTPUT: augmented Chow ring ideal of matroid `M`. + + EXAMPLES:: + + Augmented Chow ring ideal of Wheel matroid of rank 3:: + + sage: ch = AugumentedChowRingIdeal(M=matroids.Wheel(3), R=QQ) + sage: ch + Augmented Chow ring ideal of Wheel(3): Regular matroid of rank 3 on + 6 elements with 16 bases of Feitchner-Yuzvinsky presentation + """ + def __init__(self, M, R, atom_free=False): + self.atom_free = atom_free self._matroid = M - self.flats = [X for i in range(1, self._matroid.rank()) + flats = [X for i in range(1, self._matroid.rank()) for X in self._matroid.flats(i)] E = list(self._matroid.groundset()) flats_containing = {x: [] for x in E} - for i,F in enumerate(self.flats): + for F in flats: for x in F: - flats_containing[x].append(i) + flats_containing[x].append(F) self.flats_generator = dict() - #names_groundset = ['A{}'.format(''.join(str(x))) for x in E] - #names_flats = ['B{}'.format(''.join(str(x) for x in sorted(F, key=cmp_elements_key))) for F in self.flats] - self.poly_ring = PolynomialRing(R, 'A', len(E) + len(self.flats)) + try: + names_groundset = ['A{}'.format(''.join(str(x))) for x in E] + names_flats = ['B{}'.format(''.join(str(x) for x in sorted(F, key=cmp_elements_key))) for F in flats] + self.poly_ring = PolynomialRing(R, names_groundset + names_flats) + except ValueError: + self.poly_ring = PolynomialRing(R, 'A', len(E) + len(flats)) gens = self.poly_ring.gens() for i,x in enumerate(E): - self.flats_generator[x] = gens[i] - for i,F in enumerate(self.flats): + self.flats_generator[x] = gens[i] + for i,F in enumerate(flats): self.flats_generator[F] = gens[len(E) + i] le = len(E) Q = list() - for i,F in enumerate(self.flats): - for j,G in enumerate(self.flats): + for i,F in enumerate(flats): + for j,G in enumerate(flats): if not (F < G or G < F): - #print(type(gens[le+i] * gens[le+i+j+1])) Q.append(gens[le+i] * gens[le+j]) - - for j,F in enumerate(self.flats): + + for j,F in enumerate(flats): for k,x in enumerate(E): if F not in flats_containing[x]: - #print(type(gens[k]*gens[len(E)+j])) - Q.append(gens[k]*gens[le+j]) - #print("this is Q", Q) - - - - #debug Q and L. coerce must be true. Coerce allows you to add two different elements from two different rings - #Q =[gens[len(E)+i] * gens[len(E)+i+j+1] for i,F in enumerate(self.flats) - #for j,G in enumerate(self.flats[i+1:]) if not (F < G or G < F)] - #Q.append([gens[i]*gens[len(E)+j] for i,x in enumerate(E) for j,F in enumerate(self.flats) if F not in flats_containing[x]]) - L = list() - for i,x in enumerate(E): - term = self.poly_ring.zero() - for j,F in enumerate(self.flats): - if F not in flats_containing[x]: - term += gens[le+j] - L.append(gens[i] - term) - - MPolynomialIdeal.__init__(self, self.poly_ring, Q + L) + if self.atom_free: + term = self.poly_ring.zero() + for G in flats_containing[x]: + term += self.flats_generator[G] + Q.append(self.flats_generator[F]*term) + else: + Q.append(gens[k]*gens[le+j]) + + + if self.atom_free: + for i in E: + term = self.poly_ring.zero() + for F in flats_containing[i]: + term += self.flats_generator[F] + Q.append(term**2) + + MPolynomialIdeal.__init__(self, self.poly_ring, Q) + else: + L = list() + for i,x in enumerate(E): + term = self.poly_ring.zero() + for j,F in enumerate(flats): + if F not in flats_containing[x]: + term += gens[le+j] + L.append(gens[i] - term) + + MPolynomialIdeal.__init__(self, self.poly_ring, Q + L) - def _repr_(self): #use single underscore - return "Augmented Chow ring ideal of {}".format(self._matroid) + def __repr__(self): + if self.atom_free: + return "Augmented Chow ring ideal of {} of atom-free presentation".format(self._matroid) + else: + return "Augmented Chow ring ideal of {} of Feitchner-Yuzvinsky presentation".format(self._matroid) def matroid(self): return self._matroid def flat_generator(self): - return self.flats_generator - + return dict(self.flats_generator) + def groebner_basis(self): + r""" + Returns the Groebner basis of the augmented Chow ring ideal. + Return type - ``PolynomialSequence``. + EXAMPLES:: - - def groebner_basis(self, atom_free=False): + sage: ch = AugmentedChowRingIdeal(M=matroids.catalog.Fano(), R=QQ) + sage: ch.groebner_basis() + Polynomial Sequence with 2744 Polynomials in 21 Variables + + Another example would be the Groebner basis of the augmented Chow ring + ideal (atom-free presentation) of the Graphic matroid of cycle graph of + 3 vertices:: + + sage: M1 = GraphicMatroid(graphs.CycleGraph(3)) + sage: ch = AugmentedChowRingIdeal(M=M1, R=QQ, atom_free=True) + sage: ch.groebner_basis() + [B0^2, B0*B1, B0*B2, B0*B1, B1^2, B1*B2, B0*B2, B1*B2, B2^2] + """ gb = [] - flats = self.flats + flats = [X for i in range(1, self._matroid.rank()) + for X in self._matroid.flats(i)] if Set([]) in flats: flats.remove(Set([])) - if atom_free: + if self.atom_free: for F in flats: for G in flats: if not (F > G or G > F): gb.append(self.flats_generator[F]*self.flats_generator[G]) elif F < G: term = self.poly_ring.zero() - for H in self.flats: + for H in flats: if H < F: term += self.flats_generator[H] gb.append(self.flats_generator[F]*(term**self._matroid.rank(Set(G)))* From 980c63f5e9b066ce917a34e9932ce1acf788ca57 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Tue, 2 Jul 2024 10:24:13 +0530 Subject: [PATCH 052/537] Added Documentation to Chow ring class --- src/sage/matroids/chow_ring.py | 62 ++++++++++++++++++++++++++++++---- 1 file changed, 55 insertions(+), 7 deletions(-) diff --git a/src/sage/matroids/chow_ring.py b/src/sage/matroids/chow_ring.py index d4b817564a2..66de4c1a967 100644 --- a/src/sage/matroids/chow_ring.py +++ b/src/sage/matroids/chow_ring.py @@ -4,15 +4,63 @@ from sage.categories.graded_algebras_with_basis import GradedAlgebrasWithBasis import sage.misc.latex as latex -#chow rings class needs to be written properly -#gens of chow ring ideal must be debugged -#gb must be a poly sequence -#commented and documented -#use is_groebner() -#matroids - try all of them +r""" +Chow rings of matroids + +AUTHORS: + +- Travis Scrimshaw +- Shriya M + +These are the classes of Chow rings for matroids. It also takes in +a parameter boolean ``augmented`` which creates the augmented Chow +ring if given ``True``. + + +REFERENCES + +- :arxiv:`2309.14312` +- :arxiv:`2111.00393` +""" +#***************************************************************************** +# Copyright (C) 2024 Travis Scrimshaw +# 2024 Shriya M +# +# 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/ +#***************************************************************************** class ChowRing(QuotientRing_nc): + r""" + The class of Chow ring, a multi-polynomial quotient ring. + Base class - ``QuotientRing_nc``. + + INPUT: + + + - `M` -- a matroid. + - `R` -- a ring. + - ``augmented`` -- a Boolean value. When ``True``, it returns the augmented Chow + ring. If ``False``, it returns the Chow ring + + OUTPUT: Chow ring of matroid `M`. + + EXAMPLES:: + + sage: M1 = matroids.catalog.P8pp() + sage: ch = ChowRing(M=M1, R=QQ, augmented=False) + sage: ch + Chow ring of P8'': Matroid of rank 4 on 8 elements with 8 nonspanning circuits + """ def __init__(self, R, M, augmented): self._matroid = M self._augmented = augmented @@ -20,7 +68,7 @@ def __init__(self, R, M, augmented): self._ideal = AugmentedChowRingIdeal(M, R) else: self._ideal = ChowRingIdeal(M, R) #check method to get ring - QuotientRing_nc.__init__(self, R=self._ideal.poly_ring, I=self._ideal, names=self.poly_ring.variable_names(), category=GradedAlgebrasWithBasis(R)) + QuotientRing_nc.__init__(self, R=self._ideal.poly_ring, I=self._ideal, names=self._ideal.poly_ring.variable_names(), category=GradedAlgebrasWithBasis(R)) def _repr_(self): return "Chow ring of {}".format(self._matroid) From 943880097ecda81f5906ddd6c2cb5d3f88316be5 Mon Sep 17 00:00:00 2001 From: Newtech66 Date: Sun, 7 Jul 2024 00:37:38 +0530 Subject: [PATCH 053/537] Add most doctests --- src/sage/rings/burnside.py | 347 ++++++++++++++++++++++++++++++++++--- 1 file changed, 319 insertions(+), 28 deletions(-) diff --git a/src/sage/rings/burnside.py b/src/sage/rings/burnside.py index a1473770b5f..df5797d9711 100644 --- a/src/sage/rings/burnside.py +++ b/src/sage/rings/burnside.py @@ -61,10 +61,43 @@ def _group_invariant(self, H): r""" Returns the set of computed group invariants associated with a subgroup H. + + TESTS:: + + sage: G = SymmetricGroup(3) + sage: B = BurnsideRing(G) + sage: Z3 = CyclicPermutationGroup(3) + sage: B._indices._group_invariant(Z3) + 3 """ return H.order() def _normalize(self, H): + r""" + Converts a subgroup into its canonical representative + by finding a representative of its conjugacy class, or + using the group itself if the conjugacy class didn't exist + before. + + TESTS:: + + sage: P = PolynomialMolecularDecomposition() + sage: H1 = PermutationGroup([(1,2),(3,4)]) + sage: H2 = PermutationGroup([(1,3),(2,4)]) + sage: P[H1] + PMD[(4, ((3,4), (1,2)))] + sage: P[H2] + PMD[(4, ((3,4), (1,2)))] #indirect doctest + + sage: G = SymmetricGroup(4) + sage: B = BurnsideRing(G) + sage: H1 = PermutationGroup([(1,2),(3,4)]) + sage: H2 = PermutationGroup([(1,3),(2,4)]) + sage: B[H1] + B[((3,4), (1,2))] + sage: B[H2] + B[((3,4), (1,2))] #indirect doctest + """ # H is of type self.element_class G = H.subgroup_of() p = self._group_invariant(H._C) @@ -86,6 +119,18 @@ def get_name(self, H): r""" Takes a subgroup as input and returns its associated name, if any. Otherwise, the generators are returned. Returns a string. + + TESTS:: + + sage: P = PolynomialMolecularDecomposition() + sage: Z3 = CyclicPermutationGroup(3) + sage: P[Z3] + PMD[(3, ((1,2,3),))] + sage: P._indices.set_name(Z3, "C3") + sage: P[Z3] + C3 + sage: P._indices.get_name(Z3) + 'C3' """ key = self.element_class(self, H) G = self._normalize(key) @@ -95,6 +140,18 @@ def get_name(self, H): def set_name(self, H, name): r""" Takes a subgroup as input and sets its name. + + TESTS:: + + sage: P = PolynomialMolecularDecomposition() + sage: Z3 = CyclicPermutationGroup(3) + sage: P[Z3] + PMD[(3, ((1,2,3),))] + sage: P._indices.set_name(Z3, "C3") + sage: P[Z3] + C3 + sage: P._indices.get_name(Z3) + 'C3' """ if not isinstance(name, str): raise ValueError("name must be a string") @@ -105,6 +162,21 @@ def set_name(self, H, name): def unset_name(self, H): r""" Takes a subgroup as input and removes its name, if any. + + TESTS:: + + sage: P = PolynomialMolecularDecomposition() + sage: Z3 = CyclicPermutationGroup(3) + sage: P[Z3] + PMD[(3, ((1,2,3),))] + sage: P._indices.set_name(Z3, "C3") + sage: P[Z3] + C3 + sage: P._indices.get_name(Z3) + 'C3' + sage: P._indices.unset_name(Z3) + sage: P[Z3] + PMD[(3, ((1,2,3),))] """ key = self.element_class(self, H) G = self._normalize(key) @@ -126,6 +198,20 @@ def __init__(self, parent, C): self._C = C def subgroup_of(self): + r""" + Return the group which this conjugacy class of subgroups + belongs to. + + TESTS:: + + sage: G = SymmetricGroup(3) + sage: from sage.rings.burnside import ConjugacyClassesOfSubgroups + sage: C = ConjugacyClassesOfSubgroups(G) + sage: Z3 = CyclicPermutationGroup(3) + sage: CZ3 = C(Z3) + sage: CZ3.subgroup_of() + Symmetric group of order 3! as a permutation group + """ return self.parent()._G def __hash__(self): @@ -144,6 +230,19 @@ def __hash__(self): return hash(self._C) def _repr_(self): + r""" + Return a string representation of ``self``. + + TESTS:: + + sage: G = SymmetricGroup(3) + sage: from sage.rings.burnside import ConjugacyClassesOfSubgroups + sage: C = ConjugacyClassesOfSubgroups(G) + sage: Z3 = CyclicPermutationGroup(3) + sage: CZ3 = C(Z3) + sage: CZ3 + ((1,2,3),) + """ name = self.parent()._names.get(self._C, None) return name if name else repr(self._C.gens()) @@ -189,14 +288,6 @@ def __eq__(self, other): return (isinstance(other, ConjugacyClassOfSubgroups) and _is_conjugate(self.subgroup_of(), self._C, other._C)) - def __le__(self, other): - r""" - Return if this element is less than or equal to ``other``. - """ - return (isinstance(other, ConjugacyClassOfSubgroups) - and (GAP_FAIL != libgap.ContainedConjugates( - self.subgroup_of(), other._C, self._C, True))) - def __lt__(self, other): r""" Return if this element is less than ``other``. @@ -243,7 +334,7 @@ def __eq__(self, other): def __hash__(self): r""" - Return the hash of the representative of the conjugacy class. + Return the hash of the underlying group. TESTS:: @@ -267,7 +358,7 @@ def _element_constructor_(self, x): sage: G = SymmetricGroup(4) sage: C = ConjugacyClassesOfSubgroups(G) sage: Z4 = CyclicPermutationGroup(4) - sage: C(Z4) #indirect doctest + sage: C(Z4) ((1,2,3,4),) """ if x.is_subgroup(self._G): @@ -322,31 +413,77 @@ def _repr_(self): Element = ConjugacyClassOfSubgroups class ConjugacyClassOfSubgroups_SymmetricGroup(ConjugacyClassOfSubgroups): - def __init__(self, parent, C): + def __init__(self, parent, n, C): r""" Initialize the conjugacy class of ``C`` in SymmetricGroup(n). TESTS:: - sage: G = SymmetricGroup(4) - sage: B = BurnsideRing(G) + sage: P = PolynomialMolecularDecomposition() sage: Z4 = CyclicPermutationGroup(4) - sage: TestSuite(B(Z4)).run() + sage: TestSuite(P(Z4)).run() """ + self._degree = n ConjugacyClassOfSubgroups.__init__(self, parent, C) def subgroup_of(self): - return SymmetricGroup(self.grade()) + r""" + Return the symmetric group which this conjugacy class + of subgroups belongs to. + + TESTS:: + + sage: from sage.rings.burnside import ConjugacyClassesOfSubgroups_SymmetricGroup + sage: C = ConjugacyClassesOfSubgroups_SymmetricGroup(3) + sage: Z3 = CyclicPermutationGroup(3) + sage: CZ3 = C(Z3) + sage: CZ3.subgroup_of() + Symmetric group of order 3! as a permutation group + sage: Z2 = CyclicPermutationGroup(2) + sage: CZ2 = C(Z2) + sage: CZ2.subgroup_of() + Symmetric group of order 3! as a permutation group + """ + return SymmetricGroup(self._degree) def _repr_(self): + r""" + Return a string representation of ``self``. + + TESTS:: + + sage: P = PolynomialMolecularDecomposition() + sage: H = PermutationGroup([[(1,2),(5,6)],[(3,4)]]) + sage: P._indices(H) + (6, ((3,4), (1,2)(5,6))) + """ return f"({self.grade()}, {super()._repr_()})" def grade(self): - return self._C.degree() + r""" + Return the degree of this subgroup (which is the degree + of the symmetric group it is a subgroup of). + + TESTS:: + + sage: P = PolynomialMolecularDecomposition() + sage: D2 = DiCyclicGroup(2) + sage: P._indices(D2).grade() + 8 + """ + return self._degree def __hash__(self): r""" Return the hash of the representative of the conjugacy class. + + TESTS:: + + sage: P = PolynomialMolecularDecomposition() + sage: H1 = P(PermutationGroup([(1,2)],domain=[1,2,3])) + sage: H2 = P(PermutationGroup([(2,3)],domain=[1,2,3])) + sage: hash(H1) == hash(H2) + True """ return hash((hash(SymmetricGroup(self.grade())), hash(self._C))) @@ -355,6 +492,14 @@ def __eq__(self, other): Return if this element is equal to ``other``. Two elements compare equal if they are conjugate subgroups in the parent group. + + TESTS:: + + sage: P = PolynomialMolecularDecomposition() + sage: H1 = P(PermutationGroup([(1,2)],domain=[1,2,3])) + sage: H2 = P(PermutationGroup([(2,3)],domain=[1,2,3])) + sage: P[H1] == P[H2] + True """ return (isinstance(other, ConjugacyClassOfSubgroups_SymmetricGroup) and self.grade() == other.grade() @@ -373,38 +518,130 @@ def __lt__(self, other): """ return self != other and self <= other -class ConjugacyClassesOfSubgroups_SymmetricGroup(ConjugacyClassesOfSubgroups): +class ConjugacyClassesOfSubgroups_SymmetricGroup(ConjugacyClassesOfSubgroups, SubgroupStore): def __init__(self, n): + r""" + Initialize the set of conjugacy classes of SymmetricGroup(n). + + INPUT: + + ``n`` -- the degree of the symmetric group. + + TESTS:: + + sage: from sage.rings.burnside import ConjugacyClassesOfSubgroups_SymmetricGroup + sage: C = ConjugacyClassesOfSubgroups_SymmetricGroup(4) + sage: TestSuite(C).run() + """ ConjugacyClassesOfSubgroups.__init__(self, SymmetricGroup(n)) + def _element_constructor_(self, x): + r""" + Construct the conjugacy class of subgroups containing ``x``. + + TESTS:: + + sage: from sage.rings.burnside import ConjugacyClassesOfSubgroups_SymmetricGroup + sage: C = ConjugacyClassesOfSubgroups_SymmetricGroup(4) + sage: Z4 = CyclicPermutationGroup(4) + sage: C(Z4) + (4, ((1,2,3,4),)) + """ + if x.is_subgroup(self._G): + key = self.element_class(self, self._G.degree(), x) + return self._normalize(key) + raise ValueError(f"unable to convert {x} into {self}: not a subgroup of {self._G}") + Element = ConjugacyClassOfSubgroups_SymmetricGroup class ConjugacyClassesOfSubgroups_SymmetricGroup_all(UniqueRepresentation, Parent, SubgroupStore): def __init__(self): + r""" + Initialize the set of conjugacy classes of all symmetric groups. + + This is a graded set graded by the non-negative integers. The homogeneous piece + with grade n is the set of conjugacy classes of subgroups of SymmetricGroup(n). + + TESTS:: + + sage: from sage.rings.burnside import ConjugacyClassesOfSubgroups_SymmetricGroup_all + sage: C = ConjugacyClassesOfSubgroups_SymmetricGroup_all() + sage: TestSuite(C).run() + """ category = SetsWithGrading().Infinite() Parent.__init__(self, category=category) SubgroupStore.__init__(self) def _group_invariant(self, H): + r""" + Returns the set of computed group invariants + associated with a subgroup H. + + TESTS:: + + sage: P = PolynomialMolecularDecomposition() + sage: S3 = SymmetricGroup(3) + sage: P._indices._group_invariant(S3) + (6, 3) + """ return (H.order(), H.degree()) def _repr_(self): + r""" + Return a string representation of ``self``. + + TESTS:: + + sage: P = PolynomialMolecularDecomposition() + sage: P._indices + Conjugacy classes of subgroups of symmetric groups + """ return "Conjugacy classes of subgroups of symmetric groups" - def subset(self, size): - return ConjugacyClassesOfSubgroups_SymmetricGroup(size) + def subset(self, n): + r""" + Returns the conjugacy classes of subgroups of SymmetricGroup(n). + + TESTS:: + + sage: P = PolynomialMolecularDecomposition() + sage: P._indices.subset(3) + Conjugacy classes of subgroups of Symmetric group of order 3! as a permutation group + """ + return ConjugacyClassesOfSubgroups_SymmetricGroup(n) def _element_constructor_(self, x): r""" - x is a subgroup of a symmetric group. + Construct the conjugacy class of subgroups containing ``x``. + + TESTS:: + + sage: from sage.rings.burnside import ConjugacyClassesOfSubgroups_SymmetricGroup_all + sage: C = ConjugacyClassesOfSubgroups_SymmetricGroup() + sage: Z4 = CyclicPermutationGroup(4) + sage: C(Z4) + (4, ((1,2,3,4),)) + sage: S3 = SymmetricGroup(3) + sage: C(S3) + (3, ((1,2,3), (1,2))) """ G = SymmetricGroup(x.degree()) if x.is_subgroup(G): - key = self.element_class(self, x) + key = self.element_class(self, x.degree(), x) return self._normalize(key) raise ValueError(f"unable to convert {x} into {self}: not a subgroup of {G}") def __iter__(self): + r""" + Return iterator over conjugacy classes of subgroups of symmetric groups. + + TESTS:: + + sage: P = PolynomialMolecularDecomposition() + sage: it = iter(P._indices) + sage: [next(it) for _ in range(1,7)] + [(0, ((),)), (1, ((),)), (2, ((),)), (2, ((1,2),)), (3, ((),)), (3, ((2,3),))] + """ n = 0 while True: yield from self.subset(n) @@ -413,6 +650,19 @@ def __iter__(self): def __contains__(self, H): r""" Returns if H is a subgroup of a symmetric group. + + TESTS:: + + sage: P = PolynomialMolecularDecomposition() + sage: Z3 = CyclicPermutationGroup(3) + sage: Z3 in P._indices + True + sage: SH = PermutationGroup([[(1,3)]],domain=[1,3]) + sage: SH in P._indices + False + sage: SH2 = PermutationGroup([[(1,3)]]) + sage: SH2 in P._indices + True """ return H in self.subset(H.degree()) @@ -633,17 +883,32 @@ def __init__(self, base_ring=ZZ): prefix="PMD") self._print_options['names'] = self._indices._names - def __getitem__(self, x): + def __getitem__(self, H): r""" - Return the basis element indexed by ``x``. + Return the basis element indexed by ``H``. + + ``H`` must be a subgroup of a symmetric group. + + EXAMPLES:: + + sage: P = PolynomialMolecularDecomposition() + sage: Z4 = CyclicPermutationGroup(4) + sage: P[Z4] + PMD[(4, ((1,2,3,4),))] """ - return self._from_dict({self._indices(x): 1}) + return self._from_dict({self._indices(H): 1}) @cached_method def one_basis(self): r""" - Returns (0, S0), which indexes the one of this algebra, + Returns SymmetricGroup(0), which indexes the one of this algebra, as per :meth:`AlgebrasWithBasis.ParentMethods.one_basis`. + + EXAMPLES:: + + sage: P = PolynomialMolecularDecomposition() + sage: P.one_basis() + (0, ((),)) """ return self._indices(SymmetricGroup(0)) @@ -655,6 +920,14 @@ def one_basis(self): # of subgroups of S_n. def product_on_basis(self, H, K): + r""" + Return the product of the basis elements indexed by ``H`` and ``K``. + + Let `H` be a subgroup of `\mathfrak{G}_n` and `K` be a subgroup of `\mathfrak{G}_m`. + Then we define their Cauchy product as the subgroup of `\mathfrak{G}_{n+m}` given by + `H \ast K = \{h \dot k \vert h \in H_{\{1 \ldots n\}}, K_{\{n+1 \ldots n+m\}}\}` where + the subscripts denote the domains on which H and K act. + """ n, m = H.grade(), K.grade() # There is no way to create SymmetricGroup(0) using the # PermutationGroup constructor as used here, so a special @@ -674,11 +947,29 @@ def product_on_basis(self, H, K): + [H_extend.identity()], domain=range(1,n+m+1)) return self._from_dict({self._indices(G): 1}) - def degree_on_basis(self, x): + def degree_on_basis(self, H): r""" - x is an instance of ConjugacyClassOfSubgroups_SymmetricGroup. + Return the degree of the basis element indexed by ``H``. + + H is an instance of ConjugacyClassOfSubgroups_SymmetricGroup. + + EXAMPLES:: + + sage: P = PolynomialMolecularDecomposition() + sage: Z4 = CyclicPermutationGroup(4) + sage: P.degree_on_basis(P._indices(Z4)) + 4 """ - return x.grade() + return H.grade() def _repr_(self): + r""" + Return a string representation of ``self``. + + EXAMPLES:: + + sage: P = PolynomialMolecularDecomposition() + sage: P + Polynomial Molecular Decomposition + """ return "Polynomial Molecular Decomposition" From ca4bdc4876dd9d7ae140f1bb5bff62bd247fb52b Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Tue, 9 Jul 2024 18:58:20 +0530 Subject: [PATCH 054/537] Added Chow rings section in documentation --- src/doc/en/reference/matroids/index.rst | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/doc/en/reference/matroids/index.rst b/src/doc/en/reference/matroids/index.rst index b52c5b3420a..ca7d39d2f54 100644 --- a/src/doc/en/reference/matroids/index.rst +++ b/src/doc/en/reference/matroids/index.rst @@ -65,4 +65,10 @@ Internals sage/matroids/set_system sage/matroids/unpickling +.. toctree:: + :maxdepth: 1 + + sage/matroids/chow_ring_ideal + sage/matroids/chow_ring + .. include:: ../footer.txt From 79538064adfdcabea73b25b378d88e3566503d9f Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Tue, 9 Jul 2024 18:59:14 +0530 Subject: [PATCH 055/537] Split Augmented Chow ring ideal class into 3 classes --- src/sage/matroids/chow_ring_ideal.py | 325 +++++++++++++++------------ 1 file changed, 178 insertions(+), 147 deletions(-) diff --git a/src/sage/matroids/chow_ring_ideal.py b/src/sage/matroids/chow_ring_ideal.py index 5c3ebabb9d6..908012c2a7b 100644 --- a/src/sage/matroids/chow_ring_ideal.py +++ b/src/sage/matroids/chow_ring_ideal.py @@ -1,16 +1,8 @@ -from sage.rings.polynomial.multi_polynomial_ideal import MPolynomialIdeal -from sage.matroids.matroid import Matroid -from sage.matroids.utilities import cmp_elements_key -from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing -from sage.sets.set import Set -from sage.rings.polynomial.multi_polynomial_sequence import PolynomialSequence - r""" Chow ring ideals of matroids AUTHORS: -- Travis Scrimshaw - Shriya M These are the classes of Chow ring ideals for matroids. There are two classes @@ -25,21 +17,14 @@ - :arxiv:`2309.14312` - :arxiv:`2111.00393` """ -#***************************************************************************** -# Copyright (C) 2024 Travis Scrimshaw -# 2024 Shriya M -# -# 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.rings.polynomial.multi_polynomial_ideal import MPolynomialIdeal +from sage.matroids.utilities import cmp_elements_key +from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing +from sage.sets.set import Set +from sage.rings.polynomial.multi_polynomial_sequence import PolynomialSequence +from abc import ABC, abstractmethod, ABCMeta +from sage.structure.sage_object import SageObject class ChowRingIdeal(MPolynomialIdeal): r""" @@ -128,17 +113,14 @@ def groebner_basis(self): for G in flats: if not (F < G or G < F): gb.append(self.flats_generator[F]*self.flats_generator[G]) - elif Set(F).is_empty(): - term = self.poly_ring.zero() - for H in flats: - if H < F: - term += self.flats_generator[H] - gb.append(term**self._matroid.rank(Set(G))) - elif F < G: + else: term = self.poly_ring.zero() for H in flats: if H < F: term += self.flats_generator[H] + if Set(F).is_empty(): + gb.append(term**self._matroid.rank(Set(G))) + else: gb.append(term**(self._matroid.rank(Set(G))-self._matroid.rank(Set(F)))) g_basis = PolynomialSequence(self.poly_ring, [gb]) @@ -150,12 +132,28 @@ def matroid(self): def flats_generator(self): return dict(self.flats_generator) + +class AugmentedChowRingIdeal(SageObject): + + @abstractmethod + def gens_constructor(): + pass + @abstractmethod + def groebner_basis(): + pass + def matroid(self): + M = self._matroid + return M + + def flats_generator(self): + return dict(self.flats_generator) -class AugmentedChowRingIdeal(MPolynomialIdeal): +class AugmentedChowRingIdeal_fy(AugmentedChowRingIdeal, MPolynomialIdeal): r""" - The class of Chow ring ideal, a multi-polynomial ideal. + The class of augmented Chow ring ideal of Feitchner-Yuzvinsky + presentation, a multi-polynomial ideal. Base class - ``MPolynomialIdeal``. INPUT: @@ -163,96 +161,171 @@ class AugmentedChowRingIdeal(MPolynomialIdeal): - `M` -- a matroid. - `R` -- a ring. - - ``atom_free`` -- a Boolean value, default value set to ``False``. When - ``True``, it returns the atom-free presentation of the augmented Chow - ring. If ``False``, it returns the Feitchner-Yuzvinsky presentation of the - augmented Chow ring. - OUTPUT: augmented Chow ring ideal of matroid `M`. + OUTPUT: augmented Chow ring ideal of matroid `M` of Feitchner-Yuzvinsky + presentation. EXAMPLES:: Augmented Chow ring ideal of Wheel matroid of rank 3:: - sage: ch = AugumentedChowRingIdeal(M=matroids.Wheel(3), R=QQ) + sage: ch = AugumentedChowRingIdeal_fy(M=matroids.Wheel(3), R=QQ) sage: ch Augmented Chow ring ideal of Wheel(3): Regular matroid of rank 3 on 6 elements with 16 bases of Feitchner-Yuzvinsky presentation """ - def __init__(self, M, R, atom_free=False): - self.atom_free = atom_free + def __init__(self, M, R): self._matroid = M - flats = [X for i in range(1, self._matroid.rank()) + self.flats = [X for i in range(1, self._matroid.rank()) for X in self._matroid.flats(i)] - + E = list(self._matroid.groundset()) + self.flats_generator = dict() + try: + names_groundset = ['A{}'.format(''.join(str(x))) for x in E] + names_flats = ['B{}'.format(''.join(str(x) for x in sorted(F, key=cmp_elements_key))) for F in self.flats] + self.poly_ring = PolynomialRing(R, names_groundset + names_flats) + except ValueError: + self.poly_ring = PolynomialRing(R, 'A', len(E) + len(self.flats)) + for i,x in enumerate(E): + self.flats_generator[x] = self.poly_ring.gens()[i] + for i,F in enumerate(self.flats): + self.flats_generator[F] = self.poly_ring.gens()[len(E) + i] + MPolynomialIdeal.__init__(self, self.poly_ring, self.gens_constructor()) + + def gens_constructor(self): E = list(self._matroid.groundset()) flats_containing = {x: [] for x in E} - for F in flats: + for F in self.flats: for x in F: flats_containing[x].append(F) + + Q = list() + for F in self.flats: + for G in self.flats: + if not (F < G or G < F): + Q.append(self.flats_generator[F] * self.flats_generator[G]) + L = list() + for x in E: + term = self.poly_ring.zero() + for F in self.flats: + if F not in flats_containing[x]: + term += self.flats_generator[F] + L.append(self.flats_generator[x] - term) + return Q + L + + def __repr__(self): + return "Augmented Chow ring ideal of {} of Feitchner-Yuzvinsky presentation".format(self._matroid) + + def groebner_basis(self): + r""" + Returns the Groebner basis of the augmented Chow ring ideal. + Return type - ``PolynomialSequence``. + + EXAMPLES:: + + sage: ch = AugmentedChowRingIdeal_fy(M=matroids.catalog.Fano(), R=QQ) + sage: ch.groebner_basis() + Polynomial Sequence with 2744 Polynomials in 21 Variables + """ + gb = [] + E = list(self._matroid.groundset()) + for i in E: + for F in self.flats: + for G in self.flats: + term = self.poly_ring.zero() + term1 = self.poly_ring.zero() + for H in self.flats: + if i in Set(H): + term += self.flats_generator[H] + if H > F: + term1 += self.flats_generator[H] + + gb.append(self.flats_generator[i] + term) + gb.append(term1**(self._matroid.rank(Set(F))) + 1) + + if i in Set(F): + gb.append(self.flats_generator[i]*((term1)**self._matroid.rank(Set(F)))) + + elif not i in Set(F): + gb.append(self.flats_generator[i]*self.flats_generator[F]) + + elif not (F < G or G < F): + gb.append(self.flats_generator[F]*self.flats_generator[G]) + + elif G < F: + gb.append(self.flats_generator[G]*term1**(self._matroid.rank(Set(F))-self._matroid.rank(Set(G)))) + + g_basis = PolynomialSequence(self.poly_ring, [gb]) + return g_basis + +class AugmentedChowRingIdeal_atom_free(AugmentedChowRingIdeal, MPolynomialIdeal): + r""" + The class of augmented Chow ring ideal of atom-free + presentation, a multi-polynomial ideal. + Base class - ``MPolynomialIdeal``. + + INPUT: + + + - `M` -- a matroid. + - `R` -- a ring. + + OUTPUT: augmented Chow ring ideal of matroid `M` of atom-free + presentation. + + EXAMPLES:: + + Augmented Chow ring ideal of Wheel matroid of rank 3:: + + sage: ch = AugumentedChowRingIdeal_atom_free(M=matroids.Wheel(3), R=QQ) + sage: ch + Augmented Chow ring ideal of Wheel(3): Regular matroid of rank 3 on + 6 elements with 16 bases of atom-free presentation + """ + def __init__(self, M, R): + self._matroid = M + self.flats = [X for i in range(1, self._matroid.rank()) + for X in self._matroid.flats(i)] + E = list(self._matroid.groundset()) self.flats_generator = dict() try: names_groundset = ['A{}'.format(''.join(str(x))) for x in E] - names_flats = ['B{}'.format(''.join(str(x) for x in sorted(F, key=cmp_elements_key))) for F in flats] + names_flats = ['B{}'.format(''.join(str(x) for x in sorted(F, key=cmp_elements_key))) for F in self.flats] self.poly_ring = PolynomialRing(R, names_groundset + names_flats) except ValueError: - self.poly_ring = PolynomialRing(R, 'A', len(E) + len(flats)) - gens = self.poly_ring.gens() + self.poly_ring = PolynomialRing(R, 'A', len(E) + len(self.flats)) for i,x in enumerate(E): - self.flats_generator[x] = gens[i] - for i,F in enumerate(flats): - self.flats_generator[F] = gens[len(E) + i] + self.flats_generator[x] = self.poly_ring.gens()[i] + for i,F in enumerate(self.flats): + self.flats_generator[F] = self.poly_ring.gens()[len(E) + i] + MPolynomialIdeal.__init__(self, self.poly_ring, self.gens_constructor()) - - le = len(E) - Q = list() - for i,F in enumerate(flats): - for j,G in enumerate(flats): - if not (F < G or G < F): - Q.append(gens[le+i] * gens[le+j]) - - for j,F in enumerate(flats): - for k,x in enumerate(E): + def gens_constructor(self): + E = list(self._matroid.groundset()) + Q = [] + flats_containing = {x: [] for x in E} + for F in self.flats: + for x in F: + flats_containing[x].append(F) + for F in self.flats: + for x in E: if F not in flats_containing[x]: - if self.atom_free: - term = self.poly_ring.zero() - for G in flats_containing[x]: - term += self.flats_generator[G] + Q.append(self.flats_generator[x]*self.flats_generator[F]) + term = self.poly_ring.zero() + for G in flats_containing[x]: + term += self.flats_generator[G] Q.append(self.flats_generator[F]*term) - else: - Q.append(gens[k]*gens[le+j]) + for i in E: + term = self.poly_ring.zero() + for F in flats_containing[i]: + term += self.flats_generator[F] + Q.append(term**2) - if self.atom_free: - for i in E: - term = self.poly_ring.zero() - for F in flats_containing[i]: - term += self.flats_generator[F] - Q.append(term**2) - - MPolynomialIdeal.__init__(self, self.poly_ring, Q) - else: - L = list() - for i,x in enumerate(E): - term = self.poly_ring.zero() - for j,F in enumerate(flats): - if F not in flats_containing[x]: - term += gens[le+j] - L.append(gens[i] - term) + return Q - MPolynomialIdeal.__init__(self, self.poly_ring, Q + L) - def __repr__(self): - if self.atom_free: - return "Augmented Chow ring ideal of {} of atom-free presentation".format(self._matroid) - else: - return "Augmented Chow ring ideal of {} of Feitchner-Yuzvinsky presentation".format(self._matroid) - - def matroid(self): - return self._matroid - - def flat_generator(self): - return dict(self.flats_generator) + return "Augmented Chow ring ideal of {} of atom-free presentation".format(self._matroid) def groebner_basis(self): r""" @@ -261,16 +334,8 @@ def groebner_basis(self): EXAMPLES:: - sage: ch = AugmentedChowRingIdeal(M=matroids.catalog.Fano(), R=QQ) - sage: ch.groebner_basis() - Polynomial Sequence with 2744 Polynomials in 21 Variables - - Another example would be the Groebner basis of the augmented Chow ring - ideal (atom-free presentation) of the Graphic matroid of cycle graph of - 3 vertices:: - sage: M1 = GraphicMatroid(graphs.CycleGraph(3)) - sage: ch = AugmentedChowRingIdeal(M=M1, R=QQ, atom_free=True) + sage: ch = AugmentedChowRingIdeal_atom_free(M=M1, R=QQ) sage: ch.groebner_basis() [B0^2, B0*B1, B0*B2, B0*B1, B1^2, B1*B2, B0*B2, B1*B2, B2^2] """ @@ -279,56 +344,22 @@ def groebner_basis(self): for X in self._matroid.flats(i)] if Set([]) in flats: flats.remove(Set([])) - if self.atom_free: - for F in flats: - for G in flats: - if not (F > G or G > F): - gb.append(self.flats_generator[F]*self.flats_generator[G]) - elif F < G: - term = self.poly_ring.zero() - for H in flats: - if H < F: - term += self.flats_generator[H] - gb.append(self.flats_generator[F]*(term**self._matroid.rank(Set(G)))* - (term**(self._matroid.rank(Set(G))-self._matroid.rank(Set(F))))) - - else: - E = list(self._matroid.groundset()) - for i in E: - for F in flats: - for G in flats: - term = self.poly_ring.zero() - for H in flats: - if i in Set(H): - term += self.flats_generator[H] - gb.append(self.flats_generator[i] + term) - - if i in Set(F): - term = self.poly_ring.zero() - for H in flats: - if H < F: - term += self.flats_generator[H] - gb.append(self.flats_generator[i]*(term**self._matroid.rank(Set(G)))* - (term**(self._matroid.rank(Set(G))-self._matroid.rank(Set(F))))) - - elif not i in Set(F): - gb.append(self.flats_generator[i]*self.flats_generator[F]) - - elif not (F < G or G < F): - gb.append(self.flats_generator[F]*self.flats_generator[G]) - - elif F < G: - term = self.poly_ring.zero() - for H in flats: - if H < F: - term += self.flats_generator[H] - gb.append(term**(self._matroid.rank(Set(G))-self._matroid.rank(Set(F)))) + for F in flats: + for G in flats: + if not (F > G or G > F): + gb.append(self.flats_generator[F]*self.flats_generator[G]) + elif F < G: + term = self.poly_ring.zero() + for H in flats: + if H < F: + term += self.flats_generator[H] + gb.append(self.flats_generator[F]*(term**self._matroid.rank(Set(G)))* + (term**(self._matroid.rank(Set(G))-self._matroid.rank(Set(F))))) g_basis = PolynomialSequence(self.poly_ring, [gb]) return g_basis - From 1d9210a78b13a8febf9d2277c3cfac520bfe71d3 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Tue, 9 Jul 2024 19:02:38 +0530 Subject: [PATCH 056/537] Edited Documentation --- src/sage/matroids/chow_ring.py | 34 ++++++++-------------------------- 1 file changed, 8 insertions(+), 26 deletions(-) diff --git a/src/sage/matroids/chow_ring.py b/src/sage/matroids/chow_ring.py index 66de4c1a967..2c8ac514574 100644 --- a/src/sage/matroids/chow_ring.py +++ b/src/sage/matroids/chow_ring.py @@ -1,15 +1,8 @@ -from sage.matroids.chow_ring_ideal import * -from sage.rings.quotient_ring import QuotientRing_nc -from sage.rings.quotient_ring_element import QuotientRingElement -from sage.categories.graded_algebras_with_basis import GradedAlgebrasWithBasis -import sage.misc.latex as latex - r""" Chow rings of matroids AUTHORS: -- Travis Scrimshaw - Shriya M These are the classes of Chow rings for matroids. It also takes in @@ -22,26 +15,16 @@ - :arxiv:`2309.14312` - :arxiv:`2111.00393` """ -#***************************************************************************** -# Copyright (C) 2024 Travis Scrimshaw -# 2024 Shriya M -# -# 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.matroids.chow_ring_ideal import ChowRingIdeal, AugmentedChowRingIdeal +from sage.rings.quotient_ring import QuotientRing_nc +from sage.rings.quotient_ring_element import QuotientRingElement +from sage.categories.graded_algebras_with_basis import GradedAlgebrasWithBasis +import sage.misc.latex as latex class ChowRing(QuotientRing_nc): r""" - The class of Chow ring, a multi-polynomial quotient ring. + The class of Chow ring, a multi-polynomial quotient ring. Base class - ``QuotientRing_nc``. INPUT: @@ -50,7 +33,7 @@ class ChowRing(QuotientRing_nc): - `M` -- a matroid. - `R` -- a ring. - ``augmented`` -- a Boolean value. When ``True``, it returns the augmented Chow - ring. If ``False``, it returns the Chow ring + ring. If ``False``, it returns the Chow ring OUTPUT: Chow ring of matroid `M`. @@ -74,5 +57,4 @@ def _repr_(self): return "Chow ring of {}".format(self._matroid) def _latex_(self): - return "%s/%s" % (latex.latex(self.poly_ring), latex.latex(self._ideal)) - + return "%s/%s" % (latex.latex(self.poly_ring), latex.latex(self._ideal)) From afbdd9c40f8ce1b1b1b473eb5b36a3bea023b06c Mon Sep 17 00:00:00 2001 From: Newtech66 Date: Sat, 13 Jul 2024 12:09:02 +0530 Subject: [PATCH 057/537] Doctest fixes --- src/sage/rings/burnside.py | 81 +++++++++++++++++++++++++++++--------- 1 file changed, 62 insertions(+), 19 deletions(-) diff --git a/src/sage/rings/burnside.py b/src/sage/rings/burnside.py index df5797d9711..929c89d2c9f 100644 --- a/src/sage/rings/burnside.py +++ b/src/sage/rings/burnside.py @@ -87,7 +87,7 @@ def _normalize(self, H): sage: P[H1] PMD[(4, ((3,4), (1,2)))] sage: P[H2] - PMD[(4, ((3,4), (1,2)))] #indirect doctest + PMD[(4, ((3,4), (1,2)))] sage: G = SymmetricGroup(4) sage: B = BurnsideRing(G) @@ -96,7 +96,7 @@ def _normalize(self, H): sage: B[H1] B[((3,4), (1,2))] sage: B[H2] - B[((3,4), (1,2))] #indirect doctest + B[((3,4), (1,2))] """ # H is of type self.element_class G = H.subgroup_of() @@ -131,6 +131,7 @@ def get_name(self, H): C3 sage: P._indices.get_name(Z3) 'C3' + sage: P._indices.unset_name(Z3) """ key = self.element_class(self, H) G = self._normalize(key) @@ -152,6 +153,7 @@ def set_name(self, H, name): C3 sage: P._indices.get_name(Z3) 'C3' + sage: P._indices.unset_name(Z3) """ if not isinstance(name, str): raise ValueError("name must be a string") @@ -248,7 +250,7 @@ def _repr_(self): def __le__(self, other): r""" - Return if this element is less or equal to ``other``. + Return if this element is less than or equal to ``other``. ``self`` is less or equal to ``other`` if it is conjugate to a subgroup of ``other`` in the parent group. @@ -291,6 +293,22 @@ def __eq__(self, other): def __lt__(self, other): r""" Return if this element is less than ``other``. + + TESTS:: + + sage: G = SymmetricGroup(4) + sage: B = BurnsideRing(G) + sage: H1 = PermutationGroup([(1,2)]) + sage: H2 = PermutationGroup([(2,3)]) + sage: H3 = PermutationGroup([(1,2),(3,4)]) + sage: B[H1] < B[H2] + False + sage: B[H1] == B[H2] + True + sage: B[H1] < B[H3] + True + sage: B[H2] < B[H3] + True """ return self <= other and self != other @@ -413,7 +431,7 @@ def _repr_(self): Element = ConjugacyClassOfSubgroups class ConjugacyClassOfSubgroups_SymmetricGroup(ConjugacyClassOfSubgroups): - def __init__(self, parent, n, C): + def __init__(self, parent, C): r""" Initialize the conjugacy class of ``C`` in SymmetricGroup(n). @@ -423,9 +441,9 @@ def __init__(self, parent, n, C): sage: Z4 = CyclicPermutationGroup(4) sage: TestSuite(P(Z4)).run() """ - self._degree = n ConjugacyClassOfSubgroups.__init__(self, parent, C) + @cached_method def subgroup_of(self): r""" Return the symmetric group which this conjugacy class @@ -444,7 +462,7 @@ def subgroup_of(self): sage: CZ2.subgroup_of() Symmetric group of order 3! as a permutation group """ - return SymmetricGroup(self._degree) + return SymmetricGroup(self._C.degree()) def _repr_(self): r""" @@ -459,6 +477,7 @@ def _repr_(self): """ return f"({self.grade()}, {super()._repr_()})" + @cached_method def grade(self): r""" Return the degree of this subgroup (which is the degree @@ -471,7 +490,7 @@ def grade(self): sage: P._indices(D2).grade() 8 """ - return self._degree + return self._C.degree() def __hash__(self): r""" @@ -496,8 +515,8 @@ def __eq__(self, other): TESTS:: sage: P = PolynomialMolecularDecomposition() - sage: H1 = P(PermutationGroup([(1,2)],domain=[1,2,3])) - sage: H2 = P(PermutationGroup([(2,3)],domain=[1,2,3])) + sage: H1 = PermutationGroup([(1,2)],domain=[1,2,3]) + sage: H2 = PermutationGroup([(2,3)],domain=[1,2,3]) sage: P[H1] == P[H2] True """ @@ -508,9 +527,19 @@ def __eq__(self, other): def __le__(self, other): r""" Return if this element is less than or equal to ``other``. + + If ``self and ``other`` belong to the same symmetric group, then + ``self`` is less than or equal to ``other`` if it is conjugate to + a subgroup of ``other`` in the parent group. + + Otherwise, ``self`` is less than ``other`` if the degree of ``self`` + is less than the degree of ``other``. """ return (isinstance(other, ConjugacyClassOfSubgroups_SymmetricGroup) - and (self.grade() < other.grade() or self == other)) + and (self.grade() < other.grade() or + (GAP_FAIL != libgap.ContainedConjugates(self.subgroup_of(), + other._C, self._C, + True)))) def __lt__(self, other): r""" @@ -548,7 +577,7 @@ def _element_constructor_(self, x): (4, ((1,2,3,4),)) """ if x.is_subgroup(self._G): - key = self.element_class(self, self._G.degree(), x) + key = self.element_class(self, self._G.subgroup(x)) return self._normalize(key) raise ValueError(f"unable to convert {x} into {self}: not a subgroup of {self._G}") @@ -572,6 +601,10 @@ def __init__(self): Parent.__init__(self, category=category) SubgroupStore.__init__(self) + @cached_method + def an_element(self): + return self.element_class(self, SymmetricGroup(0)) + def _group_invariant(self, H): r""" Returns the set of computed group invariants @@ -617,7 +650,7 @@ def _element_constructor_(self, x): TESTS:: sage: from sage.rings.burnside import ConjugacyClassesOfSubgroups_SymmetricGroup_all - sage: C = ConjugacyClassesOfSubgroups_SymmetricGroup() + sage: C = ConjugacyClassesOfSubgroups_SymmetricGroup_all() sage: Z4 = CyclicPermutationGroup(4) sage: C(Z4) (4, ((1,2,3,4),)) @@ -625,9 +658,12 @@ def _element_constructor_(self, x): sage: C(S3) (3, ((1,2,3), (1,2))) """ + if parent(x) == self: + return x + G = SymmetricGroup(x.degree()) if x.is_subgroup(G): - key = self.element_class(self, x.degree(), x) + key = self.element_class(self, x) return self._normalize(key) raise ValueError(f"unable to convert {x} into {self}: not a subgroup of {G}") @@ -699,10 +735,9 @@ def __init__(self, G, base_ring=ZZ): sage: X = Subsets(4, 2) sage: b = B.construct_from_action(lambda g, x: X([g(e) for e in x]), X) sage: b.tensor(b) - B[((3,4), (1,2)(3,4))] # B[((3,4), (1,2)(3,4))] + B[((3,4), (1,2))] # B[((3,4), (1,2))] sage: (b.tensor(b))^2 - B[((),)] # B[((),)] + 2*B[((),)] # B[((3,4), (1,2)(3,4))] - + 2*B[((3,4), (1,2)(3,4))] # B[((),)] + 4*B[((3,4), (1,2)(3,4))] # B[((3,4), (1,2)(3,4))] + B[((),)] # B[((),)] + 2*B[((),)] # B[((3,4), (1,2))] + 2*B[((3,4), (1,2))] # B[((),)] + 4*B[((3,4), (1,2))] # B[((3,4), (1,2))] TESTS:: @@ -753,14 +788,14 @@ def construct_from_action(self, action, domain): sage: X = Subsets(4, 2) sage: a = lambda g, x: X([g(e) for e in x]) sage: B.construct_from_action(a, X) - B[((3,4), (1,2)(3,4))] + B[((3,4), (1,2))] Next, we create a group action of `S_4` on itself via conjugation:: sage: X = G sage: a = lambda g, x: g*x*g.inverse() sage: B.construct_from_action(a, X) - B[((3,4), (1,3)(2,4), (1,4)(2,3))] + B[((2,4,3),)] + B[((3,4), (1,2)(3,4))] + B[((1,2,3,4),)] + 1 + B[((3,4), (1,3)(2,4), (1,4)(2,3))] + B[((2,4,3),)] + B[((3,4), (1,2))] + B[((1,2,3,4),)] + 1 TESTS:: @@ -926,7 +961,15 @@ def product_on_basis(self, H, K): Let `H` be a subgroup of `\mathfrak{G}_n` and `K` be a subgroup of `\mathfrak{G}_m`. Then we define their Cauchy product as the subgroup of `\mathfrak{G}_{n+m}` given by `H \ast K = \{h \dot k \vert h \in H_{\{1 \ldots n\}}, K_{\{n+1 \ldots n+m\}}\}` where - the subscripts denote the domains on which H and K act. + the subscripts denote the domains on which H and K act. Note that this is isomorphic to + the direct product of `H` and `K`. + + EXAMPLES:: + + sage: P = PolynomialMolecularDecomposition() + sage: matrix([[P.product_on_basis(x,y) for x in P._indices.subset(3)] for y in P._indices.subset(2)]) + [ PMD[(5, ((),))] PMD[(5, ((2,3),))] PMD[(5, ((1,2,3),))] PMD[(5, ((1,3,2), (2,3)))]] + [ PMD[(5, ((2,3),))] PMD[(5, ((4,5), (2,3)))] PMD[(5, ((1,2,3), (4,5)))] PMD[(5, ((1,3,2), (4,5), (2,3)))]] """ n, m = H.grade(), K.grade() # There is no way to create SymmetricGroup(0) using the From 80738208ed68780c5eafc4490bffa9cc973eec01 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Sun, 14 Jul 2024 15:58:57 +0530 Subject: [PATCH 058/537] Edited Documentation --- src/sage/matroids/chow_ring_ideal.py | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/src/sage/matroids/chow_ring_ideal.py b/src/sage/matroids/chow_ring_ideal.py index 908012c2a7b..62e80774859 100644 --- a/src/sage/matroids/chow_ring_ideal.py +++ b/src/sage/matroids/chow_ring_ideal.py @@ -27,7 +27,8 @@ from sage.structure.sage_object import SageObject class ChowRingIdeal(MPolynomialIdeal): - r""" + def __init__(self, M, R): + """ The class of Chow ring ideal, a multi-polynomial ideal. Base class - ``MPolynomialIdeal``. @@ -50,8 +51,6 @@ class ChowRingIdeal(MPolynomialIdeal): sage: ch = ChowRingIdeal(M=matroids.catalog.Fano(), R=QQ) Chow ring ideal of Fano: Binary matroid of rank 3 on 7 elements, type (3, 0) """ - - def __init__(self, M, R): self._matroid = M flats = [X for i in range(1, self._matroid.rank()) for X in self._matroid.flats(i)] @@ -87,7 +86,7 @@ def __repr__(self): return "Chow ring ideal of {}".format(self._matroid) def groebner_basis(self): - r""" + """ Returns the Groebner basis of the Chow ring ideal of consideration. Return type - ``PolynomialSequence``. @@ -151,7 +150,8 @@ def flats_generator(self): return dict(self.flats_generator) class AugmentedChowRingIdeal_fy(AugmentedChowRingIdeal, MPolynomialIdeal): - r""" + def __init__(self, M, R): + """ The class of augmented Chow ring ideal of Feitchner-Yuzvinsky presentation, a multi-polynomial ideal. Base class - ``MPolynomialIdeal``. @@ -174,7 +174,6 @@ class AugmentedChowRingIdeal_fy(AugmentedChowRingIdeal, MPolynomialIdeal): Augmented Chow ring ideal of Wheel(3): Regular matroid of rank 3 on 6 elements with 16 bases of Feitchner-Yuzvinsky presentation """ - def __init__(self, M, R): self._matroid = M self.flats = [X for i in range(1, self._matroid.rank()) for X in self._matroid.flats(i)] @@ -217,7 +216,7 @@ def __repr__(self): return "Augmented Chow ring ideal of {} of Feitchner-Yuzvinsky presentation".format(self._matroid) def groebner_basis(self): - r""" + """ Returns the Groebner basis of the augmented Chow ring ideal. Return type - ``PolynomialSequence``. @@ -259,7 +258,8 @@ def groebner_basis(self): return g_basis class AugmentedChowRingIdeal_atom_free(AugmentedChowRingIdeal, MPolynomialIdeal): - r""" + def __init__(self, M, R): + """ The class of augmented Chow ring ideal of atom-free presentation, a multi-polynomial ideal. Base class - ``MPolynomialIdeal``. @@ -282,7 +282,6 @@ class AugmentedChowRingIdeal_atom_free(AugmentedChowRingIdeal, MPolynomialIdeal) Augmented Chow ring ideal of Wheel(3): Regular matroid of rank 3 on 6 elements with 16 bases of atom-free presentation """ - def __init__(self, M, R): self._matroid = M self.flats = [X for i in range(1, self._matroid.rank()) for X in self._matroid.flats(i)] @@ -328,7 +327,7 @@ def __repr__(self): return "Augmented Chow ring ideal of {} of atom-free presentation".format(self._matroid) def groebner_basis(self): - r""" + """ Returns the Groebner basis of the augmented Chow ring ideal. Return type - ``PolynomialSequence``. From b3f9e31561878f7cc56640a8b0ba96fc636f8cb1 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Sun, 14 Jul 2024 15:59:47 +0530 Subject: [PATCH 059/537] Created a documentation block for chow rings --- src/doc/en/reference/matroids/index.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/doc/en/reference/matroids/index.rst b/src/doc/en/reference/matroids/index.rst index ca7d39d2f54..5f1bf9f5f45 100644 --- a/src/doc/en/reference/matroids/index.rst +++ b/src/doc/en/reference/matroids/index.rst @@ -65,6 +65,9 @@ Internals sage/matroids/set_system sage/matroids/unpickling + Chow rings of matroids + ---------------------- + .. toctree:: :maxdepth: 1 From b867da5c3877d9a6e320ee845c7676c079909587 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Mon, 15 Jul 2024 08:14:56 +0530 Subject: [PATCH 060/537] Edited latex() method --- 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 2c8ac514574..e63998e629b 100644 --- a/src/sage/matroids/chow_ring.py +++ b/src/sage/matroids/chow_ring.py @@ -20,7 +20,6 @@ from sage.rings.quotient_ring import QuotientRing_nc from sage.rings.quotient_ring_element import QuotientRingElement from sage.categories.graded_algebras_with_basis import GradedAlgebrasWithBasis -import sage.misc.latex as latex class ChowRing(QuotientRing_nc): r""" @@ -57,4 +56,5 @@ def _repr_(self): return "Chow ring of {}".format(self._matroid) def _latex_(self): + import sage.misc.latex as latex return "%s/%s" % (latex.latex(self.poly_ring), latex.latex(self._ideal)) From cba41ab47f04c4d18da1c69060c14d58125f851c Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Tue, 16 Jul 2024 14:13:23 +0530 Subject: [PATCH 061/537] Corrected Doctests --- src/sage/matroids/chow_ring_ideal.py | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/sage/matroids/chow_ring_ideal.py b/src/sage/matroids/chow_ring_ideal.py index 62e80774859..bca13ceb384 100644 --- a/src/sage/matroids/chow_ring_ideal.py +++ b/src/sage/matroids/chow_ring_ideal.py @@ -44,11 +44,14 @@ def __init__(self, M, R): Chow ring ideal of uniform matroid of rank 3 on 6 elements:: + sage: from sage.matroids.chow_ring_ideal import ChowRingIdeal + sage: ch = ChowRingIdeal(M=matroids.Uniform(3,6), R=QQ) sage: ch Chow ring ideal of U(3, 6): Matroid of rank 3 on 6 elements with circuit-closures {3: {{0, 1, 2, 3, 4, 5}}} sage: ch = ChowRingIdeal(M=matroids.catalog.Fano(), R=QQ) + sage: ch Chow ring ideal of Fano: Binary matroid of rank 3 on 7 elements, type (3, 0) """ self._matroid = M @@ -92,6 +95,9 @@ def groebner_basis(self): EXAMPLES:: + sage: from sage.matroids.chow_ring_ideal import ChowRingIdeal + sage: from sage.matroids.basis_matroid import BasisMatroid + sage: ch = ChowRingIdeal(M=BasisMatroid(groundset='abc', bases=['ab', 'ac']), R=QQ) sage: ch.groebner_basis() [Aa^2, Aa*Abc, Aa*Abc, Abc^2] @@ -102,7 +108,7 @@ def groebner_basis(self): the Non-Fano matroid:: sage: ch = ChowRingIdeal(M=matroids.catalog.NonFano(), R=QQ) - sage: ch.groebner.basis() + sage: ch.groebner_basis() Polynomial Sequence with 592 Polynomials in 16 Variables """ @@ -169,6 +175,8 @@ def __init__(self, M, R): Augmented Chow ring ideal of Wheel matroid of rank 3:: + sage: from sage.matroids.chow_ring_ideal import AugmentedChowRingIdeal_fy + sage: ch = AugumentedChowRingIdeal_fy(M=matroids.Wheel(3), R=QQ) sage: ch Augmented Chow ring ideal of Wheel(3): Regular matroid of rank 3 on @@ -222,6 +230,8 @@ def groebner_basis(self): EXAMPLES:: + sage: from sage.matroids.chow_ring_ideal import AugmentedChowRingIdeal_fy + sage: ch = AugmentedChowRingIdeal_fy(M=matroids.catalog.Fano(), R=QQ) sage: ch.groebner_basis() Polynomial Sequence with 2744 Polynomials in 21 Variables @@ -277,6 +287,8 @@ def __init__(self, M, R): Augmented Chow ring ideal of Wheel matroid of rank 3:: + sage: from sage.matroids.chow_ring_ideal import AugmentedChowRingIdeal_atom_free + sage: ch = AugumentedChowRingIdeal_atom_free(M=matroids.Wheel(3), R=QQ) sage: ch Augmented Chow ring ideal of Wheel(3): Regular matroid of rank 3 on @@ -333,6 +345,8 @@ def groebner_basis(self): EXAMPLES:: + sage: from sage.matroids.chow_ring_ideal import AugmentedChowRingIdeal_atom_free + sage: M1 = GraphicMatroid(graphs.CycleGraph(3)) sage: ch = AugmentedChowRingIdeal_atom_free(M=M1, R=QQ) sage: ch.groebner_basis() From bd59d1ef28155ae73fb9aa39c199566504f024c1 Mon Sep 17 00:00:00 2001 From: Newtech66 Date: Tue, 16 Jul 2024 22:26:46 +0530 Subject: [PATCH 062/537] Doctest fix --- src/sage/rings/burnside.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/sage/rings/burnside.py b/src/sage/rings/burnside.py index 929c89d2c9f..ba9c56979e4 100644 --- a/src/sage/rings/burnside.py +++ b/src/sage/rings/burnside.py @@ -700,6 +700,9 @@ def __contains__(self, H): sage: SH2 in P._indices True """ + if parent(H) == self: + return True + return H in self.subset(H.degree()) Element = ConjugacyClassOfSubgroups_SymmetricGroup From c90fe5bcf003a4581235cbcfe5563190baa0bf74 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Wed, 17 Jul 2024 13:29:40 +0530 Subject: [PATCH 063/537] Edited Doctests --- src/sage/matroids/chow_ring.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/sage/matroids/chow_ring.py b/src/sage/matroids/chow_ring.py index e63998e629b..4745df22ea1 100644 --- a/src/sage/matroids/chow_ring.py +++ b/src/sage/matroids/chow_ring.py @@ -18,7 +18,6 @@ from sage.matroids.chow_ring_ideal import ChowRingIdeal, AugmentedChowRingIdeal from sage.rings.quotient_ring import QuotientRing_nc -from sage.rings.quotient_ring_element import QuotientRingElement from sage.categories.graded_algebras_with_basis import GradedAlgebrasWithBasis class ChowRing(QuotientRing_nc): @@ -38,6 +37,8 @@ class ChowRing(QuotientRing_nc): EXAMPLES:: + sage: from sage.matroids.chow_ring import ChowRing + sage: M1 = matroids.catalog.P8pp() sage: ch = ChowRing(M=M1, R=QQ, augmented=False) sage: ch From cf83d974dfe2dde9839171d5cc64bfaf939c3af6 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Wed, 17 Jul 2024 13:29:54 +0530 Subject: [PATCH 064/537] Corrected Doctests --- src/sage/matroids/chow_ring_ideal.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/sage/matroids/chow_ring_ideal.py b/src/sage/matroids/chow_ring_ideal.py index bca13ceb384..8e3751d915d 100644 --- a/src/sage/matroids/chow_ring_ideal.py +++ b/src/sage/matroids/chow_ring_ideal.py @@ -138,7 +138,8 @@ def matroid(self): def flats_generator(self): return dict(self.flats_generator) -class AugmentedChowRingIdeal(SageObject): + +class AugmentedChowRingIdeal(SageObject, metaclass=ABCMeta): @abstractmethod def gens_constructor(): @@ -155,7 +156,7 @@ def matroid(self): def flats_generator(self): return dict(self.flats_generator) -class AugmentedChowRingIdeal_fy(AugmentedChowRingIdeal, MPolynomialIdeal): +class AugmentedChowRingIdeal_fy(MPolynomialIdeal, metaclass=AugmentedChowRingIdeal): def __init__(self, M, R): """ The class of augmented Chow ring ideal of Feitchner-Yuzvinsky From d892cdb7c32a3717be8b49b61b65c496e021863e Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Thu, 18 Jul 2024 08:15:22 +0530 Subject: [PATCH 065/537] Edited abstract class - AugmentedChowRingIdeal --- src/sage/matroids/chow_ring_ideal.py | 31 +++++++++------------------- 1 file changed, 10 insertions(+), 21 deletions(-) diff --git a/src/sage/matroids/chow_ring_ideal.py b/src/sage/matroids/chow_ring_ideal.py index 8e3751d915d..cc7feb467bb 100644 --- a/src/sage/matroids/chow_ring_ideal.py +++ b/src/sage/matroids/chow_ring_ideal.py @@ -138,9 +138,10 @@ def matroid(self): def flats_generator(self): return dict(self.flats_generator) +class CombinedMeta(ABCMeta, type): + pass -class AugmentedChowRingIdeal(SageObject, metaclass=ABCMeta): - +class AugmentedChowRingIdeal(CombinedMeta): @abstractmethod def gens_constructor(): pass @@ -156,7 +157,7 @@ def matroid(self): def flats_generator(self): return dict(self.flats_generator) -class AugmentedChowRingIdeal_fy(MPolynomialIdeal, metaclass=AugmentedChowRingIdeal): +class AugmentedChowRingIdeal_fy(SageObject,MPolynomialIdeal, AugmentedChowRingIdeal): def __init__(self, M, R): """ The class of augmented Chow ring ideal of Feitchner-Yuzvinsky @@ -183,9 +184,10 @@ def __init__(self, M, R): Augmented Chow ring ideal of Wheel(3): Regular matroid of rank 3 on 6 elements with 16 bases of Feitchner-Yuzvinsky presentation """ + def __init__(self, M, R): self._matroid = M self.flats = [X for i in range(1, self._matroid.rank()) - for X in self._matroid.flats(i)] + for X in self._matroid.flats(i)] E = list(self._matroid.groundset()) self.flats_generator = dict() try: @@ -199,6 +201,7 @@ def __init__(self, M, R): for i,F in enumerate(self.flats): self.flats_generator[F] = self.poly_ring.gens()[len(E) + i] MPolynomialIdeal.__init__(self, self.poly_ring, self.gens_constructor()) + def gens_constructor(self): E = list(self._matroid.groundset()) @@ -268,7 +271,7 @@ def groebner_basis(self): g_basis = PolynomialSequence(self.poly_ring, [gb]) return g_basis -class AugmentedChowRingIdeal_atom_free(AugmentedChowRingIdeal, MPolynomialIdeal): +class AugmentedChowRingIdeal_atom_free(AugmentedChowRingIdeal): def __init__(self, M, R): """ The class of augmented Chow ring ideal of atom-free @@ -295,22 +298,8 @@ def __init__(self, M, R): Augmented Chow ring ideal of Wheel(3): Regular matroid of rank 3 on 6 elements with 16 bases of atom-free presentation """ - self._matroid = M - self.flats = [X for i in range(1, self._matroid.rank()) - for X in self._matroid.flats(i)] - E = list(self._matroid.groundset()) - self.flats_generator = dict() - try: - names_groundset = ['A{}'.format(''.join(str(x))) for x in E] - names_flats = ['B{}'.format(''.join(str(x) for x in sorted(F, key=cmp_elements_key))) for F in self.flats] - self.poly_ring = PolynomialRing(R, names_groundset + names_flats) - except ValueError: - self.poly_ring = PolynomialRing(R, 'A', len(E) + len(self.flats)) - for i,x in enumerate(E): - self.flats_generator[x] = self.poly_ring.gens()[i] - for i,F in enumerate(self.flats): - self.flats_generator[F] = self.poly_ring.gens()[len(E) + i] - MPolynomialIdeal.__init__(self, self.poly_ring, self.gens_constructor()) + + AugmentedChowRingIdeal.__init__(self, M, R) def gens_constructor(self): E = list(self._matroid.groundset()) From a08c4a4e2e56f17b9626cee8d6632d24b9a81379 Mon Sep 17 00:00:00 2001 From: Newtech66 Date: Sun, 21 Jul 2024 22:05:13 +0530 Subject: [PATCH 066/537] Rewrite of species decompositions --- src/sage/groups/perm_gps/permgroup.py | 102 +++- src/sage/rings/all.py | 3 +- src/sage/rings/burnside.py | 670 ++++++++------------------ 3 files changed, 285 insertions(+), 490 deletions(-) diff --git a/src/sage/groups/perm_gps/permgroup.py b/src/sage/groups/perm_gps/permgroup.py index 5b76232e336..d97aad93b03 100644 --- a/src/sage/groups/perm_gps/permgroup.py +++ b/src/sage/groups/perm_gps/permgroup.py @@ -125,7 +125,6 @@ as permutation groups - the construction is too slow - unless (for small values or the parameter) they are made using explicit generators. - """ # **************************************************************************** # Copyright (C) 2006 William Stein @@ -1582,6 +1581,96 @@ def smallest_moved_point(self): p = self._libgap_().SmallestMovedPoint() return self._domain_from_gap[Integer(p)] + @cached_method + def disjoint_direct_product_decomposition(self): + r""" + Return the finest partition of the underlying set such that ``self`` + is isomorphic to the direct product of the projections of ``self`` + onto each part of the partition. Each part is a union of orbits + of ``self``. + + The algorithm is from [CJ2022]_, which runs in time polynomial in + `n \cdot |X|`, where `n` is the degree of the group and `|X|` is + the size of a generating set, see Theorem 4.5. + + EXAMPLES: + + The example from the original paper:: + + sage: H = PermutationGroup([[(1,2,3),(7,9,8),(10,12,11)],[(4,5,6),(7,8,9),(10,11,12)],[(5,6),(8,9),(11,12)],[(7,8,9),(10,11,12)]]) + sage: S = H.disjoint_direct_product_decomposition(); S + {{1, 2, 3}, {4, 5, 6, 7, 8, 9, 10, 11, 12}} + sage: A = libgap.Stabilizer(H, list(S[0]), libgap.OnTuples); A + Group([ (7,8,9)(10,11,12), (5,6)(8,9)(11,12), (4,5,6)(7,8,9)(10,11,12) ]) + sage: B = libgap.Stabilizer(H, list(S[1]), libgap.OnTuples); B + Group([ (1,2,3) ]) + sage: T = PermutationGroup(gap_group=libgap.DirectProduct(A,B)) + sage: T.is_isomorphic(H) + True + sage: PermutationGroup(PermutationGroup(gap_group=A).gens(),domain=list(S[1])).disjoint_direct_product_decomposition() + {{4, 5, 6, 7, 8, 9, 10, 11, 12}} + sage: PermutationGroup(PermutationGroup(gap_group=B).gens(),domain=list(S[0])).disjoint_direct_product_decomposition() + {{1, 2, 3}} + + An example with a different domain:: + + sage: PermutationGroup([[('a','c','d'),('b','e')]]).disjoint_direct_product_decomposition() + {{'a', 'c', 'd'}, {'b', 'e'}} + sage: PermutationGroup([[('a','c','d','b','e')]]).disjoint_direct_product_decomposition() + {{'a', 'b', 'c', 'd', 'e'}} + + Counting the number of "connected" permutation groups of degree `n`:: + + sage: seq = [sum(1 for G in SymmetricGroup(n).conjugacy_classes_subgroups() if len(G.disjoint_direct_product_decomposition()) == 1) for n in range(1,8)]; seq + [1, 1, 2, 6, 6, 27, 20] + sage: oeis(seq) # optional -- internet + 0: A005226: Number of atomic species of degree n; also number of connected permutation groups of degree n. + """ + from sage.combinat.set_partition import SetPartition + from sage.sets.disjoint_set import DisjointSet + H = self._libgap_() + # sort each orbit and order list by smallest element of each orbit + O = libgap.List([libgap.ShallowCopy(orbit) for orbit in libgap.Orbits(H)]) + for orbit in O: + libgap.Sort(orbit) + O.Sort() + num_orbits = len(O) + OrbitMapping = dict() + for i in range(num_orbits): + for x in O[i]: + OrbitMapping[x] = i + C = libgap.StabChain(H, libgap.Concatenation(O)) + X = libgap.StrongGeneratorsStabChain(C) + P = DisjointSet(num_orbits) + R = libgap.List([]) + identity = libgap.Identity(H) + for i in range(num_orbits-1): + libgap.Append(R, O[i]) + Xp = libgap.List([]) + while True: + try: + if libgap.IsSubset(O[i], C['orbit']): + C = C['stabilizer'] + else: + break + except ValueError: + break + for x in X: + xs = libgap.SiftedPermutation(C, x) + if xs != identity: + libgap.Add(Xp, xs) + if libgap.RestrictedPerm(xs, O[i+1]) != identity: + cj = OrbitMapping[libgap.SmallestMovedPoint(libgap.RestrictedPerm(x, R))] + P.union(i+1, cj) + else: + libgap.Add(Xp, x) + X = Xp + return SetPartition([ + [self._domain_from_gap[Integer(x)] + for i in part + for x in O[i]] for part in P] + + [[x] for x in self.fixed_points()]) + def representative_action(self, x, y): r""" Return an element of ``self`` that maps `x` to `y` if it exists. @@ -1910,7 +1999,7 @@ def base(self, seed=None): INPUT: - - ``seed`` (optional, default: ``None``), if given must be a + - ``seed`` (default: ``None``), if given must be a subset of the domain of a base. When used, an attempt to create a base containing all or part of ``seed`` will be made. @@ -1971,7 +2060,7 @@ def strong_generating_system(self, base_of_group=None, implementation="sage"): INPUT: - - ``base_of_group`` (optional) -- (default: ``[1, 2, 3, ..., d]``) + - ``base_of_group`` -- (default: ``[1, 2, 3, ..., d]``) a list containing the integers `1, 2, \ldots , d` in any order, where `d` is the degree of ``self`` @@ -2471,7 +2560,7 @@ def intersection(self, other): INPUT: - - ``other`` - a permutation group. + - ``other`` -- a permutation group. OUTPUT: @@ -2728,7 +2817,7 @@ def semidirect_product(self, N, mapping, check=True): INPUT: - - ``N`` - A group which is acted on by ``self`` and + - ``N`` -- A group which is acted on by ``self`` and naturally embeds as a normal subgroup of the returned semidirect product. @@ -4944,14 +5033,13 @@ def upper_central_series(self): from sage.groups.generic import structure_description - def sign_representation(self, base_ring=None, side="twosided"): + def sign_representation(self, base_ring=None): r""" Return the sign representation of ``self`` over ``base_ring``. INPUT: - ``base_ring`` -- (optional) the base ring; the default is `\ZZ` - - ``side`` -- ignored EXAMPLES:: diff --git a/src/sage/rings/all.py b/src/sage/rings/all.py index 8b8d98d734e..52e29b7cb8b 100644 --- a/src/sage/rings/all.py +++ b/src/sage/rings/all.py @@ -166,7 +166,8 @@ # asymptotic ring from sage.rings.asymptotic.all import * -lazy_import('sage.rings.burnside', ['BurnsideRing', 'PolynomialMolecularDecomposition']) +lazy_import('sage.rings.burnside', ['BurnsideRing', 'PolynomialMolecularDecomposition', + 'UnivariateAtomicConjugacyClasses', 'UnivariateMolecularConjugacyClasses']) # Register classes in numbers abc from sage.rings import numbers_abc diff --git a/src/sage/rings/burnside.py b/src/sage/rings/burnside.py index ba9c56979e4..a77a7aa362b 100644 --- a/src/sage/rings/burnside.py +++ b/src/sage/rings/burnside.py @@ -4,15 +4,16 @@ from sage.structure.element import parent from sage.structure.unique_representation import UniqueRepresentation from sage.rings.integer_ring import ZZ -from sage.categories.sets_cat import cartesian_product from sage.categories.finite_enumerated_sets import FiniteEnumeratedSets from sage.categories.sets_with_grading import SetsWithGrading from sage.categories.graded_algebras_with_basis import GradedAlgebrasWithBasis from sage.categories.algebras import Algebras +from sage.categories.monoids import Monoids from sage.groups.perm_gps.permgroup import PermutationGroup, PermutationGroup_generic from sage.groups.perm_gps.permgroup_named import SymmetricGroup from sage.libs.gap.libgap import libgap from sage.combinat.free_module import CombinatorialFreeModule +from sage.monoids.indexed_free_monoid import IndexedFreeAbelianMonoid, IndexedMonoid GAP_FAIL = libgap.eval('fail') @@ -31,158 +32,35 @@ def _is_conjugate(G, H1, H2): """ return GAP_FAIL != libgap.RepresentativeAction(G, H1, H2) -class SubgroupStore(): +class ElementCache(): def __init__(self): r""" - This class caches subgroup information and provides - helper methods to handle subgroup <-> name associations. - - TESTS:: - - sage: P = PolynomialMolecularDecomposition() - sage: Z3 = CyclicPermutationGroup(3) - sage: P[Z3] - PMD[(3, ((1,2,3),))] - sage: P._indices.set_name(Z3, "C3") - sage: P[Z3] - C3 - sage: P._indices.get_name(Z3) - 'C3' - sage: P._indices.unset_name(Z3) - sage: P[Z3] - PMD[(3, ((1,2,3),))] - sage: P._indices.get_name(Z3) - '(3, ((1,2,3),))' - """ - self._cache = dict() # invariant to subgroups - self._names = dict() # stores subgroup names - - def _group_invariant(self, H): - r""" - Returns the set of computed group invariants - associated with a subgroup H. - - TESTS:: - - sage: G = SymmetricGroup(3) - sage: B = BurnsideRing(G) - sage: Z3 = CyclicPermutationGroup(3) - sage: B._indices._group_invariant(Z3) - 3 + Class for caching elements of conjugacy classes of subgroups. """ - return H.order() + self._cache = dict() - def _normalize(self, H): + def _group_invariants(self, H): r""" - Converts a subgroup into its canonical representative - by finding a representative of its conjugacy class, or - using the group itself if the conjugacy class didn't exist - before. - - TESTS:: - - sage: P = PolynomialMolecularDecomposition() - sage: H1 = PermutationGroup([(1,2),(3,4)]) - sage: H2 = PermutationGroup([(1,3),(2,4)]) - sage: P[H1] - PMD[(4, ((3,4), (1,2)))] - sage: P[H2] - PMD[(4, ((3,4), (1,2)))] - - sage: G = SymmetricGroup(4) - sage: B = BurnsideRing(G) - sage: H1 = PermutationGroup([(1,2),(3,4)]) - sage: H2 = PermutationGroup([(1,3),(2,4)]) - sage: B[H1] - B[((3,4), (1,2))] - sage: B[H2] - B[((3,4), (1,2))] + Return tuple of group invariants associated with H. """ - # H is of type self.element_class - G = H.subgroup_of() - p = self._group_invariant(H._C) - if p in self._cache: - for H0 in self._cache[p]: - if _is_conjugate(G, H._C, H0._C): - return H0 - else: - g = H._C.gens_small() - H._C = G.subgroup(g) - self._cache[p].append(H) - else: - g = H._C.gens_small() - H._C = G.subgroup(g) - self._cache[p] = [H] - return H - - def get_name(self, H): - r""" - Takes a subgroup as input and returns its associated name, if any. - Otherwise, the generators are returned. Returns a string. - - TESTS:: - - sage: P = PolynomialMolecularDecomposition() - sage: Z3 = CyclicPermutationGroup(3) - sage: P[Z3] - PMD[(3, ((1,2,3),))] - sage: P._indices.set_name(Z3, "C3") - sage: P[Z3] - C3 - sage: P._indices.get_name(Z3) - 'C3' - sage: P._indices.unset_name(Z3) - """ - key = self.element_class(self, H) - G = self._normalize(key) - name = self._names.get(G, None) - return name if name else repr(G) + return tuple([H.order(), H.degree()]) - def set_name(self, H, name): + def _cache_get(self, H): r""" - Takes a subgroup as input and sets its name. - - TESTS:: - - sage: P = PolynomialMolecularDecomposition() - sage: Z3 = CyclicPermutationGroup(3) - sage: P[Z3] - PMD[(3, ((1,2,3),))] - sage: P._indices.set_name(Z3, "C3") - sage: P[Z3] - C3 - sage: P._indices.get_name(Z3) - 'C3' - sage: P._indices.unset_name(Z3) - """ - if not isinstance(name, str): - raise ValueError("name must be a string") - key = self.element_class(self, H) - G = self._normalize(key) - self._names[G] = name - - def unset_name(self, H): - r""" - Takes a subgroup as input and removes its name, if any. - - TESTS:: - - sage: P = PolynomialMolecularDecomposition() - sage: Z3 = CyclicPermutationGroup(3) - sage: P[Z3] - PMD[(3, ((1,2,3),))] - sage: P._indices.set_name(Z3, "C3") - sage: P[Z3] - C3 - sage: P._indices.get_name(Z3) - 'C3' - sage: P._indices.unset_name(Z3) - sage: P[Z3] - PMD[(3, ((1,2,3),))] - """ - key = self.element_class(self, H) - G = self._normalize(key) - self._names.pop(G, None) + Return the cached element for H, or create it + if it doesn't exist. + """ + element = self.element_class(self, H) + key = self._group_invariants(H) + if key in self._cache: + for H0, H0_elm in self._cache[key]: + if _is_conjugate(element.subgroup_of(), H0, H): + return H0_elm + else: + self._cache[key].append((H, element)) + else: + self._cache[key] = [(H, element)] + return element class ConjugacyClassOfSubgroups(Element): def __init__(self, parent, C): @@ -245,8 +123,7 @@ def _repr_(self): sage: CZ3 ((1,2,3),) """ - name = self.parent()._names.get(self._C, None) - return name if name else repr(self._C.gens()) + return repr(self._C.gens_small()) def __le__(self, other): r""" @@ -312,7 +189,7 @@ def __lt__(self, other): """ return self <= other and self != other -class ConjugacyClassesOfSubgroups(Parent, SubgroupStore): +class ConjugacyClassesOfSubgroups(Parent, ElementCache): def __init__(self, G): r""" Initialize the set of conjugacy classes of ``G``. @@ -330,7 +207,7 @@ def __init__(self, G): """ self._G = G Parent.__init__(self, category=FiniteEnumeratedSets()) - SubgroupStore.__init__(self) + ElementCache.__init__(self) def __eq__(self, other): r""" @@ -379,10 +256,14 @@ def _element_constructor_(self, x): sage: C(Z4) ((1,2,3,4),) """ - if x.is_subgroup(self._G): - key = self.element_class(self, x) - return self._normalize(key) - raise ValueError(f"unable to convert {x} into {self}: not a subgroup of {self._G}") + if parent(x) == self: + return x + if isinstance(x, PermutationGroup_generic): + if x.is_subgroup(self._G): + return self._cache_get(x) + raise ValueError(f"unable to convert {x} into {self}: not a subgroup of {self._G}") + raise ValueError("unable to convert {x} into {self}") + def __iter__(self): r""" @@ -411,7 +292,6 @@ def __contains__(self, H): """ if parent(H) == self: return True - return (isinstance(H, PermutationGroup_generic) and H.is_subgroup(self._G)) @@ -430,283 +310,6 @@ def _repr_(self): Element = ConjugacyClassOfSubgroups -class ConjugacyClassOfSubgroups_SymmetricGroup(ConjugacyClassOfSubgroups): - def __init__(self, parent, C): - r""" - Initialize the conjugacy class of ``C`` in SymmetricGroup(n). - - TESTS:: - - sage: P = PolynomialMolecularDecomposition() - sage: Z4 = CyclicPermutationGroup(4) - sage: TestSuite(P(Z4)).run() - """ - ConjugacyClassOfSubgroups.__init__(self, parent, C) - - @cached_method - def subgroup_of(self): - r""" - Return the symmetric group which this conjugacy class - of subgroups belongs to. - - TESTS:: - - sage: from sage.rings.burnside import ConjugacyClassesOfSubgroups_SymmetricGroup - sage: C = ConjugacyClassesOfSubgroups_SymmetricGroup(3) - sage: Z3 = CyclicPermutationGroup(3) - sage: CZ3 = C(Z3) - sage: CZ3.subgroup_of() - Symmetric group of order 3! as a permutation group - sage: Z2 = CyclicPermutationGroup(2) - sage: CZ2 = C(Z2) - sage: CZ2.subgroup_of() - Symmetric group of order 3! as a permutation group - """ - return SymmetricGroup(self._C.degree()) - - def _repr_(self): - r""" - Return a string representation of ``self``. - - TESTS:: - - sage: P = PolynomialMolecularDecomposition() - sage: H = PermutationGroup([[(1,2),(5,6)],[(3,4)]]) - sage: P._indices(H) - (6, ((3,4), (1,2)(5,6))) - """ - return f"({self.grade()}, {super()._repr_()})" - - @cached_method - def grade(self): - r""" - Return the degree of this subgroup (which is the degree - of the symmetric group it is a subgroup of). - - TESTS:: - - sage: P = PolynomialMolecularDecomposition() - sage: D2 = DiCyclicGroup(2) - sage: P._indices(D2).grade() - 8 - """ - return self._C.degree() - - def __hash__(self): - r""" - Return the hash of the representative of the conjugacy class. - - TESTS:: - - sage: P = PolynomialMolecularDecomposition() - sage: H1 = P(PermutationGroup([(1,2)],domain=[1,2,3])) - sage: H2 = P(PermutationGroup([(2,3)],domain=[1,2,3])) - sage: hash(H1) == hash(H2) - True - """ - return hash((hash(SymmetricGroup(self.grade())), hash(self._C))) - - def __eq__(self, other): - r""" - Return if this element is equal to ``other``. - - Two elements compare equal if they are conjugate subgroups in the parent group. - - TESTS:: - - sage: P = PolynomialMolecularDecomposition() - sage: H1 = PermutationGroup([(1,2)],domain=[1,2,3]) - sage: H2 = PermutationGroup([(2,3)],domain=[1,2,3]) - sage: P[H1] == P[H2] - True - """ - return (isinstance(other, ConjugacyClassOfSubgroups_SymmetricGroup) - and self.grade() == other.grade() - and _is_conjugate(self.subgroup_of(), self._C, other._C)) - - def __le__(self, other): - r""" - Return if this element is less than or equal to ``other``. - - If ``self and ``other`` belong to the same symmetric group, then - ``self`` is less than or equal to ``other`` if it is conjugate to - a subgroup of ``other`` in the parent group. - - Otherwise, ``self`` is less than ``other`` if the degree of ``self`` - is less than the degree of ``other``. - """ - return (isinstance(other, ConjugacyClassOfSubgroups_SymmetricGroup) - and (self.grade() < other.grade() or - (GAP_FAIL != libgap.ContainedConjugates(self.subgroup_of(), - other._C, self._C, - True)))) - - def __lt__(self, other): - r""" - Return if this element is less than ``other``. - """ - return self != other and self <= other - -class ConjugacyClassesOfSubgroups_SymmetricGroup(ConjugacyClassesOfSubgroups, SubgroupStore): - def __init__(self, n): - r""" - Initialize the set of conjugacy classes of SymmetricGroup(n). - - INPUT: - - ``n`` -- the degree of the symmetric group. - - TESTS:: - - sage: from sage.rings.burnside import ConjugacyClassesOfSubgroups_SymmetricGroup - sage: C = ConjugacyClassesOfSubgroups_SymmetricGroup(4) - sage: TestSuite(C).run() - """ - ConjugacyClassesOfSubgroups.__init__(self, SymmetricGroup(n)) - - def _element_constructor_(self, x): - r""" - Construct the conjugacy class of subgroups containing ``x``. - - TESTS:: - - sage: from sage.rings.burnside import ConjugacyClassesOfSubgroups_SymmetricGroup - sage: C = ConjugacyClassesOfSubgroups_SymmetricGroup(4) - sage: Z4 = CyclicPermutationGroup(4) - sage: C(Z4) - (4, ((1,2,3,4),)) - """ - if x.is_subgroup(self._G): - key = self.element_class(self, self._G.subgroup(x)) - return self._normalize(key) - raise ValueError(f"unable to convert {x} into {self}: not a subgroup of {self._G}") - - Element = ConjugacyClassOfSubgroups_SymmetricGroup - -class ConjugacyClassesOfSubgroups_SymmetricGroup_all(UniqueRepresentation, Parent, SubgroupStore): - def __init__(self): - r""" - Initialize the set of conjugacy classes of all symmetric groups. - - This is a graded set graded by the non-negative integers. The homogeneous piece - with grade n is the set of conjugacy classes of subgroups of SymmetricGroup(n). - - TESTS:: - - sage: from sage.rings.burnside import ConjugacyClassesOfSubgroups_SymmetricGroup_all - sage: C = ConjugacyClassesOfSubgroups_SymmetricGroup_all() - sage: TestSuite(C).run() - """ - category = SetsWithGrading().Infinite() - Parent.__init__(self, category=category) - SubgroupStore.__init__(self) - - @cached_method - def an_element(self): - return self.element_class(self, SymmetricGroup(0)) - - def _group_invariant(self, H): - r""" - Returns the set of computed group invariants - associated with a subgroup H. - - TESTS:: - - sage: P = PolynomialMolecularDecomposition() - sage: S3 = SymmetricGroup(3) - sage: P._indices._group_invariant(S3) - (6, 3) - """ - return (H.order(), H.degree()) - - def _repr_(self): - r""" - Return a string representation of ``self``. - - TESTS:: - - sage: P = PolynomialMolecularDecomposition() - sage: P._indices - Conjugacy classes of subgroups of symmetric groups - """ - return "Conjugacy classes of subgroups of symmetric groups" - - def subset(self, n): - r""" - Returns the conjugacy classes of subgroups of SymmetricGroup(n). - - TESTS:: - - sage: P = PolynomialMolecularDecomposition() - sage: P._indices.subset(3) - Conjugacy classes of subgroups of Symmetric group of order 3! as a permutation group - """ - return ConjugacyClassesOfSubgroups_SymmetricGroup(n) - - def _element_constructor_(self, x): - r""" - Construct the conjugacy class of subgroups containing ``x``. - - TESTS:: - - sage: from sage.rings.burnside import ConjugacyClassesOfSubgroups_SymmetricGroup_all - sage: C = ConjugacyClassesOfSubgroups_SymmetricGroup_all() - sage: Z4 = CyclicPermutationGroup(4) - sage: C(Z4) - (4, ((1,2,3,4),)) - sage: S3 = SymmetricGroup(3) - sage: C(S3) - (3, ((1,2,3), (1,2))) - """ - if parent(x) == self: - return x - - G = SymmetricGroup(x.degree()) - if x.is_subgroup(G): - key = self.element_class(self, x) - return self._normalize(key) - raise ValueError(f"unable to convert {x} into {self}: not a subgroup of {G}") - - def __iter__(self): - r""" - Return iterator over conjugacy classes of subgroups of symmetric groups. - - TESTS:: - - sage: P = PolynomialMolecularDecomposition() - sage: it = iter(P._indices) - sage: [next(it) for _ in range(1,7)] - [(0, ((),)), (1, ((),)), (2, ((),)), (2, ((1,2),)), (3, ((),)), (3, ((2,3),))] - """ - n = 0 - while True: - yield from self.subset(n) - n += 1 - - def __contains__(self, H): - r""" - Returns if H is a subgroup of a symmetric group. - - TESTS:: - - sage: P = PolynomialMolecularDecomposition() - sage: Z3 = CyclicPermutationGroup(3) - sage: Z3 in P._indices - True - sage: SH = PermutationGroup([[(1,3)]],domain=[1,3]) - sage: SH in P._indices - False - sage: SH2 = PermutationGroup([[(1,3)]]) - sage: SH2 in P._indices - True - """ - if parent(H) == self: - return True - - return H in self.subset(H.degree()) - - Element = ConjugacyClassOfSubgroups_SymmetricGroup - class BurnsideRing(CombinatorialFreeModule): def __init__(self, G, base_ring=ZZ): r""" @@ -753,8 +356,7 @@ def __init__(self, G, base_ring=ZZ): category = Algebras(base_ring).Commutative().WithBasis() CombinatorialFreeModule.__init__(self, base_ring, basis_keys, category=category, prefix="B") - self._print_options['names'] = self._indices._names - self._indices.set_name(G, "1") + self._indices(G).rename("1") def __getitem__(self, H): r""" @@ -911,15 +513,155 @@ def _repr_(self): """ return "Burnside ring of " + repr(self._G) +class AtomicConjugacyClass(ConjugacyClassOfSubgroups): + def __init__(self, parent, C): + r""" + An atomic conjugacy class. + """ + ConjugacyClassOfSubgroups.__init__(self, parent, C) + + @cached_method + def subgroup_of(self): + r""" + Return the group which this atomic conjugacy class of subgroups + belongs to. + + TESTS:: + + sage: At = UnivariateAtomicConjugacyClasses() + sage: g = At(CyclicPermutationGroup(3)); g + {3, [(1,2,3)]} + sage: g.subgroup_of() + Symmetric group of order 3! as a permutation group + """ + return SymmetricGroup(self._C.degree()) + + def _repr_(self): + r""" + Return a string representation of ``self``. + + EXAMPLES:: + + sage: At = UnivariateAtomicConjugacyClasses() + sage: g = At(CyclicPermutationGroup(3)); g + {3, [(1,2,3)]} + """ + return "{" + f"{self._C.degree()}, {self._C.gens_small()}" + "}" + +class UnivariateAtomicConjugacyClasses(UniqueRepresentation, Parent, ElementCache): + def __init__(self): + r""" + Infinite set of atomic conjugacy classes of `S_n`. + + Graded by `n \geq 0`. + """ + category = SetsWithGrading().Infinite() + Parent.__init__(self, category=category) + ElementCache.__init__(self) + + @cached_method + def an_element(self): + return self._cache_get(SymmetricGroup(0)) + + def _element_constructor_(self, x): + r""" + Construct the atomic conjugacy class of subgroups containing ``x``. + """ + # BUG: SymmetricGroup(0) fails to be constructed. + if parent(x) == self: + return x + if isinstance(x, PermutationGroup_generic): + if len(x.disjoint_direct_product_decomposition()) == 1: + return self._cache_get(x) + else: + raise ValueError(f"{x} is not atomic") + raise ValueError(f"unable to convert {x} into {self}") + + def __contains__(self, H): + r""" + Return if H is an atomic subgroup. + """ + if parent(H) == self: + return True + return (isinstance(H, PermutationGroup_generic) + and len(H.disjoint_direct_product_decomposition()) == 1) + + def _repr_(self): + r""" + Return a string representation of ``self``. + + EXAMPLES:: + + sage: At = UnivariateAtomicConjugacyClasses() + sage: At + Set of all atomic conjugacy classes on 1 sort + """ + return "Set of all atomic conjugacy classes on 1 sort" + + Element=AtomicConjugacyClass + +class UnivariateMolecularConjugacyClasses(IndexedFreeAbelianMonoid): + @staticmethod + def __classcall__(cls): + r""" + Needed to make this work. Taken from example in center_uea.py. + """ + return super(IndexedMonoid, cls).__classcall__(cls) + + def __init__(self): + r""" + Infinite set of molecular conjugacy classes of `S_n`. + Implemented as elements of the free abelian monoid on + univariate atomic conjugacy classes. + + Graded by `n \geq 0`. + """ + category = Monoids() & SetsWithGrading().Infinite() + IndexedFreeAbelianMonoid.__init__(self, + indices=UnivariateAtomicConjugacyClasses(), + prefix='', bracket=False, + category=category) + + def _project(self, H, part): + r""" + Project `H` onto a subset ``part`` of its domain. + ``part`` must be a union of cycles, but this is not checked. + """ + restricted_gens = [[cyc for cyc in gen.cycle_tuples() if cyc[0] in part] for gen in H.gens_small()] + mapping = {elm: i for i, elm in enumerate(part, 1)} + normalized_gens = [[tuple(mapping[x] for x in cyc) for cyc in gen] for gen in restricted_gens] + return PermutationGroup(gens=normalized_gens) + + def _element_constructor_(self, x=None): + if x is None: + return super()._element_constructor_(x) + if parent(x) == self: + return x + if isinstance(x, PermutationGroup_generic): + domain_partition = x.disjoint_direct_product_decomposition() + return super()._element_constructor_([(self.gen(self._project(x, part)), 1) for part in domain_partition]) + raise ValueError("unable to convert {x} into {self}") + + def _repr_(self): + r""" + Return a string representation of ``self``. + + EXAMPLES:: + + sage: Mol = UnivariateMolecularConjugacyClasses() + sage: Mol + Set of all molecular conjugacy classes on 1 sort + """ + return "Set of all molecular conjugacy classes on 1 sort" + class PolynomialMolecularDecomposition(CombinatorialFreeModule): def __init__(self, base_ring=ZZ): - basis_keys = ConjugacyClassesOfSubgroups_SymmetricGroup_all() + basis_keys = UnivariateMolecularConjugacyClasses() category = GradedAlgebrasWithBasis(base_ring).Commutative() CombinatorialFreeModule.__init__(self, base_ring, basis_keys=basis_keys, category=category, - prefix="PMD") - self._print_options['names'] = self._indices._names + prefix='', bracket=False) def __getitem__(self, H): r""" @@ -932,7 +674,7 @@ def __getitem__(self, H): sage: P = PolynomialMolecularDecomposition() sage: Z4 = CyclicPermutationGroup(4) sage: P[Z4] - PMD[(4, ((1,2,3,4),))] + {4, [(1,2,3,4)]} """ return self._from_dict({self._indices(H): 1}) @@ -946,20 +688,13 @@ def one_basis(self): sage: P = PolynomialMolecularDecomposition() sage: P.one_basis() - (0, ((),)) + 1 """ return self._indices(SymmetricGroup(0)) - # Remember, a basis element here is a molecular species. - # When two basis elements are multiplied, you get another - # molecular species, ie a basis element. - # Any molecular species centered on cardinality n M_n, - # is equivalent to [S_n/H] where H is some conjugacy class - # of subgroups of S_n. - def product_on_basis(self, H, K): r""" - Return the product of the basis elements indexed by ``H`` and ``K``. + Return the product of the basis elements indexed by `H` and `K`. Let `H` be a subgroup of `\mathfrak{G}_n` and `K` be a subgroup of `\mathfrak{G}_m`. Then we define their Cauchy product as the subgroup of `\mathfrak{G}_{n+m}` given by @@ -969,44 +704,15 @@ def product_on_basis(self, H, K): EXAMPLES:: + sage: Mol = UnivariateMolecularConjugacyClasses() sage: P = PolynomialMolecularDecomposition() - sage: matrix([[P.product_on_basis(x,y) for x in P._indices.subset(3)] for y in P._indices.subset(2)]) - [ PMD[(5, ((),))] PMD[(5, ((2,3),))] PMD[(5, ((1,2,3),))] PMD[(5, ((1,3,2), (2,3)))]] - [ PMD[(5, ((2,3),))] PMD[(5, ((4,5), (2,3)))] PMD[(5, ((1,2,3), (4,5)))] PMD[(5, ((1,3,2), (4,5), (2,3)))]] + sage: L1 = SymmetricGroup(3).conjugacy_classes_subgroups() + sage: L2 = SymmetricGroup(2).conjugacy_classes_subgroups() + sage: matrix([[P.product_on_basis(Mol(x),Mol(y)) for x in L1] for y in L2]) + [ {1, [()]}^5 {1, [()]}^3*{2, [(1,2)]} {3, [(1,2,3)]}*{1, [()]}^2 {3, [(1,2,3), (2,3)]}*{1, [()]}^2] + [ {1, [()]}^3*{2, [(1,2)]} {1, [()]}*{2, [(1,2)]}^2 {3, [(1,2,3)]}*{2, [(1,2)]} {3, [(1,2,3), (2,3)]}*{2, [(1,2)]}] """ - n, m = H.grade(), K.grade() - # There is no way to create SymmetricGroup(0) using the - # PermutationGroup constructor as used here, so a special - # case has to be added. - if n+m == 0: - return self._from_dict({self._indices(SymmetricGroup(0)): 1}) - # We only really need to multiply generators, since we are multiplying - # permutations acting on disjoint domains. - H_action = lambda g, e: g(e) if e<=n else e - H_extend = PermutationGroup(H._C.gens_small(), action=H_action, domain=range(1,n+m+1)) - K_action = lambda g, e: n + g(e-n) if e>n else e - K_restrict = PermutationGroup(K._C.gens_small(), action=K_action, domain=range(1,n+m+1)) - # We need to add the identity elements to the generating sets - # to obtain a generating set for H*K. - G = PermutationGroup(H_extend.gens_small() - + K_restrict.gens_small() - + [H_extend.identity()], domain=range(1,n+m+1)) - return self._from_dict({self._indices(G): 1}) - - def degree_on_basis(self, H): - r""" - Return the degree of the basis element indexed by ``H``. - - H is an instance of ConjugacyClassOfSubgroups_SymmetricGroup. - - EXAMPLES:: - - sage: P = PolynomialMolecularDecomposition() - sage: Z4 = CyclicPermutationGroup(4) - sage: P.degree_on_basis(P._indices(Z4)) - 4 - """ - return H.grade() + return self._from_dict({H * K: 1}) def _repr_(self): r""" From 2900263226a4eacc5c0d53cb6abbec52812cc54c Mon Sep 17 00:00:00 2001 From: Newtech66 Date: Sun, 21 Jul 2024 23:11:28 +0530 Subject: [PATCH 067/537] Doctests --- src/sage/rings/burnside.py | 114 ++++++++++++++++++++++++++++--------- 1 file changed, 88 insertions(+), 26 deletions(-) diff --git a/src/sage/rings/burnside.py b/src/sage/rings/burnside.py index a77a7aa362b..2c7f11d323a 100644 --- a/src/sage/rings/burnside.py +++ b/src/sage/rings/burnside.py @@ -121,7 +121,7 @@ def _repr_(self): sage: Z3 = CyclicPermutationGroup(3) sage: CZ3 = C(Z3) sage: CZ3 - ((1,2,3),) + [(1,2,3)] """ return repr(self._C.gens_small()) @@ -254,13 +254,13 @@ def _element_constructor_(self, x): sage: C = ConjugacyClassesOfSubgroups(G) sage: Z4 = CyclicPermutationGroup(4) sage: C(Z4) - ((1,2,3,4),) + [(1,2,3,4)] """ if parent(x) == self: return x if isinstance(x, PermutationGroup_generic): if x.is_subgroup(self._G): - return self._cache_get(x) + return self._cache_get(self._G.subgroup(x.gens())) raise ValueError(f"unable to convert {x} into {self}: not a subgroup of {self._G}") raise ValueError("unable to convert {x} into {self}") @@ -274,7 +274,7 @@ def __iter__(self): sage: G = SymmetricGroup(3) sage: B = BurnsideRing(G) sage: [g for g in B._indices] - [((),), ((1,2),), ((1,2,3),), ((1,2,3), (1,2))] + [[()], [(1,2)], [(1,2,3)], 1] """ return iter(self(H) for H in self._G.conjugacy_classes_subgroups()) @@ -327,23 +327,36 @@ def __init__(self, G, base_ring=ZZ): sage: X = Subsets(6, 2) sage: b = B.construct_from_action(lambda g, x: X([g(e) for e in x]), X) sage: B.basis().keys()._cache - {48: [((1,2)(4,5,6), (3,5,4,6))], 720: [((1,2,3,4,5,6), (1,2))]} + {(48, + 6): [(Subgroup generated by [(3,5,4,6), (1,2)(4,5,6)] of (Symmetric group of order 6! as a permutation group), + [(1,2)(4,5,6), (3,5,4,6)])], + (720, + 6): [(Subgroup generated by [(1,2,3,4,5,6), (1,2)] of (Symmetric group of order 6! as a permutation group), + 1)]} sage: b^2 - B[((4,5), (4,6))] + B[((5,6), (3,4), (1,2))] + B[((1,2)(4,5,6), (3,5,4,6))] + B[[(4,6,5), (4,6)]] + B[[(5,6), (3,4)(5,6), (1,2)(5,6)]] + B[[(1,2)(4,5,6), (3,5,4,6)]] sage: B.basis().keys()._cache - {6: [((4,5), (4,6))], - 8: [((5,6), (3,4), (1,2))], - 48: [((1,2)(4,5,6), (3,5,4,6))], - 720: [((1,2,3,4,5,6), (1,2))]} + {(6, + 6): [(Subgroup generated by [(4,6), (4,6,5)] of (Symmetric group of order 6! as a permutation group), + [(4,6,5), (4,6)])], + (8, + 6): [(Subgroup generated by [(5,6), (1,2)(5,6), (3,4)(5,6)] of (Symmetric group of order 6! as a permutation group), + [(5,6), (3,4)(5,6), (1,2)(5,6)])], + (48, + 6): [(Subgroup generated by [(3,5,4,6), (1,2)(4,5,6)] of (Symmetric group of order 6! as a permutation group), + [(1,2)(4,5,6), (3,5,4,6)])], + (720, + 6): [(Subgroup generated by [(1,2,3,4,5,6), (1,2)] of (Symmetric group of order 6! as a permutation group), + 1)]} sage: G = SymmetricGroup(4) sage: B = BurnsideRing(G) sage: X = Subsets(4, 2) sage: b = B.construct_from_action(lambda g, x: X([g(e) for e in x]), X) sage: b.tensor(b) - B[((3,4), (1,2))] # B[((3,4), (1,2))] + B[[(3,4), (1,2)(3,4)]] # B[[(3,4), (1,2)(3,4)]] sage: (b.tensor(b))^2 - B[((),)] # B[((),)] + 2*B[((),)] # B[((3,4), (1,2))] + 2*B[((3,4), (1,2))] # B[((),)] + 4*B[((3,4), (1,2))] # B[((3,4), (1,2))] + B[[()]] # B[[()]] + 2*B[[()]] # B[[(3,4), (1,2)(3,4)]] + 2*B[[(3,4), (1,2)(3,4)]] # B[[()]] + 4*B[[(3,4), (1,2)(3,4)]] # B[[(3,4), (1,2)(3,4)]] TESTS:: @@ -370,7 +383,7 @@ def __getitem__(self, H): sage: B = BurnsideRing(G) sage: Z4 = CyclicPermutationGroup(4) sage: B[Z4] - B[((1,2,3,4),)] + B[[(1,2,3,4)]] """ return self._from_dict({self._indices(H): 1}) @@ -393,14 +406,14 @@ def construct_from_action(self, action, domain): sage: X = Subsets(4, 2) sage: a = lambda g, x: X([g(e) for e in x]) sage: B.construct_from_action(a, X) - B[((3,4), (1,2))] + B[[(3,4), (1,2)(3,4)]] Next, we create a group action of `S_4` on itself via conjugation:: sage: X = G sage: a = lambda g, x: g*x*g.inverse() sage: B.construct_from_action(a, X) - B[((3,4), (1,3)(2,4), (1,4)(2,3))] + B[((2,4,3),)] + B[((3,4), (1,2))] + B[((1,2,3,4),)] + 1 + B[[(3,4), (1,3)(2,4), (1,4)(2,3)]] + B[[(2,4,3)]] + B[[(3,4), (1,2)(3,4)]] + B[[(1,2,3,4)]] + B[1] TESTS:: @@ -409,12 +422,19 @@ def construct_from_action(self, action, domain): sage: [b.support()[0]._C.order() for b in B.gens()] [1, 2, 2, 3, 4, 4, 4, 6, 8, 12, 24] sage: sorted((o, len(l)) for o, l in B._indices._cache.items()) - [(1, 1), (2, 2), (3, 1), (4, 3), (6, 1), (8, 1), (12, 1), (24, 1)] + [((1, 4), 1), + ((2, 4), 2), + ((3, 4), 1), + ((4, 4), 3), + ((6, 4), 1), + ((8, 4), 1), + ((12, 4), 1), + ((24, 4), 1)] sage: G = SymmetricGroup(4) sage: B = BurnsideRing(G) sage: B(-3) - -3 + -3*B[1] """ def find_stabilizer(action, pnt): stabilizer = [] @@ -446,7 +466,7 @@ def one_basis(self): sage: G = DiCyclicGroup(4) sage: B = BurnsideRing(G) sage: B.one_basis() - ((1,2,3,4,5,6,7,8)(9,10,11,12,13,14,15,16), (1,9,5,13)(2,16,6,12)(3,15,7,11)(4,14,8,10)) + 1 """ return self._indices(self._G) @@ -462,10 +482,10 @@ def product_on_basis(self, H, K): sage: G = SymmetricGroup(3) sage: B = BurnsideRing(G) sage: matrix([[b * c for b in B.gens()] for c in B.gens()]) - [ 6*B[((),)] 3*B[((),)] 2*B[((),)] B[((),)]] - [ 3*B[((),)] B[((),)] + B[((1,2),)] B[((),)] B[((1,2),)]] - [ 2*B[((),)] B[((),)] 2*B[((1,2,3),)] B[((1,2,3),)]] - [ B[((),)] B[((1,2),)] B[((1,2,3),)] 1] + [ 6*B[[()]] 3*B[[()]] 2*B[[()]] B[[()]]] + [ 3*B[[()]] B[[()]] + B[[(1,2)]] B[[()]] B[[(1,2)]]] + [ 2*B[[()]] B[[()]] 2*B[[(1,2,3)]] B[[(1,2,3)]]] + [ B[[()]] B[[(1,2)]] B[[(1,2,3)]] B[1]] TESTS:: @@ -476,7 +496,7 @@ def product_on_basis(self, H, K): sage: from sage.rings.burnside import ConjugacyClassesOfSubgroups sage: C = ConjugacyClassesOfSubgroups(G) sage: B.product_on_basis(C(Z2), C(Z3)) - B[((),)] + B[[()]] """ g_reps = [rep for rep, size in libgap.DoubleCosetRepsAndSizes(self._G, H._C, K._C)] from collections import Counter @@ -517,6 +537,12 @@ class AtomicConjugacyClass(ConjugacyClassOfSubgroups): def __init__(self, parent, C): r""" An atomic conjugacy class. + + TESTS:: + + sage: At = UnivariateAtomicConjugacyClasses() + sage: Z4 = CyclicPermutationGroup(4) + sage: TestSuite(At(Z4)).run() """ ConjugacyClassOfSubgroups.__init__(self, parent, C) @@ -554,6 +580,11 @@ def __init__(self): Infinite set of atomic conjugacy classes of `S_n`. Graded by `n \geq 0`. + + TESTS:: + + sage: At = UnivariateAtomicConjugacyClasses() + sage: TestSuite(At).run(skip="_test_graded_components") """ category = SetsWithGrading().Infinite() Parent.__init__(self, category=category) @@ -561,11 +592,27 @@ def __init__(self): @cached_method def an_element(self): + """ + Return an element of ``self``. + + EXAMPLES:: + + sage: At = UnivariateAtomicConjugacyClasses() + sage: At.an_element() + {0, []} + """ return self._cache_get(SymmetricGroup(0)) def _element_constructor_(self, x): r""" Construct the atomic conjugacy class of subgroups containing ``x``. + + TESTS:: + + sage: At = UnivariateAtomicConjugacyClasses() + sage: Z4 = CyclicPermutationGroup(4) + sage: At(Z4) + {4, [(1,2,3,4)]} """ # BUG: SymmetricGroup(0) fails to be constructed. if parent(x) == self: @@ -615,6 +662,11 @@ def __init__(self): univariate atomic conjugacy classes. Graded by `n \geq 0`. + + TESTS:: + + sage: Mol = UnivariateMolecularConjugacyClasses() + sage: TestSuite(Mol).run(skip="_test_graded_components") """ category = Monoids() & SetsWithGrading().Infinite() IndexedFreeAbelianMonoid.__init__(self, @@ -632,9 +684,16 @@ def _project(self, H, part): normalized_gens = [[tuple(mapping[x] for x in cyc) for cyc in gen] for gen in restricted_gens] return PermutationGroup(gens=normalized_gens) - def _element_constructor_(self, x=None): - if x is None: - return super()._element_constructor_(x) + def _element_constructor_(self, x): + r""" + Construct the molecular conjugacy class of subgroups containing ``x``. + + TESTS:: + + sage: Mol = UnivariateMolecularConjugacyClasses() + sage: [Mol(H) for H in SymmetricGroup(3).conjugacy_classes_subgroups()] + [{1, [()]}^3, {1, [()]}*{2, [(1,2)]}, {3, [(1,2,3)]}, {3, [(1,2,3), (2,3)]}] + """ if parent(x) == self: return x if isinstance(x, PermutationGroup_generic): @@ -656,6 +715,9 @@ def _repr_(self): class PolynomialMolecularDecomposition(CombinatorialFreeModule): def __init__(self, base_ring=ZZ): + r""" + Ring of virtual species on 1 sort. + """ basis_keys = UnivariateMolecularConjugacyClasses() category = GradedAlgebrasWithBasis(base_ring).Commutative() CombinatorialFreeModule.__init__(self, base_ring, From 1e8ce4492de03c1d0f85b5c4ead2fcd96ad07ce9 Mon Sep 17 00:00:00 2001 From: Newtech66 Date: Mon, 22 Jul 2024 12:45:11 +0530 Subject: [PATCH 068/537] Add construct_from_action to PolynomialMolecularDecomposition --- src/sage/rings/burnside.py | 56 +++++++++++++++++++++++++++++++++++++- 1 file changed, 55 insertions(+), 1 deletion(-) diff --git a/src/sage/rings/burnside.py b/src/sage/rings/burnside.py index 2c7f11d323a..99354bbda9d 100644 --- a/src/sage/rings/burnside.py +++ b/src/sage/rings/burnside.py @@ -698,7 +698,7 @@ def _element_constructor_(self, x): return x if isinstance(x, PermutationGroup_generic): domain_partition = x.disjoint_direct_product_decomposition() - return super()._element_constructor_([(self.gen(self._project(x, part)), 1) for part in domain_partition]) + return super()._element_constructor_([(self._indices(self._project(x, part)), 1) for part in domain_partition]) raise ValueError("unable to convert {x} into {self}") def _repr_(self): @@ -754,6 +754,60 @@ def one_basis(self): """ return self._indices(SymmetricGroup(0)) + def construct_from_action(self, action, domain, domsize): + r""" + Construct an element of this ring from a group action. + + INPUT: + + - ``action`` - an action on ``domain`` + - ``domain`` - a finite set + - ``domsize`` - size of the domain + + EXAMPLES:: + + sage: P = PolynomialMolecularDecomposition() + + We create a group action of `S_4` on two-element subsets:: + + sage: X = Subsets(4, 2) + sage: a = lambda g, x: X([g(e) for e in x]) + sage: P.construct_from_action(a, X, 4) + {2, [(1,2)]}^2 + + Next, we create a group action of `S_4` on itself via conjugation:: + + sage: X = SymmetricGroup(4) + sage: a = lambda g, x: g*x*g.inverse() + sage: P.construct_from_action(a, X, 4) + {4, [(2,3,4), (1,2)]} + {4, [(2,4), (1,4)(2,3)]} + {1, [()]}*{3, [(1,2,3)]} + {2, [(1,2)]}^2 + {4, [(1,2,3,4)]} + + TESTS:: + + sage: P = PolynomialMolecularDecomposition() + sage: P(-3) + -3 + """ + def find_stabilizer(action, pnt): + stabilizer = [] + for g in G: + if action(g, pnt) == pnt: + stabilizer.append(g) + H = G.subgroup(stabilizer) + gens = H.gens_small() + return G.subgroup(gens) + + G = SymmetricGroup(domsize) + H = PermutationGroup(G.gens(), action=action, domain=domain) + # decompose H into orbits + orbit_list = H.orbits() + # find the stabilizer subgroups + stabilizer_list = [find_stabilizer(action, orbit[0]) for orbit in orbit_list] + # normalize each summand and collect terms + from collections import Counter + C = Counter([self._indices(stabilizer) for stabilizer in stabilizer_list]) + return self._from_dict(dict(C)) + def product_on_basis(self, H, K): r""" Return the product of the basis elements indexed by `H` and `K`. From fdd0444e379223d51bccceaa376f10faabf9ba04 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Tue, 23 Jul 2024 15:53:20 +0530 Subject: [PATCH 069/537] Split ChowRingIdeal into 4 classes --- src/sage/matroids/chow_ring_ideal.py | 194 +++++++++++++++++---------- 1 file changed, 122 insertions(+), 72 deletions(-) diff --git a/src/sage/matroids/chow_ring_ideal.py b/src/sage/matroids/chow_ring_ideal.py index cc7feb467bb..902dec3565f 100644 --- a/src/sage/matroids/chow_ring_ideal.py +++ b/src/sage/matroids/chow_ring_ideal.py @@ -5,7 +5,7 @@ - Shriya M -These are the classes of Chow ring ideals for matroids. There are two classes +These are the classes of Chow ring ideals for matroids. There are three classes created - Chow ring ideal and augmented Chow ring ideal. The augmented Chow ring ideal has two different presentations implemented - the Feitchner- Yuzvinsky presentation and atom-free presentation. Both classes have @@ -23,12 +23,23 @@ from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing from sage.sets.set import Set from sage.rings.polynomial.multi_polynomial_sequence import PolynomialSequence -from abc import ABC, abstractmethod, ABCMeta -from sage.structure.sage_object import SageObject +from sage.misc.abstract_method import abstract_method class ChowRingIdeal(MPolynomialIdeal): - def __init__(self, M, R): - """ + @abstract_method + def gens_constructor(): + pass + + def matroid(self): + M = self._matroid + return M + + def flats_generator(self): + return dict(self.flats_generator) + + +class ChowRingIdeal_nonaug(ChowRingIdeal): + r""" The class of Chow ring ideal, a multi-polynomial ideal. Base class - ``MPolynomialIdeal``. @@ -44,16 +55,27 @@ def __init__(self, M, R): Chow ring ideal of uniform matroid of rank 3 on 6 elements:: - sage: from sage.matroids.chow_ring_ideal import ChowRingIdeal + sage: from sage.matroids.chow_ring_ideal import ChowRingIdeal_nonaug - sage: ch = ChowRingIdeal(M=matroids.Uniform(3,6), R=QQ) + sage: ch = ChowRingIdeal_nonaug(M=matroids.Uniform(3,6), R=QQ) sage: ch Chow ring ideal of U(3, 6): Matroid of rank 3 on 6 elements with circuit-closures {3: {{0, 1, 2, 3, 4, 5}}} - sage: ch = ChowRingIdeal(M=matroids.catalog.Fano(), R=QQ) + sage: ch = ChowRingIdeal_nonaug(M=matroids.catalog.Fano(), R=QQ) sage: ch Chow ring ideal of Fano: Binary matroid of rank 3 on 7 elements, type (3, 0) """ + def __init__(self, M, R): + r""" + Initialize ``self``. + + EXAMPLES:: + + sage: from sage.matroids.chow_ring_ideal import ChowRingIdeal_nonaug + + sage: I = ChowRingIdeal_nonaug(M=matroids.catalog.Fano(), R=QQ) + sage: TestSuite(I).run() + """ self._matroid = M flats = [X for i in range(1, self._matroid.rank()) for X in self._matroid.flats(i)] @@ -89,16 +111,16 @@ def __repr__(self): return "Chow ring ideal of {}".format(self._matroid) def groebner_basis(self): - """ + r""" Returns the Groebner basis of the Chow ring ideal of consideration. Return type - ``PolynomialSequence``. EXAMPLES:: - sage: from sage.matroids.chow_ring_ideal import ChowRingIdeal + sage: from sage.matroids.chow_ring_ideal import ChowRingIdeal_nonaug sage: from sage.matroids.basis_matroid import BasisMatroid - sage: ch = ChowRingIdeal(M=BasisMatroid(groundset='abc', bases=['ab', 'ac']), R=QQ) + sage: ch = ChowRingIdeal_nonaug(M=BasisMatroid(groundset='abc', bases=['ab', 'ac']), R=QQ) sage: ch.groebner_basis() [Aa^2, Aa*Abc, Aa*Abc, Abc^2] sage: ch.groebner_basis().is_groebner() @@ -107,7 +129,7 @@ def groebner_basis(self): Another example would be the Groebner basis of the Chow ring ideal of the Non-Fano matroid:: - sage: ch = ChowRingIdeal(M=matroids.catalog.NonFano(), R=QQ) + sage: ch = ChowRingIdeal_nonaug(M=matroids.catalog.NonFano(), R=QQ) sage: ch.groebner_basis() Polynomial Sequence with 592 Polynomials in 16 Variables """ @@ -121,7 +143,7 @@ def groebner_basis(self): else: term = self.poly_ring.zero() for H in flats: - if H < F: + if H < G: term += self.flats_generator[H] if Set(F).is_empty(): gb.append(term**self._matroid.rank(Set(G))) @@ -130,61 +152,45 @@ def groebner_basis(self): g_basis = PolynomialSequence(self.poly_ring, [gb]) return g_basis - - - def matroid(self): - return self._matroid - def flats_generator(self): - return dict(self.flats_generator) -class CombinedMeta(ABCMeta, type): - pass +class AugmentedChowRingIdeal_fy(ChowRingIdeal): + r""" + The class of augmented Chow ring ideal of Feitchner-Yuzvinsky + presentation, a multi-polynomial ideal. + Base class - ``MPolynomialIdeal``. -class AugmentedChowRingIdeal(CombinedMeta): - @abstractmethod - def gens_constructor(): - pass + INPUT: - @abstractmethod - def groebner_basis(): - pass - def matroid(self): - M = self._matroid - return M - - def flats_generator(self): - return dict(self.flats_generator) + - `M` -- a matroid. + - `R` -- a ring. -class AugmentedChowRingIdeal_fy(SageObject,MPolynomialIdeal, AugmentedChowRingIdeal): - def __init__(self, M, R): - """ - The class of augmented Chow ring ideal of Feitchner-Yuzvinsky - presentation, a multi-polynomial ideal. - Base class - ``MPolynomialIdeal``. - - INPUT: + OUTPUT: augmented Chow ring ideal of matroid `M` of Feitchner-Yuzvinsky + presentation. + EXAMPLES:: - - `M` -- a matroid. - - `R` -- a ring. + Augmented Chow ring ideal of Wheel matroid of rank 3:: - OUTPUT: augmented Chow ring ideal of matroid `M` of Feitchner-Yuzvinsky - presentation. + sage: from sage.matroids.chow_ring_ideal import AugmentedChowRingIdeal_fy - EXAMPLES:: + sage: ch = AugumentedChowRingIdeal_fy(M=matroids.Wheel(3), R=QQ) + sage: ch + Augmented Chow ring ideal of Wheel(3): Regular matroid of rank 3 on + 6 elements with 16 bases of Feitchner-Yuzvinsky presentation + """ + def __init__(self, M, R): + r""" + Initialize ``self``. - Augmented Chow ring ideal of Wheel matroid of rank 3:: + EXAMPLES:: - sage: from sage.matroids.chow_ring_ideal import AugmentedChowRingIdeal_fy + sage: from sage.matroids.chow_ring_ideal import AugumentedChowRingIdeal_fy - sage: ch = AugumentedChowRingIdeal_fy(M=matroids.Wheel(3), R=QQ) - sage: ch - Augmented Chow ring ideal of Wheel(3): Regular matroid of rank 3 on - 6 elements with 16 bases of Feitchner-Yuzvinsky presentation - """ - def __init__(self, M, R): + sage: I = AugmentedChowRingIdeal_fy(M=matroids.Wheel(3), R=QQ) + sage: TestSuite(I).run() + """ self._matroid = M self.flats = [X for i in range(1, self._matroid.rank()) for X in self._matroid.flats(i)] @@ -228,7 +234,7 @@ def __repr__(self): return "Augmented Chow ring ideal of {} of Feitchner-Yuzvinsky presentation".format(self._matroid) def groebner_basis(self): - """ + r""" Returns the Groebner basis of the augmented Chow ring ideal. Return type - ``PolynomialSequence``. @@ -238,7 +244,7 @@ def groebner_basis(self): sage: ch = AugmentedChowRingIdeal_fy(M=matroids.catalog.Fano(), R=QQ) sage: ch.groebner_basis() - Polynomial Sequence with 2744 Polynomials in 21 Variables + Polynomial Sequence with 4116 Polynomials in 21 Variables """ gb = [] E = list(self._matroid.groundset()) @@ -271,23 +277,20 @@ def groebner_basis(self): g_basis = PolynomialSequence(self.poly_ring, [gb]) return g_basis -class AugmentedChowRingIdeal_atom_free(AugmentedChowRingIdeal): - def __init__(self, M, R): - """ - The class of augmented Chow ring ideal of atom-free - presentation, a multi-polynomial ideal. - Base class - ``MPolynomialIdeal``. +class AugmentedChowRingIdeal_atom_free(ChowRingIdeal): + r""" + The augmented Chow ring ideal in the atom-free + presentation. INPUT: - - - `M` -- a matroid. - - `R` -- a ring. + - ``M`` -- a matroid + - ``R`` -- a ring OUTPUT: augmented Chow ring ideal of matroid `M` of atom-free presentation. - EXAMPLES:: + EXAMPLES: Augmented Chow ring ideal of Wheel matroid of rank 3:: @@ -297,9 +300,49 @@ def __init__(self, M, R): sage: ch Augmented Chow ring ideal of Wheel(3): Regular matroid of rank 3 on 6 elements with 16 bases of atom-free presentation - """ + """ + def __init__(self, M, R): #documentation of every init + r""" + Initialize ``self``. + + EXAMPLES:: + + sage: from sage.matroids.chow_ring_ideal import AugumentedChowRingIdeal_atom_free + + sage: I = AugumentedChowRingIdeal_atom_free(M=matroids.Wheel(3), R=QQ) + sage: TestSuite(I).run() + """ + self._matroid = M + flats = [X for i in range(1, self._matroid.rank()) + for X in self._matroid.flats(i)] + + E = list(self._matroid.groundset()) + flats_containing = {x: [] for x in E} + for i,F in enumerate(flats): + for x in F: + flats_containing[x].append(i) + + names = ['A{}'.format(''.join(str(x) for x in sorted(F, key=cmp_elements_key))) for F in flats] + + try: + self.poly_ring = PolynomialRing(R, names) #self.ring + except ValueError: # variables are not proper names + self.poly_ring = PolynomialRing(R, 'A', len(self.flats)) + + + gens = self.poly_ring.gens() + self.flats_generator = dict(zip(flats, gens)) + + + Q = [gens[i] * gens[i+j+1] for i,F in enumerate(flats) + for j,G in enumerate(flats[i+1:]) if not (F < G or G < F)] + L = [sum(gens[i] for i in flats_containing[x]) + - sum(gens[i] for i in flats_containing[y]) + for j,x in enumerate(E) for y in E[j+1:]] + + + MPolynomialIdeal.__init__(self, self.poly_ring, Q + L) - AugmentedChowRingIdeal.__init__(self, M, R) def gens_constructor(self): E = list(self._matroid.groundset()) @@ -336,11 +379,12 @@ def groebner_basis(self): EXAMPLES:: sage: from sage.matroids.chow_ring_ideal import AugmentedChowRingIdeal_atom_free + sage: from sage.matroids.graphic_matroid import GraphicMatroid sage: M1 = GraphicMatroid(graphs.CycleGraph(3)) sage: ch = AugmentedChowRingIdeal_atom_free(M=M1, R=QQ) sage: ch.groebner_basis() - [B0^2, B0*B1, B0*B2, B0*B1, B1^2, B1*B2, B0*B2, B1*B2, B2^2] + [A0^2, A0*A1, A0*A2, A0*A1, A1^2, A1*A2, A0*A2, A1*A2, A2^2] """ gb = [] flats = [X for i in range(1, self._matroid.rank()) @@ -365,10 +409,16 @@ def groebner_basis(self): +#linting tests pass +#single underscore for attributes +#Developer's guide +#use 'self' in docstrings +#rebase chow_ring from repr_update +#common base class for all chow ring ideals - augmented parameter +#getting ring from chow ring ideal to chow ring +#references in the main index - - From 1d42f3ada22abc992ca19568ffd6d599cd8cbfdb Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Tue, 23 Jul 2024 15:53:34 +0530 Subject: [PATCH 070/537] Edited documentation --- src/sage/matroids/chow_ring.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/sage/matroids/chow_ring.py b/src/sage/matroids/chow_ring.py index 4745df22ea1..e67328abb5b 100644 --- a/src/sage/matroids/chow_ring.py +++ b/src/sage/matroids/chow_ring.py @@ -16,7 +16,7 @@ - :arxiv:`2111.00393` """ -from sage.matroids.chow_ring_ideal import ChowRingIdeal, AugmentedChowRingIdeal +from sage.matroids.chow_ring_ideal import ChowRingIdeal_nonaug, AugmentedChowRingIdeal_fy, AugmentedChowRingIdeal_atom_free from sage.rings.quotient_ring import QuotientRing_nc from sage.categories.graded_algebras_with_basis import GradedAlgebrasWithBasis @@ -44,13 +44,16 @@ class ChowRing(QuotientRing_nc): sage: ch Chow ring of P8'': Matroid of rank 4 on 8 elements with 8 nonspanning circuits """ - def __init__(self, R, M, augmented): + def __init__(self, R, M, augmented, presentation=None): self._matroid = M self._augmented = augmented if augmented: - self._ideal = AugmentedChowRingIdeal(M, R) + if presentation=='fy': + self._ideal = AugmentedChowRingIdeal_fy(M, R) + elif presentation=='atom-free': + self._ideal = AugmentedChowRingIdeal_fy(M, R) else: - self._ideal = ChowRingIdeal(M, R) #check method to get ring + self._ideal = ChowRingIdeal_nonaug(M, R) #check method to get ring QuotientRing_nc.__init__(self, R=self._ideal.poly_ring, I=self._ideal, names=self._ideal.poly_ring.variable_names(), category=GradedAlgebrasWithBasis(R)) def _repr_(self): From 20fa80f5f292e113492cbe797908615bb64e2817 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Tue, 23 Jul 2024 16:13:26 +0530 Subject: [PATCH 071/537] Debugged groebner_basis() method for ChowRingIdeal_nonaug --- src/sage/matroids/chow_ring_ideal.py | 81 +++++++++++++--------------- 1 file changed, 38 insertions(+), 43 deletions(-) diff --git a/src/sage/matroids/chow_ring_ideal.py b/src/sage/matroids/chow_ring_ideal.py index 902dec3565f..21b0994a8c9 100644 --- a/src/sage/matroids/chow_ring_ideal.py +++ b/src/sage/matroids/chow_ring_ideal.py @@ -79,33 +79,29 @@ def __init__(self, M, R): self._matroid = M flats = [X for i in range(1, self._matroid.rank()) for X in self._matroid.flats(i)] - - E = list(self._matroid.groundset()) - flats_containing = {x: [] for x in E} - for i,F in enumerate(flats): - for x in F: - flats_containing[x].append(i) - names = ['A{}'.format(''.join(str(x) for x in sorted(F, key=cmp_elements_key))) for F in flats] - try: self.poly_ring = PolynomialRing(R, names) #self.ring except ValueError: # variables are not proper names self.poly_ring = PolynomialRing(R, 'A', len(self.flats)) - - gens = self.poly_ring.gens() self.flats_generator = dict(zip(flats, gens)) + MPolynomialIdeal.__init__(self, self.poly_ring, self.gens_constructor()) - + def gens_constructor(self): + E = list(self._matroid.groundset()) + flats = list(self.flats_generator.keys()) + flats_containing = {x: [] for x in E} + for i,F in enumerate(flats): + for x in F: + flats_containing[x].append(i) + gens = self.poly_ring.gens() Q = [gens[i] * gens[i+j+1] for i,F in enumerate(flats) for j,G in enumerate(flats[i+1:]) if not (F < G or G < F)] L = [sum(gens[i] for i in flats_containing[x]) - sum(gens[i] for i in flats_containing[y]) for j,x in enumerate(E) for y in E[j+1:]] - - - MPolynomialIdeal.__init__(self, self.poly_ring, Q + L) + return Q + L def __repr__(self): return "Chow ring ideal of {}".format(self._matroid) @@ -131,7 +127,7 @@ def groebner_basis(self): sage: ch = ChowRingIdeal_nonaug(M=matroids.catalog.NonFano(), R=QQ) sage: ch.groebner_basis() - Polynomial Sequence with 592 Polynomials in 16 Variables + Polynomial Sequence with 232 Polynomials in 16 Variables """ flats = list(self.flats_generator.keys()) @@ -143,17 +139,16 @@ def groebner_basis(self): else: term = self.poly_ring.zero() for H in flats: - if H < G: + if H > G: term += self.flats_generator[H] if Set(F).is_empty(): gb.append(term**self._matroid.rank(Set(G))) - else: + elif F < G: gb.append(term**(self._matroid.rank(Set(G))-self._matroid.rank(Set(F)))) g_basis = PolynomialSequence(self.poly_ring, [gb]) return g_basis - class AugmentedChowRingIdeal_fy(ChowRingIdeal): r""" The class of augmented Chow ring ideal of Feitchner-Yuzvinsky @@ -175,7 +170,7 @@ class AugmentedChowRingIdeal_fy(ChowRingIdeal): sage: from sage.matroids.chow_ring_ideal import AugmentedChowRingIdeal_fy - sage: ch = AugumentedChowRingIdeal_fy(M=matroids.Wheel(3), R=QQ) + sage: ch = AugmentedChowRingIdeal_fy(M=matroids.Wheel(3), R=QQ) sage: ch Augmented Chow ring ideal of Wheel(3): Regular matroid of rank 3 on 6 elements with 16 bases of Feitchner-Yuzvinsky presentation @@ -186,25 +181,25 @@ def __init__(self, M, R): EXAMPLES:: - sage: from sage.matroids.chow_ring_ideal import AugumentedChowRingIdeal_fy + sage: from sage.matroids.chow_ring_ideal import AugmentedChowRingIdeal_fy sage: I = AugmentedChowRingIdeal_fy(M=matroids.Wheel(3), R=QQ) sage: TestSuite(I).run() """ self._matroid = M - self.flats = [X for i in range(1, self._matroid.rank()) + self._flats = [X for i in range(1, self._matroid.rank()) for X in self._matroid.flats(i)] E = list(self._matroid.groundset()) self.flats_generator = dict() try: names_groundset = ['A{}'.format(''.join(str(x))) for x in E] - names_flats = ['B{}'.format(''.join(str(x) for x in sorted(F, key=cmp_elements_key))) for F in self.flats] + names_flats = ['B{}'.format(''.join(str(x) for x in sorted(F, key=cmp_elements_key))) for F in self._flats] self.poly_ring = PolynomialRing(R, names_groundset + names_flats) except ValueError: - self.poly_ring = PolynomialRing(R, 'A', len(E) + len(self.flats)) + self.poly_ring = PolynomialRing(R, 'A', len(E) + len(self._flats)) for i,x in enumerate(E): self.flats_generator[x] = self.poly_ring.gens()[i] - for i,F in enumerate(self.flats): + for i,F in enumerate(self._flats): self.flats_generator[F] = self.poly_ring.gens()[len(E) + i] MPolynomialIdeal.__init__(self, self.poly_ring, self.gens_constructor()) @@ -212,19 +207,19 @@ def __init__(self, M, R): def gens_constructor(self): E = list(self._matroid.groundset()) flats_containing = {x: [] for x in E} - for F in self.flats: + for F in self._flats: for x in F: flats_containing[x].append(F) Q = list() - for F in self.flats: - for G in self.flats: + for F in self._flats: + for G in self._flats: if not (F < G or G < F): Q.append(self.flats_generator[F] * self.flats_generator[G]) L = list() for x in E: term = self.poly_ring.zero() - for F in self.flats: + for F in self._flats: if F not in flats_containing[x]: term += self.flats_generator[F] L.append(self.flats_generator[x] - term) @@ -249,11 +244,11 @@ def groebner_basis(self): gb = [] E = list(self._matroid.groundset()) for i in E: - for F in self.flats: - for G in self.flats: + for F in self._flats: + for G in self._flats: term = self.poly_ring.zero() term1 = self.poly_ring.zero() - for H in self.flats: + for H in self._flats: if i in Set(H): term += self.flats_generator[H] if H > F: @@ -296,7 +291,7 @@ class AugmentedChowRingIdeal_atom_free(ChowRingIdeal): sage: from sage.matroids.chow_ring_ideal import AugmentedChowRingIdeal_atom_free - sage: ch = AugumentedChowRingIdeal_atom_free(M=matroids.Wheel(3), R=QQ) + sage: ch = AugmentedChowRingIdeal_atom_free(M=matroids.Wheel(3), R=QQ) sage: ch Augmented Chow ring ideal of Wheel(3): Regular matroid of rank 3 on 6 elements with 16 bases of atom-free presentation @@ -307,35 +302,35 @@ def __init__(self, M, R): #documentation of every init EXAMPLES:: - sage: from sage.matroids.chow_ring_ideal import AugumentedChowRingIdeal_atom_free + sage: from sage.matroids.chow_ring_ideal import AugmentedChowRingIdeal_atom_free - sage: I = AugumentedChowRingIdeal_atom_free(M=matroids.Wheel(3), R=QQ) + sage: I = AugmentedChowRingIdeal_atom_free(M=matroids.Wheel(3), R=QQ) sage: TestSuite(I).run() """ self._matroid = M - flats = [X for i in range(1, self._matroid.rank()) + self._flats = [X for i in range(1, self._matroid.rank()) for X in self._matroid.flats(i)] E = list(self._matroid.groundset()) flats_containing = {x: [] for x in E} - for i,F in enumerate(flats): + for i,F in enumerate(self._flats): for x in F: flats_containing[x].append(i) - names = ['A{}'.format(''.join(str(x) for x in sorted(F, key=cmp_elements_key))) for F in flats] + names = ['A{}'.format(''.join(str(x) for x in sorted(F, key=cmp_elements_key))) for F in self._flats] try: self.poly_ring = PolynomialRing(R, names) #self.ring except ValueError: # variables are not proper names - self.poly_ring = PolynomialRing(R, 'A', len(self.flats)) + self.poly_ring = PolynomialRing(R, 'A', len(self._flats)) gens = self.poly_ring.gens() - self.flats_generator = dict(zip(flats, gens)) + self.flats_generator = dict(zip(self._flats, gens)) - Q = [gens[i] * gens[i+j+1] for i,F in enumerate(flats) - for j,G in enumerate(flats[i+1:]) if not (F < G or G < F)] + Q = [gens[i] * gens[i+j+1] for i,F in enumerate(self._flats) + for j,G in enumerate(self._flats[i+1:]) if not (F < G or G < F)] L = [sum(gens[i] for i in flats_containing[x]) - sum(gens[i] for i in flats_containing[y]) for j,x in enumerate(E) for y in E[j+1:]] @@ -348,10 +343,10 @@ def gens_constructor(self): E = list(self._matroid.groundset()) Q = [] flats_containing = {x: [] for x in E} - for F in self.flats: + for F in self._flats: for x in F: flats_containing[x].append(F) - for F in self.flats: + for F in self._flats: for x in E: if F not in flats_containing[x]: Q.append(self.flats_generator[x]*self.flats_generator[F]) From 0ee932fb2acb0a2fcbca7f14a4b80bbcee601cde Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Tue, 23 Jul 2024 16:18:16 +0530 Subject: [PATCH 072/537] Added TestSuite.run() doctest to ChowRing class --- src/sage/matroids/chow_ring.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/sage/matroids/chow_ring.py b/src/sage/matroids/chow_ring.py index e67328abb5b..bcbd31e4ba8 100644 --- a/src/sage/matroids/chow_ring.py +++ b/src/sage/matroids/chow_ring.py @@ -45,6 +45,16 @@ class ChowRing(QuotientRing_nc): Chow ring of P8'': Matroid of rank 4 on 8 elements with 8 nonspanning circuits """ def __init__(self, R, M, augmented, presentation=None): + r""" + Initialize ``self``. + + EXAMPLES:: + + sage: from sage.matroids.chow_ring import ChowRing + + sage: I = ChowRing(M=matroids.Wheel(3), R=QQ, augmented=False) + sage: TestSuite(I).run() + """ self._matroid = M self._augmented = augmented if augmented: From 125103dc46a09066f7f03ec1fdd7d1fa3d6cea0f Mon Sep 17 00:00:00 2001 From: Newtech66 Date: Wed, 24 Jul 2024 19:10:52 +0530 Subject: [PATCH 073/537] Rewrite --- src/sage/rings/all.py | 2 +- src/sage/rings/burnside.py | 403 +++++++++++++++++-------------------- 2 files changed, 191 insertions(+), 214 deletions(-) diff --git a/src/sage/rings/all.py b/src/sage/rings/all.py index 52e29b7cb8b..f34635f6989 100644 --- a/src/sage/rings/all.py +++ b/src/sage/rings/all.py @@ -167,7 +167,7 @@ from sage.rings.asymptotic.all import * lazy_import('sage.rings.burnside', ['BurnsideRing', 'PolynomialMolecularDecomposition', - 'UnivariateAtomicConjugacyClasses', 'UnivariateMolecularConjugacyClasses']) + 'MultivariateAtomicSpecies']) # Register classes in numbers abc from sage.rings import numbers_abc diff --git a/src/sage/rings/burnside.py b/src/sage/rings/burnside.py index 99354bbda9d..d8ee95b975a 100644 --- a/src/sage/rings/burnside.py +++ b/src/sage/rings/burnside.py @@ -1,4 +1,6 @@ +from sage.combinat.integer_vector import IntegerVectors from sage.misc.cachefunc import cached_method +from sage.monoids.indexed_free_monoid import IndexedFreeAbelianMonoid from sage.structure.parent import Parent from sage.structure.element import Element from sage.structure.element import parent @@ -8,12 +10,11 @@ from sage.categories.sets_with_grading import SetsWithGrading from sage.categories.graded_algebras_with_basis import GradedAlgebrasWithBasis from sage.categories.algebras import Algebras -from sage.categories.monoids import Monoids from sage.groups.perm_gps.permgroup import PermutationGroup, PermutationGroup_generic from sage.groups.perm_gps.permgroup_named import SymmetricGroup from sage.libs.gap.libgap import libgap from sage.combinat.free_module import CombinatorialFreeModule -from sage.monoids.indexed_free_monoid import IndexedFreeAbelianMonoid, IndexedMonoid +from sage.sets.set import Set GAP_FAIL = libgap.eval('fail') @@ -35,32 +36,30 @@ def _is_conjugate(G, H1, H2): class ElementCache(): def __init__(self): r""" - Class for caching elements of conjugacy classes of subgroups. + Class for caching elements. """ self._cache = dict() - - def _group_invariants(self, H): - r""" - Return tuple of group invariants associated with H. - """ - return tuple([H.order(), H.degree()]) - def _cache_get(self, H): + def _cache_get(self, elm): r""" - Return the cached element for H, or create it + Return the cached element, or create it if it doesn't exist. + + ``elm`` must implement the following methods: + ``_element_key`` - hashable type for dict lookup. + ``__eq__`` - to compare two elements. """ - element = self.element_class(self, H) - key = self._group_invariants(H) + key = elm._element_key() if key in self._cache: - for H0, H0_elm in self._cache[key]: - if _is_conjugate(element.subgroup_of(), H0, H): - return H0_elm + lookup = self._cache[key] + for other_elm in lookup: + if elm == other_elm: + return other_elm else: - self._cache[key].append((H, element)) + lookup.append(elm) else: - self._cache[key] = [(H, element)] - return element + self._cache[key] = [elm] + return elm class ConjugacyClassOfSubgroups(Element): def __init__(self, parent, C): @@ -108,6 +107,14 @@ def __hash__(self): True """ return hash(self._C) + + @cached_method + def _element_key(self): + r""" + Return tuple of group invariants associated with H. + """ + # should this be a lazy attribute instead? + return tuple([self._C.order(), self._C.degree()]) def _repr_(self): r""" @@ -260,7 +267,8 @@ def _element_constructor_(self, x): return x if isinstance(x, PermutationGroup_generic): if x.is_subgroup(self._G): - return self._cache_get(self._G.subgroup(x.gens())) + elm = self.element_class(self, self._G.subgroup(x.gens())) + return self._cache_get(elm) raise ValueError(f"unable to convert {x} into {self}: not a subgroup of {self._G}") raise ValueError("unable to convert {x} into {self}") @@ -533,32 +541,20 @@ def _repr_(self): """ return "Burnside ring of " + repr(self._G) -class AtomicConjugacyClass(ConjugacyClassOfSubgroups): +class ConjugacyClassOfDirectlyIndecomposableSubgroups(ConjugacyClassOfSubgroups): def __init__(self, parent, C): r""" - An atomic conjugacy class. - - TESTS:: - - sage: At = UnivariateAtomicConjugacyClasses() - sage: Z4 = CyclicPermutationGroup(4) - sage: TestSuite(At(Z4)).run() + A conjugacy class of directly indecomposable subgroups. """ + if len(C.disjoint_direct_product_decomposition()) != 1: + raise ValueError(f"{C} is not directly indecomposable") ConjugacyClassOfSubgroups.__init__(self, parent, C) @cached_method def subgroup_of(self): r""" - Return the group which this atomic conjugacy class of subgroups - belongs to. - - TESTS:: - - sage: At = UnivariateAtomicConjugacyClasses() - sage: g = At(CyclicPermutationGroup(3)); g - {3, [(1,2,3)]} - sage: g.subgroup_of() - Symmetric group of order 3! as a permutation group + Return the group which this conjugacy class of + directly indecomposable subgroups belongs to. """ return SymmetricGroup(self._C.degree()) @@ -574,171 +570,211 @@ def _repr_(self): """ return "{" + f"{self._C.degree()}, {self._C.gens_small()}" + "}" -class UnivariateAtomicConjugacyClasses(UniqueRepresentation, Parent, ElementCache): - def __init__(self): +class AtomicSpecies(ConjugacyClassOfDirectlyIndecomposableSubgroups): + def __init__(self, parent, C, multicardinality): r""" - Infinite set of atomic conjugacy classes of `S_n`. - - Graded by `n \geq 0`. - - TESTS:: - - sage: At = UnivariateAtomicConjugacyClasses() - sage: TestSuite(At).run(skip="_test_graded_components") + An atomic species centered on a given multicardinality: a directly + indecomposable subgroup paired with an integer vector. """ - category = SetsWithGrading().Infinite() - Parent.__init__(self, category=category) - ElementCache.__init__(self) - + total_cardinality = sum(multicardinality) + if C.degree() != sum(multicardinality): + raise ValueError(f"Degree of {C} (= {C.degree()}) must equal the total cardinality {total_cardinality}") + G = SymmetricGroup(total_cardinality).young_subgroup(multicardinality) + if not C.is_subgroup(G): + raise ValueError(f"{C} is not a subgroup of {G}") + ConjugacyClassOfDirectlyIndecomposableSubgroups.__init__(self, parent, C) + self._mc = multicardinality + @cached_method - def an_element(self): + def subgroup_of(self): + r""" + Return the group which the underlying permutation group + of this atomic species belongs to. """ - Return an element of ``self``. + return SymmetricGroup(sum(self._mc)).young_subgroup(self._mc) - EXAMPLES:: - - sage: At = UnivariateAtomicConjugacyClasses() - sage: At.an_element() - {0, []} + def __hash__(self): + r""" + Return the hash of the atomic species. """ - return self._cache_get(SymmetricGroup(0)) + return hash(tuple([self._C, self._mc])) - def _element_constructor_(self, x): + @cached_method + def _element_key(self): r""" - Construct the atomic conjugacy class of subgroups containing ``x``. - - TESTS:: - - sage: At = UnivariateAtomicConjugacyClasses() - sage: Z4 = CyclicPermutationGroup(4) - sage: At(Z4) - {4, [(1,2,3,4)]} + Return a lookup key for ``self``. """ - # BUG: SymmetricGroup(0) fails to be constructed. - if parent(x) == self: - return x - if isinstance(x, PermutationGroup_generic): - if len(x.disjoint_direct_product_decomposition()) == 1: - return self._cache_get(x) - else: - raise ValueError(f"{x} is not atomic") - raise ValueError(f"unable to convert {x} into {self}") - - def __contains__(self, H): + return tuple([*super()._element_key(), self._mc]) + + def __eq__(self, other): r""" - Return if H is an atomic subgroup. + Two atomic species are equal if the underlying groups are conjugate, + and their multicardinalities are equal. """ - if parent(H) == self: - return True - return (isinstance(H, PermutationGroup_generic) - and len(H.disjoint_direct_product_decomposition()) == 1) - + if parent(self) != parent(other): + return False + return self._mc == other._mc and super().__eq__(other) + def _repr_(self): r""" Return a string representation of ``self``. - - EXAMPLES:: - - sage: At = UnivariateAtomicConjugacyClasses() - sage: At - Set of all atomic conjugacy classes on 1 sort """ - return "Set of all atomic conjugacy classes on 1 sort" - - Element=AtomicConjugacyClass + return "{" + f"{self._C.gens_small()}: {self._mc}" + "}" -class UnivariateMolecularConjugacyClasses(IndexedFreeAbelianMonoid): - @staticmethod - def __classcall__(cls): +class MultivariateAtomicSpecies(UniqueRepresentation, Parent, ElementCache): + def __init__(self, k): r""" - Needed to make this work. Taken from example in center_uea.py. + Infinite set of `k`-variate atomic species graded by + integer vectors of length `k`. """ - return super(IndexedMonoid, cls).__classcall__(cls) + category = SetsWithGrading().Infinite() + Parent.__init__(self, category=category) + ElementCache.__init__(self) + self._k = k + self._grading_set = IntegerVectors(length=k) - def __init__(self): + def __hash__(self): r""" - Infinite set of molecular conjugacy classes of `S_n`. - Implemented as elements of the free abelian monoid on - univariate atomic conjugacy classes. + Return a hash for ``self``. + """ + return hash(self._k) - Graded by `n \geq 0`. + def __eq__(self, other): + r""" + Needed for unique representation behaviour. TESTS:: - sage: Mol = UnivariateMolecularConjugacyClasses() - sage: TestSuite(Mol).run(skip="_test_graded_components") + sage: At1 = MultivariateAtomicSpecies(1); At1 + sage: At2 = MultivariateAtomicSpecies(2); At2 + sage: At1_2 = MultivariateAtomicSpecies(1); At1_2 + sage: At1 is At1_2 + True + sage: At1 is At2 + False + sage: At1_2 is At2 + False + """ + if type(self) != type(other): + return False + return self._k == other._k + + @cached_method + def an_element(self): + """ + Return an element of ``self``. """ - category = Monoids() & SetsWithGrading().Infinite() - IndexedFreeAbelianMonoid.__init__(self, - indices=UnivariateAtomicConjugacyClasses(), - prefix='', bracket=False, - category=category) + return self._element_constructor_((SymmetricGroup(self._k).young_subgroup([1] * self._k), + [1] * self._k)) - def _project(self, H, part): + def _normalize(self, H, f): r""" - Project `H` onto a subset ``part`` of its domain. - ``part`` must be a union of cycles, but this is not checked. + Normalize `H` and return `H` and the multicardinality. """ - restricted_gens = [[cyc for cyc in gen.cycle_tuples() if cyc[0] in part] for gen in H.gens_small()] - mapping = {elm: i for i, elm in enumerate(part, 1)} - normalized_gens = [[tuple(mapping[x] for x in cyc) for cyc in gen] for gen in restricted_gens] - return PermutationGroup(gens=normalized_gens) - + # TODO: Complete the documentation. + L = [[] for _ in range(self._k)] + for k, v in f.items(): + L[v - 1].append(k) + Lc = sum(L, []) + Ls = [len(l) for l in L] + mapping = {v: i for i, v in enumerate(Lc, 1)} + normalized_gens = [[tuple(mapping[x] for x in cyc) for cyc in gen] for gen in H.gens_small()] + return PermutationGroup(gens=normalized_gens), self._grading_set(Ls) + def _element_constructor_(self, x): r""" - Construct the molecular conjugacy class of subgroups containing ``x``. + Construct the `k`-variate molecular species with the given data. - TESTS:: + INPUT: - sage: Mol = UnivariateMolecularConjugacyClasses() - sage: [Mol(H) for H in SymmetricGroup(3).conjugacy_classes_subgroups()] - [{1, [()]}^3, {1, [()]}*{2, [(1,2)]}, {3, [(1,2,3)]}, {3, [(1,2,3), (2,3)]}] + - ``x`` - an element of ``self`` or a tuple ``(H, f)`` where `H` is + the directly indecomposable permutation group representation for the + `k`-variate atomic species and `f` is a ``dict`` mapping each element + of the domain of `H` to integers in `\{ 1 \ldots k \}`, representing + the set to which the element belongs. """ + # BUG: SymmetricGroup(0) fails to be constructed. if parent(x) == self: return x - if isinstance(x, PermutationGroup_generic): - domain_partition = x.disjoint_direct_product_decomposition() - return super()._element_constructor_([(self._indices(self._project(x, part)), 1) for part in domain_partition]) + H, f = x + if Set(H.domain()) != Set(f.keys()): + raise ValueError(f"Keys of {f} do not match with domain of {H}") + if not Set(f.values()).issubset(Set(range(1, self._k + 1))): + raise ValueError(f"Values of {f} must be in the range [1, {self._k}]") + if isinstance(H, PermutationGroup_generic) and isinstance(f, dict): + elm = self.element_class(self, *self._normalize(H, f)) + return self._cache_get(elm) raise ValueError("unable to convert {x} into {self}") - + + def __getitem__(self, x): + r""" + Call ``_element_constructor_`` on ``x``. + """ + return self._element_constructor_(x) + def _repr_(self): r""" Return a string representation of ``self``. - - EXAMPLES:: - - sage: Mol = UnivariateMolecularConjugacyClasses() - sage: Mol - Set of all molecular conjugacy classes on 1 sort """ - return "Set of all molecular conjugacy classes on 1 sort" + return f"Infinite set of {self._k}-variate atomic species" + + Element = AtomicSpecies class PolynomialMolecularDecomposition(CombinatorialFreeModule): - def __init__(self, base_ring=ZZ): + def __init__(self, k, base_ring=ZZ): r""" - Ring of virtual species on 1 sort. + Ring of `k`-variate virtual species. """ - basis_keys = UnivariateMolecularConjugacyClasses() + # should we pass a category to basis_keys? + basis_keys = IndexedFreeAbelianMonoid(MultivariateAtomicSpecies(k), + prefix='', bracket=False) category = GradedAlgebrasWithBasis(base_ring).Commutative() CombinatorialFreeModule.__init__(self, base_ring, basis_keys=basis_keys, category=category, prefix='', bracket=False) + self._k = k + self._atomic_basis = basis_keys.indices() - def __getitem__(self, H): + def _project(self, H, f, part): r""" - Return the basis element indexed by ``H``. + Project `H` onto a subset ``part`` of its domain. + ``part`` must be a union of cycles, but this is not checked. + """ + restricted_gens = [[cyc for cyc in gen.cycle_tuples() if cyc[0] in part] for gen in H.gens_small()] + mapping = {p: f[p] for p in part} + return tuple([PermutationGroup(gens=restricted_gens), mapping]) + + def _element_constructor_(self, x): + r""" + Construct the `k`-variate molecular species with the given data. - ``H`` must be a subgroup of a symmetric group. + INPUT: - EXAMPLES:: + - ``x`` - an element of ``self`` or a tuple ``(H, f)`` where `H` is + the permutation group representation for the species and `f` is a + ``dict`` mapping each element of the domain of `H` to integers in + `\{ 1 \ldots k \}`, representing the set to which the element belongs. + """ + if parent(x) == self: + return x + H, f = x + if Set(H.domain()) != Set(f.keys()): + raise ValueError(f"Keys of {f} do not match with domain of {H}") + if not Set(f.values()).issubset(Set(range(1, self._k + 1))): + raise ValueError(f"Values of {f} must be in the range [1, {self._k}]") + if isinstance(H, PermutationGroup_generic) and isinstance(f, dict): + domain_partition = H.disjoint_direct_product_decomposition() + from collections import Counter + C = Counter([self._atomic_basis(self._project(H, f, part)) for part in domain_partition]) + return self._from_dict({self._indices(dict(C)): 1}) + raise ValueError("unable to convert {x} into {self}") - sage: P = PolynomialMolecularDecomposition() - sage: Z4 = CyclicPermutationGroup(4) - sage: P[Z4] - {4, [(1,2,3,4)]} + def __getitem__(self, x): + r""" + Calls _element_constructor_ on x. """ - return self._from_dict({self._indices(H): 1}) + return self._element_constructor_(x) @cached_method def one_basis(self): @@ -752,82 +788,23 @@ def one_basis(self): sage: P.one_basis() 1 """ - return self._indices(SymmetricGroup(0)) - - def construct_from_action(self, action, domain, domsize): - r""" - Construct an element of this ring from a group action. - - INPUT: - - - ``action`` - an action on ``domain`` - - ``domain`` - a finite set - - ``domsize`` - size of the domain - - EXAMPLES:: - - sage: P = PolynomialMolecularDecomposition() - - We create a group action of `S_4` on two-element subsets:: - - sage: X = Subsets(4, 2) - sage: a = lambda g, x: X([g(e) for e in x]) - sage: P.construct_from_action(a, X, 4) - {2, [(1,2)]}^2 - - Next, we create a group action of `S_4` on itself via conjugation:: - - sage: X = SymmetricGroup(4) - sage: a = lambda g, x: g*x*g.inverse() - sage: P.construct_from_action(a, X, 4) - {4, [(2,3,4), (1,2)]} + {4, [(2,4), (1,4)(2,3)]} + {1, [()]}*{3, [(1,2,3)]} + {2, [(1,2)]}^2 + {4, [(1,2,3,4)]} - - TESTS:: - - sage: P = PolynomialMolecularDecomposition() - sage: P(-3) - -3 - """ - def find_stabilizer(action, pnt): - stabilizer = [] - for g in G: - if action(g, pnt) == pnt: - stabilizer.append(g) - H = G.subgroup(stabilizer) - gens = H.gens_small() - return G.subgroup(gens) - - G = SymmetricGroup(domsize) - H = PermutationGroup(G.gens(), action=action, domain=domain) - # decompose H into orbits - orbit_list = H.orbits() - # find the stabilizer subgroups - stabilizer_list = [find_stabilizer(action, orbit[0]) for orbit in orbit_list] - # normalize each summand and collect terms - from collections import Counter - C = Counter([self._indices(stabilizer) for stabilizer in stabilizer_list]) - return self._from_dict(dict(C)) + return self._element_constructor_(tuple([SymmetricGroup(0), dict()])) def product_on_basis(self, H, K): r""" Return the product of the basis elements indexed by `H` and `K`. - Let `H` be a subgroup of `\mathfrak{G}_n` and `K` be a subgroup of `\mathfrak{G}_m`. - Then we define their Cauchy product as the subgroup of `\mathfrak{G}_{n+m}` given by - `H \ast K = \{h \dot k \vert h \in H_{\{1 \ldots n\}}, K_{\{n+1 \ldots n+m\}}\}` where - the subscripts denote the domains on which H and K act. Note that this is isomorphic to - the direct product of `H` and `K`. - EXAMPLES:: sage: Mol = UnivariateMolecularConjugacyClasses() sage: P = PolynomialMolecularDecomposition() sage: L1 = SymmetricGroup(3).conjugacy_classes_subgroups() sage: L2 = SymmetricGroup(2).conjugacy_classes_subgroups() - sage: matrix([[P.product_on_basis(Mol(x),Mol(y)) for x in L1] for y in L2]) + sage: matrix([[P(x) * P(y) for x in L1] for y in L2]) [ {1, [()]}^5 {1, [()]}^3*{2, [(1,2)]} {3, [(1,2,3)]}*{1, [()]}^2 {3, [(1,2,3), (2,3)]}*{1, [()]}^2] [ {1, [()]}^3*{2, [(1,2)]} {1, [()]}*{2, [(1,2)]}^2 {3, [(1,2,3)]}*{2, [(1,2)]} {3, [(1,2,3), (2,3)]}*{2, [(1,2)]}] - """ + """ + print("pob called") return self._from_dict({H * K: 1}) def _repr_(self): @@ -836,8 +813,8 @@ def _repr_(self): EXAMPLES:: - sage: P = PolynomialMolecularDecomposition() + sage: P = PolynomialMolecularDecomposition(2) sage: P Polynomial Molecular Decomposition """ - return "Polynomial Molecular Decomposition" + return f"Ring of {self._k}-variate virtual species" From f6690bd0d54bf795f9c784c9c5ab2495d5be0d77 Mon Sep 17 00:00:00 2001 From: Newtech66 Date: Wed, 24 Jul 2024 19:33:54 +0530 Subject: [PATCH 074/537] Minor fixes --- src/sage/rings/burnside.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/sage/rings/burnside.py b/src/sage/rings/burnside.py index d8ee95b975a..1fc098f4c05 100644 --- a/src/sage/rings/burnside.py +++ b/src/sage/rings/burnside.py @@ -678,7 +678,7 @@ def _normalize(self, H, f): Lc = sum(L, []) Ls = [len(l) for l in L] mapping = {v: i for i, v in enumerate(Lc, 1)} - normalized_gens = [[tuple(mapping[x] for x in cyc) for cyc in gen] for gen in H.gens_small()] + normalized_gens = [[tuple(mapping[x] for x in cyc) for cyc in gen.cycle_tuples()] for gen in H.gens_small()] return PermutationGroup(gens=normalized_gens), self._grading_set(Ls) def _element_constructor_(self, x): @@ -804,7 +804,6 @@ def product_on_basis(self, H, K): [ {1, [()]}^5 {1, [()]}^3*{2, [(1,2)]} {3, [(1,2,3)]}*{1, [()]}^2 {3, [(1,2,3), (2,3)]}*{1, [()]}^2] [ {1, [()]}^3*{2, [(1,2)]} {1, [()]}*{2, [(1,2)]}^2 {3, [(1,2,3)]}*{2, [(1,2)]} {3, [(1,2,3), (2,3)]}*{2, [(1,2)]}] """ - print("pob called") return self._from_dict({H * K: 1}) def _repr_(self): From 6604d28826b998a222a762de1099add4b84e6a4b Mon Sep 17 00:00:00 2001 From: Newtech66 Date: Thu, 25 Jul 2024 02:43:17 +0530 Subject: [PATCH 075/537] More fixes --- src/sage/rings/burnside.py | 117 +++++++++++++++++++++++++++++-------- 1 file changed, 93 insertions(+), 24 deletions(-) diff --git a/src/sage/rings/burnside.py b/src/sage/rings/burnside.py index 1fc098f4c05..c717a5693b8 100644 --- a/src/sage/rings/burnside.py +++ b/src/sage/rings/burnside.py @@ -546,7 +546,7 @@ def __init__(self, parent, C): r""" A conjugacy class of directly indecomposable subgroups. """ - if len(C.disjoint_direct_product_decomposition()) != 1: + if len(C.disjoint_direct_product_decomposition()) > 1: raise ValueError(f"{C} is not directly indecomposable") ConjugacyClassOfSubgroups.__init__(self, parent, C) @@ -561,12 +561,6 @@ def subgroup_of(self): def _repr_(self): r""" Return a string representation of ``self``. - - EXAMPLES:: - - sage: At = UnivariateAtomicConjugacyClasses() - sage: g = At(CyclicPermutationGroup(3)); g - {3, [(1,2,3)]} """ return "{" + f"{self._C.degree()}, {self._C.gens_small()}" + "}" @@ -665,7 +659,7 @@ def an_element(self): Return an element of ``self``. """ return self._element_constructor_((SymmetricGroup(self._k).young_subgroup([1] * self._k), - [1] * self._k)) + {e: i for i, e in enumerate(range(1, self._k + 1), 1)})) def _normalize(self, H, f): r""" @@ -679,7 +673,11 @@ def _normalize(self, H, f): Ls = [len(l) for l in L] mapping = {v: i for i, v in enumerate(Lc, 1)} normalized_gens = [[tuple(mapping[x] for x in cyc) for cyc in gen.cycle_tuples()] for gen in H.gens_small()] - return PermutationGroup(gens=normalized_gens), self._grading_set(Ls) + P = PermutationGroup(gens=normalized_gens) + # Fix for SymmetricGroup(0) + if H.degree() == 0: + P = SymmetricGroup(0) + return P, self._grading_set(Ls) def _element_constructor_(self, x): r""" @@ -693,12 +691,11 @@ def _element_constructor_(self, x): of the domain of `H` to integers in `\{ 1 \ldots k \}`, representing the set to which the element belongs. """ - # BUG: SymmetricGroup(0) fails to be constructed. if parent(x) == self: return x H, f = x if Set(H.domain()) != Set(f.keys()): - raise ValueError(f"Keys of {f} do not match with domain of {H}") + raise ValueError(f"Keys of {f} do not match with domain of {H} (= {H.domain()})") if not Set(f.values()).issubset(Set(range(1, self._k + 1))): raise ValueError(f"Values of {f} must be in the range [1, {self._k}]") if isinstance(H, PermutationGroup_generic) and isinstance(f, dict): @@ -711,10 +708,31 @@ def __getitem__(self, x): Call ``_element_constructor_`` on ``x``. """ return self._element_constructor_(x) + + def __contains__(self, x): + r""" + Return if ``x`` is in ``self``. + """ + if parent(x) == self: + return True + try: + self._element_constructor_(x) + except: + return False + return True def _repr_(self): r""" Return a string representation of ``self``. + + TESTS:: + + sage: At1 = MultivariateAtomicSpecies(1) + sage: At1 + Infinite set of 1-variate atomic species + sage: At2 = MultivariateAtomicSpecies(2) + sage: At2 + Infinite set of 2-variate atomic species """ return f"Infinite set of {self._k}-variate atomic species" @@ -724,6 +742,13 @@ class PolynomialMolecularDecomposition(CombinatorialFreeModule): def __init__(self, k, base_ring=ZZ): r""" Ring of `k`-variate virtual species. + + TESTS:: + + sage: P = PolynomialMolecularDecomposition(1) + sage: TestSuite(P).run() + sage: P2 = PolynomialMolecularDecomposition(2) + sage: TestSuite(P2).run() """ # should we pass a category to basis_keys? basis_keys = IndexedFreeAbelianMonoid(MultivariateAtomicSpecies(k), @@ -743,7 +768,7 @@ def _project(self, H, f, part): """ restricted_gens = [[cyc for cyc in gen.cycle_tuples() if cyc[0] in part] for gen in H.gens_small()] mapping = {p: f[p] for p in part} - return tuple([PermutationGroup(gens=restricted_gens), mapping]) + return tuple([PermutationGroup(gens=restricted_gens, domain=part), mapping]) def _element_constructor_(self, x): r""" @@ -773,6 +798,22 @@ def _element_constructor_(self, x): def __getitem__(self, x): r""" Calls _element_constructor_ on x. + + TESTS:: + + sage: P = PolynomialMolecularDecomposition(1) + sage: At1 = MultivariateAtomicSpecies(1) + sage: At1((SymmetricGroup(1), {1: 1})).rename("X") + sage: X = (SymmetricGroup(2).young_subgroup([1, 1]), {1: 1, 2: 1}) + sage: P[X] + X^2 + sage: P2=PolynomialMolecularDecomposition(2) + sage: At2=MultivariateAtomicSpecies(2) + sage: At2((SymmetricGroup(1), {1: 1})).rename("X") + sage: At2((SymmetricGroup(1), {1: 2})).rename("Y") + sage: XY = (SymmetricGroup(2).young_subgroup([1, 1]), {1: 1, 2: 2}) + sage: P2[XY] + Y*X """ return self._element_constructor_(x) @@ -784,11 +825,28 @@ def one_basis(self): EXAMPLES:: - sage: P = PolynomialMolecularDecomposition() + sage: P = PolynomialMolecularDecomposition(1) sage: P.one_basis() - 1 + {[]: [0]} + sage: P2 = PolynomialMolecularDecomposition(2) + sage: P2.one_basis() + {[]: [0, 0]} + """ + return self._indices({self._atomic_basis(tuple([SymmetricGroup(0), dict()])): 1}) + + @cached_method + def an_element(self): """ - return self._element_constructor_(tuple([SymmetricGroup(0), dict()])) + Return an element of ``self``. + + sage: P=PolynomialMolecularDecomposition(1) + sage: P.an_element() + {[]: [0]} + sage: P2=PolynomialMolecularDecomposition(2) + sage: P2.an_element() + {[]: [0, 0]} + """ + return self.one() def product_on_basis(self, H, K): r""" @@ -796,14 +854,22 @@ def product_on_basis(self, H, K): EXAMPLES:: - sage: Mol = UnivariateMolecularConjugacyClasses() - sage: P = PolynomialMolecularDecomposition() - sage: L1 = SymmetricGroup(3).conjugacy_classes_subgroups() - sage: L2 = SymmetricGroup(2).conjugacy_classes_subgroups() + sage: P=PolynomialMolecularDecomposition(1) + sage: d2 = {e: 1 for e in range(1, 3)} + sage: d3 = {e: 1 for e in range(1, 4)} + sage: L1 = [(H, d3) for H in SymmetricGroup(3).conjugacy_classes_subgroups()] + sage: L2 = [(H, d2) for H in SymmetricGroup(2).conjugacy_classes_subgroups()] sage: matrix([[P(x) * P(y) for x in L1] for y in L2]) - [ {1, [()]}^5 {1, [()]}^3*{2, [(1,2)]} {3, [(1,2,3)]}*{1, [()]}^2 {3, [(1,2,3), (2,3)]}*{1, [()]}^2] - [ {1, [()]}^3*{2, [(1,2)]} {1, [()]}*{2, [(1,2)]}^2 {3, [(1,2,3)]}*{2, [(1,2)]} {3, [(1,2,3), (2,3)]}*{2, [(1,2)]}] - """ + [ {[()]: [1]}^5 {[()]: [1]}^3*{[(1,2)]: [2]} {[(1,2,3)]: [3]}*{[()]: [1]}^2 {[(1,2,3), (2,3)]: [3]}*{[()]: [1]}^2] + [ {[()]: [1]}^3*{[(1,2)]: [2]} {[()]: [1]}*{[(1,2)]: [2]}^2 {[(1,2,3)]: [3]}*{[(1,2)]: [2]} {[(1,2,3), (2,3)]: [3]}*{[(1,2)]: [2]}] + """ + # Hacky workaround for handling the one of the algebra :( + if H == self.one_basis() and K == self.one_basis(): + return self._from_dict({self.one_basis(): 1}) + elif H == self.one_basis(): + return self._from_dict({K: 1}) + elif K == self.one_basis(): + return self._from_dict({H: 1}) return self._from_dict({H * K: 1}) def _repr_(self): @@ -812,8 +878,11 @@ def _repr_(self): EXAMPLES:: - sage: P = PolynomialMolecularDecomposition(2) + sage: P = PolynomialMolecularDecomposition(1) sage: P - Polynomial Molecular Decomposition + Ring of 1-variate virtual species + sage: P2 = PolynomialMolecularDecomposition(2) + sage: P2 + Ring of 2-variate virtual species """ return f"Ring of {self._k}-variate virtual species" From ad7d13fbfdda92ba611abc49ddb0ae57a50942bd Mon Sep 17 00:00:00 2001 From: Newtech66 Date: Thu, 25 Jul 2024 15:12:02 +0530 Subject: [PATCH 076/537] Add degree_on_basis --- src/sage/rings/burnside.py | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/sage/rings/burnside.py b/src/sage/rings/burnside.py index c717a5693b8..3c2f2a667e5 100644 --- a/src/sage/rings/burnside.py +++ b/src/sage/rings/burnside.py @@ -578,6 +578,7 @@ def __init__(self, parent, C, multicardinality): raise ValueError(f"{C} is not a subgroup of {G}") ConjugacyClassOfDirectlyIndecomposableSubgroups.__init__(self, parent, C) self._mc = multicardinality + self._tc = total_cardinality @cached_method def subgroup_of(self): @@ -585,13 +586,13 @@ def subgroup_of(self): Return the group which the underlying permutation group of this atomic species belongs to. """ - return SymmetricGroup(sum(self._mc)).young_subgroup(self._mc) + return SymmetricGroup(self._tc).young_subgroup(self._mc) def __hash__(self): r""" Return the hash of the atomic species. """ - return hash(tuple([self._C, self._mc])) + return hash(tuple([self._C, self._mc, self._tc])) @cached_method def _element_key(self): @@ -872,6 +873,14 @@ def product_on_basis(self, H, K): return self._from_dict({H: 1}) return self._from_dict({H * K: 1}) + def degree_on_basis(self, m): + r""" + Return the degree of the basis element indexed by ``m`` + in ``self``. + """ + d = m.dict() + return sum(at._tc * p for at, p in d.items()) + def _repr_(self): r""" Return a string representation of ``self``. From 36e6c0260ab48e01da6e4b42b89ff712c30e845c Mon Sep 17 00:00:00 2001 From: Newtech66 Date: Fri, 26 Jul 2024 02:46:38 +0530 Subject: [PATCH 077/537] more fixes --- src/sage/rings/burnside.py | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/src/sage/rings/burnside.py b/src/sage/rings/burnside.py index 3c2f2a667e5..5e5689f0a2f 100644 --- a/src/sage/rings/burnside.py +++ b/src/sage/rings/burnside.py @@ -194,7 +194,7 @@ def __lt__(self, other): sage: B[H2] < B[H3] True """ - return self <= other and self != other + return self != other and self <= other class ConjugacyClassesOfSubgroups(Parent, ElementCache): def __init__(self, G): @@ -564,6 +564,40 @@ def _repr_(self): """ return "{" + f"{self._C.degree()}, {self._C.gens_small()}" + "}" + def __le__(self, other): + r""" + Return if this element is less than or equal to ``other``. + + ``self`` is less or equal to ``other`` if it is conjugate to + a subgroup of ``other`` in the parent group of larger degree. + """ + # If selfdeg > otherdeg, return False + # then selfdeg <= otherdeg + return (isinstance(other, ConjugacyClassOfSubgroups) + and self._C.degree() <= other._C.degree() + and (self._C.degree() < other._C.degree() or + (GAP_FAIL != libgap.ContainedConjugates(self.subgroup_of(), + other._C, self._C, True)))) + + def __eq__(self, other): + r""" + Return if this element is equal to ``other``. + + Two elements compare equal if they are conjugate subgroups in the parent group. + + TESTS:: + + sage: G = SymmetricGroup(4) + sage: B = BurnsideRing(G) + sage: H1 = PermutationGroup([(1,2)]) + sage: H2 = PermutationGroup([(2,3)]) + sage: B[H1] == B[H2] + True + """ + return (isinstance(other, ConjugacyClassOfSubgroups) + and self._C.degree() == other._C.degree() and + _is_conjugate(self.subgroup_of(), self._C, other._C)) + class AtomicSpecies(ConjugacyClassOfDirectlyIndecomposableSubgroups): def __init__(self, parent, C, multicardinality): r""" From 470d69bd9c465158bfc51016474ae3f4bcabcbf9 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Mon, 29 Jul 2024 15:44:33 +0530 Subject: [PATCH 078/537] Added basis() method --- src/sage/matroids/chow_ring.py | 186 ++++++++++++++++++++++++++++++++- 1 file changed, 184 insertions(+), 2 deletions(-) diff --git a/src/sage/matroids/chow_ring.py b/src/sage/matroids/chow_ring.py index bcbd31e4ba8..304692bfbab 100644 --- a/src/sage/matroids/chow_ring.py +++ b/src/sage/matroids/chow_ring.py @@ -19,6 +19,10 @@ from sage.matroids.chow_ring_ideal import ChowRingIdeal_nonaug, AugmentedChowRingIdeal_fy, AugmentedChowRingIdeal_atom_free from sage.rings.quotient_ring import QuotientRing_nc from sage.categories.graded_algebras_with_basis import GradedAlgebrasWithBasis +from sage.rings.polynomial.multi_polynomial_sequence import PolynomialSequence +from sage.sets.set import Set +from sage.combinat.posets.posets import Poset + class ChowRing(QuotientRing_nc): r""" @@ -57,14 +61,15 @@ def __init__(self, R, M, augmented, presentation=None): """ self._matroid = M self._augmented = augmented + self._presentation = presentation if augmented: if presentation=='fy': self._ideal = AugmentedChowRingIdeal_fy(M, R) elif presentation=='atom-free': - self._ideal = AugmentedChowRingIdeal_fy(M, R) + self._ideal = AugmentedChowRingIdeal_atom_free(M, R) else: self._ideal = ChowRingIdeal_nonaug(M, R) #check method to get ring - QuotientRing_nc.__init__(self, R=self._ideal.poly_ring, I=self._ideal, names=self._ideal.poly_ring.variable_names(), category=GradedAlgebrasWithBasis(R)) + QuotientRing_nc.__init__(self, R=self._ideal.ring(), I=self._ideal, names=self._ideal.ring().variable_names(), category=GradedAlgebrasWithBasis(R)) def _repr_(self): return "Chow ring of {}".format(self._matroid) @@ -72,3 +77,180 @@ def _repr_(self): def _latex_(self): import sage.misc.latex as latex return "%s/%s" % (latex.latex(self.poly_ring), latex.latex(self._ideal)) + + def _coerce_map_from_base_ring(self): + r""" + Disable the coercion from the base ring from the category. + + TESTS:: + + sage: SGA = SymmetricGroupAlgebra(QQ, 4) + sage: GP = SGA.garsia_procesi_module([2, 2]) + sage: GP._coerce_map_from_base_ring() is None + True + """ + return None # don't need anything special + + def basis(self): + flats = [Set(X) for i in range(1, self._matroid.rank()) + for X in self._matroid.flats(i)] + flats.append(Set([])) + maximum_rank = max([self._matroid.rank(F) for F in flats]) + func = lambda A,B: A.issubset(B) + flats = Poset((flats, func), cover_relations=True).directed_subsets('down') #DEBUG + monomial_basis = [] + if self._augmented: + if self._presentation=='fy': + for i in range(maximum_rank): + term = self._ideal.ring().one() + for j in range(len(flats)): + if j == 0: + if i > self._matroid.rank(flats[0]): + term *= self._flats_generator[flats[j]]**(0) + else: + term *= self._flats_generator[flats[j]]**(i + 1) + else: + if i >= (self._matroid.rank(flats[j]) - self._matroid.rank(flats[j-1])): + term *= self._flats_generator[flats[j]]**(0) + else: + term *= self._flats_generator[flats[j]]**(i + 1) + monomial_basis.append(term) + + elif self._presentation=='atom-free': + for i in range(maximum_rank): + term = self._ideal.ring().one() + pow = [] + for j in range(1, len(flats) - 1): + if i >= (self._matroid.rank(flats[j-1]) - self._matroid.rank(flats[j])): + pow.append((j , i)) + if sum(pow) == self._matroid.rank(flats[0]): + for p in pow: + term *= self._flats_generator[flats[p[0]]]**(p[1]) + monomial_basis.append(term) + + + else: + for i in range(maximum_rank): + term = self._ideal.ring().one() + for j in range(len(flats)): + if i > (self._matroid.rank(flats[j]) - self._matroid.rank(flats[j-1]) - 1): + term *= self._flats_generator[flats[j]]**(0) + else: + term *= self._flats_generator[flats[j]]**(i + 1) + monomial_basis.append(term) + + + m_basis = PolynomialSequence([monomial_basis], self._ideal.ring()) + return m_basis + + + + + + + + + + + + + + + class Element(QuotientRing_nc.Element): + def to_vector(self, order=None): + r""" + Return ``self`` as a (dense) free module vector. + + EXAMPLES:: + + sage: SGA = SymmetricGroupAlgebra(GF(3), 4) + sage: GP22 = SGA.garsia_procesi_module([2, 2]) + sage: v = GP22.an_element(); v + -gp1 - gp2 - gp3 + sage: v.to_vector() + (0, 0, 2, 2, 2, 0) + """ + P = self.parent() + B = P.basis() + FM = P._dense_free_module() + f = self.lift() + return FM([f.monomial_coefficient(b.lift()) for b in B]) + + _vector_ = to_vector + + def monomial_coefficients(self, copy=None): + r""" + Return the monomial coefficients of ``self``. + + EXAMPLES:: + + sage: SGA = SymmetricGroupAlgebra(GF(3), 4) + sage: GP31 = SGA.garsia_procesi_module([3, 1]) + sage: v = GP31.an_element(); v + -gp1 - gp2 - gp3 + sage: v.monomial_coefficients() + {0: 2, 1: 2, 2: 2, 3: 0} + """ + B = self.parent().basis() + f = self.lift() + return {i: f.monomial_coefficient(b.lift()) for i, b in enumerate(B)} + + def degree(self): + r""" + Return the degree of ``self``. + + EXAMPLES:: + + sage: SGA = SymmetricGroupAlgebra(GF(3), 4) + sage: GP22 = SGA.garsia_procesi_module([2, 2]) + sage: for b in GP22.basis(): + ....: print(b, b.degree()) + gp2*gp3 2 + gp1*gp3 2 + gp3 1 + gp2 1 + gp1 1 + 1 0 + sage: v = sum(GP22.basis()) + sage: v.degree() + 2 + """ + return self.lift().degree() + + def homogeneous_degree(self): + r""" + Return the (homogeneous) degree of ``self`` if homogeneous + otherwise raise an error. + + EXAMPLES:: + + sage: SGA = SymmetricGroupAlgebra(GF(2), 4) + sage: GP31 = SGA.garsia_procesi_module([3, 1]) + sage: for b in GP31.basis(): + ....: print(b, b.homogeneous_degree()) + gp3 1 + gp2 1 + gp1 1 + 1 0 + sage: v = sum(GP31.basis()); v + gp1 + gp2 + gp3 + 1 + sage: v.homogeneous_degree() + Traceback (most recent call last): + ... + ValueError: element is not homogeneous + + TESTS:: + + sage: SGA = SymmetricGroupAlgebra(GF(3), 4) + sage: GP4 = SGA.garsia_procesi_module([4]) + sage: GP4.zero().homogeneous_degree() + Traceback (most recent call last): + ... + ValueError: the zero element does not have a well-defined degree + """ + if not self: + raise ValueError("the zero element does not have a well-defined degree") + f = self.lift() + if not f.is_homogeneous(): + raise ValueError("element is not homogeneous") + return f.degree() \ No newline at end of file From a724173b8887ad130c3f0f631a01e08b12e77a5c Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Mon, 29 Jul 2024 15:45:23 +0530 Subject: [PATCH 079/537] Edited attribute names --- src/sage/matroids/chow_ring_ideal.py | 138 +++++++++++---------------- 1 file changed, 58 insertions(+), 80 deletions(-) diff --git a/src/sage/matroids/chow_ring_ideal.py b/src/sage/matroids/chow_ring_ideal.py index 21b0994a8c9..6520474ab75 100644 --- a/src/sage/matroids/chow_ring_ideal.py +++ b/src/sage/matroids/chow_ring_ideal.py @@ -27,7 +27,7 @@ class ChowRingIdeal(MPolynomialIdeal): @abstract_method - def gens_constructor(): + def _gens_constructor(): pass def matroid(self): @@ -35,7 +35,7 @@ def matroid(self): return M def flats_generator(self): - return dict(self.flats_generator) + return dict(self._flats_generator) class ChowRingIdeal_nonaug(ChowRingIdeal): @@ -74,28 +74,28 @@ def __init__(self, M, R): sage: from sage.matroids.chow_ring_ideal import ChowRingIdeal_nonaug sage: I = ChowRingIdeal_nonaug(M=matroids.catalog.Fano(), R=QQ) - sage: TestSuite(I).run() + sage: TestSuite(I).run(skip="_test_category") """ self._matroid = M flats = [X for i in range(1, self._matroid.rank()) 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: - self.poly_ring = PolynomialRing(R, names) #self.ring + poly_ring = PolynomialRing(R, names) #self.ring except ValueError: # variables are not proper names - self.poly_ring = PolynomialRing(R, 'A', len(self.flats)) - gens = self.poly_ring.gens() - self.flats_generator = dict(zip(flats, gens)) - MPolynomialIdeal.__init__(self, self.poly_ring, self.gens_constructor()) + poly_ring = PolynomialRing(R, 'A', len(self.flats)) + gens = poly_ring.gens() + self._flats_generator = dict(zip(flats, gens)) + MPolynomialIdeal.__init__(self, poly_ring, self._gens_constructor(poly_ring)) - def gens_constructor(self): + def _gens_constructor(self, poly_ring): E = list(self._matroid.groundset()) - flats = list(self.flats_generator.keys()) + flats = list(self._flats_generator.keys()) flats_containing = {x: [] for x in E} for i,F in enumerate(flats): for x in F: flats_containing[x].append(i) - gens = self.poly_ring.gens() + gens = poly_ring.gens() Q = [gens[i] * gens[i+j+1] for i,F in enumerate(flats) for j,G in enumerate(flats[i+1:]) if not (F < G or G < F)] L = [sum(gens[i] for i in flats_containing[x]) @@ -130,23 +130,24 @@ def groebner_basis(self): Polynomial Sequence with 232 Polynomials in 16 Variables """ - flats = list(self.flats_generator.keys()) + flats = list(self._flats_generator) gb = list() + R = self.ring() for F in flats: for G in flats: if not (F < G or G < F): - gb.append(self.flats_generator[F]*self.flats_generator[G]) + gb.append(self._flats_generator[F]*self._flats_generator[G]) else: - term = self.poly_ring.zero() + term = R.zero() for H in flats: if H > G: - term += self.flats_generator[H] + term += self._flats_generator[H] if Set(F).is_empty(): - gb.append(term**self._matroid.rank(Set(G))) + gb.append(term**self._matroid.rank(G)) elif F < G: - gb.append(term**(self._matroid.rank(Set(G))-self._matroid.rank(Set(F)))) + gb.append(term**(self._matroid.rank(G)-self._matroid.rank(F))) - g_basis = PolynomialSequence(self.poly_ring, [gb]) + g_basis = PolynomialSequence(R, [gb]) return g_basis class AugmentedChowRingIdeal_fy(ChowRingIdeal): @@ -194,17 +195,17 @@ def __init__(self, M, R): try: names_groundset = ['A{}'.format(''.join(str(x))) for x in E] names_flats = ['B{}'.format(''.join(str(x) for x in sorted(F, key=cmp_elements_key))) for F in self._flats] - self.poly_ring = PolynomialRing(R, names_groundset + names_flats) + poly_ring = PolynomialRing(R, names_groundset + names_flats) except ValueError: - self.poly_ring = PolynomialRing(R, 'A', len(E) + len(self._flats)) + poly_ring = PolynomialRing(R, 'A', len(E) + len(self._flats)) for i,x in enumerate(E): - self.flats_generator[x] = self.poly_ring.gens()[i] + self._flats_generator[x] = poly_ring.gens()[i] for i,F in enumerate(self._flats): - self.flats_generator[F] = self.poly_ring.gens()[len(E) + i] - MPolynomialIdeal.__init__(self, self.poly_ring, self.gens_constructor()) + self._flats_generator[F] = poly_ring.gens()[len(E) + i] + MPolynomialIdeal.__init__(self, poly_ring, self._gens_constructor(poly_ring)) - def gens_constructor(self): + def _gens_constructor(self, poly_ring): E = list(self._matroid.groundset()) flats_containing = {x: [] for x in E} for F in self._flats: @@ -215,14 +216,14 @@ def gens_constructor(self): for F in self._flats: for G in self._flats: if not (F < G or G < F): - Q.append(self.flats_generator[F] * self.flats_generator[G]) + Q.append(self._flats_generator[F] * self._flats_generator[G]) L = list() for x in E: - term = self.poly_ring.zero() + term = poly_ring.zero() for F in self._flats: if F not in flats_containing[x]: - term += self.flats_generator[F] - L.append(self.flats_generator[x] - term) + term += self._flats_generator[F] + L.append(self._flats_generator[x] - term) return Q + L def __repr__(self): @@ -243,33 +244,34 @@ def groebner_basis(self): """ gb = [] E = list(self._matroid.groundset()) + poly_ring = self.ring() for i in E: for F in self._flats: for G in self._flats: - term = self.poly_ring.zero() - term1 = self.poly_ring.zero() + term = poly_ring.zero() + term1 = poly_ring.zero() for H in self._flats: if i in Set(H): - term += self.flats_generator[H] + term += self._flats_generator[H] if H > F: - term1 += self.flats_generator[H] + term1 += self._flats_generator[H] - gb.append(self.flats_generator[i] + term) + gb.append(self._flats_generator[i] + term) gb.append(term1**(self._matroid.rank(Set(F))) + 1) if i in Set(F): - gb.append(self.flats_generator[i]*((term1)**self._matroid.rank(Set(F)))) + gb.append(self._flats_generator[i]*((term1)**self._matroid.rank(Set(F)))) elif not i in Set(F): - gb.append(self.flats_generator[i]*self.flats_generator[F]) + gb.append(self._flats_generator[i]*self._flats_generator[F]) elif not (F < G or G < F): - gb.append(self.flats_generator[F]*self.flats_generator[G]) + gb.append(self._flats_generator[F]*self._flats_generator[G]) elif G < F: - gb.append(self.flats_generator[G]*term1**(self._matroid.rank(Set(F))-self._matroid.rank(Set(G)))) + gb.append(self._flats_generator[G]*term1**(self._matroid.rank(Set(F))-self._matroid.rank(Set(G)))) - g_basis = PolynomialSequence(self.poly_ring, [gb]) + g_basis = PolynomialSequence(poly_ring, [gb]) return g_basis class AugmentedChowRingIdeal_atom_free(ChowRingIdeal): @@ -296,7 +298,7 @@ class AugmentedChowRingIdeal_atom_free(ChowRingIdeal): Augmented Chow ring ideal of Wheel(3): Regular matroid of rank 3 on 6 elements with 16 bases of atom-free presentation """ - def __init__(self, M, R): #documentation of every init + def __init__(self, M, R): r""" Initialize ``self``. @@ -305,7 +307,7 @@ def __init__(self, M, R): #documentation of every init sage: from sage.matroids.chow_ring_ideal import AugmentedChowRingIdeal_atom_free sage: I = AugmentedChowRingIdeal_atom_free(M=matroids.Wheel(3), R=QQ) - sage: TestSuite(I).run() + sage: TestSuite(I).run(skip="_test_category") """ self._matroid = M self._flats = [X for i in range(1, self._matroid.rank()) @@ -320,26 +322,14 @@ def __init__(self, M, R): #documentation of every init names = ['A{}'.format(''.join(str(x) for x in sorted(F, key=cmp_elements_key))) for F in self._flats] try: - self.poly_ring = PolynomialRing(R, names) #self.ring + poly_ring = PolynomialRing(R, names) #self.ring except ValueError: # variables are not proper names - self.poly_ring = PolynomialRing(R, 'A', len(self._flats)) - - - gens = self.poly_ring.gens() - self.flats_generator = dict(zip(self._flats, gens)) - - - Q = [gens[i] * gens[i+j+1] for i,F in enumerate(self._flats) - for j,G in enumerate(self._flats[i+1:]) if not (F < G or G < F)] - L = [sum(gens[i] for i in flats_containing[x]) - - sum(gens[i] for i in flats_containing[y]) - for j,x in enumerate(E) for y in E[j+1:]] - + poly_ring = PolynomialRing(R, 'A', len(self._flats)) - MPolynomialIdeal.__init__(self, self.poly_ring, Q + L) + MPolynomialIdeal.__init__(self, poly_ring, self._gens_constructor(poly_ring)) - def gens_constructor(self): + def _gens_constructor(self, poly_ring): E = list(self._matroid.groundset()) Q = [] flats_containing = {x: [] for x in E} @@ -349,16 +339,16 @@ def gens_constructor(self): for F in self._flats: for x in E: if F not in flats_containing[x]: - Q.append(self.flats_generator[x]*self.flats_generator[F]) - term = self.poly_ring.zero() + Q.append(self._flats_generator[x]*self._flats_generator[F]) + term = poly_ring.zero() for G in flats_containing[x]: - term += self.flats_generator[G] - Q.append(self.flats_generator[F]*term) + term += self._flats_generator[G] + Q.append(self._flats_generator[F]*term) for i in E: - term = self.poly_ring.zero() + term = poly_ring.zero() for F in flats_containing[i]: - term += self.flats_generator[F] + term += self._flats_generator[F] Q.append(term**2) return Q @@ -384,36 +374,24 @@ def groebner_basis(self): gb = [] flats = [X for i in range(1, self._matroid.rank()) for X in self._matroid.flats(i)] + poly_ring = self.ring() if Set([]) in flats: flats.remove(Set([])) for F in flats: for G in flats: if not (F > G or G > F): - gb.append(self.flats_generator[F]*self.flats_generator[G]) + gb.append(self._flats_generator[F]*self._flats_generator[G]) elif F < G: - term = self.poly_ring.zero() + term = poly_ring.zero() for H in flats: if H < F: - term += self.flats_generator[H] - gb.append(self.flats_generator[F]*(term**self._matroid.rank(Set(G)))* + term += self._flats_generator[H] + gb.append(self._flats_generator[F]*(term**self._matroid.rank(Set(G)))* (term**(self._matroid.rank(Set(G))-self._matroid.rank(Set(F))))) - g_basis = PolynomialSequence(self.poly_ring, [gb]) + g_basis = PolynomialSequence(poly_ring, [gb]) return g_basis - - - -#linting tests pass -#single underscore for attributes -#Developer's guide -#use 'self' in docstrings -#rebase chow_ring from repr_update -#common base class for all chow ring ideals - augmented parameter -#getting ring from chow ring ideal to chow ring -#references in the main index - - From 7ab59ad5094d6178715f258ab466201f35e75bba Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Mon, 29 Jul 2024 15:45:50 +0530 Subject: [PATCH 080/537] Modified chow_ring() method --- src/sage/matroids/matroid.pyx | 35 +++-------------------------------- 1 file changed, 3 insertions(+), 32 deletions(-) diff --git a/src/sage/matroids/matroid.pyx b/src/sage/matroids/matroid.pyx index 5591e14c038..785dc795df4 100644 --- a/src/sage/matroids/matroid.pyx +++ b/src/sage/matroids/matroid.pyx @@ -8027,7 +8027,7 @@ cdef class Matroid(SageObject): return [F for F in FF if fsol[F]] - def chow_ring(self, R=None): + def chow_ring(self, R, augmented=False, presentation=None): r""" Return the Chow ring of ``self`` over ``R``. @@ -8099,37 +8099,8 @@ cdef class Matroid(SageObject): - [FY2004]_ - [AHK2015]_ """ - # Setup - if R is None: - R = ZZ - # We only want proper flats - flats = [X for i in range(1, self.rank()) - for X in self.flats(i)] - E = list(self.groundset()) - flats_containing = {x: [] for x in E} - for i,F in enumerate(flats): - for x in F: - flats_containing[x].append(i) - - # Create the ambient polynomial ring - from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing - try: - names = ['A{}'.format(''.join(str(x) for x in sorted(F, key=cmp_elements_key))) for F in flats] - P = PolynomialRing(R, names) - except ValueError: # variables are not proper names - P = PolynomialRing(R, 'A', len(flats)) - names = P.variable_names() - gens = P.gens() - # Create the ideal of quadratic relations - Q = [gens[i] * gens[i+j+1] for i,F in enumerate(flats) - for j,G in enumerate(flats[i+1:]) if not (F < G or G < F)] - # Create the ideal of linear relations - L = [sum(gens[i] for i in flats_containing[x]) - - sum(gens[i] for i in flats_containing[y]) - for j,x in enumerate(E) for y in E[j+1:]] - ret = P.quotient(Q + L, names=names) - ret.rename("Chow ring of {} over {}".format(self, R)) - return ret + from sage.matroids.chow_ring import ChowRing + return ChowRing(M=self, R=R, augmented=augmented, presentation=presentation) cpdef plot(self, B=None, lineorders=None, pos_method=None,pos_dict=None,save_pos=False): """ From 639616379b3a60af7363342570fd7e3ae705e49e Mon Sep 17 00:00:00 2001 From: Newtech66 Date: Mon, 29 Jul 2024 21:53:21 +0530 Subject: [PATCH 081/537] Split species into new PR --- src/sage/rings/all.py | 4 +- src/sage/rings/burnside.py | 396 ------------------------------------ src/sage/rings/species.py | 406 +++++++++++++++++++++++++++++++++++++ 3 files changed, 409 insertions(+), 397 deletions(-) create mode 100644 src/sage/rings/species.py diff --git a/src/sage/rings/all.py b/src/sage/rings/all.py index f34635f6989..cb267281b64 100644 --- a/src/sage/rings/all.py +++ b/src/sage/rings/all.py @@ -166,7 +166,9 @@ # asymptotic ring from sage.rings.asymptotic.all import * -lazy_import('sage.rings.burnside', ['BurnsideRing', 'PolynomialMolecularDecomposition', +lazy_import('sage.rings.burnside', 'BurnsideRing') + +lazy_import('sage.rings.species', ['PolynomialMolecularDecomposition', 'MultivariateAtomicSpecies']) # Register classes in numbers abc diff --git a/src/sage/rings/burnside.py b/src/sage/rings/burnside.py index 5e5689f0a2f..b9467b90324 100644 --- a/src/sage/rings/burnside.py +++ b/src/sage/rings/burnside.py @@ -1,20 +1,13 @@ -from sage.combinat.integer_vector import IntegerVectors from sage.misc.cachefunc import cached_method -from sage.monoids.indexed_free_monoid import IndexedFreeAbelianMonoid from sage.structure.parent import Parent from sage.structure.element import Element from sage.structure.element import parent -from sage.structure.unique_representation import UniqueRepresentation from sage.rings.integer_ring import ZZ from sage.categories.finite_enumerated_sets import FiniteEnumeratedSets -from sage.categories.sets_with_grading import SetsWithGrading -from sage.categories.graded_algebras_with_basis import GradedAlgebrasWithBasis from sage.categories.algebras import Algebras from sage.groups.perm_gps.permgroup import PermutationGroup, PermutationGroup_generic -from sage.groups.perm_gps.permgroup_named import SymmetricGroup from sage.libs.gap.libgap import libgap from sage.combinat.free_module import CombinatorialFreeModule -from sage.sets.set import Set GAP_FAIL = libgap.eval('fail') @@ -540,392 +533,3 @@ def _repr_(self): Burnside ring of Symmetric group of order 4! as a permutation group """ return "Burnside ring of " + repr(self._G) - -class ConjugacyClassOfDirectlyIndecomposableSubgroups(ConjugacyClassOfSubgroups): - def __init__(self, parent, C): - r""" - A conjugacy class of directly indecomposable subgroups. - """ - if len(C.disjoint_direct_product_decomposition()) > 1: - raise ValueError(f"{C} is not directly indecomposable") - ConjugacyClassOfSubgroups.__init__(self, parent, C) - - @cached_method - def subgroup_of(self): - r""" - Return the group which this conjugacy class of - directly indecomposable subgroups belongs to. - """ - return SymmetricGroup(self._C.degree()) - - def _repr_(self): - r""" - Return a string representation of ``self``. - """ - return "{" + f"{self._C.degree()}, {self._C.gens_small()}" + "}" - - def __le__(self, other): - r""" - Return if this element is less than or equal to ``other``. - - ``self`` is less or equal to ``other`` if it is conjugate to - a subgroup of ``other`` in the parent group of larger degree. - """ - # If selfdeg > otherdeg, return False - # then selfdeg <= otherdeg - return (isinstance(other, ConjugacyClassOfSubgroups) - and self._C.degree() <= other._C.degree() - and (self._C.degree() < other._C.degree() or - (GAP_FAIL != libgap.ContainedConjugates(self.subgroup_of(), - other._C, self._C, True)))) - - def __eq__(self, other): - r""" - Return if this element is equal to ``other``. - - Two elements compare equal if they are conjugate subgroups in the parent group. - - TESTS:: - - sage: G = SymmetricGroup(4) - sage: B = BurnsideRing(G) - sage: H1 = PermutationGroup([(1,2)]) - sage: H2 = PermutationGroup([(2,3)]) - sage: B[H1] == B[H2] - True - """ - return (isinstance(other, ConjugacyClassOfSubgroups) - and self._C.degree() == other._C.degree() and - _is_conjugate(self.subgroup_of(), self._C, other._C)) - -class AtomicSpecies(ConjugacyClassOfDirectlyIndecomposableSubgroups): - def __init__(self, parent, C, multicardinality): - r""" - An atomic species centered on a given multicardinality: a directly - indecomposable subgroup paired with an integer vector. - """ - total_cardinality = sum(multicardinality) - if C.degree() != sum(multicardinality): - raise ValueError(f"Degree of {C} (= {C.degree()}) must equal the total cardinality {total_cardinality}") - G = SymmetricGroup(total_cardinality).young_subgroup(multicardinality) - if not C.is_subgroup(G): - raise ValueError(f"{C} is not a subgroup of {G}") - ConjugacyClassOfDirectlyIndecomposableSubgroups.__init__(self, parent, C) - self._mc = multicardinality - self._tc = total_cardinality - - @cached_method - def subgroup_of(self): - r""" - Return the group which the underlying permutation group - of this atomic species belongs to. - """ - return SymmetricGroup(self._tc).young_subgroup(self._mc) - - def __hash__(self): - r""" - Return the hash of the atomic species. - """ - return hash(tuple([self._C, self._mc, self._tc])) - - @cached_method - def _element_key(self): - r""" - Return a lookup key for ``self``. - """ - return tuple([*super()._element_key(), self._mc]) - - def __eq__(self, other): - r""" - Two atomic species are equal if the underlying groups are conjugate, - and their multicardinalities are equal. - """ - if parent(self) != parent(other): - return False - return self._mc == other._mc and super().__eq__(other) - - def _repr_(self): - r""" - Return a string representation of ``self``. - """ - return "{" + f"{self._C.gens_small()}: {self._mc}" + "}" - -class MultivariateAtomicSpecies(UniqueRepresentation, Parent, ElementCache): - def __init__(self, k): - r""" - Infinite set of `k`-variate atomic species graded by - integer vectors of length `k`. - """ - category = SetsWithGrading().Infinite() - Parent.__init__(self, category=category) - ElementCache.__init__(self) - self._k = k - self._grading_set = IntegerVectors(length=k) - - def __hash__(self): - r""" - Return a hash for ``self``. - """ - return hash(self._k) - - def __eq__(self, other): - r""" - Needed for unique representation behaviour. - - TESTS:: - - sage: At1 = MultivariateAtomicSpecies(1); At1 - sage: At2 = MultivariateAtomicSpecies(2); At2 - sage: At1_2 = MultivariateAtomicSpecies(1); At1_2 - sage: At1 is At1_2 - True - sage: At1 is At2 - False - sage: At1_2 is At2 - False - """ - if type(self) != type(other): - return False - return self._k == other._k - - @cached_method - def an_element(self): - """ - Return an element of ``self``. - """ - return self._element_constructor_((SymmetricGroup(self._k).young_subgroup([1] * self._k), - {e: i for i, e in enumerate(range(1, self._k + 1), 1)})) - - def _normalize(self, H, f): - r""" - Normalize `H` and return `H` and the multicardinality. - """ - # TODO: Complete the documentation. - L = [[] for _ in range(self._k)] - for k, v in f.items(): - L[v - 1].append(k) - Lc = sum(L, []) - Ls = [len(l) for l in L] - mapping = {v: i for i, v in enumerate(Lc, 1)} - normalized_gens = [[tuple(mapping[x] for x in cyc) for cyc in gen.cycle_tuples()] for gen in H.gens_small()] - P = PermutationGroup(gens=normalized_gens) - # Fix for SymmetricGroup(0) - if H.degree() == 0: - P = SymmetricGroup(0) - return P, self._grading_set(Ls) - - def _element_constructor_(self, x): - r""" - Construct the `k`-variate molecular species with the given data. - - INPUT: - - - ``x`` - an element of ``self`` or a tuple ``(H, f)`` where `H` is - the directly indecomposable permutation group representation for the - `k`-variate atomic species and `f` is a ``dict`` mapping each element - of the domain of `H` to integers in `\{ 1 \ldots k \}`, representing - the set to which the element belongs. - """ - if parent(x) == self: - return x - H, f = x - if Set(H.domain()) != Set(f.keys()): - raise ValueError(f"Keys of {f} do not match with domain of {H} (= {H.domain()})") - if not Set(f.values()).issubset(Set(range(1, self._k + 1))): - raise ValueError(f"Values of {f} must be in the range [1, {self._k}]") - if isinstance(H, PermutationGroup_generic) and isinstance(f, dict): - elm = self.element_class(self, *self._normalize(H, f)) - return self._cache_get(elm) - raise ValueError("unable to convert {x} into {self}") - - def __getitem__(self, x): - r""" - Call ``_element_constructor_`` on ``x``. - """ - return self._element_constructor_(x) - - def __contains__(self, x): - r""" - Return if ``x`` is in ``self``. - """ - if parent(x) == self: - return True - try: - self._element_constructor_(x) - except: - return False - return True - - def _repr_(self): - r""" - Return a string representation of ``self``. - - TESTS:: - - sage: At1 = MultivariateAtomicSpecies(1) - sage: At1 - Infinite set of 1-variate atomic species - sage: At2 = MultivariateAtomicSpecies(2) - sage: At2 - Infinite set of 2-variate atomic species - """ - return f"Infinite set of {self._k}-variate atomic species" - - Element = AtomicSpecies - -class PolynomialMolecularDecomposition(CombinatorialFreeModule): - def __init__(self, k, base_ring=ZZ): - r""" - Ring of `k`-variate virtual species. - - TESTS:: - - sage: P = PolynomialMolecularDecomposition(1) - sage: TestSuite(P).run() - sage: P2 = PolynomialMolecularDecomposition(2) - sage: TestSuite(P2).run() - """ - # should we pass a category to basis_keys? - basis_keys = IndexedFreeAbelianMonoid(MultivariateAtomicSpecies(k), - prefix='', bracket=False) - category = GradedAlgebrasWithBasis(base_ring).Commutative() - CombinatorialFreeModule.__init__(self, base_ring, - basis_keys=basis_keys, - category=category, - prefix='', bracket=False) - self._k = k - self._atomic_basis = basis_keys.indices() - - def _project(self, H, f, part): - r""" - Project `H` onto a subset ``part`` of its domain. - ``part`` must be a union of cycles, but this is not checked. - """ - restricted_gens = [[cyc for cyc in gen.cycle_tuples() if cyc[0] in part] for gen in H.gens_small()] - mapping = {p: f[p] for p in part} - return tuple([PermutationGroup(gens=restricted_gens, domain=part), mapping]) - - def _element_constructor_(self, x): - r""" - Construct the `k`-variate molecular species with the given data. - - INPUT: - - - ``x`` - an element of ``self`` or a tuple ``(H, f)`` where `H` is - the permutation group representation for the species and `f` is a - ``dict`` mapping each element of the domain of `H` to integers in - `\{ 1 \ldots k \}`, representing the set to which the element belongs. - """ - if parent(x) == self: - return x - H, f = x - if Set(H.domain()) != Set(f.keys()): - raise ValueError(f"Keys of {f} do not match with domain of {H}") - if not Set(f.values()).issubset(Set(range(1, self._k + 1))): - raise ValueError(f"Values of {f} must be in the range [1, {self._k}]") - if isinstance(H, PermutationGroup_generic) and isinstance(f, dict): - domain_partition = H.disjoint_direct_product_decomposition() - from collections import Counter - C = Counter([self._atomic_basis(self._project(H, f, part)) for part in domain_partition]) - return self._from_dict({self._indices(dict(C)): 1}) - raise ValueError("unable to convert {x} into {self}") - - def __getitem__(self, x): - r""" - Calls _element_constructor_ on x. - - TESTS:: - - sage: P = PolynomialMolecularDecomposition(1) - sage: At1 = MultivariateAtomicSpecies(1) - sage: At1((SymmetricGroup(1), {1: 1})).rename("X") - sage: X = (SymmetricGroup(2).young_subgroup([1, 1]), {1: 1, 2: 1}) - sage: P[X] - X^2 - sage: P2=PolynomialMolecularDecomposition(2) - sage: At2=MultivariateAtomicSpecies(2) - sage: At2((SymmetricGroup(1), {1: 1})).rename("X") - sage: At2((SymmetricGroup(1), {1: 2})).rename("Y") - sage: XY = (SymmetricGroup(2).young_subgroup([1, 1]), {1: 1, 2: 2}) - sage: P2[XY] - Y*X - """ - return self._element_constructor_(x) - - @cached_method - def one_basis(self): - r""" - Returns SymmetricGroup(0), which indexes the one of this algebra, - as per :meth:`AlgebrasWithBasis.ParentMethods.one_basis`. - - EXAMPLES:: - - sage: P = PolynomialMolecularDecomposition(1) - sage: P.one_basis() - {[]: [0]} - sage: P2 = PolynomialMolecularDecomposition(2) - sage: P2.one_basis() - {[]: [0, 0]} - """ - return self._indices({self._atomic_basis(tuple([SymmetricGroup(0), dict()])): 1}) - - @cached_method - def an_element(self): - """ - Return an element of ``self``. - - sage: P=PolynomialMolecularDecomposition(1) - sage: P.an_element() - {[]: [0]} - sage: P2=PolynomialMolecularDecomposition(2) - sage: P2.an_element() - {[]: [0, 0]} - """ - return self.one() - - def product_on_basis(self, H, K): - r""" - Return the product of the basis elements indexed by `H` and `K`. - - EXAMPLES:: - - sage: P=PolynomialMolecularDecomposition(1) - sage: d2 = {e: 1 for e in range(1, 3)} - sage: d3 = {e: 1 for e in range(1, 4)} - sage: L1 = [(H, d3) for H in SymmetricGroup(3).conjugacy_classes_subgroups()] - sage: L2 = [(H, d2) for H in SymmetricGroup(2).conjugacy_classes_subgroups()] - sage: matrix([[P(x) * P(y) for x in L1] for y in L2]) - [ {[()]: [1]}^5 {[()]: [1]}^3*{[(1,2)]: [2]} {[(1,2,3)]: [3]}*{[()]: [1]}^2 {[(1,2,3), (2,3)]: [3]}*{[()]: [1]}^2] - [ {[()]: [1]}^3*{[(1,2)]: [2]} {[()]: [1]}*{[(1,2)]: [2]}^2 {[(1,2,3)]: [3]}*{[(1,2)]: [2]} {[(1,2,3), (2,3)]: [3]}*{[(1,2)]: [2]}] - """ - # Hacky workaround for handling the one of the algebra :( - if H == self.one_basis() and K == self.one_basis(): - return self._from_dict({self.one_basis(): 1}) - elif H == self.one_basis(): - return self._from_dict({K: 1}) - elif K == self.one_basis(): - return self._from_dict({H: 1}) - return self._from_dict({H * K: 1}) - - def degree_on_basis(self, m): - r""" - Return the degree of the basis element indexed by ``m`` - in ``self``. - """ - d = m.dict() - return sum(at._tc * p for at, p in d.items()) - - def _repr_(self): - r""" - Return a string representation of ``self``. - - EXAMPLES:: - - sage: P = PolynomialMolecularDecomposition(1) - sage: P - Ring of 1-variate virtual species - sage: P2 = PolynomialMolecularDecomposition(2) - sage: P2 - Ring of 2-variate virtual species - """ - return f"Ring of {self._k}-variate virtual species" diff --git a/src/sage/rings/species.py b/src/sage/rings/species.py new file mode 100644 index 00000000000..e94d0646566 --- /dev/null +++ b/src/sage/rings/species.py @@ -0,0 +1,406 @@ +from sage.combinat.integer_vector import IntegerVectors +from sage.misc.cachefunc import cached_method +from sage.monoids.indexed_free_monoid import IndexedFreeAbelianMonoid +from sage.structure.parent import Parent +from sage.structure.element import parent +from sage.structure.unique_representation import UniqueRepresentation +from sage.rings.integer_ring import ZZ +from sage.categories.sets_with_grading import SetsWithGrading +from sage.categories.graded_algebras_with_basis import GradedAlgebrasWithBasis +from sage.groups.perm_gps.permgroup import PermutationGroup, PermutationGroup_generic +from sage.groups.perm_gps.permgroup_named import SymmetricGroup +from sage.libs.gap.libgap import libgap +from sage.combinat.free_module import CombinatorialFreeModule +from sage.sets.set import Set +from sage.rings.burnside import ConjugacyClassOfSubgroups, ElementCache, _is_conjugate + +GAP_FAIL = libgap.eval('fail') + +class ConjugacyClassOfDirectlyIndecomposableSubgroups(ConjugacyClassOfSubgroups): + def __init__(self, parent, C): + r""" + A conjugacy class of directly indecomposable subgroups. + """ + if len(C.disjoint_direct_product_decomposition()) > 1: + raise ValueError(f"{C} is not directly indecomposable") + ConjugacyClassOfSubgroups.__init__(self, parent, C) + + @cached_method + def subgroup_of(self): + r""" + Return the group which this conjugacy class of + directly indecomposable subgroups belongs to. + """ + return SymmetricGroup(self._C.degree()) + + def _repr_(self): + r""" + Return a string representation of ``self``. + """ + return "{" + f"{self._C.degree()}, {self._C.gens_small()}" + "}" + + def __le__(self, other): + r""" + Return if this element is less than or equal to ``other``. + + ``self`` is less or equal to ``other`` if it is conjugate to + a subgroup of ``other`` in the parent group of larger degree. + """ + # If selfdeg > otherdeg, return False + # then selfdeg <= otherdeg + return (isinstance(other, ConjugacyClassOfSubgroups) + and self._C.degree() <= other._C.degree() + and (self._C.degree() < other._C.degree() or + (GAP_FAIL != libgap.ContainedConjugates(self.subgroup_of(), + other._C, self._C, True)))) + + def __eq__(self, other): + r""" + Return if this element is equal to ``other``. + + Two elements compare equal if they are conjugate subgroups in the parent group. + + TESTS:: + + sage: G = SymmetricGroup(4) + sage: B = BurnsideRing(G) + sage: H1 = PermutationGroup([(1,2)]) + sage: H2 = PermutationGroup([(2,3)]) + sage: B[H1] == B[H2] + True + """ + return (isinstance(other, ConjugacyClassOfSubgroups) + and self._C.degree() == other._C.degree() and + _is_conjugate(self.subgroup_of(), self._C, other._C)) + +class AtomicSpecies(ConjugacyClassOfDirectlyIndecomposableSubgroups): + def __init__(self, parent, C, multicardinality): + r""" + An atomic species centered on a given multicardinality: a directly + indecomposable subgroup paired with an integer vector. + """ + total_cardinality = sum(multicardinality) + if C.degree() != sum(multicardinality): + raise ValueError(f"Degree of {C} (= {C.degree()}) must equal the total cardinality {total_cardinality}") + G = SymmetricGroup(total_cardinality).young_subgroup(multicardinality) + if not C.is_subgroup(G): + raise ValueError(f"{C} is not a subgroup of {G}") + ConjugacyClassOfDirectlyIndecomposableSubgroups.__init__(self, parent, C) + self._mc = multicardinality + self._tc = total_cardinality + + @cached_method + def subgroup_of(self): + r""" + Return the group which the underlying permutation group + of this atomic species belongs to. + """ + return SymmetricGroup(self._tc).young_subgroup(self._mc) + + def __hash__(self): + r""" + Return the hash of the atomic species. + """ + return hash(tuple([self._C, self._mc, self._tc])) + + @cached_method + def _element_key(self): + r""" + Return a lookup key for ``self``. + """ + return tuple([*super()._element_key(), self._mc]) + + def __eq__(self, other): + r""" + Two atomic species are equal if the underlying groups are conjugate, + and their multicardinalities are equal. + """ + if parent(self) != parent(other): + return False + return self._mc == other._mc and super().__eq__(other) + + def _repr_(self): + r""" + Return a string representation of ``self``. + """ + return "{" + f"{self._C.gens_small()}: {self._mc}" + "}" + +class MultivariateAtomicSpecies(UniqueRepresentation, Parent, ElementCache): + def __init__(self, k): + r""" + Infinite set of `k`-variate atomic species graded by + integer vectors of length `k`. + """ + category = SetsWithGrading().Infinite() + Parent.__init__(self, category=category) + ElementCache.__init__(self) + self._k = k + self._grading_set = IntegerVectors(length=k) + + def __hash__(self): + r""" + Return a hash for ``self``. + """ + return hash(self._k) + + def __eq__(self, other): + r""" + Needed for unique representation behaviour. + + TESTS:: + + sage: At1 = MultivariateAtomicSpecies(1); At1 + sage: At2 = MultivariateAtomicSpecies(2); At2 + sage: At1_2 = MultivariateAtomicSpecies(1); At1_2 + sage: At1 is At1_2 + True + sage: At1 is At2 + False + sage: At1_2 is At2 + False + """ + if type(self) != type(other): + return False + return self._k == other._k + + @cached_method + def an_element(self): + """ + Return an element of ``self``. + """ + return self._element_constructor_((SymmetricGroup(self._k).young_subgroup([1] * self._k), + {e: i for i, e in enumerate(range(1, self._k + 1), 1)})) + + def _normalize(self, H, f): + r""" + Normalize `H` and return `H` and the multicardinality. + """ + # TODO: Complete the documentation. + L = [[] for _ in range(self._k)] + for k, v in f.items(): + L[v - 1].append(k) + Lc = sum(L, []) + Ls = [len(l) for l in L] + mapping = {v: i for i, v in enumerate(Lc, 1)} + normalized_gens = [[tuple(mapping[x] for x in cyc) for cyc in gen.cycle_tuples()] for gen in H.gens_small()] + P = PermutationGroup(gens=normalized_gens) + # Fix for SymmetricGroup(0) + if H.degree() == 0: + P = SymmetricGroup(0) + return P, self._grading_set(Ls) + + def _element_constructor_(self, x): + r""" + Construct the `k`-variate molecular species with the given data. + + INPUT: + + - ``x`` - an element of ``self`` or a tuple ``(H, f)`` where `H` is + the directly indecomposable permutation group representation for the + `k`-variate atomic species and `f` is a ``dict`` mapping each element + of the domain of `H` to integers in `\{ 1 \ldots k \}`, representing + the set to which the element belongs. + """ + if parent(x) == self: + return x + H, f = x + if Set(H.domain()) != Set(f.keys()): + raise ValueError(f"Keys of {f} do not match with domain of {H} (= {H.domain()})") + if not Set(f.values()).issubset(Set(range(1, self._k + 1))): + raise ValueError(f"Values of {f} must be in the range [1, {self._k}]") + if isinstance(H, PermutationGroup_generic) and isinstance(f, dict): + elm = self.element_class(self, *self._normalize(H, f)) + return self._cache_get(elm) + raise ValueError("unable to convert {x} into {self}") + + def __getitem__(self, x): + r""" + Call ``_element_constructor_`` on ``x``. + """ + return self._element_constructor_(x) + + def __contains__(self, x): + r""" + Return if ``x`` is in ``self``. + """ + if parent(x) == self: + return True + try: + self._element_constructor_(x) + except: + return False + return True + + def _repr_(self): + r""" + Return a string representation of ``self``. + + TESTS:: + + sage: At1 = MultivariateAtomicSpecies(1) + sage: At1 + Infinite set of 1-variate atomic species + sage: At2 = MultivariateAtomicSpecies(2) + sage: At2 + Infinite set of 2-variate atomic species + """ + return f"Infinite set of {self._k}-variate atomic species" + + Element = AtomicSpecies + +class PolynomialMolecularDecomposition(CombinatorialFreeModule): + def __init__(self, k, base_ring=ZZ): + r""" + Ring of `k`-variate virtual species. + + TESTS:: + + sage: P = PolynomialMolecularDecomposition(1) + sage: TestSuite(P).run() + sage: P2 = PolynomialMolecularDecomposition(2) + sage: TestSuite(P2).run() + """ + # should we pass a category to basis_keys? + basis_keys = IndexedFreeAbelianMonoid(MultivariateAtomicSpecies(k), + prefix='', bracket=False) + category = GradedAlgebrasWithBasis(base_ring).Commutative() + CombinatorialFreeModule.__init__(self, base_ring, + basis_keys=basis_keys, + category=category, + prefix='', bracket=False) + self._k = k + self._atomic_basis = basis_keys.indices() + + def _project(self, H, f, part): + r""" + Project `H` onto a subset ``part`` of its domain. + ``part`` must be a union of cycles, but this is not checked. + """ + restricted_gens = [[cyc for cyc in gen.cycle_tuples() if cyc[0] in part] for gen in H.gens_small()] + mapping = {p: f[p] for p in part} + return tuple([PermutationGroup(gens=restricted_gens, domain=part), mapping]) + + def _element_constructor_(self, x): + r""" + Construct the `k`-variate molecular species with the given data. + + INPUT: + + - ``x`` - an element of ``self`` or a tuple ``(H, f)`` where `H` is + the permutation group representation for the species and `f` is a + ``dict`` mapping each element of the domain of `H` to integers in + `\{ 1 \ldots k \}`, representing the set to which the element belongs. + """ + if parent(x) == self: + return x + H, f = x + if Set(H.domain()) != Set(f.keys()): + raise ValueError(f"Keys of {f} do not match with domain of {H}") + if not Set(f.values()).issubset(Set(range(1, self._k + 1))): + raise ValueError(f"Values of {f} must be in the range [1, {self._k}]") + if isinstance(H, PermutationGroup_generic) and isinstance(f, dict): + domain_partition = H.disjoint_direct_product_decomposition() + from collections import Counter + C = Counter([self._atomic_basis(self._project(H, f, part)) for part in domain_partition]) + return self._from_dict({self._indices(dict(C)): 1}) + raise ValueError("unable to convert {x} into {self}") + + def __getitem__(self, x): + r""" + Calls _element_constructor_ on x. + + TESTS:: + + sage: P = PolynomialMolecularDecomposition(1) + sage: At1 = MultivariateAtomicSpecies(1) + sage: At1((SymmetricGroup(1), {1: 1})).rename("X") + sage: X = (SymmetricGroup(2).young_subgroup([1, 1]), {1: 1, 2: 1}) + sage: P[X] + X^2 + sage: P2=PolynomialMolecularDecomposition(2) + sage: At2=MultivariateAtomicSpecies(2) + sage: At2((SymmetricGroup(1), {1: 1})).rename("X") + sage: At2((SymmetricGroup(1), {1: 2})).rename("Y") + sage: XY = (SymmetricGroup(2).young_subgroup([1, 1]), {1: 1, 2: 2}) + sage: P2[XY] + Y*X + """ + return self._element_constructor_(x) + + @cached_method + def one_basis(self): + r""" + Returns SymmetricGroup(0), which indexes the one of this algebra, + as per :meth:`AlgebrasWithBasis.ParentMethods.one_basis`. + + EXAMPLES:: + + sage: P = PolynomialMolecularDecomposition(1) + sage: P.one_basis() + {[]: [0]} + sage: P2 = PolynomialMolecularDecomposition(2) + sage: P2.one_basis() + {[]: [0, 0]} + """ + return self._indices({self._atomic_basis(tuple([SymmetricGroup(0), dict()])): 1}) + + @cached_method + def an_element(self): + """ + Return an element of ``self``. + + sage: P=PolynomialMolecularDecomposition(1) + sage: P.an_element() + {[]: [0]} + sage: P2=PolynomialMolecularDecomposition(2) + sage: P2.an_element() + {[]: [0, 0]} + """ + return self.one() + + def product_on_basis(self, H, K): + r""" + Return the product of the basis elements indexed by `H` and `K`. + + EXAMPLES:: + + sage: P=PolynomialMolecularDecomposition(1) + sage: d2 = {e: 1 for e in range(1, 3)} + sage: d3 = {e: 1 for e in range(1, 4)} + sage: L1 = [(H, d3) for H in SymmetricGroup(3).conjugacy_classes_subgroups()] + sage: L2 = [(H, d2) for H in SymmetricGroup(2).conjugacy_classes_subgroups()] + sage: matrix([[P(x) * P(y) for x in L1] for y in L2]) + [ {[()]: [1]}^5 {[()]: [1]}^3*{[(1,2)]: [2]} {[(1,2,3)]: [3]}*{[()]: [1]}^2 {[(1,2,3), (2,3)]: [3]}*{[()]: [1]}^2] + [ {[()]: [1]}^3*{[(1,2)]: [2]} {[()]: [1]}*{[(1,2)]: [2]}^2 {[(1,2,3)]: [3]}*{[(1,2)]: [2]} {[(1,2,3), (2,3)]: [3]}*{[(1,2)]: [2]}] + """ + # Hacky workaround for handling the one of the algebra :( + if H == self.one_basis() and K == self.one_basis(): + return self._from_dict({self.one_basis(): 1}) + elif H == self.one_basis(): + return self._from_dict({K: 1}) + elif K == self.one_basis(): + return self._from_dict({H: 1}) + return self._from_dict({H * K: 1}) + + def degree_on_basis(self, m): + r""" + Return the degree of the basis element indexed by ``m`` + in ``self``. + """ + d = m.dict() + return sum(at._tc * p for at, p in d.items()) + + def _repr_(self): + r""" + Return a string representation of ``self``. + + EXAMPLES:: + + sage: P = PolynomialMolecularDecomposition(1) + sage: P + Ring of 1-variate virtual species + sage: P2 = PolynomialMolecularDecomposition(2) + sage: P2 + Ring of 2-variate virtual species + """ + return f"Ring of {self._k}-variate virtual species" From ff1f3f3e2b6762cc28567ef9c384ce886593bc6d Mon Sep 17 00:00:00 2001 From: Newtech66 Date: Mon, 29 Jul 2024 23:08:50 +0530 Subject: [PATCH 082/537] grab changes from other PR --- src/sage/rings/burnside.py | 33 ++++++++++++--------------------- 1 file changed, 12 insertions(+), 21 deletions(-) diff --git a/src/sage/rings/burnside.py b/src/sage/rings/burnside.py index b9467b90324..43a67c82e65 100644 --- a/src/sage/rings/burnside.py +++ b/src/sage/rings/burnside.py @@ -11,6 +11,7 @@ GAP_FAIL = libgap.eval('fail') + def _is_conjugate(G, H1, H2): r""" Test if ``H1`` and ``H2`` are conjugate subgroups in ``G``. @@ -26,13 +27,14 @@ def _is_conjugate(G, H1, H2): """ return GAP_FAIL != libgap.RepresentativeAction(G, H1, H2) + class ElementCache(): def __init__(self): r""" Class for caching elements. """ self._cache = dict() - + def _cache_get(self, elm): r""" Return the cached element, or create it @@ -54,6 +56,7 @@ def _cache_get(self, elm): self._cache[key] = [elm] return elm + class ConjugacyClassOfSubgroups(Element): def __init__(self, parent, C): r""" @@ -108,7 +111,7 @@ def _element_key(self): """ # should this be a lazy attribute instead? return tuple([self._C.order(), self._C.degree()]) - + def _repr_(self): r""" Return a string representation of ``self``. @@ -189,6 +192,7 @@ def __lt__(self, other): """ return self != other and self <= other + class ConjugacyClassesOfSubgroups(Parent, ElementCache): def __init__(self, G): r""" @@ -265,7 +269,6 @@ def _element_constructor_(self, x): raise ValueError(f"unable to convert {x} into {self}: not a subgroup of {self._G}") raise ValueError("unable to convert {x} into {self}") - def __iter__(self): r""" Return iterator over conjugacy classes of subgroups of the group. @@ -311,6 +314,7 @@ def _repr_(self): Element = ConjugacyClassOfSubgroups + class BurnsideRing(CombinatorialFreeModule): def __init__(self, G, base_ring=ZZ): r""" @@ -328,27 +332,14 @@ def __init__(self, G, base_ring=ZZ): sage: X = Subsets(6, 2) sage: b = B.construct_from_action(lambda g, x: X([g(e) for e in x]), X) sage: B.basis().keys()._cache - {(48, - 6): [(Subgroup generated by [(3,5,4,6), (1,2)(4,5,6)] of (Symmetric group of order 6! as a permutation group), - [(1,2)(4,5,6), (3,5,4,6)])], - (720, - 6): [(Subgroup generated by [(1,2,3,4,5,6), (1,2)] of (Symmetric group of order 6! as a permutation group), - 1)]} + {(48, 6): [[(1,2)(4,5,6), (3,5,4,6)]], (720, 6): [1]} sage: b^2 B[[(4,6,5), (4,6)]] + B[[(5,6), (3,4)(5,6), (1,2)(5,6)]] + B[[(1,2)(4,5,6), (3,5,4,6)]] sage: B.basis().keys()._cache - {(6, - 6): [(Subgroup generated by [(4,6), (4,6,5)] of (Symmetric group of order 6! as a permutation group), - [(4,6,5), (4,6)])], - (8, - 6): [(Subgroup generated by [(5,6), (1,2)(5,6), (3,4)(5,6)] of (Symmetric group of order 6! as a permutation group), - [(5,6), (3,4)(5,6), (1,2)(5,6)])], - (48, - 6): [(Subgroup generated by [(3,5,4,6), (1,2)(4,5,6)] of (Symmetric group of order 6! as a permutation group), - [(1,2)(4,5,6), (3,5,4,6)])], - (720, - 6): [(Subgroup generated by [(1,2,3,4,5,6), (1,2)] of (Symmetric group of order 6! as a permutation group), - 1)]} + {(6, 6): [[(4,6,5), (4,6)]], + (8, 6): [[(5,6), (3,4)(5,6), (1,2)(5,6)]], + (48, 6): [[(1,2)(4,5,6), (3,5,4,6)]], + (720, 6): [1]} sage: G = SymmetricGroup(4) sage: B = BurnsideRing(G) From 2ec5329523008289d3a08d2c72197bab4a8289d5 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Tue, 30 Jul 2024 12:04:21 +0530 Subject: [PATCH 083/537] Modified basis() method --- src/sage/matroids/chow_ring.py | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/src/sage/matroids/chow_ring.py b/src/sage/matroids/chow_ring.py index 304692bfbab..6a05c45ac3f 100644 --- a/src/sage/matroids/chow_ring.py +++ b/src/sage/matroids/chow_ring.py @@ -21,7 +21,7 @@ from sage.categories.graded_algebras_with_basis import GradedAlgebrasWithBasis from sage.rings.polynomial.multi_polynomial_sequence import PolynomialSequence from sage.sets.set import Set -from sage.combinat.posets.posets import Poset +from functools import cmp_to_key class ChowRing(QuotientRing_nc): @@ -96,8 +96,15 @@ def basis(self): for X in self._matroid.flats(i)] flats.append(Set([])) maximum_rank = max([self._matroid.rank(F) for F in flats]) - func = lambda A,B: A.issubset(B) - flats = Poset((flats, func), cover_relations=True).directed_subsets('down') #DEBUG + flats_gen = self._ideal.flats_generator() + def func(A, B): + if A.issubset(B): + return 1 + elif B.issubset(A): + return -1 + else: + return 0 + flats = sorted(flats, key=cmp_to_key(func)) monomial_basis = [] if self._augmented: if self._presentation=='fy': @@ -106,14 +113,15 @@ def basis(self): for j in range(len(flats)): if j == 0: if i > self._matroid.rank(flats[0]): - term *= self._flats_generator[flats[j]]**(0) + term *= flats_gen[flats[j]]**(0) else: - term *= self._flats_generator[flats[j]]**(i + 1) + term *= flats_gen[flats[j]]**(i + 1) else: if i >= (self._matroid.rank(flats[j]) - self._matroid.rank(flats[j-1])): - term *= self._flats_generator[flats[j]]**(0) + if (flats[j] in list(flats_gen)): + term *= flats_gen[flats[j]]**(0) else: - term *= self._flats_generator[flats[j]]**(i + 1) + term *= flats_gen[flats[j]]**(i + 1) monomial_basis.append(term) elif self._presentation=='atom-free': @@ -123,9 +131,9 @@ def basis(self): for j in range(1, len(flats) - 1): if i >= (self._matroid.rank(flats[j-1]) - self._matroid.rank(flats[j])): pow.append((j , i)) - if sum(pow) == self._matroid.rank(flats[0]): + if sum([p[1] for p in pow]) == self._matroid.rank(flats[0]): for p in pow: - term *= self._flats_generator[flats[p[0]]]**(p[1]) + term *= flats_gen[flats[p[0]]]**(p[1]) monomial_basis.append(term) @@ -134,13 +142,14 @@ def basis(self): term = self._ideal.ring().one() for j in range(len(flats)): if i > (self._matroid.rank(flats[j]) - self._matroid.rank(flats[j-1]) - 1): - term *= self._flats_generator[flats[j]]**(0) + if flats[j] in list(flats_gen): + term *= flats_gen[flats[j]]**(0) else: - term *= self._flats_generator[flats[j]]**(i + 1) + term *= flats_gen[flats[j]]**(i + 1) monomial_basis.append(term) - m_basis = PolynomialSequence([monomial_basis], self._ideal.ring()) + m_basis = PolynomialSequence(self._ideal.ring(), monomial_basis) return m_basis From d9271fd17448a99d035ec0fe1b19d2b759081c2d Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Tue, 30 Jul 2024 12:04:46 +0530 Subject: [PATCH 084/537] Debugged AugmentedChowRingIdeal_atom_free.__init__() --- src/sage/matroids/chow_ring_ideal.py | 29 +++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/src/sage/matroids/chow_ring_ideal.py b/src/sage/matroids/chow_ring_ideal.py index 6520474ab75..686b11bd5eb 100644 --- a/src/sage/matroids/chow_ring_ideal.py +++ b/src/sage/matroids/chow_ring_ideal.py @@ -191,7 +191,7 @@ def __init__(self, M, R): self._flats = [X for i in range(1, self._matroid.rank()) for X in self._matroid.flats(i)] E = list(self._matroid.groundset()) - self.flats_generator = dict() + self._flats_generator = dict() try: names_groundset = ['A{}'.format(''.join(str(x))) for x in E] names_flats = ['B{}'.format(''.join(str(x) for x in sorted(F, key=cmp_elements_key))) for F in self._flats] @@ -325,7 +325,9 @@ def __init__(self, M, R): poly_ring = PolynomialRing(R, names) #self.ring except ValueError: # variables are not proper names poly_ring = PolynomialRing(R, 'A', len(self._flats)) - + gens = poly_ring.gens() + self._flats_generator = dict() + self._flats_generator = dict(zip(self._flats, gens)) MPolynomialIdeal.__init__(self, poly_ring, self._gens_constructor(poly_ring)) @@ -337,19 +339,20 @@ def _gens_constructor(self, poly_ring): for x in F: flats_containing[x].append(F) for F in self._flats: - for x in E: - if F not in flats_containing[x]: - Q.append(self._flats_generator[x]*self._flats_generator[F]) + for G in self._flats: + if not (G > F or F > G): + Q.append(self._flats_generator[F]*self._flats_generator[G]) + for x in E: term = poly_ring.zero() - for G in flats_containing[x]: - term += self._flats_generator[G] + for H in flats_containing[x]: + term += self._flats_generator[H] + Q.append(term**2) + + if F not in flats_containing[x]: + term = poly_ring.zero() + for H in flats_containing[x]: + term += self._flats_generator[H] Q.append(self._flats_generator[F]*term) - - for i in E: - term = poly_ring.zero() - for F in flats_containing[i]: - term += self._flats_generator[F] - Q.append(term**2) return Q From 5eacfb05f728c055431daca4c811fe97ecefaadc Mon Sep 17 00:00:00 2001 From: Newtech66 Date: Wed, 31 Jul 2024 12:16:30 +0530 Subject: [PATCH 085/537] Removed dependency on burnside.py (for the time being) --- src/sage/rings/burnside.py | 526 ------------------------------------- src/sage/rings/species.py | 132 ++++++---- 2 files changed, 85 insertions(+), 573 deletions(-) delete mode 100644 src/sage/rings/burnside.py diff --git a/src/sage/rings/burnside.py b/src/sage/rings/burnside.py deleted file mode 100644 index 43a67c82e65..00000000000 --- a/src/sage/rings/burnside.py +++ /dev/null @@ -1,526 +0,0 @@ -from sage.misc.cachefunc import cached_method -from sage.structure.parent import Parent -from sage.structure.element import Element -from sage.structure.element import parent -from sage.rings.integer_ring import ZZ -from sage.categories.finite_enumerated_sets import FiniteEnumeratedSets -from sage.categories.algebras import Algebras -from sage.groups.perm_gps.permgroup import PermutationGroup, PermutationGroup_generic -from sage.libs.gap.libgap import libgap -from sage.combinat.free_module import CombinatorialFreeModule - -GAP_FAIL = libgap.eval('fail') - - -def _is_conjugate(G, H1, H2): - r""" - Test if ``H1`` and ``H2`` are conjugate subgroups in ``G``. - - EXAMPLES:: - - sage: G = SymmetricGroup(3) - sage: H1 = PermutationGroup([(1,2)]) - sage: H2 = PermutationGroup([(2,3)]) - sage: from sage.rings.burnside import _is_conjugate - sage: _is_conjugate(G, H1, H2) - True - """ - return GAP_FAIL != libgap.RepresentativeAction(G, H1, H2) - - -class ElementCache(): - def __init__(self): - r""" - Class for caching elements. - """ - self._cache = dict() - - def _cache_get(self, elm): - r""" - Return the cached element, or create it - if it doesn't exist. - - ``elm`` must implement the following methods: - ``_element_key`` - hashable type for dict lookup. - ``__eq__`` - to compare two elements. - """ - key = elm._element_key() - if key in self._cache: - lookup = self._cache[key] - for other_elm in lookup: - if elm == other_elm: - return other_elm - else: - lookup.append(elm) - else: - self._cache[key] = [elm] - return elm - - -class ConjugacyClassOfSubgroups(Element): - def __init__(self, parent, C): - r""" - Initialize the conjugacy class of ``C``. - - TESTS:: - - sage: G = SymmetricGroup(4) - sage: B = BurnsideRing(G) - sage: Z4 = CyclicPermutationGroup(4) - sage: TestSuite(B(Z4)).run() - """ - Element.__init__(self, parent) - self._C = C - - def subgroup_of(self): - r""" - Return the group which this conjugacy class of subgroups - belongs to. - - TESTS:: - - sage: G = SymmetricGroup(3) - sage: from sage.rings.burnside import ConjugacyClassesOfSubgroups - sage: C = ConjugacyClassesOfSubgroups(G) - sage: Z3 = CyclicPermutationGroup(3) - sage: CZ3 = C(Z3) - sage: CZ3.subgroup_of() - Symmetric group of order 3! as a permutation group - """ - return self.parent()._G - - def __hash__(self): - r""" - Return the hash of the representative of the conjugacy class. - - TESTS:: - - sage: G = SymmetricGroup(3) - sage: B = BurnsideRing(G) - sage: H1 = B(PermutationGroup([(1,2)])) - sage: H2 = B(PermutationGroup([(2,3)])) - sage: hash(H1) == hash(H2) - True - """ - return hash(self._C) - - @cached_method - def _element_key(self): - r""" - Return tuple of group invariants associated with H. - """ - # should this be a lazy attribute instead? - return tuple([self._C.order(), self._C.degree()]) - - def _repr_(self): - r""" - Return a string representation of ``self``. - - TESTS:: - - sage: G = SymmetricGroup(3) - sage: from sage.rings.burnside import ConjugacyClassesOfSubgroups - sage: C = ConjugacyClassesOfSubgroups(G) - sage: Z3 = CyclicPermutationGroup(3) - sage: CZ3 = C(Z3) - sage: CZ3 - [(1,2,3)] - """ - return repr(self._C.gens_small()) - - def __le__(self, other): - r""" - Return if this element is less than or equal to ``other``. - - ``self`` is less or equal to ``other`` if it is conjugate to - a subgroup of ``other`` in the parent group. - - EXAMPLES: - - We recreate the poset of conjugacy classes of subgroups of - `S_4`:: - - sage: G = SymmetricGroup(4) - sage: B = BurnsideRing(G) - sage: P = Poset([B.basis(), lambda b, c: b <= c]) - sage: len(P.cover_relations()) - 17 - """ - return (isinstance(other, ConjugacyClassOfSubgroups) - and (GAP_FAIL != libgap.ContainedConjugates(self.subgroup_of(), - other._C, - self._C, - True))) - - def __eq__(self, other): - r""" - Return if this element is equal to ``other``. - - Two elements compare equal if they are conjugate subgroups in the parent group. - - TESTS:: - - sage: G = SymmetricGroup(4) - sage: B = BurnsideRing(G) - sage: H1 = PermutationGroup([(1,2)]) - sage: H2 = PermutationGroup([(2,3)]) - sage: B[H1] == B[H2] - True - """ - return (isinstance(other, ConjugacyClassOfSubgroups) - and _is_conjugate(self.subgroup_of(), self._C, other._C)) - - def __lt__(self, other): - r""" - Return if this element is less than ``other``. - - TESTS:: - - sage: G = SymmetricGroup(4) - sage: B = BurnsideRing(G) - sage: H1 = PermutationGroup([(1,2)]) - sage: H2 = PermutationGroup([(2,3)]) - sage: H3 = PermutationGroup([(1,2),(3,4)]) - sage: B[H1] < B[H2] - False - sage: B[H1] == B[H2] - True - sage: B[H1] < B[H3] - True - sage: B[H2] < B[H3] - True - """ - return self != other and self <= other - - -class ConjugacyClassesOfSubgroups(Parent, ElementCache): - def __init__(self, G): - r""" - Initialize the set of conjugacy classes of ``G``. - - INPUT: - - ``G`` -- a group. - - TESTS:: - - sage: from sage.rings.burnside import ConjugacyClassesOfSubgroups - sage: G = CyclicPermutationGroup(4) - sage: C = ConjugacyClassesOfSubgroups(G) - sage: TestSuite(C).run() - """ - self._G = G - Parent.__init__(self, category=FiniteEnumeratedSets()) - ElementCache.__init__(self) - - def __eq__(self, other): - r""" - Return if ``self`` is equal to ``other``. - - TESTS:: - - sage: from sage.rings.burnside import ConjugacyClassesOfSubgroups - sage: Z4 = CyclicPermutationGroup(4) - sage: D4 = DiCyclicGroup(4) - sage: C1 = ConjugacyClassesOfSubgroups(Z4) - sage: C2 = ConjugacyClassesOfSubgroups(D4) - sage: C1 == C2 - False - """ - if not isinstance(other, ConjugacyClassesOfSubgroups): - return False - return self._G == other._G - - def __hash__(self): - r""" - Return the hash of the underlying group. - - TESTS:: - - sage: from sage.rings.burnside import ConjugacyClassesOfSubgroups - sage: Z4 = CyclicPermutationGroup(4) - sage: D4 = DiCyclicGroup(4) - sage: C1 = ConjugacyClassesOfSubgroups(Z4) - sage: C2 = ConjugacyClassesOfSubgroups(D4) - sage: hash(C1) == hash(C2) - False - """ - return hash(self._G) - - def _element_constructor_(self, x): - r""" - Construct the conjugacy class of subgroups containing ``x``. - - TESTS:: - - sage: from sage.rings.burnside import ConjugacyClassesOfSubgroups - sage: G = SymmetricGroup(4) - sage: C = ConjugacyClassesOfSubgroups(G) - sage: Z4 = CyclicPermutationGroup(4) - sage: C(Z4) - [(1,2,3,4)] - """ - if parent(x) == self: - return x - if isinstance(x, PermutationGroup_generic): - if x.is_subgroup(self._G): - elm = self.element_class(self, self._G.subgroup(x.gens())) - return self._cache_get(elm) - raise ValueError(f"unable to convert {x} into {self}: not a subgroup of {self._G}") - raise ValueError("unable to convert {x} into {self}") - - def __iter__(self): - r""" - Return iterator over conjugacy classes of subgroups of the group. - - TESTS:: - - sage: G = SymmetricGroup(3) - sage: B = BurnsideRing(G) - sage: [g for g in B._indices] - [[()], [(1,2)], [(1,2,3)], 1] - """ - return iter(self(H) for H in self._G.conjugacy_classes_subgroups()) - - def __contains__(self, H): - r""" - Return if ``H`` is a subgroup of the group. - - TESTS:: - - sage: G = SymmetricGroup(4) - sage: B = BurnsideRing(G) - sage: Z4 = CyclicPermutationGroup(4) - sage: Z4 in B._indices - True - """ - if parent(H) == self: - return True - return (isinstance(H, PermutationGroup_generic) - and H.is_subgroup(self._G)) - - def _repr_(self): - r""" - Return a string representation of ``self``. - - TESTS:: - - sage: G = SymmetricGroup(4) - sage: B = BurnsideRing(G) - sage: B._indices - Conjugacy classes of subgroups of Symmetric group of order 4! as a permutation group - """ - return "Conjugacy classes of subgroups of " + repr(self._G) - - Element = ConjugacyClassOfSubgroups - - -class BurnsideRing(CombinatorialFreeModule): - def __init__(self, G, base_ring=ZZ): - r""" - The Burnside ring of the group ``G``. - - INPUT: - - ``G`` -- a group. - ``base_ring`` -- the ring of coefficients. Default value is ``ZZ``. - - EXAMPLES:: - - sage: G = SymmetricGroup(6) - sage: B = BurnsideRing(G) - sage: X = Subsets(6, 2) - sage: b = B.construct_from_action(lambda g, x: X([g(e) for e in x]), X) - sage: B.basis().keys()._cache - {(48, 6): [[(1,2)(4,5,6), (3,5,4,6)]], (720, 6): [1]} - sage: b^2 - B[[(4,6,5), (4,6)]] + B[[(5,6), (3,4)(5,6), (1,2)(5,6)]] + B[[(1,2)(4,5,6), (3,5,4,6)]] - sage: B.basis().keys()._cache - {(6, 6): [[(4,6,5), (4,6)]], - (8, 6): [[(5,6), (3,4)(5,6), (1,2)(5,6)]], - (48, 6): [[(1,2)(4,5,6), (3,5,4,6)]], - (720, 6): [1]} - - sage: G = SymmetricGroup(4) - sage: B = BurnsideRing(G) - sage: X = Subsets(4, 2) - sage: b = B.construct_from_action(lambda g, x: X([g(e) for e in x]), X) - sage: b.tensor(b) - B[[(3,4), (1,2)(3,4)]] # B[[(3,4), (1,2)(3,4)]] - sage: (b.tensor(b))^2 - B[[()]] # B[[()]] + 2*B[[()]] # B[[(3,4), (1,2)(3,4)]] + 2*B[[(3,4), (1,2)(3,4)]] # B[[()]] + 4*B[[(3,4), (1,2)(3,4)]] # B[[(3,4), (1,2)(3,4)]] - - TESTS:: - - sage: G = SymmetricGroup(4) - sage: B = BurnsideRing(G) - sage: TestSuite(B).run() - """ - self._G = G - basis_keys = ConjugacyClassesOfSubgroups(G) - category = Algebras(base_ring).Commutative().WithBasis() - CombinatorialFreeModule.__init__(self, base_ring, basis_keys, - category=category, prefix="B") - self._indices(G).rename("1") - - def __getitem__(self, H): - r""" - Return the basis element indexed by ``H``. - - ``H`` must be a subgroup of the group. - - EXAMPLES:: - - sage: G = SymmetricGroup(4) - sage: B = BurnsideRing(G) - sage: Z4 = CyclicPermutationGroup(4) - sage: B[Z4] - B[[(1,2,3,4)]] - """ - return self._from_dict({self._indices(H): 1}) - - def construct_from_action(self, action, domain): - r""" - Construct an element of the Burnside ring from a group action. - - INPUT: - - - ``action`` - an action on ``domain`` - - ``domain`` - a finite set - - EXAMPLES:: - - sage: G = SymmetricGroup(4) - sage: B = BurnsideRing(G) - - We create a group action of `S_4` on two-element subsets:: - - sage: X = Subsets(4, 2) - sage: a = lambda g, x: X([g(e) for e in x]) - sage: B.construct_from_action(a, X) - B[[(3,4), (1,2)(3,4)]] - - Next, we create a group action of `S_4` on itself via conjugation:: - - sage: X = G - sage: a = lambda g, x: g*x*g.inverse() - sage: B.construct_from_action(a, X) - B[[(3,4), (1,3)(2,4), (1,4)(2,3)]] + B[[(2,4,3)]] + B[[(3,4), (1,2)(3,4)]] + B[[(1,2,3,4)]] + B[1] - - TESTS:: - - sage: G = SymmetricGroup(4) - sage: B = BurnsideRing(G) - sage: [b.support()[0]._C.order() for b in B.gens()] - [1, 2, 2, 3, 4, 4, 4, 6, 8, 12, 24] - sage: sorted((o, len(l)) for o, l in B._indices._cache.items()) - [((1, 4), 1), - ((2, 4), 2), - ((3, 4), 1), - ((4, 4), 3), - ((6, 4), 1), - ((8, 4), 1), - ((12, 4), 1), - ((24, 4), 1)] - - sage: G = SymmetricGroup(4) - sage: B = BurnsideRing(G) - sage: B(-3) - -3*B[1] - """ - def find_stabilizer(action, pnt): - stabilizer = [] - for g in self._G: - if action(g, pnt) == pnt: - stabilizer.append(g) - H = self._G.subgroup(stabilizer) - gens = H.gens_small() - return self._G.subgroup(gens) - - H = PermutationGroup(self._G.gens(), action=action, domain=domain) - # decompose H into orbits - orbit_list = H.orbits() - # find the stabilizer subgroups - stabilizer_list = [find_stabilizer(action, orbit[0]) for orbit in orbit_list] - # normalize each summand and collect terms - from collections import Counter - C = Counter([self._indices(stabilizer) for stabilizer in stabilizer_list]) - return self._from_dict(dict(C)) - - @cached_method - def one_basis(self): - r""" - Returns the underlying group, which indexes the one of this algebra, - as per :meth:`AlgebrasWithBasis.ParentMethods.one_basis`. - - EXAMPLES:: - - sage: G = DiCyclicGroup(4) - sage: B = BurnsideRing(G) - sage: B.one_basis() - 1 - """ - return self._indices(self._G) - - def product_on_basis(self, H, K): - r""" - Return the product of the basis elements indexed by ``H`` and ``K``. - - For the symmetric group, this is also known as the Hadamard - or tensor product of group actions. - - EXAMPLES:: - - sage: G = SymmetricGroup(3) - sage: B = BurnsideRing(G) - sage: matrix([[b * c for b in B.gens()] for c in B.gens()]) - [ 6*B[[()]] 3*B[[()]] 2*B[[()]] B[[()]]] - [ 3*B[[()]] B[[()]] + B[[(1,2)]] B[[()]] B[[(1,2)]]] - [ 2*B[[()]] B[[()]] 2*B[[(1,2,3)]] B[[(1,2,3)]]] - [ B[[()]] B[[(1,2)]] B[[(1,2,3)]] B[1]] - - TESTS:: - - sage: G = SymmetricGroup(3) - sage: B = BurnsideRing(G) - sage: Z3 = CyclicPermutationGroup(3) - sage: Z2 = CyclicPermutationGroup(2) - sage: from sage.rings.burnside import ConjugacyClassesOfSubgroups - sage: C = ConjugacyClassesOfSubgroups(G) - sage: B.product_on_basis(C(Z2), C(Z3)) - B[[()]] - """ - g_reps = [rep for rep, size in libgap.DoubleCosetRepsAndSizes(self._G, H._C, K._C)] - from collections import Counter - C = Counter() - for g in g_reps: - g_sup_K = libgap.ConjugateSubgroup(K._C, g) - P = self._G.subgroup(gap_group=libgap.Intersection(H._C, g_sup_K)) - C[self._indices(P)] += 1 - return self._from_dict(dict(C)) - - def group(self): - r""" - Return the underlying group. - - EXAMPLES:: - - sage: G = DiCyclicGroup(4) - sage: B = BurnsideRing(G) - sage: B.group() - Dicyclic group of order 16 as a permutation group - """ - return self._G - - def _repr_(self): - r""" - Return a string representation of ``self``. - - EXAMPLES:: - - sage: G = SymmetricGroup(4) - sage: B = BurnsideRing(G) - sage: B - Burnside ring of Symmetric group of order 4! as a permutation group - """ - return "Burnside ring of " + repr(self._G) diff --git a/src/sage/rings/species.py b/src/sage/rings/species.py index e94d0646566..167f17f7c2b 100644 --- a/src/sage/rings/species.py +++ b/src/sage/rings/species.py @@ -2,6 +2,7 @@ from sage.misc.cachefunc import cached_method from sage.monoids.indexed_free_monoid import IndexedFreeAbelianMonoid from sage.structure.parent import Parent +from sage.structure.element import Element from sage.structure.element import parent from sage.structure.unique_representation import UniqueRepresentation from sage.rings.integer_ring import ZZ @@ -12,18 +13,63 @@ from sage.libs.gap.libgap import libgap from sage.combinat.free_module import CombinatorialFreeModule from sage.sets.set import Set -from sage.rings.burnside import ConjugacyClassOfSubgroups, ElementCache, _is_conjugate GAP_FAIL = libgap.eval('fail') -class ConjugacyClassOfDirectlyIndecomposableSubgroups(ConjugacyClassOfSubgroups): - def __init__(self, parent, C): +def _is_conjugate(G, H1, H2): + r""" + Test if ``H1`` and ``H2`` are conjugate subgroups in ``G``. + + EXAMPLES:: + + sage: G = SymmetricGroup(3) + sage: H1 = PermutationGroup([(1,2)]) + sage: H2 = PermutationGroup([(2,3)]) + sage: from sage.rings.burnside import _is_conjugate + sage: _is_conjugate(G, H1, H2) + True + """ + return GAP_FAIL != libgap.RepresentativeAction(G, H1, H2) + + +class ElementCache(): + def __init__(self): + r""" + Class for caching elements. + """ + self._cache = dict() + + def _cache_get(self, elm): + r""" + Return the cached element, or create it + if it doesn't exist. + + ``elm`` must implement the following methods: + ``_element_key`` - hashable type for dict lookup. + ``__eq__`` - to compare two elements. + """ + key = elm._element_key() + if key in self._cache: + lookup = self._cache[key] + for other_elm in lookup: + if elm == other_elm: + return other_elm + else: + lookup.append(elm) + else: + self._cache[key] = [elm] + return elm + + +class ConjugacyClassOfDirectlyIndecomposableSubgroups(): + def __init__(self, C, ambient_group): r""" A conjugacy class of directly indecomposable subgroups. """ if len(C.disjoint_direct_product_decomposition()) > 1: raise ValueError(f"{C} is not directly indecomposable") - ConjugacyClassOfSubgroups.__init__(self, parent, C) + self._C = self._normalize(C) + self._ambient_group = ambient_group @cached_method def subgroup_of(self): @@ -31,7 +77,7 @@ def subgroup_of(self): Return the group which this conjugacy class of directly indecomposable subgroups belongs to. """ - return SymmetricGroup(self._C.degree()) + return self._ambient_group def _repr_(self): r""" @@ -39,46 +85,32 @@ def _repr_(self): """ return "{" + f"{self._C.degree()}, {self._C.gens_small()}" + "}" - def __le__(self, other): - r""" - Return if this element is less than or equal to ``other``. - - ``self`` is less or equal to ``other`` if it is conjugate to - a subgroup of ``other`` in the parent group of larger degree. - """ - # If selfdeg > otherdeg, return False - # then selfdeg <= otherdeg - return (isinstance(other, ConjugacyClassOfSubgroups) - and self._C.degree() <= other._C.degree() - and (self._C.degree() < other._C.degree() or - (GAP_FAIL != libgap.ContainedConjugates(self.subgroup_of(), - other._C, self._C, True)))) - def __eq__(self, other): r""" - Return if this element is equal to ``other``. - - Two elements compare equal if they are conjugate subgroups in the parent group. - - TESTS:: + Return if ``self`` is equal to ``other``. - sage: G = SymmetricGroup(4) - sage: B = BurnsideRing(G) - sage: H1 = PermutationGroup([(1,2)]) - sage: H2 = PermutationGroup([(2,3)]) - sage: B[H1] == B[H2] - True + Two directly indecomposable subgroups belong to the same conjugacy + class if they have the same ambient group and are conjugate within it. """ - return (isinstance(other, ConjugacyClassOfSubgroups) - and self._C.degree() == other._C.degree() and - _is_conjugate(self.subgroup_of(), self._C, other._C)) + # No __le__ method because does it really make sense to have one here? + return (isinstance(other, ConjugacyClassOfDirectlyIndecomposableSubgroups) + and self._ambient_group == other._ambient_group + and _is_conjugate(self._ambient_group, self._C, self._other)) -class AtomicSpecies(ConjugacyClassOfDirectlyIndecomposableSubgroups): - def __init__(self, parent, C, multicardinality): +class AtomicSpeciesElement(Element): + def __init__(self, parent, C, mapping): r""" - An atomic species centered on a given multicardinality: a directly - indecomposable subgroup paired with an integer vector. + An atomic species. + + ``C`` - an instance of + ``mapping`` - a dictionary whose keys are the elements + of the domain of ``C`` and values are the "variable" to which an element + is assigned. The values must be in the range `[1, k]`. """ + # Notice that a molecular species (and therefore an atomic species) + # must be centered on a multicardinality, otherwise it wouldn't be + # molecular. So it is kind of redundant to say "atomic species + # centered on a given multicardinality." total_cardinality = sum(multicardinality) if C.degree() != sum(multicardinality): raise ValueError(f"Degree of {C} (= {C.degree()}) must equal the total cardinality {total_cardinality}") @@ -95,7 +127,7 @@ def subgroup_of(self): Return the group which the underlying permutation group of this atomic species belongs to. """ - return SymmetricGroup(self._tc).young_subgroup(self._mc) + return self._dic._ambient_group def __hash__(self): r""" @@ -125,7 +157,7 @@ def _repr_(self): """ return "{" + f"{self._C.gens_small()}: {self._mc}" + "}" -class MultivariateAtomicSpecies(UniqueRepresentation, Parent, ElementCache): +class AtomicSpecies(UniqueRepresentation, Parent, ElementCache): def __init__(self, k): r""" Infinite set of `k`-variate atomic species graded by @@ -149,9 +181,9 @@ def __eq__(self, other): TESTS:: - sage: At1 = MultivariateAtomicSpecies(1); At1 - sage: At2 = MultivariateAtomicSpecies(2); At2 - sage: At1_2 = MultivariateAtomicSpecies(1); At1_2 + sage: At1 = AtomicSpecies(1); At1 + sage: At2 = AtomicSpecies(2); At2 + sage: At1_2 = AtomicSpecies(1); At1_2 sage: At1 is At1_2 True sage: At1 is At2 @@ -246,12 +278,16 @@ def _repr_(self): """ return f"Infinite set of {self._k}-variate atomic species" - Element = AtomicSpecies + Element = AtomicSpeciesElement -class PolynomialMolecularDecomposition(CombinatorialFreeModule): +class PolynomialSpeciesElement(CombinatorialFreeModule.Element): + def __init__(self): + pass + +class PolynomialSpecies(CombinatorialFreeModule): def __init__(self, k, base_ring=ZZ): r""" - Ring of `k`-variate virtual species. + Ring of `k`-variate polynomial (virtual) species. TESTS:: @@ -261,7 +297,7 @@ def __init__(self, k, base_ring=ZZ): sage: TestSuite(P2).run() """ # should we pass a category to basis_keys? - basis_keys = IndexedFreeAbelianMonoid(MultivariateAtomicSpecies(k), + basis_keys = IndexedFreeAbelianMonoid(AtomicSpecies(k), prefix='', bracket=False) category = GradedAlgebrasWithBasis(base_ring).Commutative() CombinatorialFreeModule.__init__(self, base_ring, @@ -404,3 +440,5 @@ def _repr_(self): Ring of 2-variate virtual species """ return f"Ring of {self._k}-variate virtual species" + + Element = PolynomialSpeciesElement \ No newline at end of file From 981ed0c7da22fff1f0ee81c1d05f1a8b53a26a52 Mon Sep 17 00:00:00 2001 From: Newtech66 Date: Wed, 31 Jul 2024 18:12:51 +0530 Subject: [PATCH 086/537] Rewrite --- src/sage/rings/all.py | 3 +- src/sage/rings/species.py | 157 +++++++++++++++++++++++--------------- 2 files changed, 95 insertions(+), 65 deletions(-) diff --git a/src/sage/rings/all.py b/src/sage/rings/all.py index cb267281b64..8cad575b8e9 100644 --- a/src/sage/rings/all.py +++ b/src/sage/rings/all.py @@ -168,8 +168,7 @@ lazy_import('sage.rings.burnside', 'BurnsideRing') -lazy_import('sage.rings.species', ['PolynomialMolecularDecomposition', - 'MultivariateAtomicSpecies']) +lazy_import('sage.rings.species', ['PolynomialSpecies', 'AtomicSpecies']) # Register classes in numbers abc from sage.rings import numbers_abc diff --git a/src/sage/rings/species.py b/src/sage/rings/species.py index 167f17f7c2b..3390003ef60 100644 --- a/src/sage/rings/species.py +++ b/src/sage/rings/species.py @@ -1,3 +1,4 @@ +from sage.categories.infinite_enumerated_sets import InfiniteEnumeratedSets from sage.combinat.integer_vector import IntegerVectors from sage.misc.cachefunc import cached_method from sage.monoids.indexed_free_monoid import IndexedFreeAbelianMonoid @@ -25,7 +26,7 @@ def _is_conjugate(G, H1, H2): sage: G = SymmetricGroup(3) sage: H1 = PermutationGroup([(1,2)]) sage: H2 = PermutationGroup([(2,3)]) - sage: from sage.rings.burnside import _is_conjugate + sage: from sage.rings.species import _is_conjugate sage: _is_conjugate(G, H1, H2) True """ @@ -61,14 +62,14 @@ def _cache_get(self, elm): return elm -class ConjugacyClassOfDirectlyIndecomposableSubgroups(): - def __init__(self, C, ambient_group): +class ConjugacyClassOfDirectlyIndecomposableSubgroups(Element): + def __init__(self, parent, C, ambient_group): r""" A conjugacy class of directly indecomposable subgroups. """ - if len(C.disjoint_direct_product_decomposition()) > 1: - raise ValueError(f"{C} is not directly indecomposable") - self._C = self._normalize(C) + Element.__init__(self, parent) + self._C = C + self._smallgen = C.gens_small() self._ambient_group = ambient_group @cached_method @@ -78,12 +79,23 @@ def subgroup_of(self): directly indecomposable subgroups belongs to. """ return self._ambient_group - + + @cached_method + def _element_key(self): + r""" + Return the key for this element. + """ + return tuple([self._C.degree(), self._C.order(), + self._ambient_group]) + + def __hash__(self): + return hash(self._element_key) + def _repr_(self): r""" Return a string representation of ``self``. """ - return "{" + f"{self._C.degree()}, {self._C.gens_small()}" + "}" + return f"{self._smallgen}" def __eq__(self, other): r""" @@ -95,52 +107,66 @@ class if they have the same ambient group and are conjugate within it. # No __le__ method because does it really make sense to have one here? return (isinstance(other, ConjugacyClassOfDirectlyIndecomposableSubgroups) and self._ambient_group == other._ambient_group - and _is_conjugate(self._ambient_group, self._C, self._other)) + and _is_conjugate(self._ambient_group, self._C, other._C)) -class AtomicSpeciesElement(Element): - def __init__(self, parent, C, mapping): +class ConjugacyClassesOfDirectlyIndecomposableSubgroups(UniqueRepresentation, Parent, ElementCache): + + def __init__(self): + r""" + Conjugacy classes of directly indecomposable subgroups. + """ + Parent.__init__(self, category=InfiniteEnumeratedSets()) + ElementCache.__init__(self) + + def _element_constructor_(self, x): r""" - An atomic species. + ``x`` is an element of ``self`` or a tuple `(H, G)` such that + `H` is directly indecomposable and `G` is the ambient group of + `H`. + """ + if parent(x) == self: + return x + H, G = x + # can't handle any normalization before this point because + # of subgroup check + if H.is_subgroup(G): + if len(H.disjoint_direct_product_decomposition()) > 1: + raise ValueError(f"{H} is not directly indecomposable") + # do domain normalization here? + elm = self.element_class(self, H, G) + return self._cache_get(elm) + raise ValueError(f"{H} is not a subgroup of {G}") + + Element = ConjugacyClassOfDirectlyIndecomposableSubgroups - ``C`` - an instance of - ``mapping`` - a dictionary whose keys are the elements - of the domain of ``C`` and values are the "variable" to which an element - is assigned. The values must be in the range `[1, k]`. +class AtomicSpeciesElement(Element): + def __init__(self, parent, dis, mc): + r""" + An atomic species. ``dis`` is an instance of + ConjugacyClassOfDirectlyIndecomposableSubgroups + and ``mc`` is the multicardinality of the atomic + species. """ # Notice that a molecular species (and therefore an atomic species) # must be centered on a multicardinality, otherwise it wouldn't be # molecular. So it is kind of redundant to say "atomic species # centered on a given multicardinality." - total_cardinality = sum(multicardinality) - if C.degree() != sum(multicardinality): - raise ValueError(f"Degree of {C} (= {C.degree()}) must equal the total cardinality {total_cardinality}") - G = SymmetricGroup(total_cardinality).young_subgroup(multicardinality) - if not C.is_subgroup(G): - raise ValueError(f"{C} is not a subgroup of {G}") - ConjugacyClassOfDirectlyIndecomposableSubgroups.__init__(self, parent, C) - self._mc = multicardinality - self._tc = total_cardinality - - @cached_method - def subgroup_of(self): - r""" - Return the group which the underlying permutation group - of this atomic species belongs to. - """ - return self._dic._ambient_group + Element.__init__(self, parent) + self._dis = dis + self._mc = mc def __hash__(self): r""" Return the hash of the atomic species. """ - return hash(tuple([self._C, self._mc, self._tc])) + return hash(tuple([self._dis, self._mc])) @cached_method def _element_key(self): r""" Return a lookup key for ``self``. """ - return tuple([*super()._element_key(), self._mc]) + return tuple([self._dis._C, self._mc]) def __eq__(self, other): r""" @@ -149,13 +175,13 @@ def __eq__(self, other): """ if parent(self) != parent(other): return False - return self._mc == other._mc and super().__eq__(other) + return self._mc == other._mc and self._dis == self._dis def _repr_(self): r""" Return a string representation of ``self``. """ - return "{" + f"{self._C.gens_small()}: {self._mc}" + "}" + return "{" + f"{self._dis}: {self._mc}" + "}" class AtomicSpecies(UniqueRepresentation, Parent, ElementCache): def __init__(self, k): @@ -168,6 +194,7 @@ def __init__(self, k): ElementCache.__init__(self) self._k = k self._grading_set = IntegerVectors(length=k) + self._dis = ConjugacyClassesOfDirectlyIndecomposableSubgroups() def __hash__(self): r""" @@ -203,23 +230,25 @@ def an_element(self): return self._element_constructor_((SymmetricGroup(self._k).young_subgroup([1] * self._k), {e: i for i, e in enumerate(range(1, self._k + 1), 1)})) - def _normalize(self, H, f): + def _normalize(self, H, M): r""" - Normalize `H` and return `H` and the multicardinality. + Normalize the domain of `H` and return `H`, the ambient group, + and the multicardinality. """ # TODO: Complete the documentation. L = [[] for _ in range(self._k)] - for k, v in f.items(): + for k, v in M.items(): L[v - 1].append(k) Lc = sum(L, []) Ls = [len(l) for l in L] + # normalize domain to {1..n} mapping = {v: i for i, v in enumerate(Lc, 1)} normalized_gens = [[tuple(mapping[x] for x in cyc) for cyc in gen.cycle_tuples()] for gen in H.gens_small()] P = PermutationGroup(gens=normalized_gens) # Fix for SymmetricGroup(0) if H.degree() == 0: P = SymmetricGroup(0) - return P, self._grading_set(Ls) + return P, SymmetricGroup(len(Lc)).young_subgroup(Ls), self._grading_set(Ls) def _element_constructor_(self, x): r""" @@ -227,23 +256,23 @@ def _element_constructor_(self, x): INPUT: - - ``x`` - an element of ``self`` or a tuple ``(H, f)`` where `H` is + - ``x`` - an element of ``self`` or a tuple ``(H, M)`` where `H` is the directly indecomposable permutation group representation for the - `k`-variate atomic species and `f` is a ``dict`` mapping each element + `k`-variate atomic species and `M` is a ``dict`` mapping each element of the domain of `H` to integers in `\{ 1 \ldots k \}`, representing the set to which the element belongs. """ if parent(x) == self: return x - H, f = x - if Set(H.domain()) != Set(f.keys()): - raise ValueError(f"Keys of {f} do not match with domain of {H} (= {H.domain()})") - if not Set(f.values()).issubset(Set(range(1, self._k + 1))): - raise ValueError(f"Values of {f} must be in the range [1, {self._k}]") - if isinstance(H, PermutationGroup_generic) and isinstance(f, dict): - elm = self.element_class(self, *self._normalize(H, f)) - return self._cache_get(elm) - raise ValueError("unable to convert {x} into {self}") + H, M = x + if Set(H.domain()) != Set(M.keys()): + raise ValueError(f"Keys of {M} do not match with domain of {H} (= {H.domain()})") + if not Set(M.values()).issubset(Set(range(1, self._k + 1))): + raise ValueError(f"Values of {M} must be in the range [1, {self._k}]") + H_norm, ambient_group, mc = self._normalize(H, M) + dis_elm = self._dis((H_norm, ambient_group)) + elm = self.element_class(self, dis_elm, mc) + return self._cache_get(elm) def __getitem__(self, x): r""" @@ -255,11 +284,12 @@ def __contains__(self, x): r""" Return if ``x`` is in ``self``. """ + # This needs to be improved. if parent(x) == self: return True try: self._element_constructor_(x) - except: + except ValueError: return False return True @@ -269,10 +299,10 @@ def _repr_(self): TESTS:: - sage: At1 = MultivariateAtomicSpecies(1) + sage: At1 = AtomicSpecies(1) sage: At1 Infinite set of 1-variate atomic species - sage: At2 = MultivariateAtomicSpecies(2) + sage: At2 = AtomicSpecies(2) sage: At2 Infinite set of 2-variate atomic species """ @@ -280,10 +310,6 @@ def _repr_(self): Element = AtomicSpeciesElement -class PolynomialSpeciesElement(CombinatorialFreeModule.Element): - def __init__(self): - pass - class PolynomialSpecies(CombinatorialFreeModule): def __init__(self, k, base_ring=ZZ): r""" @@ -303,6 +329,7 @@ def __init__(self, k, base_ring=ZZ): CombinatorialFreeModule.__init__(self, base_ring, basis_keys=basis_keys, category=category, + element_class=self.Element, prefix='', bracket=False) self._k = k self._atomic_basis = basis_keys.indices() @@ -336,9 +363,10 @@ def _element_constructor_(self, x): raise ValueError(f"Values of {f} must be in the range [1, {self._k}]") if isinstance(H, PermutationGroup_generic) and isinstance(f, dict): domain_partition = H.disjoint_direct_product_decomposition() - from collections import Counter - C = Counter([self._atomic_basis(self._project(H, f, part)) for part in domain_partition]) - return self._from_dict({self._indices(dict(C)): 1}) + term = self._indices.one() + for part in domain_partition: + term *= self._indices.gen(self._project(H, f, part)) + return self._from_dict({term: 1}) raise ValueError("unable to convert {x} into {self}") def __getitem__(self, x): @@ -441,4 +469,7 @@ def _repr_(self): """ return f"Ring of {self._k}-variate virtual species" - Element = PolynomialSpeciesElement \ No newline at end of file + class Element(CombinatorialFreeModule.Element): + pass + # def _mul_(self, other): + # return type(self)() \ No newline at end of file From b1b028cac364248e202cd1c20165363a576e02c6 Mon Sep 17 00:00:00 2001 From: Newtech66 Date: Thu, 1 Aug 2024 02:36:27 +0530 Subject: [PATCH 087/537] Normalization fixes --- src/sage/rings/all.py | 2 - src/sage/rings/species.py | 87 ++++++++++++++++----------------------- 2 files changed, 35 insertions(+), 54 deletions(-) diff --git a/src/sage/rings/all.py b/src/sage/rings/all.py index 8cad575b8e9..8cc4b2ccf0e 100644 --- a/src/sage/rings/all.py +++ b/src/sage/rings/all.py @@ -166,8 +166,6 @@ # asymptotic ring from sage.rings.asymptotic.all import * -lazy_import('sage.rings.burnside', 'BurnsideRing') - lazy_import('sage.rings.species', ['PolynomialSpecies', 'AtomicSpecies']) # Register classes in numbers abc diff --git a/src/sage/rings/species.py b/src/sage/rings/species.py index 3390003ef60..6787eee3e5a 100644 --- a/src/sage/rings/species.py +++ b/src/sage/rings/species.py @@ -1,3 +1,4 @@ +from sage.all__sagemath_objects import Integer from sage.categories.infinite_enumerated_sets import InfiniteEnumeratedSets from sage.combinat.integer_vector import IntegerVectors from sage.misc.cachefunc import cached_method @@ -20,9 +21,7 @@ def _is_conjugate(G, H1, H2): r""" Test if ``H1`` and ``H2`` are conjugate subgroups in ``G``. - EXAMPLES:: - sage: G = SymmetricGroup(3) sage: H1 = PermutationGroup([(1,2)]) sage: H2 = PermutationGroup([(2,3)]) @@ -63,30 +62,20 @@ def _cache_get(self, elm): class ConjugacyClassOfDirectlyIndecomposableSubgroups(Element): - def __init__(self, parent, C, ambient_group): + def __init__(self, parent, C): r""" A conjugacy class of directly indecomposable subgroups. """ Element.__init__(self, parent) self._C = C self._smallgen = C.gens_small() - self._ambient_group = ambient_group - - @cached_method - def subgroup_of(self): - r""" - Return the group which this conjugacy class of - directly indecomposable subgroups belongs to. - """ - return self._ambient_group @cached_method def _element_key(self): r""" Return the key for this element. """ - return tuple([self._C.degree(), self._C.order(), - self._ambient_group]) + return tuple([self._C.degree(), self._C.order()]) def __hash__(self): return hash(self._element_key) @@ -101,16 +90,14 @@ def __eq__(self, other): r""" Return if ``self`` is equal to ``other``. - Two directly indecomposable subgroups belong to the same conjugacy - class if they have the same ambient group and are conjugate within it. + ``self`` is equal to ``other`` if they have the same degree (say `n`) + and order and are conjugate within `S_n`. """ - # No __le__ method because does it really make sense to have one here? return (isinstance(other, ConjugacyClassOfDirectlyIndecomposableSubgroups) - and self._ambient_group == other._ambient_group - and _is_conjugate(self._ambient_group, self._C, other._C)) + and self._element_key() == other._element_key() + and _is_conjugate(SymmetricGroup(self._C.degree()), self._C, other._C)) class ConjugacyClassesOfDirectlyIndecomposableSubgroups(UniqueRepresentation, Parent, ElementCache): - def __init__(self): r""" Conjugacy classes of directly indecomposable subgroups. @@ -120,32 +107,28 @@ def __init__(self): def _element_constructor_(self, x): r""" - ``x`` is an element of ``self`` or a tuple `(H, G)` such that - `H` is directly indecomposable and `G` is the ambient group of - `H`. + ``x`` is an element of ``self`` or a group `H` such that + `H` is directly indecomposable. """ if parent(x) == self: return x - H, G = x - # can't handle any normalization before this point because - # of subgroup check - if H.is_subgroup(G): - if len(H.disjoint_direct_product_decomposition()) > 1: - raise ValueError(f"{H} is not directly indecomposable") - # do domain normalization here? - elm = self.element_class(self, H, G) + if isinstance(x, PermutationGroup_generic): + if len(x.disjoint_direct_product_decomposition()) > 1: + raise ValueError(f"{x} is not directly indecomposable") + elm = self.element_class(self, x) return self._cache_get(elm) - raise ValueError(f"{H} is not a subgroup of {G}") + raise ValueError(f"unable to convert {x} to {self}") Element = ConjugacyClassOfDirectlyIndecomposableSubgroups class AtomicSpeciesElement(Element): - def __init__(self, parent, dis, mc): + def __init__(self, parent, dis, domain_partition): r""" An atomic species. ``dis`` is an instance of ConjugacyClassOfDirectlyIndecomposableSubgroups - and ``mc`` is the multicardinality of the atomic - species. + and ``domain_partition`` is a dict, which + represents the assignment of each element of the + domain of ``dis`` to a "variable". """ # Notice that a molecular species (and therefore an atomic species) # must be centered on a multicardinality, otherwise it wouldn't be @@ -153,7 +136,8 @@ def __init__(self, parent, dis, mc): # centered on a given multicardinality." Element.__init__(self, parent) self._dis = dis - self._mc = mc + self._dompart = domain_partition + self._mc = [len(s) for s in domain_partition] def __hash__(self): r""" @@ -175,6 +159,7 @@ def __eq__(self, other): """ if parent(self) != parent(other): return False + # Here it is enough to compare mc return self._mc == other._mc and self._dis == self._dis def _repr_(self): @@ -232,23 +217,23 @@ def an_element(self): def _normalize(self, H, M): r""" - Normalize the domain of `H` and return `H`, the ambient group, - and the multicardinality. + Normalize the domain of `H` and return `H` and the domain partition. """ # TODO: Complete the documentation. - L = [[] for _ in range(self._k)] - for k, v in M.items(): - L[v - 1].append(k) - Lc = sum(L, []) - Ls = [len(l) for l in L] + if Set(H.domain()) != Set(M.keys()): + raise ValueError(f"Keys of {M} do not match with domain of {H} (= {H.domain()})") + if not Set(M.values()).issubset(Set(range(1, self._k + 1))): + raise ValueError(f"Values of {M} must be in the range [1, {self._k}]") # normalize domain to {1..n} - mapping = {v: i for i, v in enumerate(Lc, 1)} + mapping = {v: i for i, v in enumerate(H.domain(), 1)} normalized_gens = [[tuple(mapping[x] for x in cyc) for cyc in gen.cycle_tuples()] for gen in H.gens_small()] P = PermutationGroup(gens=normalized_gens) # Fix for SymmetricGroup(0) if H.degree() == 0: P = SymmetricGroup(0) - return P, SymmetricGroup(len(Lc)).young_subgroup(Ls), self._grading_set(Ls) + # create domain partition + dompart = {mapping[k]: v for k, v in M.items()} + return P, dompart def _element_constructor_(self, x): r""" @@ -265,13 +250,11 @@ def _element_constructor_(self, x): if parent(x) == self: return x H, M = x - if Set(H.domain()) != Set(M.keys()): - raise ValueError(f"Keys of {M} do not match with domain of {H} (= {H.domain()})") - if not Set(M.values()).issubset(Set(range(1, self._k + 1))): - raise ValueError(f"Values of {M} must be in the range [1, {self._k}]") - H_norm, ambient_group, mc = self._normalize(H, M) - dis_elm = self._dis((H_norm, ambient_group)) - elm = self.element_class(self, dis_elm, mc) + H_norm, dompart = self._normalize(H, M) + dis_elm = self._dis(H_norm) + perm = libgap.RepresentativeAction(H_norm, dis_elm._C) + dompart_norm = {Integer(k ^ perm): v for k, v in dompart.items()} + elm = self.element_class(self, dis_elm, dompart_norm) return self._cache_get(elm) def __getitem__(self, x): From a0f1cc428e61aaf01b0c9cdb716e368d736f7734 Mon Sep 17 00:00:00 2001 From: Newtech66 Date: Thu, 1 Aug 2024 13:10:17 +0530 Subject: [PATCH 088/537] More fixes --- src/sage/rings/species.py | 56 ++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 33 deletions(-) diff --git a/src/sage/rings/species.py b/src/sage/rings/species.py index 6787eee3e5a..6a7b0bda6fe 100644 --- a/src/sage/rings/species.py +++ b/src/sage/rings/species.py @@ -137,7 +137,10 @@ def __init__(self, parent, dis, domain_partition): Element.__init__(self, parent) self._dis = dis self._dompart = domain_partition - self._mc = [len(s) for s in domain_partition] + L = [0 for _ in range(self.parent()._k)] + for v in self._dompart.values(): + L[v - 1] += 1 + self._mc = tuple(L) def __hash__(self): r""" @@ -252,8 +255,8 @@ def _element_constructor_(self, x): H, M = x H_norm, dompart = self._normalize(H, M) dis_elm = self._dis(H_norm) - perm = libgap.RepresentativeAction(H_norm, dis_elm._C) - dompart_norm = {Integer(k ^ perm): v for k, v in dompart.items()} + perm = libgap.RepresentativeAction(SymmetricGroup(H_norm.degree()), H_norm, dis_elm._C) + dompart_norm = {Integer(k ** perm): v for k, v in dompart.items()} elm = self.element_class(self, dis_elm, dompart_norm) return self._cache_get(elm) @@ -332,25 +335,19 @@ def _element_constructor_(self, x): INPUT: - - ``x`` - an element of ``self`` or a tuple ``(H, f)`` where `H` is - the permutation group representation for the species and `f` is a + - ``x`` - an element of ``self`` or a tuple ``(H, M)`` where `H` is + the permutation group representation for the species and `M` is a ``dict`` mapping each element of the domain of `H` to integers in `\{ 1 \ldots k \}`, representing the set to which the element belongs. """ if parent(x) == self: return x - H, f = x - if Set(H.domain()) != Set(f.keys()): - raise ValueError(f"Keys of {f} do not match with domain of {H}") - if not Set(f.values()).issubset(Set(range(1, self._k + 1))): - raise ValueError(f"Values of {f} must be in the range [1, {self._k}]") - if isinstance(H, PermutationGroup_generic) and isinstance(f, dict): - domain_partition = H.disjoint_direct_product_decomposition() - term = self._indices.one() - for part in domain_partition: - term *= self._indices.gen(self._project(H, f, part)) - return self._from_dict({term: 1}) - raise ValueError("unable to convert {x} into {self}") + H, M = x + domain_partition = H.disjoint_direct_product_decomposition() + term = self._indices.one() + for part in domain_partition: + term *= self._indices.gen(self._project(H, M, part)) + return self._from_dict({term: 1}) def __getitem__(self, x): r""" @@ -382,26 +379,26 @@ def one_basis(self): EXAMPLES:: - sage: P = PolynomialMolecularDecomposition(1) + sage: P = PolynomialSpecies(1) sage: P.one_basis() - {[]: [0]} - sage: P2 = PolynomialMolecularDecomposition(2) + 1 + sage: P2 = PolynomialSpecies(2) sage: P2.one_basis() - {[]: [0, 0]} + 1 """ - return self._indices({self._atomic_basis(tuple([SymmetricGroup(0), dict()])): 1}) + return self._indices.one() @cached_method def an_element(self): """ Return an element of ``self``. - sage: P=PolynomialMolecularDecomposition(1) + sage: P = PolynomialSpecies(1) sage: P.an_element() - {[]: [0]} - sage: P2=PolynomialMolecularDecomposition(2) + 1 + sage: P2 = PolynomialSpecies(2) sage: P2.an_element() - {[]: [0, 0]} + 1 """ return self.one() @@ -420,13 +417,6 @@ def product_on_basis(self, H, K): [ {[()]: [1]}^5 {[()]: [1]}^3*{[(1,2)]: [2]} {[(1,2,3)]: [3]}*{[()]: [1]}^2 {[(1,2,3), (2,3)]: [3]}*{[()]: [1]}^2] [ {[()]: [1]}^3*{[(1,2)]: [2]} {[()]: [1]}*{[(1,2)]: [2]}^2 {[(1,2,3)]: [3]}*{[(1,2)]: [2]} {[(1,2,3), (2,3)]: [3]}*{[(1,2)]: [2]}] """ - # Hacky workaround for handling the one of the algebra :( - if H == self.one_basis() and K == self.one_basis(): - return self._from_dict({self.one_basis(): 1}) - elif H == self.one_basis(): - return self._from_dict({K: 1}) - elif K == self.one_basis(): - return self._from_dict({H: 1}) return self._from_dict({H * K: 1}) def degree_on_basis(self, m): From b932b910d2b40640495db8b1871f03ee9adca8ca Mon Sep 17 00:00:00 2001 From: Newtech66 Date: Thu, 1 Aug 2024 13:33:50 +0530 Subject: [PATCH 089/537] removed __eq__, added _repr_, and doctest fixes --- src/sage/rings/species.py | 43 +++++++++++++-------------------------- 1 file changed, 14 insertions(+), 29 deletions(-) diff --git a/src/sage/rings/species.py b/src/sage/rings/species.py index 6a7b0bda6fe..9eaae36c9f4 100644 --- a/src/sage/rings/species.py +++ b/src/sage/rings/species.py @@ -119,6 +119,9 @@ def _element_constructor_(self, x): return self._cache_get(elm) raise ValueError(f"unable to convert {x} to {self}") + def _repr_(self): + return "Infinite set of conjugacy classes of directly indecomposable subgroups" + Element = ConjugacyClassOfDirectlyIndecomposableSubgroups class AtomicSpeciesElement(Element): @@ -189,26 +192,6 @@ def __hash__(self): Return a hash for ``self``. """ return hash(self._k) - - def __eq__(self, other): - r""" - Needed for unique representation behaviour. - - TESTS:: - - sage: At1 = AtomicSpecies(1); At1 - sage: At2 = AtomicSpecies(2); At2 - sage: At1_2 = AtomicSpecies(1); At1_2 - sage: At1 is At1_2 - True - sage: At1 is At2 - False - sage: At1_2 is At2 - False - """ - if type(self) != type(other): - return False - return self._k == other._k @cached_method def an_element(self): @@ -273,8 +256,10 @@ def __contains__(self, x): # This needs to be improved. if parent(x) == self: return True + H, M = x try: - self._element_constructor_(x) + H_norm, _ = self._normalize(H, M) + self._dis(H_norm) except ValueError: return False return True @@ -303,9 +288,9 @@ def __init__(self, k, base_ring=ZZ): TESTS:: - sage: P = PolynomialMolecularDecomposition(1) + sage: P = PolynomialSpecies(1) sage: TestSuite(P).run() - sage: P2 = PolynomialMolecularDecomposition(2) + sage: P2 = PolynomialSpecies(2) sage: TestSuite(P2).run() """ # should we pass a category to basis_keys? @@ -356,18 +341,18 @@ def __getitem__(self, x): TESTS:: sage: P = PolynomialMolecularDecomposition(1) - sage: At1 = MultivariateAtomicSpecies(1) + sage: At1 = AtomicSpecies(1) sage: At1((SymmetricGroup(1), {1: 1})).rename("X") - sage: X = (SymmetricGroup(2).young_subgroup([1, 1]), {1: 1, 2: 1}) - sage: P[X] + sage: X2 = (SymmetricGroup(2).young_subgroup([1, 1]), {1: 1, 2: 1}) + sage: P[X2] X^2 - sage: P2=PolynomialMolecularDecomposition(2) - sage: At2=MultivariateAtomicSpecies(2) + sage: P2 = PolynomialSpecies(2) + sage: At2 = AtomicSpecies(2) sage: At2((SymmetricGroup(1), {1: 1})).rename("X") sage: At2((SymmetricGroup(1), {1: 2})).rename("Y") sage: XY = (SymmetricGroup(2).young_subgroup([1, 1]), {1: 1, 2: 2}) sage: P2[XY] - Y*X + X*Y """ return self._element_constructor_(x) From a5405318c6540ce866b743c9c9030372348771a8 Mon Sep 17 00:00:00 2001 From: Newtech66 Date: Thu, 1 Aug 2024 21:45:53 +0530 Subject: [PATCH 090/537] remove Set, add shortcut element init for AtomicSpecies and PolynomialSpecies --- src/sage/rings/species.py | 59 +++++++++++++++++++++++++++++---------- 1 file changed, 44 insertions(+), 15 deletions(-) diff --git a/src/sage/rings/species.py b/src/sage/rings/species.py index 9eaae36c9f4..cf91feef377 100644 --- a/src/sage/rings/species.py +++ b/src/sage/rings/species.py @@ -14,7 +14,6 @@ from sage.groups.perm_gps.permgroup_named import SymmetricGroup from sage.libs.gap.libgap import libgap from sage.combinat.free_module import CombinatorialFreeModule -from sage.sets.set import Set GAP_FAIL = libgap.eval('fail') @@ -144,6 +143,7 @@ def __init__(self, parent, dis, domain_partition): for v in self._dompart.values(): L[v - 1] += 1 self._mc = tuple(L) + self._tc = sum(self._mc) def __hash__(self): r""" @@ -206,9 +206,9 @@ def _normalize(self, H, M): Normalize the domain of `H` and return `H` and the domain partition. """ # TODO: Complete the documentation. - if Set(H.domain()) != Set(M.keys()): + if set(H.domain()) != set(M.keys()): raise ValueError(f"Keys of {M} do not match with domain of {H} (= {H.domain()})") - if not Set(M.values()).issubset(Set(range(1, self._k + 1))): + if not set(M.values()).issubset(range(1, self._k + 1)): raise ValueError(f"Values of {M} must be in the range [1, {self._k}]") # normalize domain to {1..n} mapping = {v: i for i, v in enumerate(H.domain(), 1)} @@ -223,19 +223,33 @@ def _normalize(self, H, M): def _element_constructor_(self, x): r""" - Construct the `k`-variate molecular species with the given data. + Construct the `k`-variate atomic species with the given data. INPUT: - - ``x`` - an element of ``self`` or a tuple ``(H, M)`` where `H` is - the directly indecomposable permutation group representation for the - `k`-variate atomic species and `M` is a ``dict`` mapping each element - of the domain of `H` to integers in `\{ 1 \ldots k \}`, representing - the set to which the element belongs. + - ``x`` can be any of the following: + - an element of ``self``. + - a tuple ``(H, M)`` where `H` is the permutation group representation + for the atomic species and `M` is a ``dict`` mapping each element of the + domain of `H` to integers in `\{ 1 \ldots k \}`, representing the set to + which the element belongs. + - if `k=1`, i.e. we are working with univariate atomic species, the mapping + `M` may be omitted and just the group `H` may be passed. """ if parent(x) == self: return x - H, M = x + H, M = None, None + if isinstance(x, tuple): + H, M = x + else: + if self._k == 1: + if isinstance(x, PermutationGroup_generic): + H = x + M = {e: 1 for e in H.domain()} + else: + raise ValueError(f"{x} must be a permutation group") + else: + raise ValueError(f"{x} must be a tuple for multivariate species") H_norm, dompart = self._normalize(H, M) dis_elm = self._dis(H_norm) perm = libgap.RepresentativeAction(SymmetricGroup(H_norm.degree()), H_norm, dis_elm._C) @@ -320,14 +334,29 @@ def _element_constructor_(self, x): INPUT: - - ``x`` - an element of ``self`` or a tuple ``(H, M)`` where `H` is - the permutation group representation for the species and `M` is a - ``dict`` mapping each element of the domain of `H` to integers in - `\{ 1 \ldots k \}`, representing the set to which the element belongs. + - ``x`` can be any of the following: + - an element of ``self``. + - a tuple ``(H, M)`` where `H` is the permutation group representation + for the species and `M` is a ``dict`` mapping each element of the domain + of `H` to integers in `\{ 1 \ldots k \}`, representing the set to which + the element belongs. + - if `k=1`, i.e. we are working with univariate species, the mapping `M` + may be omitted and just the group `H` may be passed. """ if parent(x) == self: return x - H, M = x + H, M = None, None + if isinstance(x, tuple): + H, M = x + else: + if self._k == 1: + if isinstance(x, PermutationGroup_generic): + H = x + M = {e: 1 for e in H.domain()} + else: + raise ValueError(f"{x} must be a permutation group") + else: + raise ValueError(f"{x} must be a tuple for multivariate species") domain_partition = H.disjoint_direct_product_decomposition() term = self._indices.one() for part in domain_partition: From 8b508907a9be9be980c74b125e21180bb61ef698 Mon Sep 17 00:00:00 2001 From: Newtech66 Date: Thu, 1 Aug 2024 21:58:26 +0530 Subject: [PATCH 091/537] doctest fixes --- src/sage/rings/species.py | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/src/sage/rings/species.py b/src/sage/rings/species.py index cf91feef377..572a296632f 100644 --- a/src/sage/rings/species.py +++ b/src/sage/rings/species.py @@ -369,10 +369,10 @@ def __getitem__(self, x): TESTS:: - sage: P = PolynomialMolecularDecomposition(1) + sage: P = PolynomialSpecies(1) sage: At1 = AtomicSpecies(1) - sage: At1((SymmetricGroup(1), {1: 1})).rename("X") - sage: X2 = (SymmetricGroup(2).young_subgroup([1, 1]), {1: 1, 2: 1}) + sage: At1(SymmetricGroup(1)).rename("X") + sage: X2 = SymmetricGroup(2).young_subgroup([1, 1]) sage: P[X2] X^2 sage: P2 = PolynomialSpecies(2) @@ -422,14 +422,18 @@ def product_on_basis(self, H, K): EXAMPLES:: - sage: P=PolynomialMolecularDecomposition(1) - sage: d2 = {e: 1 for e in range(1, 3)} - sage: d3 = {e: 1 for e in range(1, 4)} - sage: L1 = [(H, d3) for H in SymmetricGroup(3).conjugacy_classes_subgroups()] - sage: L2 = [(H, d2) for H in SymmetricGroup(2).conjugacy_classes_subgroups()] - sage: matrix([[P(x) * P(y) for x in L1] for y in L2]) - [ {[()]: [1]}^5 {[()]: [1]}^3*{[(1,2)]: [2]} {[(1,2,3)]: [3]}*{[()]: [1]}^2 {[(1,2,3), (2,3)]: [3]}*{[()]: [1]}^2] - [ {[()]: [1]}^3*{[(1,2)]: [2]} {[()]: [1]}*{[(1,2)]: [2]}^2 {[(1,2,3)]: [3]}*{[(1,2)]: [2]} {[(1,2,3), (2,3)]: [3]}*{[(1,2)]: [2]}] + sage: A = AtomicSpecies(1) + sage: A(SymmetricGroup(1)).rename("X") + sage: [A(SymmetricGroup(n)).rename(f"E_{n}") for n in range(2, 5)] + [None, None, None] + sage: [A(CyclicPermutationGroup(n)).rename(f"C_{n}") for n in range(3, 5)] + [None, None] + sage: P = PolynomialSpecies(1) + sage: L1 = [P(H) for H in SymmetricGroup(3).conjugacy_classes_subgroups()] + sage: L2 = [P(H) for H in SymmetricGroup(2).conjugacy_classes_subgroups()] + sage: matrix([[F * G for F in L1] for G in L2]) + [ X^5 X^3*E_2 C_3*X^2 E_3*X^2] + [X^3*E_2 X*E_2^2 C_3*E_2 E_3*E_2] """ return self._from_dict({H * K: 1}) @@ -447,10 +451,10 @@ def _repr_(self): EXAMPLES:: - sage: P = PolynomialMolecularDecomposition(1) + sage: P = PolynomialSpecies(1) sage: P Ring of 1-variate virtual species - sage: P2 = PolynomialMolecularDecomposition(2) + sage: P2 = PolynomialSpecies(2) sage: P2 Ring of 2-variate virtual species """ From 1ad7c46f032ddcb5d7e474cf2496084c5a824c0e Mon Sep 17 00:00:00 2001 From: Newtech66 Date: Fri, 2 Aug 2024 13:15:26 +0530 Subject: [PATCH 092/537] improvements (mantepse) --- src/sage/rings/species.py | 190 +++++++++++++++++++++++--------------- 1 file changed, 114 insertions(+), 76 deletions(-) diff --git a/src/sage/rings/species.py b/src/sage/rings/species.py index 572a296632f..d78378581a1 100644 --- a/src/sage/rings/species.py +++ b/src/sage/rings/species.py @@ -1,26 +1,28 @@ -from sage.all__sagemath_objects import Integer +from sage.categories.graded_algebras_with_basis import GradedAlgebrasWithBasis from sage.categories.infinite_enumerated_sets import InfiniteEnumeratedSets +from sage.categories.sets_with_grading import SetsWithGrading +from sage.combinat.free_module import CombinatorialFreeModule from sage.combinat.integer_vector import IntegerVectors +from sage.groups.perm_gps.constructor import PermutationGroupElement +from sage.groups.perm_gps.permgroup import PermutationGroup, PermutationGroup_generic +from sage.groups.perm_gps.permgroup_named import SymmetricGroup +from sage.libs.gap.libgap import libgap from sage.misc.cachefunc import cached_method from sage.monoids.indexed_free_monoid import IndexedFreeAbelianMonoid +from sage.rings.integer_ring import ZZ +from sage.structure.element import Element, parent from sage.structure.parent import Parent -from sage.structure.element import Element -from sage.structure.element import parent from sage.structure.unique_representation import UniqueRepresentation -from sage.rings.integer_ring import ZZ -from sage.categories.sets_with_grading import SetsWithGrading -from sage.categories.graded_algebras_with_basis import GradedAlgebrasWithBasis -from sage.groups.perm_gps.permgroup import PermutationGroup, PermutationGroup_generic -from sage.groups.perm_gps.permgroup_named import SymmetricGroup -from sage.libs.gap.libgap import libgap -from sage.combinat.free_module import CombinatorialFreeModule GAP_FAIL = libgap.eval('fail') + def _is_conjugate(G, H1, H2): r""" Test if ``H1`` and ``H2`` are conjugate subgroups in ``G``. + EXAMPLES:: + sage: G = SymmetricGroup(3) sage: H1 = PermutationGroup([(1,2)]) sage: H2 = PermutationGroup([(2,3)]) @@ -53,12 +55,16 @@ def _cache_get(self, elm): for other_elm in lookup: if elm == other_elm: return other_elm - else: - lookup.append(elm) + elm = self._canonical_label(elm) + lookup.append(elm) else: + elm = self._canonical_label(elm) self._cache[key] = [elm] return elm + def _canonical_label(self, elm): + return elm + class ConjugacyClassOfDirectlyIndecomposableSubgroups(Element): def __init__(self, parent, C): @@ -74,7 +80,7 @@ def _element_key(self): r""" Return the key for this element. """ - return tuple([self._C.degree(), self._C.order()]) + return self._C.degree(), self._C.order() def __hash__(self): return hash(self._element_key) @@ -87,23 +93,26 @@ def _repr_(self): def __eq__(self, other): r""" - Return if ``self`` is equal to ``other``. + Return whether ``self`` is equal to ``other``. ``self`` is equal to ``other`` if they have the same degree (say `n`) and order and are conjugate within `S_n`. """ return (isinstance(other, ConjugacyClassOfDirectlyIndecomposableSubgroups) and self._element_key() == other._element_key() - and _is_conjugate(SymmetricGroup(self._C.degree()), self._C, other._C)) + and _is_conjugate(SymmetricGroup(self._C.degree()), + self._C, other._C)) -class ConjugacyClassesOfDirectlyIndecomposableSubgroups(UniqueRepresentation, Parent, ElementCache): + +class ConjugacyClassesOfDirectlyIndecomposableSubgroups(UniqueRepresentation, + Parent, ElementCache): def __init__(self): r""" Conjugacy classes of directly indecomposable subgroups. """ Parent.__init__(self, category=InfiniteEnumeratedSets()) ElementCache.__init__(self) - + def _element_constructor_(self, x): r""" ``x`` is an element of ``self`` or a group `H` such that @@ -117,20 +126,41 @@ def _element_constructor_(self, x): elm = self.element_class(self, x) return self._cache_get(elm) raise ValueError(f"unable to convert {x} to {self}") - + def _repr_(self): return "Infinite set of conjugacy classes of directly indecomposable subgroups" - + + def _canonical_label(self, elm): + """ + + EXAMPLES:: + + sage: G = PermutationGroup([[(1,3),(4,7)], [(2,5),(6,8)], [(1,4),(2,5),(3,7)]]) + sage: A = AtomicSpecies(1) + sage: A(G) + {[(5,6)(7,8), (1,2)(5,7)(6,8), (1,2)(3,4)]: (8,)} + """ + orbits = sorted(elm._C.orbits(), key=len) + pi = PermutationGroupElement([e for o in orbits for e in o]) + pi_inv = pi.inverse() + gens = [pi * g * pi_inv for g in elm._smallgen] + return self.element_class(self, PermutationGroup(gens)) + Element = ConjugacyClassOfDirectlyIndecomposableSubgroups + class AtomicSpeciesElement(Element): def __init__(self, parent, dis, domain_partition): r""" - An atomic species. ``dis`` is an instance of - ConjugacyClassOfDirectlyIndecomposableSubgroups - and ``domain_partition`` is a dict, which - represents the assignment of each element of the - domain of ``dis`` to a "variable". + Initialize an atomic species. + + INPUT: + + - ``dis``, a :class:`ConjugacyClassOfDirectlyIndecomposableSubgroups` + + - ``domain_partition``, a dict representing the + assignment of each element of the domain of ``dis`` to + a "variable". """ # Notice that a molecular species (and therefore an atomic species) # must be centered on a multicardinality, otherwise it wouldn't be @@ -145,18 +175,18 @@ def __init__(self, parent, dis, domain_partition): self._mc = tuple(L) self._tc = sum(self._mc) - def __hash__(self): - r""" - Return the hash of the atomic species. - """ - return hash(tuple([self._dis, self._mc])) - @cached_method def _element_key(self): r""" Return a lookup key for ``self``. """ - return tuple([self._dis._C, self._mc]) + return self._dis._C, self._mc + + def __hash__(self): + r""" + Return the hash of the atomic species. + """ + return hash(self._element_key()) def __eq__(self, other): r""" @@ -174,6 +204,7 @@ def _repr_(self): """ return "{" + f"{self._dis}: {self._mc}" + "}" + class AtomicSpecies(UniqueRepresentation, Parent, ElementCache): def __init__(self, k): r""" @@ -185,21 +216,22 @@ def __init__(self, k): ElementCache.__init__(self) self._k = k self._grading_set = IntegerVectors(length=k) - self._dis = ConjugacyClassesOfDirectlyIndecomposableSubgroups() + self._dis_ctor = ConjugacyClassesOfDirectlyIndecomposableSubgroups() def __hash__(self): r""" Return a hash for ``self``. """ return hash(self._k) - + @cached_method def an_element(self): """ Return an element of ``self``. """ - return self._element_constructor_((SymmetricGroup(self._k).young_subgroup([1] * self._k), - {e: i for i, e in enumerate(range(1, self._k + 1), 1)})) + G = SymmetricGroup(self._k).young_subgroup([1] * self._k) + m = {e: i for i, e in enumerate(range(1, self._k + 1), 1)} + return self._element_constructor_((G, m)) def _normalize(self, H, M): r""" @@ -212,7 +244,9 @@ def _normalize(self, H, M): raise ValueError(f"Values of {M} must be in the range [1, {self._k}]") # normalize domain to {1..n} mapping = {v: i for i, v in enumerate(H.domain(), 1)} - normalized_gens = [[tuple(mapping[x] for x in cyc) for cyc in gen.cycle_tuples()] for gen in H.gens_small()] + normalized_gens = [[tuple(mapping[x] for x in cyc) + for cyc in gen.cycle_tuples()] + for gen in H.gens_small()] P = PermutationGroup(gens=normalized_gens) # Fix for SymmetricGroup(0) if H.degree() == 0: @@ -229,34 +263,36 @@ def _element_constructor_(self, x): - ``x`` can be any of the following: - an element of ``self``. - - a tuple ``(H, M)`` where `H` is the permutation group representation - for the atomic species and `M` is a ``dict`` mapping each element of the - domain of `H` to integers in `\{ 1 \ldots k \}`, representing the set to - which the element belongs. - - if `k=1`, i.e. we are working with univariate atomic species, the mapping - `M` may be omitted and just the group `H` may be passed. + - a tuple ``(H, M)`` where `H` is the permutation group + representation for the atomic species and `M` is a + ``dict`` mapping each element of the domain of `H` to + integers in `\{ 1 \ldots k \}`, representing the set to + which the element belongs. + - if `k=1`, i.e. we are working with univariate atomic + species, the mapping `M` may be omitted and just the + group `H` may be passed. + """ if parent(x) == self: return x H, M = None, None if isinstance(x, tuple): H, M = x - else: - if self._k == 1: - if isinstance(x, PermutationGroup_generic): - H = x - M = {e: 1 for e in H.domain()} - else: - raise ValueError(f"{x} must be a permutation group") + elif self._k == 1: + if isinstance(x, PermutationGroup_generic): + H = x + M = {e: 1 for e in H.domain()} else: - raise ValueError(f"{x} must be a tuple for multivariate species") + raise ValueError(f"{x} must be a permutation group") + else: + raise ValueError(f"{x} must be a tuple for multivariate species") H_norm, dompart = self._normalize(H, M) - dis_elm = self._dis(H_norm) + dis_elm = self._dis_ctor(H_norm) perm = libgap.RepresentativeAction(SymmetricGroup(H_norm.degree()), H_norm, dis_elm._C) - dompart_norm = {Integer(k ** perm): v for k, v in dompart.items()} + dompart_norm = {ZZ(k ** perm): v for k, v in dompart.items()} elm = self.element_class(self, dis_elm, dompart_norm) return self._cache_get(elm) - + def __getitem__(self, x): r""" Call ``_element_constructor_`` on ``x``. @@ -273,11 +309,11 @@ def __contains__(self, x): H, M = x try: H_norm, _ = self._normalize(H, M) - self._dis(H_norm) + self._dis_ctor(H_norm) except ValueError: return False return True - + def _repr_(self): r""" Return a string representation of ``self``. @@ -292,9 +328,10 @@ def _repr_(self): Infinite set of 2-variate atomic species """ return f"Infinite set of {self._k}-variate atomic species" - + Element = AtomicSpeciesElement + class PolynomialSpecies(CombinatorialFreeModule): def __init__(self, k, base_ring=ZZ): r""" @@ -322,12 +359,13 @@ def __init__(self, k, base_ring=ZZ): def _project(self, H, f, part): r""" Project `H` onto a subset ``part`` of its domain. + ``part`` must be a union of cycles, but this is not checked. """ restricted_gens = [[cyc for cyc in gen.cycle_tuples() if cyc[0] in part] for gen in H.gens_small()] mapping = {p: f[p] for p in part} - return tuple([PermutationGroup(gens=restricted_gens, domain=part), mapping]) - + return PermutationGroup(gens=restricted_gens, domain=part), mapping + def _element_constructor_(self, x): r""" Construct the `k`-variate molecular species with the given data. @@ -336,27 +374,29 @@ def _element_constructor_(self, x): - ``x`` can be any of the following: - an element of ``self``. - - a tuple ``(H, M)`` where `H` is the permutation group representation - for the species and `M` is a ``dict`` mapping each element of the domain - of `H` to integers in `\{ 1 \ldots k \}`, representing the set to which - the element belongs. - - if `k=1`, i.e. we are working with univariate species, the mapping `M` - may be omitted and just the group `H` may be passed. + - a tuple ``(H, M)`` where `H` is the permutation group + representation for the species and `M` is a ``dict`` + mapping each element of the domain of `H` to integers + in `\{ 1 \ldots k \}`, representing the set to which + the element belongs. + - if `k=1`, i.e. we are working with univariate species, + the mapping `M` may be omitted and just the group `H` + may be passed. + """ if parent(x) == self: return x H, M = None, None if isinstance(x, tuple): H, M = x - else: - if self._k == 1: - if isinstance(x, PermutationGroup_generic): - H = x - M = {e: 1 for e in H.domain()} - else: - raise ValueError(f"{x} must be a permutation group") + elif self._k == 1: + if isinstance(x, PermutationGroup_generic): + H = x + M = {e: 1 for e in H.domain()} else: - raise ValueError(f"{x} must be a tuple for multivariate species") + raise ValueError(f"{x} must be a permutation group") + else: + raise ValueError(f"{x} must be a tuple for multivariate species") domain_partition = H.disjoint_direct_product_decomposition() term = self._indices.one() for part in domain_partition: @@ -459,8 +499,6 @@ def _repr_(self): Ring of 2-variate virtual species """ return f"Ring of {self._k}-variate virtual species" - + class Element(CombinatorialFreeModule.Element): - pass - # def _mul_(self, other): - # return type(self)() \ No newline at end of file + pass \ No newline at end of file From 3b0f03d85ce2258f17a55fc43ab07812333e5372 Mon Sep 17 00:00:00 2001 From: Newtech66 Date: Sun, 4 Aug 2024 03:30:54 +0530 Subject: [PATCH 093/537] Add __call__ for partitional composition --- src/sage/rings/species.py | 100 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 97 insertions(+), 3 deletions(-) diff --git a/src/sage/rings/species.py b/src/sage/rings/species.py index d78378581a1..0670adcb4c9 100644 --- a/src/sage/rings/species.py +++ b/src/sage/rings/species.py @@ -1,3 +1,4 @@ +from itertools import chain from sage.categories.graded_algebras_with_basis import GradedAlgebrasWithBasis from sage.categories.infinite_enumerated_sets import InfiniteEnumeratedSets from sage.categories.sets_with_grading import SetsWithGrading @@ -8,7 +9,8 @@ from sage.groups.perm_gps.permgroup_named import SymmetricGroup from sage.libs.gap.libgap import libgap from sage.misc.cachefunc import cached_method -from sage.monoids.indexed_free_monoid import IndexedFreeAbelianMonoid +from sage.misc.lazy_attribute import lazy_attribute +from sage.monoids.indexed_free_monoid import IndexedFreeAbelianMonoid, IndexedFreeAbelianMonoidElement from sage.rings.integer_ring import ZZ from sage.structure.element import Element, parent from sage.structure.parent import Parent @@ -331,6 +333,22 @@ def _repr_(self): Element = AtomicSpeciesElement +class MolecularSpecies(IndexedFreeAbelianMonoid): + class Element(IndexedFreeAbelianMonoidElement): + @lazy_attribute + def _group(self): + def gmul(H, K): + n, m = H.degree(), K.degree() + gens = H.gens_small() + for gen in K.gens_small(): + shift = libgap.MappingPermListList(K.domain().list(), [n + k for k in K.domain()]) + gens.append(shift ** -1 * gen * shift) + return PermutationGroup(gens, domain=range(1, n + m + 1)) + G = SymmetricGroup(0) + for A, p in self._monomial.items(): + for _ in range(p): + G = gmul(G, A._dis._C) + return G class PolynomialSpecies(CombinatorialFreeModule): def __init__(self, k, base_ring=ZZ): @@ -345,7 +363,7 @@ def __init__(self, k, base_ring=ZZ): sage: TestSuite(P2).run() """ # should we pass a category to basis_keys? - basis_keys = IndexedFreeAbelianMonoid(AtomicSpecies(k), + basis_keys = MolecularSpecies(AtomicSpecies(k), prefix='', bracket=False) category = GradedAlgebrasWithBasis(base_ring).Commutative() CombinatorialFreeModule.__init__(self, base_ring, @@ -501,4 +519,80 @@ def _repr_(self): return f"Ring of {self._k}-variate virtual species" class Element(CombinatorialFreeModule.Element): - pass \ No newline at end of file + @cached_method + def is_virtual(self): + return any(x < 0 for x in self.coefficients(sort=False)) + + @cached_method + def is_molecular(self): + return len(self.coefficients(sort=False)) == 1 and self.coefficients(sort=False)[0] == 1 + + @cached_method + def is_atomic(self): + return self.is_molecular() and len(self.support()[0]) == 1 + + def __call__(self, *args): + # should this also have a base ring check or is it coerced? + # the usage of type(self)(...), is it correct? + if len(args) != self.parent()._k: + raise ValueError(f"Number of args (= {len(args)}) must equal arity of self (= {len(args)})") + if any(not isinstance(arg, PolynomialSpecies.Element) for arg in args): + raise ValueError("All args must be elements of PolynomialSpecies") + if self.parent()._k > 1 or max(arg.parent()._k for arg in args) > 1: + raise NotImplementedError("Only univariate species are supported") + if self.is_virtual() or any(arg.is_virtual() for arg in args): + raise NotImplementedError(f"Only non-virtual species are supported") + # Now we only have non-virtual univariate species + res = 0 + Gm = args[0].monomial_coefficients() + for M, fM in self.monomial_coefficients().items(): + term = 0 + # maybe move degree_on_basis to MolecularSpecies (and it will become "grade") + n = self.parent().degree_on_basis(M) + powvecs = IntegerVectors(n, len(Gm)) + for vec in powvecs: + coeff = 1 + for fN, exponent in zip(Gm.values(), vec): + coeff *= fN ** exponent + N_list = list(chain.from_iterable([[N._group for _ in range(c)] for N, c in zip(Gm.keys(), vec)])) + R = self.parent()(wreath_imprimitive_general(N_list, M._group)) + term += coeff * R + res += fM * term + return res + + +def wreath_imprimitive_general(G_list, H): + r""" + H([G[0]] - [G[1]] - ... - [G[m]]) + """ + if len(G_list) != H.degree(): + raise ValueError(f"length of G_list (= {len(G_list)}) must be equal to degree of H (= {H.degree()})") + gens, dlist = [], [] + dsum = 0 + for G in G_list: + dlist.append(list(range(dsum + 1, dsum + G.degree() + 1))) + dsum += G.degree() + + # First find gens of H + for gen in H.gens(): + # each cycle must be homogenous in the degrees of groups shifted + # bad things happen if this isn't checked + # example: partitional_composition(E2, X+X^2) + # look at the structure with 1 X and 1 X^2, like {(1), (2,3)} + all_homogenous = True + for cyc in gen.cycle_tuples(): + cyclens = [len(dlist[x - 1]) for x in cyc] + all_homogenous &= min(cyclens) == max(cyclens) + if not all_homogenous: + continue + perm = libgap.Flat(libgap.Permuted(dlist, gen)) + gens.append(perm) + + # Then find gens of G_i + for i in range(len(G_list)): + for gen in G_list[i].gens(): + images = libgap.MappingPermListList(G_list[i].domain().list(),dlist[i]) + gens.append(gen ** images) + + # Finally create group + return PermutationGroup(gens, domain = range(1, dsum + 1)) From 6c7156ec07d453a9812ed900a023a08fa8639092 Mon Sep 17 00:00:00 2001 From: Newtech66 Date: Mon, 5 Aug 2024 05:36:11 +0530 Subject: [PATCH 094/537] Highly experimental commit aimed at improving performance, needs a lot of feedback --- src/sage/groups/perm_gps/permgroup.py | 5 +- src/sage/rings/species.py | 266 +++++++++++++++++--------- 2 files changed, 179 insertions(+), 92 deletions(-) diff --git a/src/sage/groups/perm_gps/permgroup.py b/src/sage/groups/perm_gps/permgroup.py index d97aad93b03..3cb92d8c74a 100644 --- a/src/sage/groups/perm_gps/permgroup.py +++ b/src/sage/groups/perm_gps/permgroup.py @@ -1628,6 +1628,8 @@ def disjoint_direct_product_decomposition(self): """ from sage.combinat.set_partition import SetPartition from sage.sets.disjoint_set import DisjointSet + if len(self.orbits()) <= 1: + return SetPartition(self.orbits()) H = self._libgap_() # sort each orbit and order list by smallest element of each orbit O = libgap.List([libgap.ShallowCopy(orbit) for orbit in libgap.Orbits(H)]) @@ -1639,7 +1641,7 @@ def disjoint_direct_product_decomposition(self): for i in range(num_orbits): for x in O[i]: OrbitMapping[x] = i - C = libgap.StabChain(H, libgap.Concatenation(O)) + C = libgap.StabChain(H, libgap.Flat(O)) X = libgap.StrongGeneratorsStabChain(C) P = DisjointSet(num_orbits) R = libgap.List([]) @@ -5056,6 +5058,7 @@ def sign_representation(self, base_ring=None): class PermutationGroup_subgroup(PermutationGroup_generic): + """ Subgroup subclass of ``PermutationGroup_generic``, so instance methods are inherited. diff --git a/src/sage/rings/species.py b/src/sage/rings/species.py index 0670adcb4c9..d40c8b2265b 100644 --- a/src/sage/rings/species.py +++ b/src/sage/rings/species.py @@ -1,6 +1,7 @@ from itertools import chain from sage.categories.graded_algebras_with_basis import GradedAlgebrasWithBasis from sage.categories.infinite_enumerated_sets import InfiniteEnumeratedSets +from sage.categories.monoids import Monoids from sage.categories.sets_with_grading import SetsWithGrading from sage.combinat.free_module import CombinatorialFreeModule from sage.combinat.integer_vector import IntegerVectors @@ -9,12 +10,12 @@ from sage.groups.perm_gps.permgroup_named import SymmetricGroup from sage.libs.gap.libgap import libgap from sage.misc.cachefunc import cached_method -from sage.misc.lazy_attribute import lazy_attribute -from sage.monoids.indexed_free_monoid import IndexedFreeAbelianMonoid, IndexedFreeAbelianMonoidElement +from sage.monoids.indexed_free_monoid import IndexedFreeAbelianMonoid, IndexedFreeAbelianMonoidElement, IndexedMonoid from sage.rings.integer_ring import ZZ from sage.structure.element import Element, parent from sage.structure.parent import Parent from sage.structure.unique_representation import UniqueRepresentation +from sage.sets.finite_enumerated_set import FiniteEnumeratedSet GAP_FAIL = libgap.eval('fail') @@ -57,16 +58,11 @@ def _cache_get(self, elm): for other_elm in lookup: if elm == other_elm: return other_elm - elm = self._canonical_label(elm) lookup.append(elm) else: - elm = self._canonical_label(elm) self._cache[key] = [elm] return elm - def _canonical_label(self, elm): - return elm - class ConjugacyClassOfDirectlyIndecomposableSubgroups(Element): def __init__(self, parent, C): @@ -75,23 +71,17 @@ def __init__(self, parent, C): """ Element.__init__(self, parent) self._C = C - self._smallgen = C.gens_small() - - @cached_method - def _element_key(self): - r""" - Return the key for this element. - """ - return self._C.degree(), self._C.order() + self._sorted_orbits = tuple(sorted(len(orbit) for orbit in C.orbits())) + self._order = C.order() def __hash__(self): - return hash(self._element_key) + return hash(self._C) def _repr_(self): r""" Return a string representation of ``self``. """ - return f"{self._smallgen}" + return f"{self._C.gens_small()}" def __eq__(self, other): r""" @@ -101,13 +91,12 @@ def __eq__(self, other): and order and are conjugate within `S_n`. """ return (isinstance(other, ConjugacyClassOfDirectlyIndecomposableSubgroups) - and self._element_key() == other._element_key() - and _is_conjugate(SymmetricGroup(self._C.degree()), - self._C, other._C)) + and self._C.degree() == other._C.degree() + and _is_conjugate(SymmetricGroup(self._C.degree()), + self._C, other._C)) -class ConjugacyClassesOfDirectlyIndecomposableSubgroups(UniqueRepresentation, - Parent, ElementCache): +class ConjugacyClassesOfDirectlyIndecomposableSubgroups(UniqueRepresentation, Parent): def __init__(self): r""" Conjugacy classes of directly indecomposable subgroups. @@ -119,34 +108,33 @@ def _element_constructor_(self, x): r""" ``x`` is an element of ``self`` or a group `H` such that `H` is directly indecomposable. + + EXAMPLES:: + + sage: G = PermutationGroup([[(1,3),(4,7)], [(2,5),(6,8)], [(1,4),(2,5),(3,7)]]) + sage: A = AtomicSpecies(1) + sage: A(G) + {[(5,6)(7,8), (1,2)(5,7)(6,8), (1,2)(3,4)]: (8,)} """ if parent(x) == self: return x if isinstance(x, PermutationGroup_generic): if len(x.disjoint_direct_product_decomposition()) > 1: raise ValueError(f"{x} is not directly indecomposable") - elm = self.element_class(self, x) - return self._cache_get(elm) + pi = self.canonical_label(x) + return self.element_class(self, PermutationGroup(gap_group=libgap.ConjugateGroup(x, pi))) raise ValueError(f"unable to convert {x} to {self}") def _repr_(self): return "Infinite set of conjugacy classes of directly indecomposable subgroups" - def _canonical_label(self, elm): - """ - - EXAMPLES:: - - sage: G = PermutationGroup([[(1,3),(4,7)], [(2,5),(6,8)], [(1,4),(2,5),(3,7)]]) - sage: A = AtomicSpecies(1) - sage: A(G) - {[(5,6)(7,8), (1,2)(5,7)(6,8), (1,2)(3,4)]: (8,)} + @cached_method + def canonical_label(self, H): + r""" + Return the permutation group element `g` such that + `g^{-1} H g` is a canonical representative. """ - orbits = sorted(elm._C.orbits(), key=len) - pi = PermutationGroupElement([e for o in orbits for e in o]) - pi_inv = pi.inverse() - gens = [pi * g * pi_inv for g in elm._smallgen] - return self.element_class(self, PermutationGroup(gens)) + return PermutationGroupElement([e for o in sorted([sorted(orbit) for orbit in H.orbits()], key=len) for e in o], check=False) Element = ConjugacyClassOfDirectlyIndecomposableSubgroups @@ -177,18 +165,17 @@ def __init__(self, parent, dis, domain_partition): self._mc = tuple(L) self._tc = sum(self._mc) - @cached_method def _element_key(self): r""" Return a lookup key for ``self``. """ - return self._dis._C, self._mc + return self._mc, self._dis._order, self._dis._sorted_orbits def __hash__(self): r""" Return the hash of the atomic species. """ - return hash(self._element_key()) + return hash((self._mc, self._dis)) def __eq__(self, other): r""" @@ -197,8 +184,7 @@ def __eq__(self, other): """ if parent(self) != parent(other): return False - # Here it is enough to compare mc - return self._mc == other._mc and self._dis == self._dis + return self._mc == other._mc and self._dis == other._dis def _repr_(self): r""" @@ -245,10 +231,12 @@ def _normalize(self, H, M): if not set(M.values()).issubset(range(1, self._k + 1)): raise ValueError(f"Values of {M} must be in the range [1, {self._k}]") # normalize domain to {1..n} + if sorted(M.keys()) == list(range(1, H.degree() + 1)): + return H, M mapping = {v: i for i, v in enumerate(H.domain(), 1)} normalized_gens = [[tuple(mapping[x] for x in cyc) for cyc in gen.cycle_tuples()] - for gen in H.gens_small()] + for gen in H.gens()] P = PermutationGroup(gens=normalized_gens) # Fix for SymmetricGroup(0) if H.degree() == 0: @@ -290,8 +278,10 @@ def _element_constructor_(self, x): raise ValueError(f"{x} must be a tuple for multivariate species") H_norm, dompart = self._normalize(H, M) dis_elm = self._dis_ctor(H_norm) - perm = libgap.RepresentativeAction(SymmetricGroup(H_norm.degree()), H_norm, dis_elm._C) - dompart_norm = {ZZ(k ** perm): v for k, v in dompart.items()} + # Python sorts are stable so we can use sorted twice without worrying about a change + # in the output. + pi = self._dis_ctor.canonical_label(H_norm) + dompart_norm = {pi(k): v for k, v in dompart.items()} elm = self.element_class(self, dis_elm, dompart_norm) return self._cache_get(elm) @@ -305,16 +295,12 @@ def __contains__(self, x): r""" Return if ``x`` is in ``self``. """ - # This needs to be improved. if parent(x) == self: return True H, M = x - try: - H_norm, _ = self._normalize(H, M) - self._dis_ctor(H_norm) - except ValueError: - return False - return True + return (set(H.domain()) == set(M.keys()) + and set(M.values()).issubset(range(1, self._k + 1)) + and len(H.disjoint_direct_product_decomposition()) == 1) def _repr_(self): r""" @@ -333,22 +319,123 @@ def _repr_(self): Element = AtomicSpeciesElement -class MolecularSpecies(IndexedFreeAbelianMonoid): +class MolecularSpecies(IndexedFreeAbelianMonoid, ElementCache): + @staticmethod + def __classcall__(cls, indices, prefix, **kwds): + return super(IndexedMonoid, cls).__classcall__(cls, indices, prefix, **kwds) + + def __init__(self, indices, prefix, **kwds): + category = Monoids() & InfiniteEnumeratedSets() + IndexedFreeAbelianMonoid.__init__(self, indices, prefix=prefix, category=category, **kwds) + ElementCache.__init__(self) + + def _element_constructor_(self, x=None): + elm = self._cache_get(super()._element_constructor_(x)) + if elm._group is None: + elm._group_constructor() + return elm + + @cached_method + def one(self): + elm = super().one() + elm._group = SymmetricGroup(0) + return elm + + def gen(self, x): + elm = self._cache_get(super().gen(x)) + if elm._group is None: + elm._group_constructor() + return elm + class Element(IndexedFreeAbelianMonoidElement): - @lazy_attribute - def _group(self): - def gmul(H, K): - n, m = H.degree(), K.degree() - gens = H.gens_small() - for gen in K.gens_small(): - shift = libgap.MappingPermListList(K.domain().list(), [n + k for k in K.domain()]) - gens.append(shift ** -1 * gen * shift) - return PermutationGroup(gens, domain=range(1, n + m + 1)) - G = SymmetricGroup(0) + def __init__(self, F, x): + super().__init__(F, x) + self._group = None + + def _group_constructor(self): + r""" + Construct the group of ``self``. + """ + if self._group is None: + self._group = SymmetricGroup(0) for A, p in self._monomial.items(): - for _ in range(p): - G = gmul(G, A._dis._C) - return G + curgrp = self._groupexp(A._dis._C, p) + self._group = self._groupmul(self._group, curgrp) + + def _groupmul(self, G1, G2): + r""" + Multiply two groups. + """ + # Would be great to be able to cache the intermediate results + if G1.degree() + G2.degree() == 0: + return SymmetricGroup(0) + if G1.degree() == 0: + return G2 + if G2.degree() == 0: + return G1 + gens1 = G1.gens() + if len(gens1) > 50: + gens1 = G1.gens_small() + gens2 = G2.gens() + if len(gens2) > 50: + gens1 = G2.gens_small() + # always loop over the smaller gens list + if len(gens1) < len(gens2): + gens1, gens2 = gens2, gens1 + G1, G2 = G2, G1 + gens = list(gens1) + for gen in gens2: + gens.append([tuple(G1.degree() + k for k in cyc) for cyc in gen.cycle_tuples()]) + return PermutationGroup(gens, domain=range(1, G1.degree() + G2.degree() + 1)) + + def _groupexp(self, G, n): + r""" + Exponentiate a group. + """ + grp = SymmetricGroup(0) + while n > 0: + if n % 2 == 1: + grp = self._groupmul(grp, G) + G = self._groupmul(G, G) + n //= 2 + return grp + + # TODO: didn't override __floordiv__ + def _mul_(self, other): + res = super()._mul_(other) + elm = self.parent()._cache_get(res) + if self._group is None: + self._group = SymmetricGroup(0) + if elm._group is None: + # Multiply two groups + elm._group = elm._groupmul(self._group, other._group) + return elm + + def __pow__(self, n): + res = super().__pow__(n) + elm = self.parent()._cache_get(res) + if self._group is None: + self._group = SymmetricGroup(0) + if elm._group is None: + # Exponentiate the group + elm._group = elm._groupexp(self._group, n) + return elm + + def _element_key(self): + return self + + def grade(self): + r""" + Return the grade of ``self``. + """ + return sum(A._tc * p for A, p in self._monomial.items()) + + def domain(self): + r""" + Return the domain of ``self``. + """ + return FiniteEnumeratedSet(range(1, self.grade() + 1)) + class PolynomialSpecies(CombinatorialFreeModule): def __init__(self, k, base_ring=ZZ): @@ -374,13 +461,19 @@ def __init__(self, k, base_ring=ZZ): self._k = k self._atomic_basis = basis_keys.indices() + def degree_on_basis(self, m): + r""" + Return the degree of the molecular species indexed by ``m``. + """ + return m.grade() + def _project(self, H, f, part): r""" Project `H` onto a subset ``part`` of its domain. ``part`` must be a union of cycles, but this is not checked. """ - restricted_gens = [[cyc for cyc in gen.cycle_tuples() if cyc[0] in part] for gen in H.gens_small()] + restricted_gens = [[cyc for cyc in gen.cycle_tuples() if cyc[0] in part] for gen in H.gens()] mapping = {p: f[p] for p in part} return PermutationGroup(gens=restricted_gens, domain=part), mapping @@ -495,14 +588,6 @@ def product_on_basis(self, H, K): """ return self._from_dict({H * K: 1}) - def degree_on_basis(self, m): - r""" - Return the degree of the basis element indexed by ``m`` - in ``self``. - """ - d = m.dict() - return sum(at._tc * p for at, p in d.items()) - def _repr_(self): r""" Return a string representation of ``self``. @@ -519,15 +604,12 @@ def _repr_(self): return f"Ring of {self._k}-variate virtual species" class Element(CombinatorialFreeModule.Element): - @cached_method def is_virtual(self): return any(x < 0 for x in self.coefficients(sort=False)) - @cached_method def is_molecular(self): return len(self.coefficients(sort=False)) == 1 and self.coefficients(sort=False)[0] == 1 - @cached_method def is_atomic(self): return self.is_molecular() and len(self.support()[0]) == 1 @@ -547,15 +629,13 @@ def __call__(self, *args): Gm = args[0].monomial_coefficients() for M, fM in self.monomial_coefficients().items(): term = 0 - # maybe move degree_on_basis to MolecularSpecies (and it will become "grade") - n = self.parent().degree_on_basis(M) - powvecs = IntegerVectors(n, len(Gm)) + powvecs = IntegerVectors(M.grade(), len(Gm)) for vec in powvecs: coeff = 1 for fN, exponent in zip(Gm.values(), vec): coeff *= fN ** exponent - N_list = list(chain.from_iterable([[N._group for _ in range(c)] for N, c in zip(Gm.keys(), vec)])) - R = self.parent()(wreath_imprimitive_general(N_list, M._group)) + N_list = list(chain.from_iterable([[N for _ in range(c)] for N, c in zip(Gm.keys(), vec)])) + R = self.parent()(wreath_imprimitive_general(N_list, M)) term += coeff * R res += fM * term return res @@ -564,17 +644,20 @@ def __call__(self, *args): def wreath_imprimitive_general(G_list, H): r""" H([G[0]] - [G[1]] - ... - [G[m]]) + All members of MolecularSpecies. """ - if len(G_list) != H.degree(): - raise ValueError(f"length of G_list (= {len(G_list)}) must be equal to degree of H (= {H.degree()})") + if len(G_list) != H.grade(): + raise ValueError(f"length of G_list (= {len(G_list)}) must be equal to degree of H (= {H.grade()})") + gens, dlist = [], [] dsum = 0 for G in G_list: - dlist.append(list(range(dsum + 1, dsum + G.degree() + 1))) - dsum += G.degree() + dlist.append(list(range(dsum + 1, dsum + G.grade() + 1))) + dsum += G.grade() + Hgens = H._group.gens() # First find gens of H - for gen in H.gens(): + for gen in Hgens: # each cycle must be homogenous in the degrees of groups shifted # bad things happen if this isn't checked # example: partitional_composition(E2, X+X^2) @@ -590,8 +673,9 @@ def wreath_imprimitive_general(G_list, H): # Then find gens of G_i for i in range(len(G_list)): - for gen in G_list[i].gens(): - images = libgap.MappingPermListList(G_list[i].domain().list(),dlist[i]) + Ggens = G_list[i]._group.gens() + for gen in Ggens: + images = libgap.MappingPermListList(G_list[i].domain().list(), dlist[i]) gens.append(gen ** images) # Finally create group From 4d1097d38ae3a967e1626f3c3a506c4572d195ab Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Mon, 5 Aug 2024 11:45:27 +0530 Subject: [PATCH 095/537] Added Element() class --- src/sage/matroids/chow_ring.py | 27 +++++++++++---------------- 1 file changed, 11 insertions(+), 16 deletions(-) diff --git a/src/sage/matroids/chow_ring.py b/src/sage/matroids/chow_ring.py index 6a05c45ac3f..1a8e8f2bed1 100644 --- a/src/sage/matroids/chow_ring.py +++ b/src/sage/matroids/chow_ring.py @@ -22,7 +22,7 @@ from sage.rings.polynomial.multi_polynomial_sequence import PolynomialSequence from sage.sets.set import Set from functools import cmp_to_key - +from sage.misc.misc_c import prod class ChowRing(QuotientRing_nc): r""" @@ -112,29 +112,24 @@ def func(A, B): term = self._ideal.ring().one() for j in range(len(flats)): if j == 0: - if i > self._matroid.rank(flats[0]): - term *= flats_gen[flats[j]]**(0) - else: + if i <= self._matroid.rank(flats[0]): term *= flats_gen[flats[j]]**(i + 1) else: - if i >= (self._matroid.rank(flats[j]) - self._matroid.rank(flats[j-1])): - if (flats[j] in list(flats_gen)): - term *= flats_gen[flats[j]]**(0) - else: - term *= flats_gen[flats[j]]**(i + 1) + if i < (self._matroid.rank(flats[j]) - self._matroid.rank(flats[j-1])): #store the ranks as a list + if flats[j] in flats_gen: + term *= flats_gen[flats[j]]**(i + 1) monomial_basis.append(term) - elif self._presentation=='atom-free': + elif self._presentation == 'atom-free': #all double equals need spacing + first_rank = self._matroid.rank(flats[len(flats)]) for i in range(maximum_rank): - term = self._ideal.ring().one() pow = [] for j in range(1, len(flats) - 1): - if i >= (self._matroid.rank(flats[j-1]) - self._matroid.rank(flats[j])): + if i >= (self._matroid.rank(flats[j]) - self._matroid.rank(flats[j-1])): pow.append((j , i)) - if sum([p[1] for p in pow]) == self._matroid.rank(flats[0]): - for p in pow: - term *= flats_gen[flats[p[0]]]**(p[1]) - monomial_basis.append(term) + if sum(p[1] for p in pow) == first_rank: + term = prod(flats_gen[flats[p[0]]] ** p[1] for p in pow) + monomial_basis.append(term) else: From d03c0e0220ea400e1e4bd3af2f7e3abf26cbcab1 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Mon, 5 Aug 2024 11:45:49 +0530 Subject: [PATCH 096/537] Written doctests for every method --- src/sage/matroids/chow_ring_ideal.py | 94 ++++++++++++++++++++++++---- 1 file changed, 81 insertions(+), 13 deletions(-) diff --git a/src/sage/matroids/chow_ring_ideal.py b/src/sage/matroids/chow_ring_ideal.py index 686b11bd5eb..73f4ed0eb86 100644 --- a/src/sage/matroids/chow_ring_ideal.py +++ b/src/sage/matroids/chow_ring_ideal.py @@ -31,27 +31,44 @@ def _gens_constructor(): pass def matroid(self): + r""" + Return the matroid of the given Chow ring ideal. + + EXAMPLE:: + + sage: ch = ChowRingIdeal_nonaug(M=matroids.Uniform(3,6), R=QQ) + sage: ch.matroid() + U(3, 6): Matroid of rank 3 on 6 elements with circuit-closures + {3: {{0, 1, 2, 3, 4, 5}}} + """ M = self._matroid return M def flats_generator(self): + r""" + Return the variables of every corresponding flat/groundset element + of the matroid. + + EXAMPLE:: + + sage: ch = ChowRingIdeal_nonaug(M=matroids.catalog.Fano(), R=QQ) + sage: ch.flats_generator() #WHERE IS OUTPUT? + """ return dict(self._flats_generator) -class ChowRingIdeal_nonaug(ChowRingIdeal): +class ChowRingIdeal_nonaug(ChowRingIdeal): r""" - The class of Chow ring ideal, a multi-polynomial ideal. - Base class - ``MPolynomialIdeal``. + The Chow ring ideal. INPUT: + - `M` -- a matroid + - `R` -- a ring - - `M` -- a matroid. - - `R` -- a ring. - - OUTPUT: Chow ring ideal of matroid `M`. + OUTPUT: Chow ring ideal of matroid `M` - EXAMPLES:: + EXAMPLES: Chow ring ideal of uniform matroid of rank 3 on 6 elements:: @@ -89,6 +106,14 @@ def __init__(self, M, R): MPolynomialIdeal.__init__(self, poly_ring, self._gens_constructor(poly_ring)) def _gens_constructor(self, poly_ring): + r""" + Returns the generators of the Chow ring ideal. + + EXAMPLE:: + sage: ch = ChowRingIdeal_nonaug(M=matroids.catalog.NonFano(), R=QQ) + sage: ch._gens_constructor() #WHERE IS OUTPUT? + + """ E = list(self._matroid.groundset()) flats = list(self._flats_generator.keys()) flats_containing = {x: [] for x in E} @@ -103,12 +128,19 @@ def _gens_constructor(self, poly_ring): for j,x in enumerate(E) for y in E[j+1:]] return Q + L - def __repr__(self): + def _repr_(self): + r""" + EXAMPLE:: + + sage: ch = ChowRingIdeal_nonaug(M=matroids.catalog.Fano(), R=QQ) + sage: ch + Chow ring ideal of Fano: Binary matroid of rank 3 on 7 elements, type (3, 0) + """ return "Chow ring ideal of {}".format(self._matroid) def groebner_basis(self): r""" - Returns the Groebner basis of the Chow ring ideal of consideration. + Returns the Groebner basis of the Chow ring ideal. Return type - ``PolynomialSequence``. EXAMPLES:: @@ -206,6 +238,16 @@ def __init__(self, M, R): def _gens_constructor(self, poly_ring): + r""" + Return the generators of augmented Chow ring ideal of + Feitchner-Yuzvinsky presentation. + + EXAMPLES:: + + sage: ch = AugmentedChowRingIdeal_fy(M=matroids.Wheel(3), R=QQ) + sage: ch._gens_constructor() #WHERE IS OUTPUT? + + """ E = list(self._matroid.groundset()) flats_containing = {x: [] for x in E} for F in self._flats: @@ -226,7 +268,15 @@ def _gens_constructor(self, poly_ring): L.append(self._flats_generator[x] - term) return Q + L - def __repr__(self): + def _repr_(self): + r""" + EXAMPLES:: + + sage: ch = AugmentedChowRingIdeal_fy(M=matroids.Wheel(3), R=QQ) + sage: ch + Augmented Chow ring ideal of Wheel(3): Regular matroid of rank 3 on + 6 elements with 16 bases of Feitchner-Yuzvinsky presentation + """ return "Augmented Chow ring ideal of {} of Feitchner-Yuzvinsky presentation".format(self._matroid) def groebner_basis(self): @@ -331,7 +381,17 @@ def __init__(self, M, R): MPolynomialIdeal.__init__(self, poly_ring, self._gens_constructor(poly_ring)) - def _gens_constructor(self, poly_ring): + def _gens_constructor(self, poly_ring): + r""" + Return the generators of augmented Chow ring ideal of + atom-free presentation. + + EXAMPLES:: + + sage: ch = AugmentedChowRingIdeal_atom_free(M=matroids.Wheel(3), R=QQ) + sage: ch._gens_constructor() #WHERE IS OUTPUT? + + """ E = list(self._matroid.groundset()) Q = [] flats_containing = {x: [] for x in E} @@ -356,7 +416,15 @@ def _gens_constructor(self, poly_ring): return Q - def __repr__(self): + def _repr_(self): + r""" + EXAMPLE:: + + sage: ch = AugmentedChowRingIdeal_atom_free(M=matroids.Wheel(3), R=QQ) + sage: ch + Augmented Chow ring ideal of Wheel(3): Regular matroid of rank 3 on + 6 elements with 16 bases of atom-free presentation + """ return "Augmented Chow ring ideal of {} of atom-free presentation".format(self._matroid) def groebner_basis(self): From 22b3980a42dc78b0c469df97652973ed2e38e502 Mon Sep 17 00:00:00 2001 From: Newtech66 Date: Mon, 5 Aug 2024 17:06:20 +0530 Subject: [PATCH 097/537] Refactoring and bug fixes --- src/sage/rings/species.py | 184 ++++++++++++++++++++++++-------------- 1 file changed, 119 insertions(+), 65 deletions(-) diff --git a/src/sage/rings/species.py b/src/sage/rings/species.py index d40c8b2265b..fd969f5dbfe 100644 --- a/src/sage/rings/species.py +++ b/src/sage/rings/species.py @@ -10,6 +10,7 @@ from sage.groups.perm_gps.permgroup_named import SymmetricGroup from sage.libs.gap.libgap import libgap from sage.misc.cachefunc import cached_method +from sage.misc.lazy_attribute import lazy_attribute from sage.monoids.indexed_free_monoid import IndexedFreeAbelianMonoid, IndexedFreeAbelianMonoidElement, IndexedMonoid from sage.rings.integer_ring import ZZ from sage.structure.element import Element, parent @@ -45,7 +46,7 @@ def __init__(self): def _cache_get(self, elm): r""" - Return the cached element, or create it + Return the cached element, or add it if it doesn't exist. ``elm`` must implement the following methods: @@ -58,11 +59,16 @@ def _cache_get(self, elm): for other_elm in lookup: if elm == other_elm: return other_elm + elm = self._canonical_label(elm) lookup.append(elm) else: + elm = self._canonical_label(elm) self._cache[key] = [elm] return elm + @cached_method + def _canonical_label(self, elm): + return elm class ConjugacyClassOfDirectlyIndecomposableSubgroups(Element): def __init__(self, parent, C): @@ -71,9 +77,14 @@ def __init__(self, parent, C): """ Element.__init__(self, parent) self._C = C - self._sorted_orbits = tuple(sorted(len(orbit) for orbit in C.orbits())) + self._sorted_orbits = sorted([sorted(orbit) for orbit in C.orbits()], key=len) + self._orbit_lens = tuple(len(orbit) for orbit in self._sorted_orbits) self._order = C.order() + @lazy_attribute + def _canonicalizing_perm(self): + return PermutationGroupElement([e for o in self._sorted_orbits for e in o], check=False) + def __hash__(self): return hash(self._C) @@ -83,6 +94,9 @@ def _repr_(self): """ return f"{self._C.gens_small()}" + def _element_key(self): + return self._C.degree(), self._order, self._orbit_lens + def __eq__(self, other): r""" Return whether ``self`` is equal to ``other``. @@ -92,11 +106,12 @@ def __eq__(self, other): """ return (isinstance(other, ConjugacyClassOfDirectlyIndecomposableSubgroups) and self._C.degree() == other._C.degree() - and _is_conjugate(SymmetricGroup(self._C.degree()), - self._C, other._C)) + and (self._C == other._C + or _is_conjugate(SymmetricGroup(self._C.degree()), + self._C, other._C))) -class ConjugacyClassesOfDirectlyIndecomposableSubgroups(UniqueRepresentation, Parent): +class ConjugacyClassesOfDirectlyIndecomposableSubgroups(UniqueRepresentation, Parent, ElementCache): def __init__(self): r""" Conjugacy classes of directly indecomposable subgroups. @@ -121,20 +136,25 @@ def _element_constructor_(self, x): if isinstance(x, PermutationGroup_generic): if len(x.disjoint_direct_product_decomposition()) > 1: raise ValueError(f"{x} is not directly indecomposable") - pi = self.canonical_label(x) - return self.element_class(self, PermutationGroup(gap_group=libgap.ConjugateGroup(x, pi))) + elm = self.element_class(self, x) + return self._cache_get(elm) raise ValueError(f"unable to convert {x} to {self}") def _repr_(self): return "Infinite set of conjugacy classes of directly indecomposable subgroups" @cached_method - def canonical_label(self, H): + def canonical_label(self, elm): r""" - Return the permutation group element `g` such that - `g^{-1} H g` is a canonical representative. + + EXAMPLES:: + + sage: G = PermutationGroup([[(1,3),(4,7)], [(2,5),(6,8)], [(1,4),(2,5),(3,7)]]) + sage: A = AtomicSpecies(1) + sage: A(G) + {[(5,6)(7,8), (1,2)(5,7)(6,8), (1,2)(3,4)]: (8,)} """ - return PermutationGroupElement([e for o in sorted([sorted(orbit) for orbit in H.orbits()], key=len) for e in o], check=False) + return self.element_class(self, PermutationGroup(gap_group=libgap.ConjugateGroup(elm._C, elm._canonicalizing_perm))) Element = ConjugacyClassOfDirectlyIndecomposableSubgroups @@ -169,13 +189,13 @@ def _element_key(self): r""" Return a lookup key for ``self``. """ - return self._mc, self._dis._order, self._dis._sorted_orbits + return self._mc, self._dis def __hash__(self): r""" Return the hash of the atomic species. """ - return hash((self._mc, self._dis)) + return hash(self._element_key()) def __eq__(self, other): r""" @@ -192,7 +212,7 @@ def _repr_(self): """ return "{" + f"{self._dis}: {self._mc}" + "}" - +# How to remember the names without ElementCache? class AtomicSpecies(UniqueRepresentation, Parent, ElementCache): def __init__(self, k): r""" @@ -278,9 +298,8 @@ def _element_constructor_(self, x): raise ValueError(f"{x} must be a tuple for multivariate species") H_norm, dompart = self._normalize(H, M) dis_elm = self._dis_ctor(H_norm) - # Python sorts are stable so we can use sorted twice without worrying about a change - # in the output. - pi = self._dis_ctor.canonical_label(H_norm) + # Trying to avoid libgap.RepresentativeAction; it is slow + pi = dis_elm._canonicalizing_perm dompart_norm = {pi(k): v for k, v in dompart.items()} elm = self.element_class(self, dis_elm, dompart_norm) return self._cache_get(elm) @@ -328,97 +347,132 @@ def __init__(self, indices, prefix, **kwds): category = Monoids() & InfiniteEnumeratedSets() IndexedFreeAbelianMonoid.__init__(self, indices, prefix=prefix, category=category, **kwds) ElementCache.__init__(self) + self._k = indices._k + # I don't think _element_constructor is ever called, so def _element_constructor_(self, x=None): - elm = self._cache_get(super()._element_constructor_(x)) - if elm._group is None: - elm._group_constructor() - return elm + print("molecular species element constructor is called!") + raise NotImplementedError @cached_method def one(self): elm = super().one() elm._group = SymmetricGroup(0) + elm._dompart = dict() + elm._mc = [0 for _ in range(self._k)] + elm._tc = 0 return elm def gen(self, x): - elm = self._cache_get(super().gen(x)) + r""" + Create the molecular species from an atomic species. + """ + if x not in self._indices: + raise IndexError(f"{x} is not in the index set") + at = self._indices(x) + elm = self._cache_get(self.element_class(self, {at: ZZ.one()})) if elm._group is None: - elm._group_constructor() + elm._group = at._dis._C + elm._dompart = at._dompart + elm._mc = at._mc + elm._tc = at._tc return elm class Element(IndexedFreeAbelianMonoidElement): def __init__(self, F, x): super().__init__(F, x) self._group = None + self._dompart = None + self._mc = None + self._tc = None + + def _assign_group_info(self, other): + self._group = other._group + self._dompart = other._dompart + self._mc = other._mc + self._tc = other._tc def _group_constructor(self): r""" Construct the group of ``self``. """ - if self._group is None: - self._group = SymmetricGroup(0) + temp = self.parent().one() for A, p in self._monomial.items(): - curgrp = self._groupexp(A._dis._C, p) - self._group = self._groupmul(self._group, curgrp) + at = self.parent().gen(A) + at_p = at ** p + temp = temp * at_p + self._assign_group_info(temp) - def _groupmul(self, G1, G2): + def _elmmul(self, elm1, elm2): r""" - Multiply two groups. + Populate the group info of ``self`` by multiplying + the groups of ``elm1`` and ``elm2``. """ - # Would be great to be able to cache the intermediate results - if G1.degree() + G2.degree() == 0: - return SymmetricGroup(0) - if G1.degree() == 0: - return G2 - if G2.degree() == 0: - return G1 - gens1 = G1.gens() + if elm1._group is None: + elm1._group_constructor() + if elm2._group is None: + elm2._group_constructor() + if elm1.grade() == 0: + self._assign_group_info(elm2) + return + if elm2.grade() == 0: + self._assign_group_info(elm1) + return + self._mc = [elm1._mc[i] + elm2._mc[i] for i in range(self.parent()._k)] + self._tc = elm1._tc + elm2._tc + gens1 = elm1._group.gens() + # Try to avoid gens_small unless necessary if len(gens1) > 50: - gens1 = G1.gens_small() - gens2 = G2.gens() + gens1 = elm1._group.gens_small() + gens2 = elm2._group.gens() if len(gens2) > 50: - gens1 = G2.gens_small() + gens2 = elm2._group.gens_small() # always loop over the smaller gens list if len(gens1) < len(gens2): gens1, gens2 = gens2, gens1 - G1, G2 = G2, G1 + elm1, elm2 = elm2, elm1 gens = list(gens1) + self._dompart = elm1._dompart | {(elm1._tc + k): v for k, v in elm2._dompart.items()} for gen in gens2: - gens.append([tuple(G1.degree() + k for k in cyc) for cyc in gen.cycle_tuples()]) - return PermutationGroup(gens, domain=range(1, G1.degree() + G2.degree() + 1)) + gens.append([tuple(elm1._tc + k for k in cyc) for cyc in gen.cycle_tuples()]) + self._group = PermutationGroup(gens, domain=range(1, elm1._tc + elm2._tc + 1)) - def _groupexp(self, G, n): - r""" - Exponentiate a group. - """ - grp = SymmetricGroup(0) - while n > 0: - if n % 2 == 1: - grp = self._groupmul(grp, G) - G = self._groupmul(G, G) - n //= 2 - return grp + def __floordiv__(self, elt): + raise NotImplementedError("Cannot cancel in this monoid") - # TODO: didn't override __floordiv__ def _mul_(self, other): + r""" + Multiply ``self`` by ``other``. + """ res = super()._mul_(other) elm = self.parent()._cache_get(res) - if self._group is None: - self._group = SymmetricGroup(0) if elm._group is None: - # Multiply two groups - elm._group = elm._groupmul(self._group, other._group) + elm._elmmul(self, other) return elm + def _elmexp(self, other, n): + r""" + Populate the group info of ``self`` by exponentiating + the group of ``other``. + """ + if other._group is None: + other._group_constructor() + temp = self.parent().one() + while n > 0: + if n % 2 == 1: + temp = temp * other + other = other * other + n //= 2 + self._assign_group_info(temp) + def __pow__(self, n): + r""" + Raise ``self`` to the power of ``n``. + """ res = super().__pow__(n) elm = self.parent()._cache_get(res) - if self._group is None: - self._group = SymmetricGroup(0) if elm._group is None: - # Exponentiate the group - elm._group = elm._groupexp(self._group, n) + elm._elmexp(self, n) return elm def _element_key(self): @@ -428,13 +482,13 @@ def grade(self): r""" Return the grade of ``self``. """ - return sum(A._tc * p for A, p in self._monomial.items()) + return self._tc def domain(self): r""" Return the domain of ``self``. """ - return FiniteEnumeratedSet(range(1, self.grade() + 1)) + return FiniteEnumeratedSet(range(1, self._tc + 1)) class PolynomialSpecies(CombinatorialFreeModule): From c9a138f1ac7fcd6230882a61dae6e1a58e7f62c2 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Mon, 5 Aug 2024 17:22:07 +0530 Subject: [PATCH 098/537] Corrected Doctests for Element class --- src/sage/matroids/chow_ring.py | 82 +++++++++++++++++----------------- 1 file changed, 40 insertions(+), 42 deletions(-) diff --git a/src/sage/matroids/chow_ring.py b/src/sage/matroids/chow_ring.py index 1a8e8f2bed1..2267bb67741 100644 --- a/src/sage/matroids/chow_ring.py +++ b/src/sage/matroids/chow_ring.py @@ -72,6 +72,16 @@ def __init__(self, R, M, augmented, presentation=None): QuotientRing_nc.__init__(self, R=self._ideal.ring(), I=self._ideal, names=self._ideal.ring().variable_names(), category=GradedAlgebrasWithBasis(R)) def _repr_(self): + r""" + EXAMPLE:: + + sage: from sage.matroids.chow_ring import ChowRing + + sage: M1 = matroids.catalog.Fano() + sage: ch = ChowRing(M=M1, R=QQ, augmented=False) + sage: ch + Chow ring of Fano: Binary matroid of rank 3 on 7 elements, type (3, 0) + """ return "Chow ring of {}".format(self._matroid) def _latex_(self): @@ -84,14 +94,21 @@ def _coerce_map_from_base_ring(self): TESTS:: - sage: SGA = SymmetricGroupAlgebra(QQ, 4) - sage: GP = SGA.garsia_procesi_module([2, 2]) - sage: GP._coerce_map_from_base_ring() is None + sage: ch = ChowRing(M=matroids.Wheel(3), R=QQ, augmented=False) + sage: ch._coerce_map_from_base_ring() is None True """ return None # don't need anything special def basis(self): + r""" + Return the monomial basis of the given Chow ring. + + EXAMPLES:: + + sage: ch = ChowRing(M=matroids.Uniform(3, 6), augmented=True, presentation='fy') + sage: ch.basis() + """ flats = [Set(X) for i in range(1, self._matroid.rank()) for X in self._matroid.flats(i)] flats.append(Set([])) @@ -120,7 +137,7 @@ def func(A, B): term *= flats_gen[flats[j]]**(i + 1) monomial_basis.append(term) - elif self._presentation == 'atom-free': #all double equals need spacing + elif self._presentation == 'atom-free': #all double equals need spacing DEBUG first_rank = self._matroid.rank(flats[len(flats)]) for i in range(maximum_rank): pow = [] @@ -131,7 +148,6 @@ def func(A, B): term = prod(flats_gen[flats[p[0]]] ** p[1] for p in pow) monomial_basis.append(term) - else: for i in range(maximum_rank): term = self._ideal.ring().one() @@ -146,19 +162,6 @@ def func(A, B): m_basis = PolynomialSequence(self._ideal.ring(), monomial_basis) return m_basis - - - - - - - - - - - - - class Element(QuotientRing_nc.Element): def to_vector(self, order=None): @@ -167,12 +170,11 @@ def to_vector(self, order=None): EXAMPLES:: - sage: SGA = SymmetricGroupAlgebra(GF(3), 4) - sage: GP22 = SGA.garsia_procesi_module([2, 2]) - sage: v = GP22.an_element(); v - -gp1 - gp2 - gp3 - sage: v.to_vector() - (0, 0, 2, 2, 2, 0) + sage: ch = ChowRing(M=matroids.Uniform(3, 6), R=QQ, augmented=False) + sage: v = ch.an_element(); v #WHAT IS OUTPUT? + + sage: v.to_vector() #WHAT IS OUTPUT? + """ P = self.parent() B = P.basis() @@ -188,12 +190,11 @@ def monomial_coefficients(self, copy=None): EXAMPLES:: - sage: SGA = SymmetricGroupAlgebra(GF(3), 4) - sage: GP31 = SGA.garsia_procesi_module([3, 1]) - sage: v = GP31.an_element(); v - -gp1 - gp2 - gp3 - sage: v.monomial_coefficients() - {0: 2, 1: 2, 2: 2, 3: 0} + sage: ch = ChowRing(M=matroids.catalog.NonFano(), R=QQ, augmented=True, presentation='fy') + sage: v = ch.an_element(); v #WHAT IS OUTPUT + + sage: v.monomial_coefficients() #WHAT IS OUTPUT + """ B = self.parent().basis() f = self.lift() @@ -205,9 +206,8 @@ def degree(self): EXAMPLES:: - sage: SGA = SymmetricGroupAlgebra(GF(3), 4) - sage: GP22 = SGA.garsia_procesi_module([2, 2]) - sage: for b in GP22.basis(): + sage: ch = ChowRing(M=matroids.catalog.Fano(), R=QQ, augmented=True, presentation='atom-free') + sage: for b in ch.basis(): ....: print(b, b.degree()) gp2*gp3 2 gp1*gp3 2 @@ -215,7 +215,7 @@ def degree(self): gp2 1 gp1 1 1 0 - sage: v = sum(GP22.basis()) + sage: v = sum(ch.basis()) sage: v.degree() 2 """ @@ -228,15 +228,14 @@ def homogeneous_degree(self): EXAMPLES:: - sage: SGA = SymmetricGroupAlgebra(GF(2), 4) - sage: GP31 = SGA.garsia_procesi_module([3, 1]) - sage: for b in GP31.basis(): + ch = ChowRing(M=matroids.Uniform(2, 5), R=QQ, augmented=False) + sage: for b in ch.basis(): ....: print(b, b.homogeneous_degree()) gp3 1 gp2 1 gp1 1 1 0 - sage: v = sum(GP31.basis()); v + sage: v = sum(ch.basis()); v gp1 + gp2 + gp3 + 1 sage: v.homogeneous_degree() Traceback (most recent call last): @@ -244,10 +243,9 @@ def homogeneous_degree(self): ValueError: element is not homogeneous TESTS:: - - sage: SGA = SymmetricGroupAlgebra(GF(3), 4) - sage: GP4 = SGA.garsia_procesi_module([4]) - sage: GP4.zero().homogeneous_degree() + + sage: ch = ChowRing(M=matroids.Wheel(3), R=QQ, augmented=False) + sage: ch.zero().homogeneous_degree() Traceback (most recent call last): ... ValueError: the zero element does not have a well-defined degree From 72a160df51b2e66bf6e23d764bb3b39894ea25e3 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Mon, 5 Aug 2024 17:37:40 +0530 Subject: [PATCH 099/537] Edited _repr_() method --- src/sage/matroids/chow_ring.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/sage/matroids/chow_ring.py b/src/sage/matroids/chow_ring.py index 2267bb67741..2ddd7f53032 100644 --- a/src/sage/matroids/chow_ring.py +++ b/src/sage/matroids/chow_ring.py @@ -82,6 +82,11 @@ def _repr_(self): sage: ch Chow ring of Fano: Binary matroid of rank 3 on 7 elements, type (3, 0) """ + if self._augmented: + if self._presentation=='fy': + return "Augmented Chow ring of {} of Feitchner-Yuzvinsky presentation".format(self._matroid) + elif self._presentation=='atom-free': + return "Augmented Chow ring of {} of atom-free presentation".format(self._matroid) return "Chow ring of {}".format(self._matroid) def _latex_(self): From 4da26f39676365cfacfb75cc3fa998183623ad86 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Mon, 5 Aug 2024 17:37:57 +0530 Subject: [PATCH 100/537] Edited chow_ring() doctest --- src/sage/matroids/matroid.pyx | 35 ++++++++++++----------------------- 1 file changed, 12 insertions(+), 23 deletions(-) diff --git a/src/sage/matroids/matroid.pyx b/src/sage/matroids/matroid.pyx index 7a5300bc59b..d7e39f3839f 100644 --- a/src/sage/matroids/matroid.pyx +++ b/src/sage/matroids/matroid.pyx @@ -8059,10 +8059,10 @@ cdef class Matroid(SageObject): EXAMPLES:: sage: M = matroids.Wheel(2) - sage: A = M.chow_ring(); A + sage: A = M.chow_ring(R=ZZ, augmented=False); A Chow ring of Wheel(2): Regular matroid of rank 2 on 4 elements with 5 bases over Integer Ring - sage: A.gens() # needs sage.libs.singular + sage: A._gens_constructor() # needs sage.libs.singular (A23, A23, A23) sage: A23 = A.gen(0) # needs sage.libs.singular sage: A23*A23 # needs sage.libs.singular @@ -8071,28 +8071,17 @@ cdef class Matroid(SageObject): We construct a more interesting example using the Fano matroid:: sage: M = matroids.catalog.Fano() - sage: A = M.chow_ring(QQ); A + sage: A = M.chow_ring(QQ, augmented=False); A Chow ring of Fano: Binary matroid of rank 3 on 7 elements, - type (3, 0) over Rational Field - - Next we get the non-trivial generators and do some computations:: - - sage: # needs sage.libs.singular sage.rings.finite_rings - sage: G = A.gens()[6:] - sage: Ag, Aabf, Aace, Aadg, Abcd, Abeg, Acfg, Adef = G - sage: Ag * Ag - 2*Adef^2 - sage: Ag * Abeg - -Adef^2 - sage: matrix([[x * y for x in G] for y in G]) - [2*Adef^2 0 0 -Adef^2 0 -Adef^2 -Adef^2 0] - [ 0 Adef^2 0 0 0 0 0 0] - [ 0 0 Adef^2 0 0 0 0 0] - [ -Adef^2 0 0 Adef^2 0 0 0 0] - [ 0 0 0 0 Adef^2 0 0 0] - [ -Adef^2 0 0 0 0 Adef^2 0 0] - [ -Adef^2 0 0 0 0 0 Adef^2 0] - [ 0 0 0 0 0 0 0 Adef^2] + type (3, 0) over Rational Field. + + The augmented Chow ring can also be instantiated with the + Feitchner-Yuzvinsky and atom-free presentation:: + + sage: M = matroids.Wheel(3) + sage: ch = M.chow_ring(QQ, augmented=True, presentation='fy') + Augmented Chow ring of Wheel(3): Regular matroid of rank 3 on + 6 elements with 16 bases of Feitchner-Yuzvinsky presentation REFERENCES: From ca5ec9a83eef800b4581e1f09e76246163d31069 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Wed, 7 Aug 2024 09:54:50 +0530 Subject: [PATCH 101/537] Wrote doctests for Element class --- src/sage/matroids/chow_ring.py | 95 +++++++++++++++++++++------------- 1 file changed, 59 insertions(+), 36 deletions(-) diff --git a/src/sage/matroids/chow_ring.py b/src/sage/matroids/chow_ring.py index 2ddd7f53032..25b57b6eb8b 100644 --- a/src/sage/matroids/chow_ring.py +++ b/src/sage/matroids/chow_ring.py @@ -90,8 +90,26 @@ def _repr_(self): return "Chow ring of {}".format(self._matroid) def _latex_(self): + r""" + Return the LaTeX output of the polynomial ring and Chow ring ideal. + + EXAMPLE:: + + sage: from sage.matroids.chow_ring import ChowRing + sage: from sage.matroids.graphic_matroid import GraphicMatroid + + sage: M1 = GraphicMatroid(graphs.CycleGraph(3)) + sage: ch = ChowRing(M=M1, R=QQ, augmented=True, presentation='fy') + sage: ch._latex_() + \Bold{Q}[A_{0}, A_{1}, A_{2}, B_{0}, B_{1}, B_{2}]/\left(B_{0}^{2}, + B_{0} B_{1}, B_{0} B_{2}, B_{0} B_{1}, B_{1}^{2}, B_{1} B_{2}, + B_{0} B_{2}, B_{1} B_{2}, B_{2}^{2}, A_{0} - B_{1} - B_{2}, + A_{1} - B_{0} - B_{2}, A_{2} - B_{0} - B_{1}\right) + \Bold{Q}[A_{0}, A_{1}, A_{2}, B_{0}, B_{1}, B_{2}] + + """ import sage.misc.latex as latex - return "%s/%s" % (latex.latex(self.poly_ring), latex.latex(self._ideal)) + return "%s/%s" % (latex.latex(self._ideal.ring()), latex.latex(self._ideal)) def _coerce_map_from_base_ring(self): r""" @@ -99,6 +117,8 @@ def _coerce_map_from_base_ring(self): TESTS:: + sage: from sage.matroids.chow_ring import ChowRing + sage: ch = ChowRing(M=matroids.Wheel(3), R=QQ, augmented=False) sage: ch._coerce_map_from_base_ring() is None True @@ -111,8 +131,13 @@ def basis(self): EXAMPLES:: - sage: ch = ChowRing(M=matroids.Uniform(3, 6), augmented=True, presentation='fy') + sage: from sage.matroids.chow_ring import ChowRing + + sage: ch = ChowRing(M=matroids.Uniform(3, 6), R=QQ, augmented=True, presentation='fy') sage: ch.basis() + [B0*B01, 1] + sage: ch = ChowRing(M=matroids.Wheel(3), R=ZZ, augmented=False) + [A0*A013, 1] """ flats = [Set(X) for i in range(1, self._matroid.rank()) for X in self._matroid.flats(i)] @@ -121,47 +146,51 @@ def basis(self): flats_gen = self._ideal.flats_generator() def func(A, B): if A.issubset(B): - return 1 - elif B.issubset(A): return -1 + elif B.issubset(A): + return 1 else: return 0 flats = sorted(flats, key=cmp_to_key(func)) + ranks = [self._matroid.rank(F) for F in flats] monomial_basis = [] if self._augmented: - if self._presentation=='fy': + if self._presentation == 'fy': for i in range(maximum_rank): term = self._ideal.ring().one() for j in range(len(flats)): if j == 0: - if i <= self._matroid.rank(flats[0]): - term *= flats_gen[flats[j]]**(i + 1) + if i <= ranks[0]: + if flats[j] in flats_gen: + term *= flats_gen[flats[j]]**(i + 1) else: - if i < (self._matroid.rank(flats[j]) - self._matroid.rank(flats[j-1])): #store the ranks as a list + if i < ranks[j] - ranks[j-1]: if flats[j] in flats_gen: term *= flats_gen[flats[j]]**(i + 1) monomial_basis.append(term) - elif self._presentation == 'atom-free': #all double equals need spacing DEBUG - first_rank = self._matroid.rank(flats[len(flats)]) + elif self._presentation == 'atom-free': #all double equals need spacing + first_rank = self._matroid.rank(flats[len(flats) - 1]) + print(first_rank) for i in range(maximum_rank): pow = [] for j in range(1, len(flats) - 1): - if i >= (self._matroid.rank(flats[j]) - self._matroid.rank(flats[j-1])): + if i < ranks[j] - ranks[j-1]: pow.append((j , i)) - if sum(p[1] for p in pow) == first_rank: + if sum(p[1] for p in pow) == first_rank + 1: term = prod(flats_gen[flats[p[0]]] ** p[1] for p in pow) monomial_basis.append(term) - + else: for i in range(maximum_rank): term = self._ideal.ring().one() for j in range(len(flats)): - if i > (self._matroid.rank(flats[j]) - self._matroid.rank(flats[j-1]) - 1): + if i > ranks[j] - ranks[j-1] - 1: if flats[j] in list(flats_gen): term *= flats_gen[flats[j]]**(0) else: - term *= flats_gen[flats[j]]**(i + 1) + if flats[j] in list(flats_gen): + term *= flats_gen[flats[j]]**(i + 1) monomial_basis.append(term) @@ -176,9 +205,9 @@ def to_vector(self, order=None): EXAMPLES:: sage: ch = ChowRing(M=matroids.Uniform(3, 6), R=QQ, augmented=False) - sage: v = ch.an_element(); v #WHAT IS OUTPUT? - - sage: v.to_vector() #WHAT IS OUTPUT? + sage: v = ch.an_element(); v + A0 + sage: v.to_vector() #Error in output! """ P = self.parent() @@ -196,9 +225,9 @@ def monomial_coefficients(self, copy=None): EXAMPLES:: sage: ch = ChowRing(M=matroids.catalog.NonFano(), R=QQ, augmented=True, presentation='fy') - sage: v = ch.an_element(); v #WHAT IS OUTPUT - - sage: v.monomial_coefficients() #WHAT IS OUTPUT + sage: v = ch.an_element(); v + 0 + sage: v.monomial_coefficients() #error in output! """ B = self.parent().basis() @@ -211,14 +240,10 @@ def degree(self): EXAMPLES:: - sage: ch = ChowRing(M=matroids.catalog.Fano(), R=QQ, augmented=True, presentation='atom-free') + sage: ch = ChowRing(M=matroids.Uniform(3, 6), R=QQ, augmented=False) sage: for b in ch.basis(): ....: print(b, b.degree()) - gp2*gp3 2 - gp1*gp3 2 - gp3 1 - gp2 1 - gp1 1 + A0*A01 2 1 0 sage: v = sum(ch.basis()) sage: v.degree() @@ -233,16 +258,14 @@ def homogeneous_degree(self): EXAMPLES:: - ch = ChowRing(M=matroids.Uniform(2, 5), R=QQ, augmented=False) + ch = ChowRing(M=matroids.catalog.Fano(), R=QQ, augmented=True, presentation='fy') sage: for b in ch.basis(): ....: print(b, b.homogeneous_degree()) - gp3 1 - gp2 1 - gp1 1 - 1 0 + Ba*Babf 2 + Ba^2 2 sage: v = sum(ch.basis()); v - gp1 + gp2 + gp3 + 1 - sage: v.homogeneous_degree() + Ba^2 + Ba*Babf + sage: v.homogeneous_degree() #error - basis() type is wrong! Traceback (most recent call last): ... ValueError: element is not homogeneous @@ -250,8 +273,8 @@ def homogeneous_degree(self): TESTS:: sage: ch = ChowRing(M=matroids.Wheel(3), R=QQ, augmented=False) - sage: ch.zero().homogeneous_degree() - Traceback (most recent call last): + sage: ch.zero().homogeneous_degree() #error! + Traceback (most recent call last): ... ValueError: the zero element does not have a well-defined degree """ From a90f02fc88eafe311d71fe266dd64ba6b5e00bf0 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Wed, 7 Aug 2024 09:55:10 +0530 Subject: [PATCH 102/537] Edited chow_ring() doctest --- src/sage/matroids/matroid.pyx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/sage/matroids/matroid.pyx b/src/sage/matroids/matroid.pyx index d7e39f3839f..924d2db2878 100644 --- a/src/sage/matroids/matroid.pyx +++ b/src/sage/matroids/matroid.pyx @@ -8082,6 +8082,10 @@ cdef class Matroid(SageObject): sage: ch = M.chow_ring(QQ, augmented=True, presentation='fy') Augmented Chow ring of Wheel(3): Regular matroid of rank 3 on 6 elements with 16 bases of Feitchner-Yuzvinsky presentation + sage: M = matroids.Uniform(3, 6) + sage: ch = M.chow_ring(QQ, augmented=True, presentation='atom-free') + Augmented Chow ring of U(3, 6): Matroid of rank 3 on 6 elements with circuit-closures + {3: {{0, 1, 2, 3, 4, 5}}} of atom-free presentation REFERENCES: From 9d6489a33f6e5f368b646558e514253c85fc54f7 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Wed, 7 Aug 2024 09:56:52 +0530 Subject: [PATCH 103/537] Wrote doctests for _gens_constructor() --- src/sage/matroids/chow_ring_ideal.py | 110 ++++++++++++++++++++++++--- 1 file changed, 101 insertions(+), 9 deletions(-) diff --git a/src/sage/matroids/chow_ring_ideal.py b/src/sage/matroids/chow_ring_ideal.py index 73f4ed0eb86..a9abde90c2b 100644 --- a/src/sage/matroids/chow_ring_ideal.py +++ b/src/sage/matroids/chow_ring_ideal.py @@ -51,8 +51,16 @@ def flats_generator(self): EXAMPLE:: + sage: from sage.matroids.chow_ring_ideal import ChowRingIdeal_nonaug + sage: ch = ChowRingIdeal_nonaug(M=matroids.catalog.Fano(), R=QQ) - sage: ch.flats_generator() #WHERE IS OUTPUT? + 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({'b', 'a', 'f'}): Aabf, + frozenset({'c', 'e', 'a'}): Aace, frozenset({'d', 'g', 'a'}): Aadg, + frozenset({'c', 'b', 'd'}): Abcd, frozenset({'b', 'g', 'e'}): Abeg, + frozenset({'c', 'g', 'f'}): Acfg, frozenset({'d', 'e', 'f'}): Adef} """ return dict(self._flats_generator) @@ -107,11 +115,51 @@ def __init__(self, M, R): def _gens_constructor(self, poly_ring): r""" - Returns the generators of the Chow ring ideal. + Returns the generators of the Chow ring ideal. Takes in the + ring of Chow ring ideal as input. EXAMPLE:: + + sage: from sage.matroids.chow_ring_ideal import ChowRingIdeal_nonaug + sage: ch = ChowRingIdeal_nonaug(M=matroids.catalog.NonFano(), R=QQ) - sage: ch._gens_constructor() #WHERE IS OUTPUT? + sage: ch._gens_constructor(ch.ring()) + [Aa*Ab, Aa*Ac, Aa*Ad, Aa*Ae, Aa*Af, Aa*Ag, Aa*Abcd, Aa*Abeg, + Aa*Acfg, Aa*Ade, Aa*Adf, Aa*Aef, Ab*Ac, Ab*Ad, Ab*Ae, Ab*Af, Ab*Ag, + Ab*Aace, Ab*Aadg, Ab*Acfg, Ab*Ade, Ab*Adf, Ab*Aef, Ac*Ad, Ac*Ae, + Ac*Af, Ac*Ag, Ac*Aabf, Ac*Aadg, Ac*Abeg, Ac*Ade, Ac*Adf, Ac*Aef, + Ad*Ae, Ad*Af, Ad*Ag, Ad*Aabf, Ad*Aace, Ad*Abeg, Ad*Acfg, Ad*Aef, + Ae*Af, Ae*Ag, Ae*Aabf, Ae*Aadg, Ae*Abcd, Ae*Acfg, Ae*Adf, Af*Ag, + Af*Aace, Af*Aadg, Af*Abcd, Af*Abeg, Af*Ade, Ag*Aabf, Ag*Aace, + Ag*Abcd, Ag*Ade, Ag*Adf, Ag*Aef, Aabf*Aace, Aabf*Aadg, Aabf*Abcd, + Aabf*Abeg, Aabf*Acfg, Aabf*Ade, Aabf*Adf, Aabf*Aef, Aace*Aadg, + Aace*Abcd, Aace*Abeg, Aace*Acfg, Aace*Ade, Aace*Adf, Aace*Aef, + Aadg*Abcd, Aadg*Abeg, Aadg*Acfg, Aadg*Ade, Aadg*Adf, Aadg*Aef, + Abcd*Abeg, Abcd*Acfg, Abcd*Ade, Abcd*Adf, Abcd*Aef, Abeg*Acfg, + Abeg*Ade, Abeg*Adf, Abeg*Aef, Acfg*Ade, Acfg*Adf, Acfg*Aef, + Ade*Adf, Ade*Aef, Adf*Aef, + -Ab + Ae - Aabf + Aace - Abcd + Ade + Aef, + -Ac + Ae - Abcd + Abeg - Acfg + Ade + Aef, + Ae - Ag + Aace - Aadg - Acfg + Ade + Aef, + -Ad + Ae + Aace - Aadg - Abcd + Abeg - Adf + Aef, + -Aa + Ae - Aabf - Aadg + Abeg + Ade + Aef, + Ae - Af - Aabf + Aace + Abeg - Acfg + Ade - Adf, + Ab - Ac + Aabf - Aace + Abeg - Acfg, + Ab - Ag + Aabf - Aadg + Abcd - Acfg, + Ab - Ad + Aabf - Aadg + Abeg - Ade - Adf, + -Aa + Ab - Aace - Aadg + Abcd + Abeg, + Ab - Af + Abcd + Abeg - Acfg - Adf - Aef, + Ac - Ag + Aace - Aadg + Abcd - Abeg, + Ac - Ad + Aace - Aadg + Acfg - Ade - Adf, + -Aa + Ac - Aabf - Aadg + Abcd + Acfg, + Ac - Af - Aabf + Aace + Abcd - Adf - Aef, + -Ad + Ag - Abcd + Abeg + Acfg - Ade - Adf, + -Aa + Ag - Aabf - Aace + Abeg + Acfg, + -Af + Ag - Aabf + Aadg + Abeg - Adf - Aef, + -Aa + Ad - Aabf - Aace + Abcd + Ade + Adf, + Ad - Af - Aabf + Aadg + Abcd - Acfg + Ade - Aef, + Aa - Af + Aace + Aadg - Acfg - Adf - Aef] + """ E = list(self._matroid.groundset()) @@ -132,6 +180,8 @@ def _repr_(self): r""" EXAMPLE:: + sage: from sage.matroids.chow_ring_ideal import ChowRingIdeal_nonaug + sage: ch = ChowRingIdeal_nonaug(M=matroids.catalog.Fano(), R=QQ) sage: ch Chow ring ideal of Fano: Binary matroid of rank 3 on 7 elements, type (3, 0) @@ -217,7 +267,7 @@ def __init__(self, M, R): sage: from sage.matroids.chow_ring_ideal import AugmentedChowRingIdeal_fy sage: I = AugmentedChowRingIdeal_fy(M=matroids.Wheel(3), R=QQ) - sage: TestSuite(I).run() + sage: TestSuite(I).run(skip="_test_category") """ self._matroid = M self._flats = [X for i in range(1, self._matroid.rank()) @@ -240,12 +290,39 @@ def __init__(self, M, R): def _gens_constructor(self, poly_ring): r""" Return the generators of augmented Chow ring ideal of - Feitchner-Yuzvinsky presentation. + Feitchner-Yuzvinsky presentation. Takes in the ring of + that augmented Chow ring ideal as input. EXAMPLES:: + sage: from sage.matroids.chow_ring_ideal import AugmentedChowRingIdeal_fy + sage: ch = AugmentedChowRingIdeal_fy(M=matroids.Wheel(3), R=QQ) - sage: ch._gens_constructor() #WHERE IS OUTPUT? + sage: ch._gens_constructor(ch.ring()) + [B0^2, B0*B1, B0*B2, B0*B3, B0*B4, B0*B5, B0*B124, B0*B15, B0*B23, + B0*B345, B0*B1, B1^2, B1*B2, B1*B3, B1*B4, B1*B5, B1*B025, B1*B04, + B1*B23, B1*B345, B0*B2, B1*B2, B2^2, B2*B3, B2*B4, B2*B5, B2*B013, + B2*B04, B2*B15, B2*B345, B0*B3, B1*B3, B2*B3, B3^2, B3*B4, B3*B5, + B3*B025, B3*B04, B3*B124, B3*B15, B0*B4, B1*B4, B2*B4, B3*B4, B4^2, + B4*B5, B4*B013, B4*B025, B4*B15, B4*B23, B0*B5, B1*B5, B2*B5, + B3*B5, B4*B5, B5^2, B5*B013, B5*B04, B5*B124, B5*B23, B2*B013, + B4*B013, B5*B013, B013^2, B013*B025, B013*B04, B013*B124, B013*B15, + B013*B23, B013*B345, B1*B025, B3*B025, B4*B025, B013*B025, B025^2, + B025*B04, B025*B124, B025*B15, B025*B23, B025*B345, B1*B04, B2*B04, + B3*B04, B5*B04, B013*B04, B025*B04, B04^2, B04*B124, B04*B15, + B04*B23, B04*B345, B0*B124, B3*B124, B5*B124, B013*B124, B025*B124, + B04*B124, B124^2, B124*B15, B124*B23, B124*B345, B0*B15, B2*B15, + B3*B15, B4*B15, B013*B15, B025*B15, B04*B15, B124*B15, B15^2, + B15*B23, B15*B345, B0*B23, B1*B23, B4*B23, B5*B23, B013*B23, + B025*B23, B04*B23, B124*B23, B15*B23, B23^2, B23*B345, B0*B345, + B1*B345, B2*B345, B013*B345, B025*B345, B04*B345, B124*B345, + B15*B345, B23*B345, B345^2, + A0 - B1 - B2 - B3 - B4 - B5 - B124 - B15 - B23 - B345, + A1 - B0 - B2 - B3 - B4 - B5 - B025 - B04 - B23 - B345, + A2 - B0 - B1 - B3 - B4 - B5 - B013 - B04 - B15 - B345, + A3 - B0 - B1 - B2 - B4 - B5 - B025 - B04 - B124 - B15, + A4 - B0 - B1 - B2 - B3 - B5 - B013 - B025 - B15 - B23, + A5 - B0 - B1 - B2 - B3 - B4 - B013 - B04 - B124 - B23] """ E = list(self._matroid.groundset()) @@ -272,6 +349,8 @@ def _repr_(self): r""" EXAMPLES:: + sage: from sage.matroids.chow_ring_ideal import AugmentedChowRingIdeal_fy + sage: ch = AugmentedChowRingIdeal_fy(M=matroids.Wheel(3), R=QQ) sage: ch Augmented Chow ring ideal of Wheel(3): Regular matroid of rank 3 on @@ -384,12 +463,23 @@ def __init__(self, M, R): def _gens_constructor(self, poly_ring): r""" Return the generators of augmented Chow ring ideal of - atom-free presentation. + atom-free presentation. Takes in the ring of that augmented + Chow ring ideal as input. EXAMPLES:: - sage: ch = AugmentedChowRingIdeal_atom_free(M=matroids.Wheel(3), R=QQ) - sage: ch._gens_constructor() #WHERE IS OUTPUT? + sage: from sage.matroids.chow_ring_ideal import AugmentedChowRingIdeal_atom_free + sage: from sage.matroids.graphic_matroid import GraphicMatroid + + sage: M1 = GraphicMatroid(graphs.CycleGraph(3)) + sage: ch = AugmentedChowRingIdeal_atom_free(M=M1, R=QQ) + sage: ch._gens_constructor(ch.ring()) + [A0^2, A0^2, A1^2, A0*A1, A2^2, A0*A2, A0*A1, A0^2, A1^2, A0*A1, + A2^2, A0*A2, A0*A2, A0^2, A1^2, A0*A1, A2^2, A0*A2, A0*A1, A0^2, + A0*A1, A1^2, A2^2, A1*A2, A1^2, A0^2, A0*A1, A1^2, A2^2, A1*A2, + A1*A2, A0^2, A0*A1, A1^2, A2^2, A1*A2, A0*A2, A0^2, A0*A2, A1^2, + A1*A2, A2^2, A1*A2, A0^2, A0*A2, A1^2, A1*A2, A2^2, A2^2, A0^2, + A0*A2, A1^2, A1*A2, A2^2] """ E = list(self._matroid.groundset()) @@ -420,6 +510,8 @@ def _repr_(self): r""" EXAMPLE:: + sage: from sage.matroids.chow_ring_ideal import AugmentedChowRingIdeal_atom_free + sage: ch = AugmentedChowRingIdeal_atom_free(M=matroids.Wheel(3), R=QQ) sage: ch Augmented Chow ring ideal of Wheel(3): Regular matroid of rank 3 on From c7fa9eadac2291351feddcec28321d6819f0ddd6 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Wed, 7 Aug 2024 11:13:16 +0530 Subject: [PATCH 104/537] Changed ChowRing category --- src/sage/matroids/chow_ring.py | 31 ++++++++++++------------------- 1 file changed, 12 insertions(+), 19 deletions(-) diff --git a/src/sage/matroids/chow_ring.py b/src/sage/matroids/chow_ring.py index 25b57b6eb8b..d5dd7e1f17f 100644 --- a/src/sage/matroids/chow_ring.py +++ b/src/sage/matroids/chow_ring.py @@ -17,17 +17,17 @@ """ from sage.matroids.chow_ring_ideal import ChowRingIdeal_nonaug, AugmentedChowRingIdeal_fy, AugmentedChowRingIdeal_atom_free -from sage.rings.quotient_ring import QuotientRing_nc +from sage.rings.quotient_ring import QuotientRing_generic from sage.categories.graded_algebras_with_basis import GradedAlgebrasWithBasis +from sage.categories.commutative_rings import CommutativeRings from sage.rings.polynomial.multi_polynomial_sequence import PolynomialSequence from sage.sets.set import Set from functools import cmp_to_key from sage.misc.misc_c import prod -class ChowRing(QuotientRing_nc): +class ChowRing(QuotientRing_generic): r""" The class of Chow ring, a multi-polynomial quotient ring. - Base class - ``QuotientRing_nc``. INPUT: @@ -69,7 +69,8 @@ def __init__(self, R, M, augmented, presentation=None): self._ideal = AugmentedChowRingIdeal_atom_free(M, R) else: self._ideal = ChowRingIdeal_nonaug(M, R) #check method to get ring - QuotientRing_nc.__init__(self, R=self._ideal.ring(), I=self._ideal, names=self._ideal.ring().variable_names(), category=GradedAlgebrasWithBasis(R)) + C = CommutativeRings().Quotients() & GradedAlgebrasWithBasis(R).FiniteDimensional() + QuotientRing_generic.__init__(self, R=self._ideal.ring(), I=self._ideal, names=self._ideal.ring().variable_names(), category=C) def _repr_(self): r""" @@ -139,19 +140,12 @@ def basis(self): sage: ch = ChowRing(M=matroids.Wheel(3), R=ZZ, augmented=False) [A0*A013, 1] """ - flats = [Set(X) for i in range(1, self._matroid.rank()) + flats = [X for i in range(1, self._matroid.rank()) for X in self._matroid.flats(i)] - flats.append(Set([])) - maximum_rank = max([self._matroid.rank(F) for F in flats]) + flats.append(frozenset()) + maximum_rank = max(self._matroid.rank(F) for F in flats) flats_gen = self._ideal.flats_generator() - def func(A, B): - if A.issubset(B): - return -1 - elif B.issubset(A): - return 1 - else: - return 0 - flats = sorted(flats, key=cmp_to_key(func)) + flats = sorted(flats, key=lambda X: (len(X), sorted(X))) ranks = [self._matroid.rank(F) for F in flats] monomial_basis = [] if self._augmented: @@ -193,11 +187,10 @@ def func(A, B): term *= flats_gen[flats[j]]**(i + 1) monomial_basis.append(term) + from sage.sets.family import Family + return Family([self.element_class(self, mon, reduce=False) for mon in monomial_basis]) - m_basis = PolynomialSequence(self._ideal.ring(), monomial_basis) - return m_basis - - class Element(QuotientRing_nc.Element): + class Element(QuotientRing_generic.Element): def to_vector(self, order=None): r""" Return ``self`` as a (dense) free module vector. From 33aa1c01e93a9ab5b4389b04e3d3daf5a35e008d Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Wed, 7 Aug 2024 11:13:42 +0530 Subject: [PATCH 105/537] Edited groebner_basis() method --- 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 a9abde90c2b..e7f67f6b6af 100644 --- a/src/sage/matroids/chow_ring_ideal.py +++ b/src/sage/matroids/chow_ring_ideal.py @@ -224,7 +224,7 @@ def groebner_basis(self): for H in flats: if H > G: term += self._flats_generator[H] - if Set(F).is_empty(): + if F.is_empty(): gb.append(term**self._matroid.rank(G)) elif F < G: gb.append(term**(self._matroid.rank(G)-self._matroid.rank(F))) From 6a5af17f70bf054f094208862b80486f328c3e4e Mon Sep 17 00:00:00 2001 From: Newtech66 Date: Thu, 8 Aug 2024 01:11:07 +0530 Subject: [PATCH 106/537] Composition works, if there are no coefficients --- src/sage/rings/species.py | 178 +++++++++++++++++++++++++------------- 1 file changed, 118 insertions(+), 60 deletions(-) diff --git a/src/sage/rings/species.py b/src/sage/rings/species.py index fd969f5dbfe..24763ddd33f 100644 --- a/src/sage/rings/species.py +++ b/src/sage/rings/species.py @@ -1,10 +1,13 @@ -from itertools import chain +from itertools import accumulate, chain, combinations +from sage.categories.cartesian_product import cartesian_product from sage.categories.graded_algebras_with_basis import GradedAlgebrasWithBasis from sage.categories.infinite_enumerated_sets import InfiniteEnumeratedSets from sage.categories.monoids import Monoids from sage.categories.sets_with_grading import SetsWithGrading from sage.combinat.free_module import CombinatorialFreeModule from sage.combinat.integer_vector import IntegerVectors +from sage.combinat.partition import Partitions +from sage.combinat.permutation import Permutations from sage.groups.perm_gps.constructor import PermutationGroupElement from sage.groups.perm_gps.permgroup import PermutationGroup, PermutationGroup_generic from sage.groups.perm_gps.permgroup_named import SymmetricGroup @@ -247,9 +250,13 @@ def _normalize(self, H, M): """ # TODO: Complete the documentation. if set(H.domain()) != set(M.keys()): - raise ValueError(f"Keys of {M} do not match with domain of {H} (= {H.domain()})") + raise ValueError(f"Keys of mapping do not match with domain of {H}") if not set(M.values()).issubset(range(1, self._k + 1)): - raise ValueError(f"Values of {M} must be in the range [1, {self._k}]") + raise ValueError(f"Values of mapping must be in the range [1, {self._k}]") + # each orbit of H must only contain elements from one sort + for orbit in H.orbits(): + if len(set(M[k] for k in orbit)) > 1: + raise ValueError(f"For each orbit of {H}, all elements must belong to the same set") # normalize domain to {1..n} if sorted(M.keys()) == list(range(1, H.degree() + 1)): return H, M @@ -418,7 +425,7 @@ def _elmmul(self, elm1, elm2): if elm2.grade() == 0: self._assign_group_info(elm1) return - self._mc = [elm1._mc[i] + elm2._mc[i] for i in range(self.parent()._k)] + self._mc = tuple(elm1._mc[i] + elm2._mc[i] for i in range(self.parent()._k)) self._tc = elm1._tc + elm2._tc gens1 = elm1._group.gens() # Try to avoid gens_small unless necessary @@ -668,69 +675,120 @@ def is_atomic(self): return self.is_molecular() and len(self.support()[0]) == 1 def __call__(self, *args): + r""" + Return the (partitional) composition of ``self`` with ``args``. + Uses the word class expansion (Theorem 2.3, Auger paper). + """ # should this also have a base ring check or is it coerced? - # the usage of type(self)(...), is it correct? if len(args) != self.parent()._k: raise ValueError(f"Number of args (= {len(args)}) must equal arity of self (= {len(args)})") if any(not isinstance(arg, PolynomialSpecies.Element) for arg in args): raise ValueError("All args must be elements of PolynomialSpecies") - if self.parent()._k > 1 or max(arg.parent()._k for arg in args) > 1: - raise NotImplementedError("Only univariate species are supported") + if min(arg.parent()._k for arg in args) != max(arg.parent()._k for arg in args): + raise ValueError("All args must have same arity") if self.is_virtual() or any(arg.is_virtual() for arg in args): raise NotImplementedError(f"Only non-virtual species are supported") - # Now we only have non-virtual univariate species + + # Now we only have non-virtual species res = 0 - Gm = args[0].monomial_coefficients() - for M, fM in self.monomial_coefficients().items(): + for F, coeff in self.monomial_coefficients().items(): term = 0 - powvecs = IntegerVectors(M.grade(), len(Gm)) - for vec in powvecs: - coeff = 1 - for fN, exponent in zip(Gm.values(), vec): - coeff *= fN ** exponent - N_list = list(chain.from_iterable([[N for _ in range(c)] for N, c in zip(Gm.keys(), vec)])) - R = self.parent()(wreath_imprimitive_general(N_list, M)) - term += coeff * R - res += fM * term + # F(G1;G2;...) each Gi has some molecular decomposition + # Find the automorphisms + combos = [Partitions(p, max_length=len(arg)) for arg, p in zip(args, F._mc)] + # make F such that sort 1 is [123...], and so on + # cache? lol, cache everything + dominverted = sorted(F._dompart.keys(), key=lambda x: F._dompart[x]) + pi = libgap.MappingPermListList(dominverted, libgap.eval(f'[1..{F.grade()}]')) + Fconj = libgap.ConjugateGroup(F._group, pi) + for IVcombo in cartesian_product(combos): + # TODO: calculate coefficient (because each group has some multiplicity) + # Use F(...) x E(..)^m1 ... + dsumpartial = list(accumulate(chain.from_iterable(IVcombo),initial=0)) + Autlist = self._word_automorphism_groups(Fconj, F._mc, IVcombo, dsumpartial) + Gcombos = cartesian_product([[zip(Gs, permedpart) + # for each permutation of the partition + for permedpart in Permutations(IV) + # we want an embedding of permedpart into the Gs + for Gs in combinations(arg.support(), r=len(IV))] + # for each sort + for arg, IV in zip(args, IVcombo)]) + for Gcombo in Gcombos: + gens = [] + mapping = dict() + Fdom = [] + # Find the gens for each group + # Also handles mapping + dsum = 0 + # For the i-th sort + for Gs_sort in Gcombo: + # For each (group, power) pair + for G, cnt in Gs_sort: + dlist = G.domain().list() + Gdeg = G.grade() + curgens = G._group.gens() + cur_mapping = G._dompart + # calculate the gens + for i in range(cnt): + Fdom.append([k + dsum + Gdeg * i for k in sorted(cur_mapping.keys(), key=lambda x: cur_mapping[x])]) + images = libgap.MappingPermListList(dlist, [k + dsum + Gdeg * i for k in dlist]) + mapping |= {(k + dsum + Gdeg * i): v for k, v in cur_mapping.items()} + # Find the gens for this group + for gen in curgens: + gens.append(gen ** images) + dsum += Gdeg * cnt + + Fdom = libgap(Fdom) + Fdomf = libgap.Flat(Fdom) + # for each automorphism group + for Aut in Autlist: + gensrem = [] + # Find the gens for F + for gen in libgap.GeneratorsOfGroup(Aut): + # Since we picked F as the stabilizer subgroup of our current class, + # we don't have to worry about any extra conditions. + perm = libgap.MappingPermListList(Fdomf, libgap.Flat(libgap.Permuted(Fdom, gen))) + gensrem.append(perm) + totgens = gens + gensrem + term += args[0].parent()((PermutationGroup(totgens, domain=range(1, dsum + 1)), mapping)) + res += coeff * term return res - - -def wreath_imprimitive_general(G_list, H): - r""" - H([G[0]] - [G[1]] - ... - [G[m]]) - All members of MolecularSpecies. - """ - if len(G_list) != H.grade(): - raise ValueError(f"length of G_list (= {len(G_list)}) must be equal to degree of H (= {H.grade()})") - - gens, dlist = [], [] - dsum = 0 - for G in G_list: - dlist.append(list(range(dsum + 1, dsum + G.grade() + 1))) - dsum += G.grade() - - Hgens = H._group.gens() - # First find gens of H - for gen in Hgens: - # each cycle must be homogenous in the degrees of groups shifted - # bad things happen if this isn't checked - # example: partitional_composition(E2, X+X^2) - # look at the structure with 1 X and 1 X^2, like {(1), (2,3)} - all_homogenous = True - for cyc in gen.cycle_tuples(): - cyclens = [len(dlist[x - 1]) for x in cyc] - all_homogenous &= min(cyclens) == max(cyclens) - if not all_homogenous: - continue - perm = libgap.Flat(libgap.Permuted(dlist, gen)) - gens.append(perm) - - # Then find gens of G_i - for i in range(len(G_list)): - Ggens = G_list[i]._group.gens() - for gen in Ggens: - images = libgap.MappingPermListList(G_list[i].domain().list(), dlist[i]) - gens.append(gen ** images) - - # Finally create group - return PermutationGroup(gens, domain = range(1, dsum + 1)) + + def _word_automorphism_groups(self, F, Fmc, IVcombo, dsumpartial): + r""" + Given a group F and a tuple of partitions on sorts, + find the word classes and corresponding stabilizer subgroups. + See Theorem 2.3 of the Auger paper. + IVcombo is a tuple of integer partitions. + (I1[x1, x2,...], ..., In[z1,z2,...]) + """ + # It feels like the output of this function can be HEAVILY optimised. + # For example, we only care about unordered integer vectors here. + # Wait, we don't want 0 either. So we actually just want normal integer + # partitions. + + # create domain + # can this be taken out? you could cache this too + domain = list(list(chain.from_iterable(x)) for x in + cartesian_product([Permutations(list(chain.from_iterable([i + precard] * v for i, v in enumerate(part, 1)))) + for precard, part in zip(accumulate(Fmc, initial=0), IVcombo)])) + + orig = domain[0] + orbits = libgap.OrbitsDomain(F, domain, libgap.Permuted) + grps = [] + def relabel(arr): + from collections import Counter + C = Counter({k: v for k, v in enumerate(dsumpartial[:-1], 1)}) + for i in range(len(arr)): + C[arr[i]] += 1 + arr[i] = C[arr[i]] + return arr + origl = relabel(orig) + for orbit in orbits: + # Ok, now I have to find a mapping from orbrep to the original + mutorb = orbit[0].sage() + mutorbl = relabel(mutorb) + pi = libgap.MappingPermListList(mutorbl, origl) + stab = libgap.Stabilizer(F, domain, orbit[0], libgap.Permuted) + grps.append(libgap.ConjugateGroup(stab, pi)) + return grps From 8dabfd60c40c7545274fbc0e0aa2664fff0dbfb1 Mon Sep 17 00:00:00 2001 From: Newtech66 Date: Thu, 8 Aug 2024 03:11:15 +0530 Subject: [PATCH 107/537] Added cartesian product --- src/sage/rings/species.py | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/src/sage/rings/species.py b/src/sage/rings/species.py index 24763ddd33f..2a251ca71f4 100644 --- a/src/sage/rings/species.py +++ b/src/sage/rings/species.py @@ -792,3 +792,36 @@ def relabel(arr): stab = libgap.Stabilizer(F, domain, orbit[0], libgap.Permuted) grps.append(libgap.ConjugateGroup(stab, pi)) return grps + + def cartesian_product(self, other): + r""" + Return the cartesian product of ``self`` with ``other``. + """ + if not isinstance(other, PolynomialSpecies.Element): + raise ValueError(f"{other} must be a polynomial species") + + # Do we want to allow cartesian products between different k-variates? + if self.parent()._k != other.parent()._k: + return self.parent().zero() + + terms = cartesian_product([self.terms(), other.terms()]) + res = 0 + for t1, t2 in terms: + H, coeffH = t1.support()[0], t1.coefficients()[0] + K, coeffK = t2.support()[0], t2.coefficients()[0] + if H._mc != K._mc: + continue + coeff = coeffH * coeffK + Sn = SymmetricGroup(H._tc).young_subgroup(H._mc) + Hgap, Kgap = libgap(H._group), libgap(K._group) + # We need to normalize H and K to have the same domparts + Hd = sorted(H._dompart.keys(), key=lambda x: H._dompart[x]) + Kd = sorted(K._dompart.keys(), key=lambda x: K._dompart[x]) + piH = libgap.MappingPermListList(Hd, Kd) + taus = libgap.DoubleCosetRepsAndSizes(Sn, Hgap, Kgap) + Hgap = libgap.ConjugateGroup(Hgap, piH) + for tau, _ in taus: + tHt = libgap.ConjugateSubgroup(Hgap, tau) + G = PermutationGroup(gap_group=libgap.Intersection(tHt, Kgap), domain=K._dompart.keys()) + res += coeff * self.parent()((G, K._dompart)) + return res From 3cec6b5927601c16ad3dc5c6e432eed4b7fcc0f0 Mon Sep 17 00:00:00 2001 From: Newtech66 Date: Fri, 9 Aug 2024 00:54:17 +0530 Subject: [PATCH 108/537] Added addition formula decomposition --- src/sage/rings/species.py | 66 ++++++++++++++++++++++++++++++--------- 1 file changed, 51 insertions(+), 15 deletions(-) diff --git a/src/sage/rings/species.py b/src/sage/rings/species.py index 2a251ca71f4..59053737957 100644 --- a/src/sage/rings/species.py +++ b/src/sage/rings/species.py @@ -564,7 +564,7 @@ def _element_constructor_(self, x): elif self._k == 1: if isinstance(x, PermutationGroup_generic): H = x - M = {e: 1 for e in H.domain()} + M = {e: ZZ.one() for e in H.domain()} else: raise ValueError(f"{x} must be a permutation group") else: @@ -573,7 +573,7 @@ def _element_constructor_(self, x): term = self._indices.one() for part in domain_partition: term *= self._indices.gen(self._project(H, M, part)) - return self._from_dict({term: 1}) + return self._from_dict({term: ZZ.one()}) def __getitem__(self, x): r""" @@ -701,11 +701,16 @@ def __call__(self, *args): dominverted = sorted(F._dompart.keys(), key=lambda x: F._dompart[x]) pi = libgap.MappingPermListList(dominverted, libgap.eval(f'[1..{F.grade()}]')) Fconj = libgap.ConjugateGroup(F._group, pi) + print('Fconj',Fconj) for IVcombo in cartesian_product(combos): # TODO: calculate coefficient (because each group has some multiplicity) # Use F(...) x E(..)^m1 ... + print('IVcombo',IVcombo) dsumpartial = list(accumulate(chain.from_iterable(IVcombo),initial=0)) - Autlist = self._word_automorphism_groups(Fconj, F._mc, IVcombo, dsumpartial) + print('dsumpartial',dsumpartial) + Gtop = libgap.eval(f'SymmetricGroup({F._tc})') + Autlist = self._word_automorphism_groups(Fconj, F._mc, IVcombo, Gtop, dsumpartial) + print('Autlist',Autlist) Gcombos = cartesian_product([[zip(Gs, permedpart) # for each permutation of the partition for permedpart in Permutations(IV) @@ -714,6 +719,7 @@ def __call__(self, *args): # for each sort for arg, IV in zip(args, IVcombo)]) for Gcombo in Gcombos: + print('Gcombo',Gcombo) gens = [] mapping = dict() Fdom = [] @@ -754,7 +760,7 @@ def __call__(self, *args): res += coeff * term return res - def _word_automorphism_groups(self, F, Fmc, IVcombo, dsumpartial): + def _word_automorphism_groups(self, F, Fmc, IVcombo, Gtop, dsumpartial): r""" Given a group F and a tuple of partitions on sorts, find the word classes and corresponding stabilizer subgroups. @@ -772,24 +778,18 @@ def _word_automorphism_groups(self, F, Fmc, IVcombo, dsumpartial): domain = list(list(chain.from_iterable(x)) for x in cartesian_product([Permutations(list(chain.from_iterable([i + precard] * v for i, v in enumerate(part, 1)))) for precard, part in zip(accumulate(Fmc, initial=0), IVcombo)])) + print('domain', domain) orig = domain[0] orbits = libgap.OrbitsDomain(F, domain, libgap.Permuted) grps = [] - def relabel(arr): - from collections import Counter - C = Counter({k: v for k, v in enumerate(dsumpartial[:-1], 1)}) - for i in range(len(arr)): - C[arr[i]] += 1 - arr[i] = C[arr[i]] - return arr - origl = relabel(orig) for orbit in orbits: # Ok, now I have to find a mapping from orbrep to the original - mutorb = orbit[0].sage() - mutorbl = relabel(mutorb) - pi = libgap.MappingPermListList(mutorbl, origl) + pi = libgap.RepresentativeAction(Gtop, domain, orbit[0], orig, libgap.Permuted) + print(pi) stab = libgap.Stabilizer(F, domain, orbit[0], libgap.Permuted) + print('stab',stab) + print('cj',libgap.ConjugateGroup(stab, pi)) grps.append(libgap.ConjugateGroup(stab, pi)) return grps @@ -825,3 +825,39 @@ def cartesian_product(self, other): G = PermutationGroup(gap_group=libgap.Intersection(tHt, Kgap), domain=K._dompart.keys()) res += coeff * self.parent()((G, K._dompart)) return res + + def addition_formula(self, arg): + r""" + args is a list of the number of terms in each sort. + Returns the addition formula decomposition of + H(X1+X2..+Xk, Y1+Y2+..., ...). + """ + if len(arg) != self.parent()._k: + raise ValueError(f"Number of args (= {len(arg)}) must equal arity of self (= {len(arg)})") + if self.is_virtual() or any(x < 0 for x in arg): + raise NotImplementedError(f"Only non-virtual species are supported") + + # Now we only have non-virtual species + res = 0 + Parg = PolynomialSpecies(sum(arg)) + for F, coeff in self.monomial_coefficients().items(): + term = 0 + S_top = SymmetricGroup(F._tc).young_subgroup(F._mc) + dominv = sorted(F._dompart.keys(),key=lambda x: F._dompart[x]) + pi = libgap.MappingPermListList(dominv, libgap.eval(f'[1..{F.grade()}]')) + Fconj = libgap.ConjugateGroup(F._group, pi) + for parts in cartesian_product([IntegerVectors(k, l) for k, l in zip(F._mc, arg)]): + term2 = 0 + # parts is a tuple of partitions + part = list(chain.from_iterable(parts)) + S_bottom = SymmetricGroup(F._tc).young_subgroup(part) + taus = libgap.DoubleCosetRepsAndSizes(S_top, Fconj, S_bottom) + domvals = chain.from_iterable([[i] * v for i, v in enumerate(part, 1)]) + newdom = {k: v for k, v in zip(range(1, F.grade() + 1), domvals)} + for tau, _ in taus: + tHt = libgap.ConjugateGroup(Fconj, tau) + G = PermutationGroup(gap_group=libgap.Intersection(tHt, S_bottom), domain=F.domain()) + term2 += Parg((G, newdom)) + term += term2 + res += coeff * term + return res \ No newline at end of file From 776bd642b4caeef097fc8dae6e517dbd92799ed4 Mon Sep 17 00:00:00 2001 From: Newtech66 Date: Fri, 9 Aug 2024 16:20:37 +0530 Subject: [PATCH 109/537] Added multiplicity handling --- src/sage/rings/species.py | 51 ++++++++++++++++++++++++++++++++++----- 1 file changed, 45 insertions(+), 6 deletions(-) diff --git a/src/sage/rings/species.py b/src/sage/rings/species.py index 59053737957..4e841a2d727 100644 --- a/src/sage/rings/species.py +++ b/src/sage/rings/species.py @@ -1,4 +1,6 @@ from itertools import accumulate, chain, combinations +from math import prod +from sage.arith.misc import binomial from sage.categories.cartesian_product import cartesian_product from sage.categories.graded_algebras_with_basis import GradedAlgebrasWithBasis from sage.categories.infinite_enumerated_sets import InfiniteEnumeratedSets @@ -834,10 +836,9 @@ def addition_formula(self, arg): """ if len(arg) != self.parent()._k: raise ValueError(f"Number of args (= {len(arg)}) must equal arity of self (= {len(arg)})") - if self.is_virtual() or any(x < 0 for x in arg): - raise NotImplementedError(f"Only non-virtual species are supported") + if any(x <= 0 for x in arg): + raise ValueError(f"All values must be strictly positive") - # Now we only have non-virtual species res = 0 Parg = PolynomialSpecies(sum(arg)) for F, coeff in self.monomial_coefficients().items(): @@ -847,7 +848,6 @@ def addition_formula(self, arg): pi = libgap.MappingPermListList(dominv, libgap.eval(f'[1..{F.grade()}]')) Fconj = libgap.ConjugateGroup(F._group, pi) for parts in cartesian_product([IntegerVectors(k, l) for k, l in zip(F._mc, arg)]): - term2 = 0 # parts is a tuple of partitions part = list(chain.from_iterable(parts)) S_bottom = SymmetricGroup(F._tc).young_subgroup(part) @@ -857,7 +857,46 @@ def addition_formula(self, arg): for tau, _ in taus: tHt = libgap.ConjugateGroup(Fconj, tau) G = PermutationGroup(gap_group=libgap.Intersection(tHt, S_bottom), domain=F.domain()) - term2 += Parg((G, newdom)) - term += term2 + term += Parg((G, newdom)) res += coeff * term + return res + + def _embedding_coeff(self, part, n): + r""" + Number of embeddings of the partition ``part`` into a + list of length `n` (where holes are filled with `0`). + """ + return Permutations(part).cardinality() * binomial(n, len(part)) + + def _multiplicity_handling(self, F, coeffs): + r""" + Handles cases of the form F(m1X1,m2X2,...). + coeffs is the mi. Hmc is the cardinality on each sort. + F is a PolynomialSpeciesElement. + """ + if len(coeffs) != self.parent()._k: + raise ValueError(f"Number of args (= {len(coeffs)}) must equal arity of self (= {len(coeffs)})") + if any(x <= 0 for x in coeffs): + raise ValueError(f"All values must be strictly positive") + + Fm = F.support()[0] + Fmc = Fm._mc + Fgap = Fm._group.gap() + # What we basically have is a specialisation of the addition + # formula, but setting X1=...=Xk=X. + res = 0 + PF = F.parent() + S_top = SymmetricGroup(Fm._tc).young_subgroup(Fmc) + for parts in cartesian_product([Partitions(k, max_length=l) for k, l in zip(Fmc, coeffs)]): + term = 0 + # parts is a tuple of partitions + part = list(chain.from_iterable(parts)) + S_bottom = SymmetricGroup(Fm._tc).young_subgroup(part) + taus = libgap.DoubleCosetRepsAndSizes(S_top, Fgap, S_bottom) + for tau, _ in taus: + tHt = libgap.ConjugateGroup(Fgap, tau) + G = PermutationGroup(gap_group=libgap.Intersection(tHt, S_bottom), domain=Fm.domain()) + term += PF((G, Fm._dompart)) + term *= prod([self._embedding_coeff(p, n) for p, n in zip(parts, coeffs)]) + res += term return res \ No newline at end of file From 8c71e8251e8b5c57df007568f867f010764d4d47 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Sat, 10 Aug 2024 15:48:11 +0530 Subject: [PATCH 110/537] Added references --- src/doc/en/reference/references/index.rst | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/doc/en/reference/references/index.rst b/src/doc/en/reference/references/index.rst index db5afe04784..46e3bf33f3a 100644 --- a/src/doc/en/reference/references/index.rst +++ b/src/doc/en/reference/references/index.rst @@ -260,6 +260,9 @@ REFERENCES: .. [Ang1997] B. Anglès. 1997. *On some characteristic polynomials attached to finite Drinfeld modules.* manuscripta mathematica 93, 1 (01 Aug 1997), 369–379. https://doi.org/10.1007/BF02677478 + +.. [ANR2023] Robert Angarone, Anastasia Nathanson, and Victor Reiner. *Chow rings of + matroids as permutation representations*, 2023. :arxiv: `2309.14312`. .. [AP1986] \S. Arnborg, A. Proskurowski, *Characterization and Recognition of Partial 3-Trees*, @@ -4860,6 +4863,9 @@ REFERENCES: .. [MM2015] \J. Matherne and \G. Muller, *Computing upper cluster algebras*, Int. Math. Res. Not. IMRN, 2015, 3121-3149. +.. [MM2022] Matthew Mastroeni and Jason McCullough. Chow rings of matroids are + koszul. *Mathematische Annalen*, 387(3–4):1819–1851, November 2022. + .. [MMRS2022] Ruslan G. Marzo, Rafael A. Melo, Celso C. Ribeiro and Marcio C. Santos: *New formulations and branch-and-cut procedures for the longest induced path problem*. Computers & Operations From 6b6d0e1e752a0b35474b4bdcf159d6c7a443573b Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Sat, 10 Aug 2024 15:48:35 +0530 Subject: [PATCH 111/537] Wrote mathematical definition of Chow ring --- src/sage/matroids/chow_ring.py | 64 ++++++++++++++++++++++++++++++---- 1 file changed, 58 insertions(+), 6 deletions(-) diff --git a/src/sage/matroids/chow_ring.py b/src/sage/matroids/chow_ring.py index d5dd7e1f17f..e94be14a2cc 100644 --- a/src/sage/matroids/chow_ring.py +++ b/src/sage/matroids/chow_ring.py @@ -9,20 +9,72 @@ a parameter boolean ``augmented`` which creates the augmented Chow ring if given ``True``. +INPUT:: -REFERENCES +- `R` -- commutative ring +- `M` -- matroid +- `augmented` -- If `True`, returns augmented Chow ring of input presentation + and returns non-augmented Chow ring if `False`. +- `presentation` -- Takes in augmented Chow ring presentation as a string if + augmented is `True`. Implemented resentations are `fy` and `atom-free`, + default value is `None` -- :arxiv:`2309.14312` -- :arxiv:`2111.00393` +The Chow ring of a matroid is defined as the quotient ring: + +.. MATH:: + + A^*(M)_R := R[x_{F_1}, \ldots, x_{F_k}] / (Q_M + L_M) + + where + +..MATH:: + + (Q_M + L_M) + + is the Chow ring ideal of matroid `M`. + +The augmented Chow ring of matroid `M` of Feitchner-Yuzvinsky presentation +is the quotient ring: + +..MATH:: + + A(M)_R := R[y_{e_1}, \ldots, y_{e_n}, x_{F_1}, \ldots, x_{F_k}] / (I_M + J_M) + + where + +..MATH:: + + (I_M + J_M) + + is the augmented Chow ring ideal of matroid `M` of Feitchner-Yuzvinsky + presentation. + +The augmented Chow ring ideal of atom-free presentation is the quotient ring: + +..MATH:: + + A(M)_R := R[x_{F_1}, \ldots, x_{F_k}] / I_{af}M + + where + + I_{af}M + + is the augmented Chow ring ideal of matroid `M` of atom-free presentation. + +.. SEEALSO:: + + :mod: sage.matroids.chow_ring_ideal + +REFERENCES: + + - [FY2004]_ + - [AHK2015]_ """ 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.commutative_rings import CommutativeRings -from sage.rings.polynomial.multi_polynomial_sequence import PolynomialSequence -from sage.sets.set import Set -from functools import cmp_to_key from sage.misc.misc_c import prod class ChowRing(QuotientRing_generic): From 01ab04bf26c1ee9dc925b09160960a38658cadbb Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Sat, 10 Aug 2024 15:48:56 +0530 Subject: [PATCH 112/537] Wrote mathematical definition of Chow ring ideal --- src/sage/matroids/chow_ring_ideal.py | 99 +++++++++++++++++++++++++++- 1 file changed, 96 insertions(+), 3 deletions(-) diff --git a/src/sage/matroids/chow_ring_ideal.py b/src/sage/matroids/chow_ring_ideal.py index e7f67f6b6af..c3a88b780e5 100644 --- a/src/sage/matroids/chow_ring_ideal.py +++ b/src/sage/matroids/chow_ring_ideal.py @@ -12,10 +12,102 @@ ``grobner_basis()`` methods as well, as an explicit Groebner basis is known in each case. +..INPUT:: + + - `R` -- commutative ring + - `M` -- matroid + +The Chow ring ideal is defined over a polynomial ring for a matroid `M`: + +..MATH:: + + R[x_{F_1}, \ldots, x_{F_k}] + + as + +..MATH:: + + (Q_M + L_M) + + where + + - `F_1, \ldots, F_k` are the non-empty proper flats of `M`, + - `Q_M` is the ideal generated by all `x_{F_i} x_{F_j}` where + `F_i` and `F_j` are incomparable elements in the lattice of + flats, and + - `L_M` is the ideal generated by all linear forms + +.. MATH:: + + \sum_{i_1 \in F} x_F - \sum_{i_2 \in F} x_F + + for all `i_1 \neq i_2 \in E`. + +The augmented Chow ring ideal of Feitchner-Yuzvinsky presentation is defined +over the following polynomial ring: + +..MATH:: + + R[y_{e_1}, \ldots, y_{e_n}, x_{F_1}, \ldots, x_{F_k}] + + as + +..MATH:: + + (I_M + J_M) + + where + + - `F_1, \ldots, F_k` are the non-empty proper flats of `M`, + - `e_1 \ldots, e_n` are `n` elements of groundset of `M`, + - `J_M` is the ideal generated by all quadratic forms `x_{F_i} x_{F_j}` + where `F_i` and `F_j` are incomparable elements in the lattice of + flats, and `y_{i} x_F` for every `i \in E` and `i \notin F`, and + - `I_M` is the ideal generated by all linear forms + +..MATH:: + + y_i - \sum_{i \notin F} x_F + + for all `i \in E`. + +The augmented Chow ring ideal for the atom-free presentation is defined +over the polynomial ring: + +..MATH:: + + R[x_{F_1}, \ldots, x_{F_k}] + + as + +..MATH:: + + I_{af}(M) + + where + + - `F_1, \ldots, F_k` are the non-empty proper flats of `M`, + - `I_{af }M` is the ideal generated by all quadratic forms `x_{F_i} x_{F_j}` + where `F_i` and `F_j` are incomparable elements in the lattice of + flats, + +..MATH:: + + x_F \sum_{i \in F'} x_{F'} + + for all `i \in E` and `i \notin F`, and + +..MATH:: + + \sum_{i \in F'} (x_{F'})^2 + + for all `i \in E`. + + REFERENCES -- :arxiv:`2309.14312` -- :arxiv:`2111.00393` +- [ANR2023]_ +- [MM2022]_ """ from sage.rings.polynomial.multi_polynomial_ideal import MPolynomialIdeal @@ -68,7 +160,8 @@ def flats_generator(self): class ChowRingIdeal_nonaug(ChowRingIdeal): r""" The Chow ring ideal. - + Returns the Chow ring ideal over ring `R` of matroid `M`. + INPUT: - `M` -- a matroid From f7377c8051564ee66cfb7ee4f8a4eb1457d6d01f Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Sat, 10 Aug 2024 15:49:15 +0530 Subject: [PATCH 113/537] Modified chow_ring() doctest --- src/sage/matroids/matroid.pyx | 32 +++++--------------------------- 1 file changed, 5 insertions(+), 27 deletions(-) diff --git a/src/sage/matroids/matroid.pyx b/src/sage/matroids/matroid.pyx index 924d2db2878..587fed8a556 100644 --- a/src/sage/matroids/matroid.pyx +++ b/src/sage/matroids/matroid.pyx @@ -8030,31 +8030,13 @@ cdef class Matroid(SageObject): def chow_ring(self, R, augmented=False, presentation=None): r""" Return the Chow ring of ``self`` over ``R``. + Return the augmented Chow ring of `self` over `R`of `presentation` + if `augmented` is `True`. - Let `M` be a matroid and `R` be a commutative ring. - The *Chow ring* of `M` is the quotient ring - - .. MATH:: - - A^*(M)_R := R[x_{F_1}, \ldots, x_{F_k}] / (Q_M + L_M), - - where - - - `F_1, \ldots, F_k` are the non-empty proper flats of `M`, - - `Q_M` is the ideal generated by all `x_{F_i} x_{F_j}` where - `F_i` and `F_j` are incomparable elements in the lattice of - flats, and - - `L_M` is the ideal generated by all linear forms - - .. MATH:: - - \sum_{i_1 \in F} x_F - \sum_{i_2 \in F} x_F - - for all `i_1 \neq i_2 \in E`. - - INPUT: + .. SEEALSO:: - - ``R`` -- (default: `\ZZ`) the base ring + :mod: sage.matroids.chow_ring_ideal + :mod: sage.matroids.chow_ring EXAMPLES:: @@ -8087,10 +8069,6 @@ cdef class Matroid(SageObject): Augmented Chow ring of U(3, 6): Matroid of rank 3 on 6 elements with circuit-closures {3: {{0, 1, 2, 3, 4, 5}}} of atom-free presentation - REFERENCES: - - - [FY2004]_ - - [AHK2015]_ """ from sage.matroids.chow_ring import ChowRing return ChowRing(M=self, R=R, augmented=augmented, presentation=presentation) From e41edf87bf05f9cf48de799c56e87db82f523f90 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Sat, 10 Aug 2024 22:10:09 +0530 Subject: [PATCH 114/537] Debugged basis() method --- src/sage/matroids/chow_ring.py | 33 ++++++++++++++++++++++++--------- 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/src/sage/matroids/chow_ring.py b/src/sage/matroids/chow_ring.py index e94be14a2cc..03b289f3781 100644 --- a/src/sage/matroids/chow_ring.py +++ b/src/sage/matroids/chow_ring.py @@ -76,6 +76,7 @@ from sage.categories.graded_algebras_with_basis import GradedAlgebrasWithBasis from sage.categories.commutative_rings import CommutativeRings from sage.misc.misc_c import prod +from itertools import product class ChowRing(QuotientRing_generic): r""" @@ -228,16 +229,30 @@ def basis(self): monomial_basis.append(term) else: - for i in range(maximum_rank): + print(ranks) + rank_diff = [] + for i in range(len(flats)): + max_pow = 0 + for j in range(i): + if flats[j] < flats[i]: + max_pow += ranks[j] + rank_diff.append(ranks[i] - max_pow) + print(rank_diff) + def generate_terms(current_term, index, max_powers, f_dict): + if index == len(max_powers): term = self._ideal.ring().one() - for j in range(len(flats)): - if i > ranks[j] - ranks[j-1] - 1: - if flats[j] in list(flats_gen): - term *= flats_gen[flats[j]]**(0) - else: - if flats[j] in list(flats_gen): - term *= flats_gen[flats[j]]**(i + 1) - monomial_basis.append(term) + term *= f_dict[i+1]**(current_term[i] for i in range(len(current_term))) + yield term + return + + for power in range(max_powers[index]): + current_term[index] = power + generate_terms(current_term, index + 1, max_powers, f_dict) + + current_term = [0]*len(flats) + monomial_basis = list(generate_terms(current_term, 0, rank_diff, flats_gen)) + print(monomial_basis) + from sage.sets.family import Family return Family([self.element_class(self, mon, reduce=False) for mon in monomial_basis]) From 367225ae7c68036a4ca34c18a1edb538c849bc6c Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Sat, 10 Aug 2024 22:10:35 +0530 Subject: [PATCH 115/537] Wrote doctests for groebner_basis() methods --- src/sage/matroids/chow_ring_ideal.py | 45 +++++++++++++++------------- 1 file changed, 25 insertions(+), 20 deletions(-) diff --git a/src/sage/matroids/chow_ring_ideal.py b/src/sage/matroids/chow_ring_ideal.py index c3a88b780e5..e3f7fab94b7 100644 --- a/src/sage/matroids/chow_ring_ideal.py +++ b/src/sage/matroids/chow_ring_ideal.py @@ -317,10 +317,11 @@ def groebner_basis(self): for H in flats: if H > G: term += self._flats_generator[H] - if F.is_empty(): - gb.append(term**self._matroid.rank(G)) - elif F < G: - gb.append(term**(self._matroid.rank(G)-self._matroid.rank(F))) + if term != R.zero(): + if Set(F).is_empty(): + gb.append(term**self._matroid.rank(G)) + elif F < G: + gb.append(term**(self._matroid.rank(G)-self._matroid.rank(F))) g_basis = PolynomialSequence(R, [gb]) return g_basis @@ -462,36 +463,37 @@ def groebner_basis(self): sage: ch = AugmentedChowRingIdeal_fy(M=matroids.catalog.Fano(), R=QQ) sage: ch.groebner_basis() - Polynomial Sequence with 4116 Polynomials in 21 Variables + Polynomial Sequence with 1400 Polynomials in 10 Variables + sage: ch.groebner_basis().is_groebner() + True """ gb = [] E = list(self._matroid.groundset()) poly_ring = self.ring() - for i in E: - for F in self._flats: - for G in self._flats: + for F in self._flats: + for G in self._flats: + if not (F < G or G < F): + gb.append(self._flats_generator[F]*self._flats_generator[G]) + for i in E: term = poly_ring.zero() term1 = poly_ring.zero() for H in self._flats: - if i in Set(H): + if i in H: term += self._flats_generator[H] if H > F: term1 += self._flats_generator[H] - gb.append(self._flats_generator[i] + term) - gb.append(term1**(self._matroid.rank(Set(F))) + 1) + gb.append(self._flats_generator[i] + term) + gb.append(term1**(self._matroid.rank(F)) + 1) - if i in Set(F): - gb.append(self._flats_generator[i]*((term1)**self._matroid.rank(Set(F)))) + if i in F: + gb.append(self._flats_generator[i]*((term1)**self._matroid.rank(F))) - elif not i in Set(F): + elif not i in F: gb.append(self._flats_generator[i]*self._flats_generator[F]) - elif not (F < G or G < F): - gb.append(self._flats_generator[F]*self._flats_generator[G]) - elif G < F: - gb.append(self._flats_generator[G]*term1**(self._matroid.rank(Set(F))-self._matroid.rank(Set(G)))) + gb.append(self._flats_generator[G]*term1**(self._matroid.rank(F)-self._matroid.rank(G))) g_basis = PolynomialSequence(poly_ring, [gb]) return g_basis @@ -626,6 +628,8 @@ def groebner_basis(self): sage: ch = AugmentedChowRingIdeal_atom_free(M=M1, R=QQ) sage: ch.groebner_basis() [A0^2, A0*A1, A0*A2, A0*A1, A1^2, A1*A2, A0*A2, A1*A2, A2^2] + sage: ch.groebner_basis().is_groebner() + True """ gb = [] flats = [X for i in range(1, self._matroid.rank()) @@ -642,8 +646,9 @@ def groebner_basis(self): for H in flats: if H < F: term += self._flats_generator[H] - gb.append(self._flats_generator[F]*(term**self._matroid.rank(Set(G)))* - (term**(self._matroid.rank(Set(G))-self._matroid.rank(Set(F))))) + if term != poly_ring.zero(): + gb.append(self._flats_generator[F]*(term**self._matroid.rank(G))* + (term**(self._matroid.rank(G)-self._matroid.rank(F)))) g_basis = PolynomialSequence(poly_ring, [gb]) return g_basis From 9ec9b184598b227bc68e2ed431d057a563700e56 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Tue, 13 Aug 2024 10:33:13 +0530 Subject: [PATCH 116/537] Updated references --- src/doc/en/reference/references/index.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/en/reference/references/index.rst b/src/doc/en/reference/references/index.rst index 46e3bf33f3a..5e8c70a7b7e 100644 --- a/src/doc/en/reference/references/index.rst +++ b/src/doc/en/reference/references/index.rst @@ -262,7 +262,7 @@ REFERENCES: 369–379. https://doi.org/10.1007/BF02677478 .. [ANR2023] Robert Angarone, Anastasia Nathanson, and Victor Reiner. *Chow rings of - matroids as permutation representations*, 2023. :arxiv: `2309.14312`. + matroids as permutation representations*, 2023. :arxiv: `2309.14312`. .. [AP1986] \S. Arnborg, A. Proskurowski, *Characterization and Recognition of Partial 3-Trees*, From c63627a043f70af1679cfd4895ef3915685de711 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Tue, 13 Aug 2024 10:34:12 +0530 Subject: [PATCH 117/537] Incorporated GitHub comments --- src/sage/matroids/chow_ring.py | 157 +++++++++++++++------------------ 1 file changed, 70 insertions(+), 87 deletions(-) diff --git a/src/sage/matroids/chow_ring.py b/src/sage/matroids/chow_ring.py index 03b289f3781..9b42b9a32a6 100644 --- a/src/sage/matroids/chow_ring.py +++ b/src/sage/matroids/chow_ring.py @@ -4,100 +4,90 @@ AUTHORS: - Shriya M +""" -These are the classes of Chow rings for matroids. It also takes in -a parameter boolean ``augmented`` which creates the augmented Chow -ring if given ``True``. - -INPUT:: +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.commutative_rings import CommutativeRings +from sage.misc.misc_c import prod +from itertools import product -- `R` -- commutative ring -- `M` -- matroid -- `augmented` -- If `True`, returns augmented Chow ring of input presentation - and returns non-augmented Chow ring if `False`. -- `presentation` -- Takes in augmented Chow ring presentation as a string if - augmented is `True`. Implemented resentations are `fy` and `atom-free`, - default value is `None` +class ChowRing(QuotientRing_generic): + r""" + The class of Chow ring, a multi-polynomial quotient ring. -The Chow ring of a matroid is defined as the quotient ring: + INPUT: -.. MATH:: - A^*(M)_R := R[x_{F_1}, \ldots, x_{F_k}] / (Q_M + L_M) + - `M` -- a matroid + - `R` -- a commutative ring + - ``augmented`` -- a Boolean value. When ``True``, it returns the augmented + Chow ring. If ``False``, it returns the Chow ring + - ``presentation`` -- a string literal. Takes in the presentation of + augmented Chow ring (`fy` or `atom-free`). Default value `None` - where + OUTPUT: Chow ring of matroid `M` -..MATH:: + These are the classes of Chow rings for matroids. It also takes in + a parameter boolean ``augmented`` which creates the augmented Chow + ring if given ``True``. - (Q_M + L_M) + The Chow ring of a matroid is defined as the quotient ring: - is the Chow ring ideal of matroid `M`. + .. MATH:: -The augmented Chow ring of matroid `M` of Feitchner-Yuzvinsky presentation -is the quotient ring: + A^*(M)_R := R[x_{F_1}, \ldots, x_{F_k}] / (Q_M + L_M) -..MATH:: + where - A(M)_R := R[y_{e_1}, \ldots, y_{e_n}, x_{F_1}, \ldots, x_{F_k}] / (I_M + J_M) + ..MATH:: - where + (Q_M + L_M) -..MATH:: + is the Chow ring ideal of matroid `M`. - (I_M + J_M) + The augmented Chow ring of matroid `M` of Feitchner-Yuzvinsky presentation + is the quotient ring: - is the augmented Chow ring ideal of matroid `M` of Feitchner-Yuzvinsky - presentation. + ..MATH:: -The augmented Chow ring ideal of atom-free presentation is the quotient ring: + A(M)_R := R[y_{e_1}, \ldots, y_{e_n}, x_{F_1}, \ldots, x_{F_k}] / (I_M + J_M) -..MATH:: + where - A(M)_R := R[x_{F_1}, \ldots, x_{F_k}] / I_{af}M + ..MATH:: - where + (I_M + J_M) - I_{af}M - - is the augmented Chow ring ideal of matroid `M` of atom-free presentation. + is the augmented Chow ring ideal of matroid `M` of Feitchner-Yuzvinsky + presentation. -.. SEEALSO:: + The augmented Chow ring of atom-free presentation is the quotient ring: - :mod: sage.matroids.chow_ring_ideal + ..MATH:: -REFERENCES: + A(M)_R := R[x_{F_1}, \ldots, x_{F_k}] / I_{af}M - - [FY2004]_ - - [AHK2015]_ -""" + where -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.commutative_rings import CommutativeRings -from sage.misc.misc_c import prod -from itertools import product + I_{af}M + + is the augmented Chow ring ideal of matroid `M` of atom-free presentation. -class ChowRing(QuotientRing_generic): - r""" - The class of Chow ring, a multi-polynomial quotient ring. + .. SEEALSO:: - INPUT: + :mod: sage.matroids.chow_ring_ideal + REFERENCES: - - `M` -- a matroid. - - `R` -- a ring. - - ``augmented`` -- a Boolean value. When ``True``, it returns the augmented Chow - ring. If ``False``, it returns the Chow ring - - OUTPUT: Chow ring of matroid `M`. + - [FY2004]_ + - [AHK2015]_ EXAMPLES:: - sage: from sage.matroids.chow_ring import ChowRing - sage: M1 = matroids.catalog.P8pp() - sage: ch = ChowRing(M=M1, R=QQ, augmented=False) + sage: ch = M1.chow_ring(QQ, False) sage: ch Chow ring of P8'': Matroid of rank 4 on 8 elements with 8 nonspanning circuits """ @@ -107,18 +97,16 @@ def __init__(self, R, M, augmented, presentation=None): EXAMPLES:: - sage: from sage.matroids.chow_ring import ChowRing - - sage: I = ChowRing(M=matroids.Wheel(3), R=QQ, augmented=False) + sage: I = matroids.Wheel(3).chow_ring(QQ, False) sage: TestSuite(I).run() """ self._matroid = M self._augmented = augmented self._presentation = presentation - if augmented: - if presentation=='fy': + if augmented is True: + if presentation == 'fy': self._ideal = AugmentedChowRingIdeal_fy(M, R) - elif presentation=='atom-free': + elif presentation == 'atom-free': self._ideal = AugmentedChowRingIdeal_atom_free(M, R) else: self._ideal = ChowRingIdeal_nonaug(M, R) #check method to get ring @@ -127,19 +115,17 @@ def __init__(self, R, M, augmented, presentation=None): def _repr_(self): r""" - EXAMPLE:: - - sage: from sage.matroids.chow_ring import ChowRing + EXAMPLES:: sage: M1 = matroids.catalog.Fano() - sage: ch = ChowRing(M=M1, R=QQ, augmented=False) + sage: ch = M1.chow_ring(QQ, False) sage: ch Chow ring of Fano: Binary matroid of rank 3 on 7 elements, type (3, 0) """ - if self._augmented: - if self._presentation=='fy': + if self._augmented is True: + if self._presentation == 'fy': return "Augmented Chow ring of {} of Feitchner-Yuzvinsky presentation".format(self._matroid) - elif self._presentation=='atom-free': + elif self._presentation == 'atom-free': return "Augmented Chow ring of {} of atom-free presentation".format(self._matroid) return "Chow ring of {}".format(self._matroid) @@ -147,13 +133,12 @@ def _latex_(self): r""" Return the LaTeX output of the polynomial ring and Chow ring ideal. - EXAMPLE:: + EXAMPLES:: - sage: from sage.matroids.chow_ring import ChowRing sage: from sage.matroids.graphic_matroid import GraphicMatroid sage: M1 = GraphicMatroid(graphs.CycleGraph(3)) - sage: ch = ChowRing(M=M1, R=QQ, augmented=True, presentation='fy') + sage: ch = M1.chow_ring(QQ, True, 'fy') sage: ch._latex_() \Bold{Q}[A_{0}, A_{1}, A_{2}, B_{0}, B_{1}, B_{2}]/\left(B_{0}^{2}, B_{0} B_{1}, B_{0} B_{2}, B_{0} B_{1}, B_{1}^{2}, B_{1} B_{2}, @@ -171,9 +156,8 @@ def _coerce_map_from_base_ring(self): TESTS:: - sage: from sage.matroids.chow_ring import ChowRing - sage: ch = ChowRing(M=matroids.Wheel(3), R=QQ, augmented=False) + sage: ch = matroids.Wheel(3).chow_ring(QQ, False) sage: ch._coerce_map_from_base_ring() is None True """ @@ -185,12 +169,11 @@ def basis(self): EXAMPLES:: - sage: from sage.matroids.chow_ring import ChowRing - sage: ch = ChowRing(M=matroids.Uniform(3, 6), R=QQ, augmented=True, presentation='fy') + sage: ch = matroids.Uniform(3, 6).chow_ring(QQ, True, 'fy') sage: ch.basis() [B0*B01, 1] - sage: ch = ChowRing(M=matroids.Wheel(3), R=ZZ, augmented=False) + sage: ch = matroids.Wheel(3).chow_ring(ZZ, False) [A0*A013, 1] """ flats = [X for i in range(1, self._matroid.rank()) @@ -201,7 +184,7 @@ def basis(self): flats = sorted(flats, key=lambda X: (len(X), sorted(X))) ranks = [self._matroid.rank(F) for F in flats] monomial_basis = [] - if self._augmented: + if self._augmented is True: if self._presentation == 'fy': for i in range(maximum_rank): term = self._ideal.ring().one() @@ -264,7 +247,7 @@ def to_vector(self, order=None): EXAMPLES:: - sage: ch = ChowRing(M=matroids.Uniform(3, 6), R=QQ, augmented=False) + sage: ch = matroids.Uniform(3, 6).chow_ring(QQ, False) sage: v = ch.an_element(); v A0 sage: v.to_vector() #Error in output! @@ -284,7 +267,7 @@ def monomial_coefficients(self, copy=None): EXAMPLES:: - sage: ch = ChowRing(M=matroids.catalog.NonFano(), R=QQ, augmented=True, presentation='fy') + sage: ch = matroids.catalog.NonFano().chow_ring(QQ, True, 'fy') sage: v = ch.an_element(); v 0 sage: v.monomial_coefficients() #error in output! @@ -300,7 +283,7 @@ def degree(self): EXAMPLES:: - sage: ch = ChowRing(M=matroids.Uniform(3, 6), R=QQ, augmented=False) + sage: ch = matroids.Uniform(3, 6).chow_ring(QQ, False) sage: for b in ch.basis(): ....: print(b, b.degree()) A0*A01 2 @@ -318,7 +301,7 @@ def homogeneous_degree(self): EXAMPLES:: - ch = ChowRing(M=matroids.catalog.Fano(), R=QQ, augmented=True, presentation='fy') + ch = matroids.catalog.Fano().chow_ring(QQ, True, 'fy') sage: for b in ch.basis(): ....: print(b, b.homogeneous_degree()) Ba*Babf 2 @@ -332,7 +315,7 @@ def homogeneous_degree(self): TESTS:: - sage: ch = ChowRing(M=matroids.Wheel(3), R=QQ, augmented=False) + sage: ch = matroids.Wheel(3).chow_ring(QQ, False) sage: ch.zero().homogeneous_degree() #error! Traceback (most recent call last): ... From 434c8603a73e288427b8118b2f149e5d62ae7864 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Tue, 13 Aug 2024 10:34:34 +0530 Subject: [PATCH 118/537] Incorporated GitHub comments for ideal file --- src/sage/matroids/chow_ring_ideal.py | 304 ++++++++++++--------------- 1 file changed, 137 insertions(+), 167 deletions(-) diff --git a/src/sage/matroids/chow_ring_ideal.py b/src/sage/matroids/chow_ring_ideal.py index e3f7fab94b7..173efaba912 100644 --- a/src/sage/matroids/chow_ring_ideal.py +++ b/src/sage/matroids/chow_ring_ideal.py @@ -4,110 +4,6 @@ AUTHORS: - Shriya M - -These are the classes of Chow ring ideals for matroids. There are three classes -created - Chow ring ideal and augmented Chow ring ideal. The augmented -Chow ring ideal has two different presentations implemented - the Feitchner- -Yuzvinsky presentation and atom-free presentation. Both classes have -``grobner_basis()`` methods as well, as an explicit Groebner basis is known -in each case. - -..INPUT:: - - - `R` -- commutative ring - - `M` -- matroid - -The Chow ring ideal is defined over a polynomial ring for a matroid `M`: - -..MATH:: - - R[x_{F_1}, \ldots, x_{F_k}] - - as - -..MATH:: - - (Q_M + L_M) - - where - - - `F_1, \ldots, F_k` are the non-empty proper flats of `M`, - - `Q_M` is the ideal generated by all `x_{F_i} x_{F_j}` where - `F_i` and `F_j` are incomparable elements in the lattice of - flats, and - - `L_M` is the ideal generated by all linear forms - -.. MATH:: - - \sum_{i_1 \in F} x_F - \sum_{i_2 \in F} x_F - - for all `i_1 \neq i_2 \in E`. - -The augmented Chow ring ideal of Feitchner-Yuzvinsky presentation is defined -over the following polynomial ring: - -..MATH:: - - R[y_{e_1}, \ldots, y_{e_n}, x_{F_1}, \ldots, x_{F_k}] - - as - -..MATH:: - - (I_M + J_M) - - where - - - `F_1, \ldots, F_k` are the non-empty proper flats of `M`, - - `e_1 \ldots, e_n` are `n` elements of groundset of `M`, - - `J_M` is the ideal generated by all quadratic forms `x_{F_i} x_{F_j}` - where `F_i` and `F_j` are incomparable elements in the lattice of - flats, and `y_{i} x_F` for every `i \in E` and `i \notin F`, and - - `I_M` is the ideal generated by all linear forms - -..MATH:: - - y_i - \sum_{i \notin F} x_F - - for all `i \in E`. - -The augmented Chow ring ideal for the atom-free presentation is defined -over the polynomial ring: - -..MATH:: - - R[x_{F_1}, \ldots, x_{F_k}] - - as - -..MATH:: - - I_{af}(M) - - where - - - `F_1, \ldots, F_k` are the non-empty proper flats of `M`, - - `I_{af }M` is the ideal generated by all quadratic forms `x_{F_i} x_{F_j}` - where `F_i` and `F_j` are incomparable elements in the lattice of - flats, - -..MATH:: - - x_F \sum_{i \in F'} x_{F'} - - for all `i \in E` and `i \notin F`, and - -..MATH:: - - \sum_{i \in F'} (x_{F'})^2 - - for all `i \in E`. - - -REFERENCES - -- [ANR2023]_ -- [MM2022]_ """ from sage.rings.polynomial.multi_polynomial_ideal import MPolynomialIdeal @@ -119,16 +15,13 @@ class ChowRingIdeal(MPolynomialIdeal): @abstract_method - def _gens_constructor(): - pass - def matroid(self): r""" Return the matroid of the given Chow ring ideal. - EXAMPLE:: + EXAMPLES:: - sage: ch = ChowRingIdeal_nonaug(M=matroids.Uniform(3,6), R=QQ) + sage: ch = matroids.Uniform(3,6).chow_ring(QQ, False) sage: ch.matroid() U(3, 6): Matroid of rank 3 on 6 elements with circuit-closures {3: {{0, 1, 2, 3, 4, 5}}} @@ -141,11 +34,9 @@ def flats_generator(self): Return the variables of every corresponding flat/groundset element of the matroid. - EXAMPLE:: - - sage: from sage.matroids.chow_ring_ideal import ChowRingIdeal_nonaug + EXAMPLES:: - sage: ch = ChowRingIdeal_nonaug(M=matroids.catalog.Fano(), R=QQ) + sage: ch = matroids.catalog.Fano().chow_ring(QQ, False) sage: ch.flats_generator() {frozenset({'a'}): Aa, frozenset({'b'}): Ab, frozenset({'c'}): Ac, frozenset({'d'}): Ad, frozenset({'e'}): Ae, frozenset({'f'}): Af, @@ -165,21 +56,57 @@ class ChowRingIdeal_nonaug(ChowRingIdeal): INPUT: - `M` -- a matroid - - `R` -- a ring + - `R` -- a commutative ring OUTPUT: Chow ring ideal of matroid `M` + These are the classes of Chow ring ideals for matroids. There are three classes + created - Chow ring ideal and augmented Chow ring ideal. The augmented + Chow ring ideal has two different presentations implemented - the Feitchner- + Yuzvinsky presentation and atom-free presentation. Both classes have + ``grobner_basis()`` methods as well, as an explicit Groebner basis is known + in each case. + + The Chow ring ideal is defined over a polynomial ring for a matroid `M`: + + ..MATH:: + + R[x_{F_1}, \ldots, x_{F_k}] + + as + + ..MATH:: + + (Q_M + L_M) + + where + + - `F_1, \ldots, F_k` are the non-empty proper flats of `M`, + - `Q_M` is the ideal generated by all `x_{F_i} x_{F_j}` where + `F_i` and `F_j` are incomparable elements in the lattice of + flats, and + - `L_M` is the ideal generated by all linear forms + + .. MATH:: + + \sum_{i_1 \in F} x_F - \sum_{i_2 \in F} x_F + + for all `i_1 \neq i_2 \in E`. + + REFERENCES + + - [ANR2023]_ + - [MM2022]_ + EXAMPLES: Chow ring ideal of uniform matroid of rank 3 on 6 elements:: - sage: from sage.matroids.chow_ring_ideal import ChowRingIdeal_nonaug - - sage: ch = ChowRingIdeal_nonaug(M=matroids.Uniform(3,6), R=QQ) + sage: ch = matroids.Uniform(3,6).chow_ring(QQ, False) sage: ch Chow ring ideal of U(3, 6): Matroid of rank 3 on 6 elements with circuit-closures {3: {{0, 1, 2, 3, 4, 5}}} - sage: ch = ChowRingIdeal_nonaug(M=matroids.catalog.Fano(), R=QQ) + sage: ch = matroids.catalog.Fano().chow_ring(QQ, False) sage: ch Chow ring ideal of Fano: Binary matroid of rank 3 on 7 elements, type (3, 0) """ @@ -189,9 +116,7 @@ def __init__(self, M, R): EXAMPLES:: - sage: from sage.matroids.chow_ring_ideal import ChowRingIdeal_nonaug - - sage: I = ChowRingIdeal_nonaug(M=matroids.catalog.Fano(), R=QQ) + sage: I = matroids.catalog.Fano().chow_ring(QQ, False) sage: TestSuite(I).run(skip="_test_category") """ self._matroid = M @@ -211,11 +136,9 @@ def _gens_constructor(self, poly_ring): Returns the generators of the Chow ring ideal. Takes in the ring of Chow ring ideal as input. - EXAMPLE:: - - sage: from sage.matroids.chow_ring_ideal import ChowRingIdeal_nonaug + EXAMPLES:: - sage: ch = ChowRingIdeal_nonaug(M=matroids.catalog.NonFano(), R=QQ) + sage: ch = matroids.catalog.NonFano().chow_ring(QQ, False) sage: ch._gens_constructor(ch.ring()) [Aa*Ab, Aa*Ac, Aa*Ad, Aa*Ae, Aa*Af, Aa*Ag, Aa*Abcd, Aa*Abeg, Aa*Acfg, Aa*Ade, Aa*Adf, Aa*Aef, Ab*Ac, Ab*Ad, Ab*Ae, Ab*Af, Ab*Ag, @@ -252,8 +175,6 @@ def _gens_constructor(self, poly_ring): -Aa + Ad - Aabf - Aace + Abcd + Ade + Adf, Ad - Af - Aabf + Aadg + Abcd - Acfg + Ade - Aef, Aa - Af + Aace + Aadg - Acfg - Adf - Aef] - - """ E = list(self._matroid.groundset()) flats = list(self._flats_generator.keys()) @@ -271,11 +192,9 @@ def _gens_constructor(self, poly_ring): def _repr_(self): r""" - EXAMPLE:: - - sage: from sage.matroids.chow_ring_ideal import ChowRingIdeal_nonaug + EXAMPLES:: - sage: ch = ChowRingIdeal_nonaug(M=matroids.catalog.Fano(), R=QQ) + sage: ch = matroids.catalog.Fano().chow_ring(QQ, False) sage: ch Chow ring ideal of Fano: Binary matroid of rank 3 on 7 elements, type (3, 0) """ @@ -288,10 +207,9 @@ def groebner_basis(self): EXAMPLES:: - sage: from sage.matroids.chow_ring_ideal import ChowRingIdeal_nonaug sage: from sage.matroids.basis_matroid import BasisMatroid - sage: ch = ChowRingIdeal_nonaug(M=BasisMatroid(groundset='abc', bases=['ab', 'ac']), R=QQ) + sage: ch = M=BasisMatroid(groundset='abc', bases=['ab', 'ac'])).chow_ring(QQ, False) sage: ch.groebner_basis() [Aa^2, Aa*Abc, Aa*Abc, Abc^2] sage: ch.groebner_basis().is_groebner() @@ -300,9 +218,11 @@ def groebner_basis(self): Another example would be the Groebner basis of the Chow ring ideal of the Non-Fano matroid:: - sage: ch = ChowRingIdeal_nonaug(M=matroids.catalog.NonFano(), R=QQ) + sage: ch = matroids.catalog.NonFano().chow_ring(QQ, False) sage: ch.groebner_basis() Polynomial Sequence with 232 Polynomials in 16 Variables + sage: ch.groebner_basis().is_groebner() + True """ flats = list(self._flats_generator) @@ -335,22 +255,52 @@ class AugmentedChowRingIdeal_fy(ChowRingIdeal): INPUT: - - `M` -- a matroid. - - `R` -- a ring. + - `M` -- a matroid + - `R` -- a commutative ring OUTPUT: augmented Chow ring ideal of matroid `M` of Feitchner-Yuzvinsky presentation. + The augmented Chow ring ideal of Feitchner-Yuzvinsky presentation is defined + over the following polynomial ring: + + ..MATH:: + + R[y_{e_1}, \ldots, y_{e_n}, x_{F_1}, \ldots, x_{F_k}] + + as + + ..MATH:: + + (I_M + J_M) + + where + + - `F_1, \ldots, F_k` are the non-empty proper flats of `M`, + - `e_1 \ldots, e_n` are `n` elements of groundset of `M`, + - `J_M` is the ideal generated by all quadratic forms `x_{F_i} x_{F_j}` + where `F_i` and `F_j` are incomparable elements in the lattice of + flats, and `y_{i} x_F` for every `i \in E` and `i \notin F`, and + - `I_M` is the ideal generated by all linear forms + + ..MATH:: + + y_i - \sum_{i \notin F} x_F + + for all `i \in E`. + EXAMPLES:: Augmented Chow ring ideal of Wheel matroid of rank 3:: - sage: from sage.matroids.chow_ring_ideal import AugmentedChowRingIdeal_fy - - sage: ch = AugmentedChowRingIdeal_fy(M=matroids.Wheel(3), R=QQ) + sage: ch = matroids.Wheel(3).chow_ring(QQ, True, 'fy') sage: ch Augmented Chow ring ideal of Wheel(3): Regular matroid of rank 3 on 6 elements with 16 bases of Feitchner-Yuzvinsky presentation + + REFERENCES + + - [MM2022]_ """ def __init__(self, M, R): r""" @@ -358,9 +308,7 @@ def __init__(self, M, R): EXAMPLES:: - sage: from sage.matroids.chow_ring_ideal import AugmentedChowRingIdeal_fy - - sage: I = AugmentedChowRingIdeal_fy(M=matroids.Wheel(3), R=QQ) + sage: I = matroids.Wheel(3).chow_ring(QQ, True, 'fy') sage: TestSuite(I).run(skip="_test_category") """ self._matroid = M @@ -389,9 +337,7 @@ def _gens_constructor(self, poly_ring): EXAMPLES:: - sage: from sage.matroids.chow_ring_ideal import AugmentedChowRingIdeal_fy - - sage: ch = AugmentedChowRingIdeal_fy(M=matroids.Wheel(3), R=QQ) + sage: ch = matroids.Wheel(3).chow_ring(QQ, True, 'fy') sage: ch._gens_constructor(ch.ring()) [B0^2, B0*B1, B0*B2, B0*B3, B0*B4, B0*B5, B0*B124, B0*B15, B0*B23, B0*B345, B0*B1, B1^2, B1*B2, B1*B3, B1*B4, B1*B5, B1*B025, B1*B04, @@ -443,9 +389,7 @@ def _repr_(self): r""" EXAMPLES:: - sage: from sage.matroids.chow_ring_ideal import AugmentedChowRingIdeal_fy - - sage: ch = AugmentedChowRingIdeal_fy(M=matroids.Wheel(3), R=QQ) + sage: ch = matroids.Wheel(3).chow_ring(QQ, True, 'fy') sage: ch Augmented Chow ring ideal of Wheel(3): Regular matroid of rank 3 on 6 elements with 16 bases of Feitchner-Yuzvinsky presentation @@ -459,9 +403,7 @@ def groebner_basis(self): EXAMPLES:: - sage: from sage.matroids.chow_ring_ideal import AugmentedChowRingIdeal_fy - - sage: ch = AugmentedChowRingIdeal_fy(M=matroids.catalog.Fano(), R=QQ) + sage: ch = matroids.catalog.Fano().chow_ring(QQ, True, 'fy') sage: ch.groebner_basis() Polynomial Sequence with 1400 Polynomials in 10 Variables sage: ch.groebner_basis().is_groebner() @@ -506,21 +448,55 @@ class AugmentedChowRingIdeal_atom_free(ChowRingIdeal): INPUT: - ``M`` -- a matroid - - ``R`` -- a ring + - ``R`` -- a commutative ring OUTPUT: augmented Chow ring ideal of matroid `M` of atom-free presentation. + The augmented Chow ring ideal for the atom-free presentation is defined + over the polynomial ring: + + ..MATH:: + + R[x_{F_1}, \ldots, x_{F_k}] + + as + + ..MATH:: + + I_{af}(M) + + where + + - `F_1, \ldots, F_k` are the non-empty proper flats of `M`, + - `I_{af }M` is the ideal generated by all quadratic forms `x_{F_i} x_{F_j}` + where `F_i` and `F_j` are incomparable elements in the lattice of + flats, + + ..MATH:: + + x_F \sum_{i \in F'} x_{F'} + + for all `i \in E` and `i \notin F`, and + + ..MATH:: + + \sum_{i \in F'} (x_{F'})^2 + + for all `i \in E`. + EXAMPLES: Augmented Chow ring ideal of Wheel matroid of rank 3:: - sage: from sage.matroids.chow_ring_ideal import AugmentedChowRingIdeal_atom_free - - sage: ch = AugmentedChowRingIdeal_atom_free(M=matroids.Wheel(3), R=QQ) + sage: ch = matroids.Wheel(3).chow_ring(QQ, True, 'atom-free') sage: ch Augmented Chow ring ideal of Wheel(3): Regular matroid of rank 3 on 6 elements with 16 bases of atom-free presentation + + REFERENCES + + - [MM2022]_ """ def __init__(self, M, R): r""" @@ -528,9 +504,7 @@ def __init__(self, M, R): EXAMPLES:: - sage: from sage.matroids.chow_ring_ideal import AugmentedChowRingIdeal_atom_free - - sage: I = AugmentedChowRingIdeal_atom_free(M=matroids.Wheel(3), R=QQ) + sage: I = matroids.Wheel(3).chow_ring(QQ, True, 'atom-free') sage: TestSuite(I).run(skip="_test_category") """ self._matroid = M @@ -563,11 +537,10 @@ def _gens_constructor(self, poly_ring): EXAMPLES:: - sage: from sage.matroids.chow_ring_ideal import AugmentedChowRingIdeal_atom_free sage: from sage.matroids.graphic_matroid import GraphicMatroid sage: M1 = GraphicMatroid(graphs.CycleGraph(3)) - sage: ch = AugmentedChowRingIdeal_atom_free(M=M1, R=QQ) + sage: ch = M1.chow_ring(QQ, True, 'atom-free') sage: ch._gens_constructor(ch.ring()) [A0^2, A0^2, A1^2, A0*A1, A2^2, A0*A2, A0*A1, A0^2, A1^2, A0*A1, A2^2, A0*A2, A0*A2, A0^2, A1^2, A0*A1, A2^2, A0*A2, A0*A1, A0^2, @@ -605,9 +578,7 @@ def _repr_(self): r""" EXAMPLE:: - sage: from sage.matroids.chow_ring_ideal import AugmentedChowRingIdeal_atom_free - - sage: ch = AugmentedChowRingIdeal_atom_free(M=matroids.Wheel(3), R=QQ) + sage: ch = matroids.Wheel(3).chow_ring(QQ, True, 'atom-free') sage: ch Augmented Chow ring ideal of Wheel(3): Regular matroid of rank 3 on 6 elements with 16 bases of atom-free presentation @@ -621,11 +592,10 @@ def groebner_basis(self): EXAMPLES:: - sage: from sage.matroids.chow_ring_ideal import AugmentedChowRingIdeal_atom_free sage: from sage.matroids.graphic_matroid import GraphicMatroid sage: M1 = GraphicMatroid(graphs.CycleGraph(3)) - sage: ch = AugmentedChowRingIdeal_atom_free(M=M1, R=QQ) + sage: ch = M1.chow_ring(QQ, True, 'atom-free') sage: ch.groebner_basis() [A0^2, A0*A1, A0*A2, A0*A1, A1^2, A1*A2, A0*A2, A1*A2, A2^2] sage: ch.groebner_basis().is_groebner() @@ -635,8 +605,8 @@ def groebner_basis(self): flats = [X for i in range(1, self._matroid.rank()) for X in self._matroid.flats(i)] poly_ring = self.ring() - if Set([]) in flats: - flats.remove(Set([])) + if frozenset() in flats: + flats.remove(frozenset()) for F in flats: for G in flats: if not (F > G or G > F): From 268b2c4b846c78732eecd150bf3e576173feb216 Mon Sep 17 00:00:00 2001 From: Newtech66 Date: Wed, 14 Aug 2024 15:22:19 +0530 Subject: [PATCH 119/537] Fixed dompart, caching and construction errors, and equality checking for atomic species --- src/sage/rings/species.py | 394 +++++++++++++++++++++++++++----------- 1 file changed, 278 insertions(+), 116 deletions(-) diff --git a/src/sage/rings/species.py b/src/sage/rings/species.py index 4e841a2d727..dfab2e91dbe 100644 --- a/src/sage/rings/species.py +++ b/src/sage/rings/species.py @@ -49,6 +49,12 @@ def __init__(self): """ self._cache = dict() + def clear_cache(self): + r""" + Clear the cache. + """ + self._cache = dict() + def _cache_get(self, elm): r""" Return the cached element, or add it @@ -79,6 +85,13 @@ class ConjugacyClassOfDirectlyIndecomposableSubgroups(Element): def __init__(self, parent, C): r""" A conjugacy class of directly indecomposable subgroups. + + TESTS:: + + sage: from sage.rings.species import ConjugacyClassesOfDirectlyIndecomposableSubgroups + sage: C = ConjugacyClassesOfDirectlyIndecomposableSubgroups() + sage: G = C(PermutationGroup([[(1,2),(3,4)],[(1,2),(5,6)]])) + sage: TestSuite(G).run() """ Element.__init__(self, parent) self._C = C @@ -86,16 +99,34 @@ def __init__(self, parent, C): self._orbit_lens = tuple(len(orbit) for orbit in self._sorted_orbits) self._order = C.order() - @lazy_attribute - def _canonicalizing_perm(self): - return PermutationGroupElement([e for o in self._sorted_orbits for e in o], check=False) - def __hash__(self): + r""" + Return the hash for the conjugacy class. + + TESTS:: + + sage: from sage.rings.species import ConjugacyClassesOfDirectlyIndecomposableSubgroups + sage: C = ConjugacyClassesOfDirectlyIndecomposableSubgroups() + sage: G = PermutationGroup([[(1,2),(3,4),(5,6),(7,8,9,10)]]); G + Permutation Group with generators [(1,2)(3,4)(5,6)(7,8,9,10)] + sage: H = PermutationGroup([[(1,2,3,4),(5,6),(7,8),(9,10)]]); H + Permutation Group with generators [(1,2,3,4)(5,6)(7,8)(9,10)] + sage: hash(C(G)) == hash(C(H)) + True + """ return hash(self._C) def _repr_(self): r""" Return a string representation of ``self``. + + EXAMPLES:: + + sage: from sage.rings.species import ConjugacyClassesOfDirectlyIndecomposableSubgroups + sage: C = ConjugacyClassesOfDirectlyIndecomposableSubgroups() + sage: G = PermutationGroup([[(1,3),(4,7)], [(2,5),(6,8)], [(1,4),(2,5),(3,7)]]) + sage: C(G) + [(2,5)(6,8), (1,3)(4,7), (1,4)(2,5)(3,7)] """ return f"{self._C.gens_small()}" @@ -108,6 +139,17 @@ def __eq__(self, other): ``self`` is equal to ``other`` if they have the same degree (say `n`) and order and are conjugate within `S_n`. + + TESTS:: + + sage: from sage.rings.species import ConjugacyClassesOfDirectlyIndecomposableSubgroups + sage: C = ConjugacyClassesOfDirectlyIndecomposableSubgroups() + sage: G = PermutationGroup([[(1,2),(3,4),(5,6),(7,8,9,10)]]); G + Permutation Group with generators [(1,2)(3,4)(5,6)(7,8,9,10)] + sage: H = PermutationGroup([[(1,2,3,4),(5,6),(7,8),(9,10)]]); H + Permutation Group with generators [(1,2,3,4)(5,6)(7,8)(9,10)] + sage: C(G) == C(H) + True """ return (isinstance(other, ConjugacyClassOfDirectlyIndecomposableSubgroups) and self._C.degree() == other._C.degree() @@ -120,10 +162,20 @@ class ConjugacyClassesOfDirectlyIndecomposableSubgroups(UniqueRepresentation, Pa def __init__(self): r""" Conjugacy classes of directly indecomposable subgroups. + + TESTS:: + + sage: from sage.rings.species import ConjugacyClassesOfDirectlyIndecomposableSubgroups + sage: C = ConjugacyClassesOfDirectlyIndecomposableSubgroups() + sage: TestSuite(C).run(max_runs=5) # It takes far too long otherwise """ Parent.__init__(self, category=InfiniteEnumeratedSets()) ElementCache.__init__(self) + @cached_method + def an_element(self): + return self._element_constructor_(SymmetricGroup(1)) + def _element_constructor_(self, x): r""" ``x`` is an element of ``self`` or a group `H` such that @@ -131,35 +183,83 @@ def _element_constructor_(self, x): EXAMPLES:: - sage: G = PermutationGroup([[(1,3),(4,7)], [(2,5),(6,8)], [(1,4),(2,5),(3,7)]]) - sage: A = AtomicSpecies(1) - sage: A(G) - {[(5,6)(7,8), (1,2)(5,7)(6,8), (1,2)(3,4)]: (8,)} + sage: from sage.rings.species import ConjugacyClassesOfDirectlyIndecomposableSubgroups + sage: C = ConjugacyClassesOfDirectlyIndecomposableSubgroups() + sage: C.clear_cache() + sage: C(PermutationGroup([("a", "b", "c")])) + [(1,2,3)] + sage: C._cache + {(3, 3, (3,)): [[(1,2,3)]]} + sage: C(PermutationGroup([(1, 3, 5)], domain=[1,3,5])) + [(1,2,3)] + sage: C(PermutationGroup([[(1,3),(4,7)],[(2,5),(6,8)], [(1,4),(2,5),(3,7)]])) + [(2,5)(6,8), (1,3)(4,7), (1,4)(2,5)(3,7)] + sage: C._cache + {(3, 3, (3,)): [[(1,2,3)]], + (8, 8, (2, 2, 4)): [[(2,5)(6,8), (1,3)(4,7), (1,4)(2,5)(3,7)]]} """ if parent(x) == self: return x if isinstance(x, PermutationGroup_generic): if len(x.disjoint_direct_product_decomposition()) > 1: raise ValueError(f"{x} is not directly indecomposable") - elm = self.element_class(self, x) + mapping = {v: i for i, v in enumerate(x.domain(), 1)} + normalized_gens = [[tuple(mapping[x] for x in cyc) + for cyc in gen.cycle_tuples()] + for gen in x.gens()] + P = PermutationGroup(gens=normalized_gens) + # Fix for SymmetricGroup(0) + if x.degree() == 0: + P = SymmetricGroup(0) + elm = self.element_class(self, P) return self._cache_get(elm) raise ValueError(f"unable to convert {x} to {self}") + + def __iter__(self): + # Is SymmetricGroup(0) directly indecomposable? + n = 0 + while True: + for G in SymmetricGroup(n).conjugacy_classes_subgroups(): + if len(G.disjoint_direct_product_decomposition()) <= 1: + yield self._element_constructor_(G) + n += 1 + + def __contains__(self, G): + r""" + Return if ``G`` is in ``self``. + """ + if parent(G) == self: + return True + return len(G.disjoint_direct_product_decomposition()) <= 1 def _repr_(self): + r""" + Return the string representation for ``self``. + + TESTS:: + + sage: from sage.rings.species import ConjugacyClassesOfDirectlyIndecomposableSubgroups + sage: C = ConjugacyClassesOfDirectlyIndecomposableSubgroups(); C + Infinite set of conjugacy classes of directly indecomposable subgroups + """ return "Infinite set of conjugacy classes of directly indecomposable subgroups" @cached_method def canonical_label(self, elm): r""" + Construct the canonical representative of a conjugacy class + by sorting the orbits by length and making them consecutive. EXAMPLES:: + sage: from sage.rings.species import ConjugacyClassesOfDirectlyIndecomposableSubgroups + sage: C = ConjugacyClassesOfDirectlyIndecomposableSubgroups() sage: G = PermutationGroup([[(1,3),(4,7)], [(2,5),(6,8)], [(1,4),(2,5),(3,7)]]) - sage: A = AtomicSpecies(1) - sage: A(G) - {[(5,6)(7,8), (1,2)(5,7)(6,8), (1,2)(3,4)]: (8,)} + sage: C(G) + [(2,5)(6,8), (1,3)(4,7), (1,4)(2,5)(3,7)] """ - return self.element_class(self, PermutationGroup(gap_group=libgap.ConjugateGroup(elm._C, elm._canonicalizing_perm))) + pi = PermutationGroupElement([e for o in elm._sorted_orbits for e in o], check=False) + return self.element_class(self, PermutationGroup(gap_group=libgap.ConjugateGroup(elm._C, pi))) Element = ConjugacyClassOfDirectlyIndecomposableSubgroups @@ -176,6 +276,12 @@ def __init__(self, parent, dis, domain_partition): - ``domain_partition``, a dict representing the assignment of each element of the domain of ``dis`` to a "variable". + + TESTS:: + + sage: A = AtomicSpecies(1) + sage: G = PermutationGroup([[(1,3),(4,7)], [(2,5),(6,8)], [(1,4),(2,5),(3,7)]]) + sage: TestSuite(A(G)).run() """ # Notice that a molecular species (and therefore an atomic species) # must be centered on a multicardinality, otherwise it wouldn't be @@ -184,10 +290,7 @@ def __init__(self, parent, dis, domain_partition): Element.__init__(self, parent) self._dis = dis self._dompart = domain_partition - L = [0 for _ in range(self.parent()._k)] - for v in self._dompart.values(): - L[v - 1] += 1 - self._mc = tuple(L) + self._mc = tuple(len(v) for v in self._dompart) self._tc = sum(self._mc) def _element_key(self): @@ -205,11 +308,40 @@ def __hash__(self): def __eq__(self, other): r""" Two atomic species are equal if the underlying groups are conjugate, - and their multicardinalities are equal. + and their domain partitions are equal under the conjugating element. + + TESTS:: + + sage: P = PolynomialSpecies(2) + sage: G = PermutationGroup([[(1,2),(3,4),(5,6),(7,8,9,10)]]); G + Permutation Group with generators [(1,2)(3,4)(5,6)(7,8,9,10)] + sage: H = PermutationGroup([[(1,2,3,4),(5,6),(7,8),(9,10)]]); H + Permutation Group with generators [(1,2,3,4)(5,6)(7,8)(9,10)] + sage: A = P(G, {1: [1,2,3,4], 2: [5,6,7,8,9,10]}) + sage: B = P(H, {1: [1,2,3,4], 2: [5,6,7,8,9,10]}) + sage: C = P(G, {1: [1,2,5,6], 2: [3,4,7,8,9,10]}) + sage: A != B + True + sage: A == C + True """ if parent(self) != parent(other): return False - return self._mc == other._mc and self._dis == other._dis + # Check if multicardinalities match + if self._mc != other._mc: + return False + # If they do, construct the mapping between the groups + selflist, otherlist = [], [] + for i in range(self.parent()._k): + if len(self._dompart[i]) != len(other._dompart[i]): + return False + selflist.extend(self._dompart[i]) + otherlist.extend(other._dompart[i]) + mapping = libgap.MappingPermListList(selflist, otherlist) + G = PermutationGroup(gap_group=libgap.ConjugateGroup(self._dis._C, mapping), + domain=self._dis._C.domain()) + # The conjugated group must be exactly equal to the other group + return G == other._dis._C def _repr_(self): r""" @@ -243,74 +375,52 @@ def an_element(self): Return an element of ``self``. """ G = SymmetricGroup(self._k).young_subgroup([1] * self._k) - m = {e: i for i, e in enumerate(range(1, self._k + 1), 1)} - return self._element_constructor_((G, m)) - - def _normalize(self, H, M): - r""" - Normalize the domain of `H` and return `H` and the domain partition. - """ - # TODO: Complete the documentation. - if set(H.domain()) != set(M.keys()): - raise ValueError(f"Keys of mapping do not match with domain of {H}") - if not set(M.values()).issubset(range(1, self._k + 1)): - raise ValueError(f"Values of mapping must be in the range [1, {self._k}]") - # each orbit of H must only contain elements from one sort - for orbit in H.orbits(): - if len(set(M[k] for k in orbit)) > 1: - raise ValueError(f"For each orbit of {H}, all elements must belong to the same set") - # normalize domain to {1..n} - if sorted(M.keys()) == list(range(1, H.degree() + 1)): - return H, M - mapping = {v: i for i, v in enumerate(H.domain(), 1)} - normalized_gens = [[tuple(mapping[x] for x in cyc) - for cyc in gen.cycle_tuples()] - for gen in H.gens()] - P = PermutationGroup(gens=normalized_gens) - # Fix for SymmetricGroup(0) - if H.degree() == 0: - P = SymmetricGroup(0) - # create domain partition - dompart = {mapping[k]: v for k, v in M.items()} - return P, dompart + m = {i: i for i in range(1, self._k + 1)} + return self._element_constructor_(G, m) - def _element_constructor_(self, x): + def _element_constructor_(self, G, pi=None): r""" Construct the `k`-variate atomic species with the given data. INPUT: - - ``x`` can be any of the following: - - an element of ``self``. - - a tuple ``(H, M)`` where `H` is the permutation group - representation for the atomic species and `M` is a - ``dict`` mapping each element of the domain of `H` to - integers in `\{ 1 \ldots k \}`, representing the set to - which the element belongs. - - if `k=1`, i.e. we are working with univariate atomic - species, the mapping `M` may be omitted and just the - group `H` may be passed. - + - ``G`` - an element of ``self`` (in this case pi must be ``None``) + or a permutation group. + - ``pi`` - a dict mapping sorts to iterables whose union is the domain. + If `k=1`, `pi` can be omitted. """ - if parent(x) == self: - return x - H, M = None, None - if isinstance(x, tuple): - H, M = x - elif self._k == 1: - if isinstance(x, PermutationGroup_generic): - H = x - M = {e: 1 for e in H.domain()} + if parent(G) == self: + if pi is not None: + raise ValueError("cannot reassign sorts to an atomic species") + return G + if not isinstance(G, PermutationGroup_generic): + raise ValueError(f"{G} must be a permutation group") + if pi is None: + if self._k == 1: + pi = {1: G.domain()} else: - raise ValueError(f"{x} must be a permutation group") - else: - raise ValueError(f"{x} must be a tuple for multivariate species") - H_norm, dompart = self._normalize(H, M) - dis_elm = self._dis_ctor(H_norm) - # Trying to avoid libgap.RepresentativeAction; it is slow - pi = dis_elm._canonicalizing_perm - dompart_norm = {pi(k): v for k, v in dompart.items()} - elm = self.element_class(self, dis_elm, dompart_norm) + raise ValueError("the assignment of sorts to the domain elements must be provided") + if any(len(set(v)) != len(v) for v in pi.values()): + raise ValueError("each sort must contain distinct elements") + pi = {k: set(v) for k, v in pi.items()} + if not set(pi.keys()).issubset(range(1, self._k + 1)): + raise ValueError(f"keys of pi must be in the range [1, {self._k}]") + if sum(len(p) for p in pi.values()) != len(G.domain()) or set.union(*[p for p in pi.values()]) != set(G.domain()): + raise ValueError("values of pi must partition the domain of G") + for orbit in G.orbits(): + if not any(set(orbit).issubset(p) for p in pi.values()): + raise ValueError(f"For each orbit of {G}, all elements must belong to the same sort") + dis_elm = self._dis_ctor(G) + # Now use this mapping to get dompart + mapping = {v: i for i, v in enumerate(G.domain(), 1)} + mapping2 = PermutationGroupElement([mapping[e] for o in + sorted([sorted(orbit) for orbit in G.orbits()], key=len) + for e in o], check=False) + # domain partition should be immutable + dpart = [frozenset() for _ in range(self._k)] + for k, v in pi.items(): + dpart[k - 1] = frozenset(mapping2(mapping[x]) for x in v) + elm = self.element_class(self, dis_elm, tuple(dpart)) return self._cache_get(elm) def __getitem__(self, x): @@ -325,10 +435,26 @@ def __contains__(self, x): """ if parent(x) == self: return True - H, M = x - return (set(H.domain()) == set(M.keys()) - and set(M.values()).issubset(range(1, self._k + 1)) - and len(H.disjoint_direct_product_decomposition()) == 1) + G, pi = None, None + if isinstance(x, PermutationGroup_generic): + if self._k == 1: + G = x + pi = {1: G.domain()} + else: + raise ValueError("the assignment of sorts to the domain elements must be provided") + else: + G, pi = x + if not isinstance(G, PermutationGroup_generic): + raise ValueError(f"{G} must be a permutation group") + if not set(pi.keys()).issubset(range(1, self._k + 1)): + raise ValueError(f"keys of pi must be in the range [1, {self._k}]") + pi = {k: set(v) for k, v in pi.items()} + if sum(len(p) for p in pi.values()) != len(G.domain()) or set.union(*[p for p in pi.values()]) != set(G.domain()): + raise ValueError("values of pi must partition the domain of G") + for orbit in G.orbits(): + if not any(set(orbit).issubset(p) for p in pi.values()): + raise ValueError(f"For each orbit of {G}, all elements must belong to the same sort") + return len(G.disjoint_direct_product_decomposition()) <= 1 def _repr_(self): r""" @@ -367,8 +493,8 @@ def _element_constructor_(self, x=None): def one(self): elm = super().one() elm._group = SymmetricGroup(0) - elm._dompart = dict() - elm._mc = [0 for _ in range(self._k)] + elm._dompart = tuple() + elm._mc = tuple(0 for _ in range(self._k)) elm._tc = 0 return elm @@ -378,7 +504,7 @@ def gen(self, x): """ if x not in self._indices: raise IndexError(f"{x} is not in the index set") - at = self._indices(x) + at = self._indices(x[0], x[1]) elm = self._cache_get(self.element_class(self, {at: ZZ.one()})) if elm._group is None: elm._group = at._dis._C @@ -395,6 +521,8 @@ def __init__(self, F, x): self._mc = None self._tc = None + # There is weirdness going on here and below with copying + # and references. def _assign_group_info(self, other): self._group = other._group self._dompart = other._dompart @@ -441,10 +569,14 @@ def _elmmul(self, elm1, elm2): gens1, gens2 = gens2, gens1 elm1, elm2 = elm2, elm1 gens = list(gens1) - self._dompart = elm1._dompart | {(elm1._tc + k): v for k, v in elm2._dompart.items()} for gen in gens2: gens.append([tuple(elm1._tc + k for k in cyc) for cyc in gen.cycle_tuples()]) self._group = PermutationGroup(gens, domain=range(1, elm1._tc + elm2._tc + 1)) + # TODO: Set the dompart + self._dompart = list(elm1._dompart) + for i in range(elm2.parent()._k): + self._dompart[i] = frozenset(list(self._dompart[i]) + [elm1._tc + e for e in elm2._dompart[i]]) + self._dompart = tuple(self._dompart) def __floordiv__(self, elt): raise NotImplementedError("Cannot cancel in this monoid") @@ -530,17 +662,21 @@ def degree_on_basis(self, m): """ return m.grade() - def _project(self, H, f, part): + def _project(self, G, pi, part): r""" - Project `H` onto a subset ``part`` of its domain. + Project `G` onto a subset ``part`` of its domain. ``part`` must be a union of cycles, but this is not checked. """ - restricted_gens = [[cyc for cyc in gen.cycle_tuples() if cyc[0] in part] for gen in H.gens()] - mapping = {p: f[p] for p in part} + restricted_gens = [[cyc for cyc in gen.cycle_tuples() if cyc[0] in part] for gen in G.gens()] + mapping = dict() + for k, v in pi.items(): + es = [e for e in v if e in part] + if es: + mapping[k] = es return PermutationGroup(gens=restricted_gens, domain=part), mapping - def _element_constructor_(self, x): + def _element_constructor_(self, G, pi=None): r""" Construct the `k`-variate molecular species with the given data. @@ -558,23 +694,30 @@ def _element_constructor_(self, x): may be passed. """ - if parent(x) == self: - return x - H, M = None, None - if isinstance(x, tuple): - H, M = x - elif self._k == 1: - if isinstance(x, PermutationGroup_generic): - H = x - M = {e: ZZ.one() for e in H.domain()} + if parent(G) == self: + if pi is not None: + raise ValueError("cannot reassign sorts to a polynomial species") + return G + if not isinstance(G, PermutationGroup_generic): + raise ValueError(f"{G} must be a permutation group") + if pi is None: + if self._k == 1: + pi = {1: G.domain()} else: - raise ValueError(f"{x} must be a permutation group") - else: - raise ValueError(f"{x} must be a tuple for multivariate species") - domain_partition = H.disjoint_direct_product_decomposition() + raise ValueError("the assignment of sorts to the domain elements must be provided") + if not set(pi.keys()).issubset(range(1, self._k + 1)): + raise ValueError(f"keys of pi must be in the range [1, {self._k}]") + pi = {k: set(v) for k, v in pi.items()} + if sum(len(p) for p in pi.values()) != len(G.domain()) or set.union(*[p for p in pi.values()]) != set(G.domain()): + raise ValueError("values of pi must partition the domain of G") + for orbit in G.orbits(): + if not any(set(orbit).issubset(p) for p in pi.values()): + raise ValueError(f"For each orbit of {G}, all elements must belong to the same sort") + + domain_partition = G.disjoint_direct_product_decomposition() term = self._indices.one() for part in domain_partition: - term *= self._indices.gen(self._project(H, M, part)) + term *= self._indices.gen(self._project(G, pi, part)) return self._from_dict({term: ZZ.one()}) def __getitem__(self, x): @@ -591,13 +734,15 @@ def __getitem__(self, x): X^2 sage: P2 = PolynomialSpecies(2) sage: At2 = AtomicSpecies(2) - sage: At2((SymmetricGroup(1), {1: 1})).rename("X") - sage: At2((SymmetricGroup(1), {1: 2})).rename("Y") - sage: XY = (SymmetricGroup(2).young_subgroup([1, 1]), {1: 1, 2: 2}) + sage: At2(SymmetricGroup(1), {1: [1]}).rename("X") + sage: At2(SymmetricGroup(1), {2: [1]}).rename("Y") + sage: XY = (SymmetricGroup(2).young_subgroup([1, 1]), {1: [1], 2: [2]}) sage: P2[XY] X*Y """ - return self._element_constructor_(x) + if isinstance(x, PermutationGroup_generic): + return self._element_constructor_(x) + return self._element_constructor_(*x) @cached_method def one_basis(self): @@ -861,10 +1006,30 @@ def addition_formula(self, arg): res += coeff * term return res - def _embedding_coeff(self, part, n): + @staticmethod + def _embedding_coeff(part, n): r""" Number of embeddings of the partition ``part`` into a list of length `n` (where holes are filled with `0`). + + EXAMPLES: + Ways to fill [0, 0, 0, 0] with [2, 1, 1]: + - [2, 1, 1, 0] + - [2, 1, 0, 1] + - [2, 0, 1, 1] + - [0, 2, 1, 1] + - [1, 2, 1, 0] + - [1, 2, 0, 1] + - [1, 0, 2, 1] + - [0, 1, 2, 1] + - [1, 1, 2, 0] + - [1, 1, 0, 2] + - [1, 0, 1, 2] + - [0, 1, 1, 2] + + So, 12 ways:: + sage: PolynomialSpecies.Element._embedding_coeff([2, 1, 1], 4) + 12 """ return Permutations(part).cardinality() * binomial(n, len(part)) @@ -874,11 +1039,8 @@ def _multiplicity_handling(self, F, coeffs): coeffs is the mi. Hmc is the cardinality on each sort. F is a PolynomialSpeciesElement. """ - if len(coeffs) != self.parent()._k: - raise ValueError(f"Number of args (= {len(coeffs)}) must equal arity of self (= {len(coeffs)})") - if any(x <= 0 for x in coeffs): - raise ValueError(f"All values must be strictly positive") - + # This is supposed to be an internal method so we perform + # no domain normalizations or argument checking. Fm = F.support()[0] Fmc = Fm._mc Fgap = Fm._group.gap() From a64700da528e520d30d7f3d3d3552c2317124f4f Mon Sep 17 00:00:00 2001 From: Newtech66 Date: Wed, 14 Aug 2024 15:24:21 +0530 Subject: [PATCH 120/537] revert changes to permgroup.py --- src/sage/groups/perm_gps/permgroup.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/sage/groups/perm_gps/permgroup.py b/src/sage/groups/perm_gps/permgroup.py index 3cb92d8c74a..d97aad93b03 100644 --- a/src/sage/groups/perm_gps/permgroup.py +++ b/src/sage/groups/perm_gps/permgroup.py @@ -1628,8 +1628,6 @@ def disjoint_direct_product_decomposition(self): """ from sage.combinat.set_partition import SetPartition from sage.sets.disjoint_set import DisjointSet - if len(self.orbits()) <= 1: - return SetPartition(self.orbits()) H = self._libgap_() # sort each orbit and order list by smallest element of each orbit O = libgap.List([libgap.ShallowCopy(orbit) for orbit in libgap.Orbits(H)]) @@ -1641,7 +1639,7 @@ def disjoint_direct_product_decomposition(self): for i in range(num_orbits): for x in O[i]: OrbitMapping[x] = i - C = libgap.StabChain(H, libgap.Flat(O)) + C = libgap.StabChain(H, libgap.Concatenation(O)) X = libgap.StrongGeneratorsStabChain(C) P = DisjointSet(num_orbits) R = libgap.List([]) @@ -5058,7 +5056,6 @@ def sign_representation(self, base_ring=None): class PermutationGroup_subgroup(PermutationGroup_generic): - """ Subgroup subclass of ``PermutationGroup_generic``, so instance methods are inherited. From 5ce6e11cc2f059131804832989c185df443b589b Mon Sep 17 00:00:00 2001 From: Newtech66 Date: Sun, 18 Aug 2024 01:03:37 +0530 Subject: [PATCH 121/537] Canonicalization fixes, doctest additions --- src/sage/rings/species.py | 172 +++++++++++++++++++++++++++++--------- 1 file changed, 133 insertions(+), 39 deletions(-) diff --git a/src/sage/rings/species.py b/src/sage/rings/species.py index dfab2e91dbe..ac6769a0793 100644 --- a/src/sage/rings/species.py +++ b/src/sage/rings/species.py @@ -52,6 +52,19 @@ def __init__(self): def clear_cache(self): r""" Clear the cache. + + EXAMPLES:: + + sage: A = AtomicSpecies(1) + sage: A(SymmetricGroup(1)) + {[()]: (1,)} + sage: A(SymmetricGroup(0)) + {[]: (0,)} + sage: A._cache + {((0,), []): [{[]: (0,)}], ((1,), [()]): [{[()]: (1,)}]} + sage: A.clear_cache() + sage: A._cache + {} """ self._cache = dict() @@ -70,17 +83,13 @@ def _cache_get(self, elm): for other_elm in lookup: if elm == other_elm: return other_elm - elm = self._canonical_label(elm) + elm._canonicalize() lookup.append(elm) else: - elm = self._canonical_label(elm) + elm._canonicalize() self._cache[key] = [elm] return elm - @cached_method - def _canonical_label(self, elm): - return elm - class ConjugacyClassOfDirectlyIndecomposableSubgroups(Element): def __init__(self, parent, C): r""" @@ -95,9 +104,6 @@ def __init__(self, parent, C): """ Element.__init__(self, parent) self._C = C - self._sorted_orbits = sorted([sorted(orbit) for orbit in C.orbits()], key=len) - self._orbit_lens = tuple(len(orbit) for orbit in self._sorted_orbits) - self._order = C.order() def __hash__(self): r""" @@ -126,19 +132,42 @@ def _repr_(self): sage: C = ConjugacyClassesOfDirectlyIndecomposableSubgroups() sage: G = PermutationGroup([[(1,3),(4,7)], [(2,5),(6,8)], [(1,4),(2,5),(3,7)]]) sage: C(G) - [(2,5)(6,8), (1,3)(4,7), (1,4)(2,5)(3,7)] + [(5,6)(7,8), (1,2)(3,4), (1,3)(2,4)(5,6)] """ return f"{self._C.gens_small()}" def _element_key(self): - return self._C.degree(), self._order, self._orbit_lens + r""" + Return the cache lookup key for ``self``. + """ + return self._C.degree(), self._C.order(), tuple(len(orbit) for orbit in sorted(self._C.orbits(), key=len)) + + @cached_method + def _canonicalize(self): + r""" + Canonicalize this conjugacy class by sorting the orbits by + length and making them consecutive. + + EXAMPLES:: + + sage: from sage.rings.species import ConjugacyClassesOfDirectlyIndecomposableSubgroups + sage: C = ConjugacyClassesOfDirectlyIndecomposableSubgroups() + sage: G = PermutationGroup([[(1,3),(4,7)], [(2,5),(6,8)], [(1,4),(2,5),(3,7)]]) + sage: C(G) + [(5,6)(7,8), (1,2)(3,4), (1,3)(2,4)(5,6)] + """ + if self._C == SymmetricGroup(0): + return + sorted_orbits = sorted([sorted(orbit) for orbit in self._C.orbits()], key=len, reverse=True) + pi = PermutationGroupElement(list(chain.from_iterable(sorted_orbits))).inverse() + self._C = PermutationGroup(gap_group=libgap.ConjugateGroup(self._C, pi)) def __eq__(self, other): r""" Return whether ``self`` is equal to ``other``. ``self`` is equal to ``other`` if they have the same degree (say `n`) - and order and are conjugate within `S_n`. + and are conjugate within `S_n`. TESTS:: @@ -174,6 +203,16 @@ def __init__(self): @cached_method def an_element(self): + r""" + Return an element of ``self``. + + EXAMPLES:: + + sage: from sage.rings.species import ConjugacyClassesOfDirectlyIndecomposableSubgroups + sage: C = ConjugacyClassesOfDirectlyIndecomposableSubgroups() + sage: C.an_element() + [()] + """ return self._element_constructor_(SymmetricGroup(1)) def _element_constructor_(self, x): @@ -193,10 +232,10 @@ def _element_constructor_(self, x): sage: C(PermutationGroup([(1, 3, 5)], domain=[1,3,5])) [(1,2,3)] sage: C(PermutationGroup([[(1,3),(4,7)],[(2,5),(6,8)], [(1,4),(2,5),(3,7)]])) - [(2,5)(6,8), (1,3)(4,7), (1,4)(2,5)(3,7)] + [(5,6)(7,8), (1,2)(3,4), (1,3)(2,4)(5,6)] sage: C._cache {(3, 3, (3,)): [[(1,2,3)]], - (8, 8, (2, 2, 4)): [[(2,5)(6,8), (1,3)(4,7), (1,4)(2,5)(3,7)]]} + (8, 8, (2, 2, 4)): [[(5,6)(7,8), (1,2)(3,4), (1,3)(2,4)(5,6)]]} """ if parent(x) == self: return x @@ -216,6 +255,24 @@ def _element_constructor_(self, x): raise ValueError(f"unable to convert {x} to {self}") def __iter__(self): + r""" + An iterator over all conjugacy classes of directly indecomposable + subgroups. + + TESTS:: + + sage: from sage.rings.species import ConjugacyClassesOfDirectlyIndecomposableSubgroups + sage: C = ConjugacyClassesOfDirectlyIndecomposableSubgroups() + sage: iterC = iter(C) + sage: for i in range(5): + ....: print(next(iterC)) + ....: + [] + [()] + [(1,2)] + [(1,2,3)] + [(1,2,3), (2,3)] + """ # Is SymmetricGroup(0) directly indecomposable? n = 0 while True: @@ -244,23 +301,6 @@ def _repr_(self): """ return "Infinite set of conjugacy classes of directly indecomposable subgroups" - @cached_method - def canonical_label(self, elm): - r""" - Construct the canonical representative of a conjugacy class - by sorting the orbits by length and making them consecutive. - - EXAMPLES:: - - sage: from sage.rings.species import ConjugacyClassesOfDirectlyIndecomposableSubgroups - sage: C = ConjugacyClassesOfDirectlyIndecomposableSubgroups() - sage: G = PermutationGroup([[(1,3),(4,7)], [(2,5),(6,8)], [(1,4),(2,5),(3,7)]]) - sage: C(G) - [(2,5)(6,8), (1,3)(4,7), (1,4)(2,5)(3,7)] - """ - pi = PermutationGroupElement([e for o in elm._sorted_orbits for e in o], check=False) - return self.element_class(self, PermutationGroup(gap_group=libgap.ConjugateGroup(elm._C, pi))) - Element = ConjugacyClassOfDirectlyIndecomposableSubgroups @@ -299,6 +339,29 @@ def _element_key(self): """ return self._mc, self._dis + @cached_method + def _canonicalize(self): + r""" + Canonicalize this atomic species by sorting the orbits by + length and making them consecutive. + + EXAMPLES:: + + sage: At = AtomicSpecies(2) + sage: G = PermutationGroup([[(1,2),(3,4),(5,6),(7,8,9,10)]]); G + Permutation Group with generators [(1,2)(3,4)(5,6)(7,8,9,10)] + sage: H = PermutationGroup([[(1,2,3,4),(5,6),(7,8),(9,10)]]); H + Permutation Group with generators [(1,2,3,4)(5,6)(7,8)(9,10)] + sage: A = At(G, {1: [1,2,3,4], 2: [5,6,7,8,9,10]}) + sage: A._dompart + ((5, 6, 7, 8), (9, 10, 1, 2, 3, 4)) + sage: C = At(G, {1: [1,2,5,6], 2: [3,4,7,8,9,10]}) + sage: C._dompart + ((5, 6, 7, 8), (9, 10, 1, 2, 3, 4)) + """ + # The canonicalization is done in the element constructor. + pass + def __hash__(self): r""" Return the hash of the atomic species. @@ -413,13 +476,12 @@ def _element_constructor_(self, G, pi=None): dis_elm = self._dis_ctor(G) # Now use this mapping to get dompart mapping = {v: i for i, v in enumerate(G.domain(), 1)} - mapping2 = PermutationGroupElement([mapping[e] for o in - sorted([sorted(orbit) for orbit in G.orbits()], key=len) - for e in o], check=False) + mapping2 = PermutationGroupElement([mapping[e] for o in sorted(G.orbits(), key=len, reverse=True) + for e in o]).inverse() # domain partition should be immutable - dpart = [frozenset() for _ in range(self._k)] + dpart = [tuple() for _ in range(self._k)] for k, v in pi.items(): - dpart[k - 1] = frozenset(mapping2(mapping[x]) for x in v) + dpart[k - 1] = tuple(mapping2(mapping[x]) for x in v) elm = self.element_class(self, dis_elm, tuple(dpart)) return self._cache_get(elm) @@ -575,7 +637,7 @@ def _elmmul(self, elm1, elm2): # TODO: Set the dompart self._dompart = list(elm1._dompart) for i in range(elm2.parent()._k): - self._dompart[i] = frozenset(list(self._dompart[i]) + [elm1._tc + e for e in elm2._dompart[i]]) + self._dompart[i] = tuple(list(self._dompart[i]) + [elm1._tc + e for e in elm2._dompart[i]]) self._dompart = tuple(self._dompart) def __floordiv__(self, elt): @@ -589,6 +651,7 @@ def _mul_(self, other): elm = self.parent()._cache_get(res) if elm._group is None: elm._elmmul(self, other) + elm._canonicalize() return elm def _elmexp(self, other, n): @@ -614,11 +677,39 @@ def __pow__(self, n): elm = self.parent()._cache_get(res) if elm._group is None: elm._elmexp(self, n) + elm._canonicalize() return elm def _element_key(self): return self + @cached_method + def _canonicalize(self): + r""" + Canonicalize this molecular species by sorting the orbits by + length and making them consecutive. + + EXAMPLES:: + + sage: P = PolynomialSpecies(2) + sage: G = PermutationGroup([[(1,2),(3,4),(5,6),(7,8,9,10)]]); G + Permutation Group with generators [(1,2)(3,4)(5,6)(7,8,9,10)] + sage: H = PermutationGroup([[(1,2,3,4),(5,6),(7,8),(9,10)]]); H + Permutation Group with generators [(1,2,3,4)(5,6)(7,8)(9,10)] + sage: A = P(G, {1: [1,2,3,4], 2: [5,6,7,8,9,10]}) + sage: A.support()[0]._dompart + ((5, 6, 7, 8), (9, 10, 1, 2, 3, 4)) + sage: C = P(G, {1: [1,2,5,6], 2: [3,4,7,8,9,10]}) + sage: C.support()[0]._dompart + ((5, 6, 7, 8), (9, 10, 1, 2, 3, 4)) + """ + if self._group is None or self._group == SymmetricGroup(0): + return + sorted_orbits = sorted([sorted(orbit) for orbit in self._group.orbits()], key=len, reverse=True) + pi = PermutationGroupElement(list(chain.from_iterable(sorted_orbits))).inverse() + self._group = PermutationGroup(gap_group=libgap.ConjugateGroup(self._group, pi)) + self._dompart = tuple(tuple(pi(k) for k in v) for v in self._dompart) + def grade(self): r""" Return the grade of ``self``. @@ -949,7 +1040,7 @@ def cartesian_product(self, other): # Do we want to allow cartesian products between different k-variates? if self.parent()._k != other.parent()._k: - return self.parent().zero() + return ValueError() terms = cartesian_product([self.terms(), other.terms()]) res = 0 @@ -1061,4 +1152,7 @@ def _multiplicity_handling(self, F, coeffs): term += PF((G, Fm._dompart)) term *= prod([self._embedding_coeff(p, n) for p, n in zip(parts, coeffs)]) res += term - return res \ No newline at end of file + return res + + def substitution(self, args): + pass \ No newline at end of file From a081b60d6f25f62d550aa89c0450f1acf3bcc47c Mon Sep 17 00:00:00 2001 From: Newtech66 Date: Sun, 18 Aug 2024 01:43:45 +0530 Subject: [PATCH 122/537] More doctests --- src/sage/rings/species.py | 164 ++++++++++++++++++++++++++++++++------ 1 file changed, 139 insertions(+), 25 deletions(-) diff --git a/src/sage/rings/species.py b/src/sage/rings/species.py index ac6769a0793..be08e67a797 100644 --- a/src/sage/rings/species.py +++ b/src/sage/rings/species.py @@ -284,6 +284,17 @@ def __iter__(self): def __contains__(self, G): r""" Return if ``G`` is in ``self``. + + TESTS:: + + sage: from sage.rings.species import ConjugacyClassesOfDirectlyIndecomposableSubgroups + sage: C = ConjugacyClassesOfDirectlyIndecomposableSubgroups() + sage: G = PermutationGroup([[(1,2)], [(3,4)]]); G + Permutation Group with generators [(3,4), (1,2)] + sage: G.disjoint_direct_product_decomposition() + {{1, 2}, {3, 4}} + sage: G in C + False """ if parent(G) == self: return True @@ -335,7 +346,7 @@ def __init__(self, parent, dis, domain_partition): def _element_key(self): r""" - Return a lookup key for ``self``. + Return the cache lookup key for ``self``. """ return self._mc, self._dis @@ -365,6 +376,24 @@ def _canonicalize(self): def __hash__(self): r""" Return the hash of the atomic species. + + TESTS:: + + sage: At = AtomicSpecies(2) + sage: G = PermutationGroup([[(1,2),(3,4),(5,6),(7,8,9,10)]]); G + Permutation Group with generators [(1,2)(3,4)(5,6)(7,8,9,10)] + sage: H = PermutationGroup([[(1,2,3,4),(5,6),(7,8),(9,10)]]); H + Permutation Group with generators [(1,2,3,4)(5,6)(7,8)(9,10)] + sage: A = At(G, {1: [1,2,3,4], 2: [5,6,7,8,9,10]}); A + {[(1,2,3,4)(5,6)(7,8)(9,10)]: (4, 6)} + sage: B = At(H, {1: [1,2,3,4], 2: [5,6,7,8,9,10]}); B + {[(1,2,3,4)(5,6)(7,8)(9,10)]: (4, 6)} + sage: C = At(G, {1: [1,2,5,6], 2: [3,4,7,8,9,10]}); C + {[(1,2,3,4)(5,6)(7,8)(9,10)]: (4, 6)} + sage: hash(A) == hash(B) + True + sage: hash(A) == hash(C) + True """ return hash(self._element_key()) @@ -375,14 +404,14 @@ def __eq__(self, other): TESTS:: - sage: P = PolynomialSpecies(2) + sage: At = AtomicSpecies(2) sage: G = PermutationGroup([[(1,2),(3,4),(5,6),(7,8,9,10)]]); G Permutation Group with generators [(1,2)(3,4)(5,6)(7,8,9,10)] sage: H = PermutationGroup([[(1,2,3,4),(5,6),(7,8),(9,10)]]); H Permutation Group with generators [(1,2,3,4)(5,6)(7,8)(9,10)] - sage: A = P(G, {1: [1,2,3,4], 2: [5,6,7,8,9,10]}) - sage: B = P(H, {1: [1,2,3,4], 2: [5,6,7,8,9,10]}) - sage: C = P(G, {1: [1,2,5,6], 2: [3,4,7,8,9,10]}) + sage: A = At(G, {1: [1,2,3,4], 2: [5,6,7,8,9,10]}) + sage: B = At(H, {1: [1,2,3,4], 2: [5,6,7,8,9,10]}) + sage: C = At(G, {1: [1,2,5,6], 2: [3,4,7,8,9,10]}) sage: A != B True sage: A == C @@ -409,15 +438,29 @@ def __eq__(self, other): def _repr_(self): r""" Return a string representation of ``self``. + + TESTS:: + + sage: At = AtomicSpecies(2) + sage: G = PermutationGroup([[(1,2),(3,4),(5,6),(7,8,9,10)]]); G + Permutation Group with generators [(1,2)(3,4)(5,6)(7,8,9,10)] + sage: A = At(G, {1: [1,2,3,4], 2: [5,6,7,8,9,10]}); A + {[(1,2,3,4)(5,6)(7,8)(9,10)]: (4, 6)} """ return "{" + f"{self._dis}: {self._mc}" + "}" -# How to remember the names without ElementCache? class AtomicSpecies(UniqueRepresentation, Parent, ElementCache): def __init__(self, k): r""" Infinite set of `k`-variate atomic species graded by integer vectors of length `k`. + + TESTS:: + + sage: At1 = AtomicSpecies(1) + sage: At2 = AtomicSpecies(2) + sage: TestSuite(At1).run(skip="_test_graded_components") + sage: TestSuite(At2).run(skip="_test_graded_components") """ category = SetsWithGrading().Infinite() Parent.__init__(self, category=category) @@ -426,19 +469,22 @@ def __init__(self, k): self._grading_set = IntegerVectors(length=k) self._dis_ctor = ConjugacyClassesOfDirectlyIndecomposableSubgroups() - def __hash__(self): - r""" - Return a hash for ``self``. - """ - return hash(self._k) - @cached_method def an_element(self): """ Return an element of ``self``. + + TESTS:: + + sage: At1 = AtomicSpecies(1) + sage: At2 = AtomicSpecies(2) + sage: At1.an_element() + {[(1,2)]: (2,)} + sage: At2.an_element() + {[(1,2)(3,4)]: (2, 2)} """ - G = SymmetricGroup(self._k).young_subgroup([1] * self._k) - m = {i: i for i in range(1, self._k + 1)} + G = PermutationGroup([[(2 * i - 1, 2 * i) for i in range(1, self._k + 1)]]) + m = {i: [2 * i - 1, 2 * i] for i in range(1, self._k + 1)} return self._element_constructor_(G, m) def _element_constructor_(self, G, pi=None): @@ -474,11 +520,9 @@ def _element_constructor_(self, G, pi=None): if not any(set(orbit).issubset(p) for p in pi.values()): raise ValueError(f"For each orbit of {G}, all elements must belong to the same sort") dis_elm = self._dis_ctor(G) - # Now use this mapping to get dompart mapping = {v: i for i, v in enumerate(G.domain(), 1)} mapping2 = PermutationGroupElement([mapping[e] for o in sorted(G.orbits(), key=len, reverse=True) for e in o]).inverse() - # domain partition should be immutable dpart = [tuple() for _ in range(self._k)] for k, v in pi.items(): dpart[k - 1] = tuple(mapping2(mapping[x]) for x in v) @@ -489,7 +533,8 @@ def __getitem__(self, x): r""" Call ``_element_constructor_`` on ``x``. """ - return self._element_constructor_(x) + # TODO: This needs to be checked. + return self._element_constructor_(*x) def __contains__(self, x): r""" @@ -524,11 +569,9 @@ def _repr_(self): TESTS:: - sage: At1 = AtomicSpecies(1) - sage: At1 + sage: At1 = AtomicSpecies(1); At1 Infinite set of 1-variate atomic species - sage: At2 = AtomicSpecies(2) - sage: At2 + sage: At2 = AtomicSpecies(2); At2 Infinite set of 2-variate atomic species """ return f"Infinite set of {self._k}-variate atomic species" @@ -553,6 +596,15 @@ def _element_constructor_(self, x=None): @cached_method def one(self): + r""" + Return the one of this monoid. + + EXAMPLES:: + + sage: P = PolynomialSpecies(2) + sage: P._indices.one() + 1 + """ elm = super().one() elm._group = SymmetricGroup(0) elm._dompart = tuple() @@ -583,9 +635,10 @@ def __init__(self, F, x): self._mc = None self._tc = None - # There is weirdness going on here and below with copying - # and references. def _assign_group_info(self, other): + r""" + Assign the group info of ``other`` to ``self``. + """ self._group = other._group self._dompart = other._dompart self._mc = other._mc @@ -634,7 +687,6 @@ def _elmmul(self, elm1, elm2): for gen in gens2: gens.append([tuple(elm1._tc + k for k in cyc) for cyc in gen.cycle_tuples()]) self._group = PermutationGroup(gens, domain=range(1, elm1._tc + elm2._tc + 1)) - # TODO: Set the dompart self._dompart = list(elm1._dompart) for i in range(elm2.parent()._k): self._dompart[i] = tuple(list(self._dompart[i]) + [elm1._tc + e for e in elm2._dompart[i]]) @@ -681,6 +733,9 @@ def __pow__(self, n): return elm def _element_key(self): + r""" + Return the cache lookup key for ``self``. + """ return self @cached_method @@ -783,7 +838,6 @@ def _element_constructor_(self, G, pi=None): - if `k=1`, i.e. we are working with univariate species, the mapping `M` may be omitted and just the group `H` may be passed. - """ if parent(G) == self: if pi is not None: @@ -904,12 +958,72 @@ def _repr_(self): class Element(CombinatorialFreeModule.Element): def is_virtual(self): + r""" + Return if ``self`` is a virtual species. + + TESTS:: + + sage: P = PolynomialSpecies(2) + sage: At = AtomicSpecies(2) + sage: X = P(SymmetricGroup(1), {1: [1]}) + sage: Y = P(SymmetricGroup(1), {2: [1]}) + sage: At(SymmetricGroup(1), {1: [1]}).rename("X") + sage: At(SymmetricGroup(1), {2: [1]}).rename("Y") + sage: V = 2 * X - 3 * Y; V + 2*X - 3*Y + sage: V.is_virtual() + True + sage: (X * Y).is_virtual() + False + """ return any(x < 0 for x in self.coefficients(sort=False)) def is_molecular(self): + r""" + Return if ``self`` is a molecular species. + + TESTS:: + + sage: P = PolynomialSpecies(2) + sage: At = AtomicSpecies(2) + sage: X = P(SymmetricGroup(1), {1: [1]}) + sage: Y = P(SymmetricGroup(1), {2: [1]}) + sage: At(SymmetricGroup(1), {1: [1]}).rename("X") + sage: At(SymmetricGroup(1), {2: [1]}).rename("Y") + sage: V = 2 * X - 3 * Y; V + 2*X - 3*Y + sage: V.is_molecular() + False + sage: (2 * X).is_molecular() + False + sage: (X * Y).is_molecular() + True + """ return len(self.coefficients(sort=False)) == 1 and self.coefficients(sort=False)[0] == 1 def is_atomic(self): + r""" + Return if ``self`` is an atomic species. + + TESTS:: + + sage: P = PolynomialSpecies(2) + sage: At = AtomicSpecies(2) + sage: X = P(SymmetricGroup(1), {1: [1]}) + sage: Y = P(SymmetricGroup(1), {2: [1]}) + sage: At(SymmetricGroup(1), {1: [1]}).rename("X") + sage: At(SymmetricGroup(1), {2: [1]}).rename("Y") + sage: V = 2 * X - 3 * Y; V + 2*X - 3*Y + sage: V.is_atomic() + False + sage: (2 * X).is_atomic() + False + sage: (X * Y).is_atomic() + False + sage: Y.is_atomic() + True + """ return self.is_molecular() and len(self.support()[0]) == 1 def __call__(self, *args): From 16099c4376e1cebdaf2fb5bf1db63e9b0367ca93 Mon Sep 17 00:00:00 2001 From: Newtech66 Date: Sun, 18 Aug 2024 01:44:49 +0530 Subject: [PATCH 123/537] Remove current composition and cartesian product framework --- src/sage/rings/species.py | 245 -------------------------------------- 1 file changed, 245 deletions(-) diff --git a/src/sage/rings/species.py b/src/sage/rings/species.py index be08e67a797..e5e85742e77 100644 --- a/src/sage/rings/species.py +++ b/src/sage/rings/species.py @@ -1025,248 +1025,3 @@ def is_atomic(self): True """ return self.is_molecular() and len(self.support()[0]) == 1 - - def __call__(self, *args): - r""" - Return the (partitional) composition of ``self`` with ``args``. - Uses the word class expansion (Theorem 2.3, Auger paper). - """ - # should this also have a base ring check or is it coerced? - if len(args) != self.parent()._k: - raise ValueError(f"Number of args (= {len(args)}) must equal arity of self (= {len(args)})") - if any(not isinstance(arg, PolynomialSpecies.Element) for arg in args): - raise ValueError("All args must be elements of PolynomialSpecies") - if min(arg.parent()._k for arg in args) != max(arg.parent()._k for arg in args): - raise ValueError("All args must have same arity") - if self.is_virtual() or any(arg.is_virtual() for arg in args): - raise NotImplementedError(f"Only non-virtual species are supported") - - # Now we only have non-virtual species - res = 0 - for F, coeff in self.monomial_coefficients().items(): - term = 0 - # F(G1;G2;...) each Gi has some molecular decomposition - # Find the automorphisms - combos = [Partitions(p, max_length=len(arg)) for arg, p in zip(args, F._mc)] - # make F such that sort 1 is [123...], and so on - # cache? lol, cache everything - dominverted = sorted(F._dompart.keys(), key=lambda x: F._dompart[x]) - pi = libgap.MappingPermListList(dominverted, libgap.eval(f'[1..{F.grade()}]')) - Fconj = libgap.ConjugateGroup(F._group, pi) - print('Fconj',Fconj) - for IVcombo in cartesian_product(combos): - # TODO: calculate coefficient (because each group has some multiplicity) - # Use F(...) x E(..)^m1 ... - print('IVcombo',IVcombo) - dsumpartial = list(accumulate(chain.from_iterable(IVcombo),initial=0)) - print('dsumpartial',dsumpartial) - Gtop = libgap.eval(f'SymmetricGroup({F._tc})') - Autlist = self._word_automorphism_groups(Fconj, F._mc, IVcombo, Gtop, dsumpartial) - print('Autlist',Autlist) - Gcombos = cartesian_product([[zip(Gs, permedpart) - # for each permutation of the partition - for permedpart in Permutations(IV) - # we want an embedding of permedpart into the Gs - for Gs in combinations(arg.support(), r=len(IV))] - # for each sort - for arg, IV in zip(args, IVcombo)]) - for Gcombo in Gcombos: - print('Gcombo',Gcombo) - gens = [] - mapping = dict() - Fdom = [] - # Find the gens for each group - # Also handles mapping - dsum = 0 - # For the i-th sort - for Gs_sort in Gcombo: - # For each (group, power) pair - for G, cnt in Gs_sort: - dlist = G.domain().list() - Gdeg = G.grade() - curgens = G._group.gens() - cur_mapping = G._dompart - # calculate the gens - for i in range(cnt): - Fdom.append([k + dsum + Gdeg * i for k in sorted(cur_mapping.keys(), key=lambda x: cur_mapping[x])]) - images = libgap.MappingPermListList(dlist, [k + dsum + Gdeg * i for k in dlist]) - mapping |= {(k + dsum + Gdeg * i): v for k, v in cur_mapping.items()} - # Find the gens for this group - for gen in curgens: - gens.append(gen ** images) - dsum += Gdeg * cnt - - Fdom = libgap(Fdom) - Fdomf = libgap.Flat(Fdom) - # for each automorphism group - for Aut in Autlist: - gensrem = [] - # Find the gens for F - for gen in libgap.GeneratorsOfGroup(Aut): - # Since we picked F as the stabilizer subgroup of our current class, - # we don't have to worry about any extra conditions. - perm = libgap.MappingPermListList(Fdomf, libgap.Flat(libgap.Permuted(Fdom, gen))) - gensrem.append(perm) - totgens = gens + gensrem - term += args[0].parent()((PermutationGroup(totgens, domain=range(1, dsum + 1)), mapping)) - res += coeff * term - return res - - def _word_automorphism_groups(self, F, Fmc, IVcombo, Gtop, dsumpartial): - r""" - Given a group F and a tuple of partitions on sorts, - find the word classes and corresponding stabilizer subgroups. - See Theorem 2.3 of the Auger paper. - IVcombo is a tuple of integer partitions. - (I1[x1, x2,...], ..., In[z1,z2,...]) - """ - # It feels like the output of this function can be HEAVILY optimised. - # For example, we only care about unordered integer vectors here. - # Wait, we don't want 0 either. So we actually just want normal integer - # partitions. - - # create domain - # can this be taken out? you could cache this too - domain = list(list(chain.from_iterable(x)) for x in - cartesian_product([Permutations(list(chain.from_iterable([i + precard] * v for i, v in enumerate(part, 1)))) - for precard, part in zip(accumulate(Fmc, initial=0), IVcombo)])) - print('domain', domain) - - orig = domain[0] - orbits = libgap.OrbitsDomain(F, domain, libgap.Permuted) - grps = [] - for orbit in orbits: - # Ok, now I have to find a mapping from orbrep to the original - pi = libgap.RepresentativeAction(Gtop, domain, orbit[0], orig, libgap.Permuted) - print(pi) - stab = libgap.Stabilizer(F, domain, orbit[0], libgap.Permuted) - print('stab',stab) - print('cj',libgap.ConjugateGroup(stab, pi)) - grps.append(libgap.ConjugateGroup(stab, pi)) - return grps - - def cartesian_product(self, other): - r""" - Return the cartesian product of ``self`` with ``other``. - """ - if not isinstance(other, PolynomialSpecies.Element): - raise ValueError(f"{other} must be a polynomial species") - - # Do we want to allow cartesian products between different k-variates? - if self.parent()._k != other.parent()._k: - return ValueError() - - terms = cartesian_product([self.terms(), other.terms()]) - res = 0 - for t1, t2 in terms: - H, coeffH = t1.support()[0], t1.coefficients()[0] - K, coeffK = t2.support()[0], t2.coefficients()[0] - if H._mc != K._mc: - continue - coeff = coeffH * coeffK - Sn = SymmetricGroup(H._tc).young_subgroup(H._mc) - Hgap, Kgap = libgap(H._group), libgap(K._group) - # We need to normalize H and K to have the same domparts - Hd = sorted(H._dompart.keys(), key=lambda x: H._dompart[x]) - Kd = sorted(K._dompart.keys(), key=lambda x: K._dompart[x]) - piH = libgap.MappingPermListList(Hd, Kd) - taus = libgap.DoubleCosetRepsAndSizes(Sn, Hgap, Kgap) - Hgap = libgap.ConjugateGroup(Hgap, piH) - for tau, _ in taus: - tHt = libgap.ConjugateSubgroup(Hgap, tau) - G = PermutationGroup(gap_group=libgap.Intersection(tHt, Kgap), domain=K._dompart.keys()) - res += coeff * self.parent()((G, K._dompart)) - return res - - def addition_formula(self, arg): - r""" - args is a list of the number of terms in each sort. - Returns the addition formula decomposition of - H(X1+X2..+Xk, Y1+Y2+..., ...). - """ - if len(arg) != self.parent()._k: - raise ValueError(f"Number of args (= {len(arg)}) must equal arity of self (= {len(arg)})") - if any(x <= 0 for x in arg): - raise ValueError(f"All values must be strictly positive") - - res = 0 - Parg = PolynomialSpecies(sum(arg)) - for F, coeff in self.monomial_coefficients().items(): - term = 0 - S_top = SymmetricGroup(F._tc).young_subgroup(F._mc) - dominv = sorted(F._dompart.keys(),key=lambda x: F._dompart[x]) - pi = libgap.MappingPermListList(dominv, libgap.eval(f'[1..{F.grade()}]')) - Fconj = libgap.ConjugateGroup(F._group, pi) - for parts in cartesian_product([IntegerVectors(k, l) for k, l in zip(F._mc, arg)]): - # parts is a tuple of partitions - part = list(chain.from_iterable(parts)) - S_bottom = SymmetricGroup(F._tc).young_subgroup(part) - taus = libgap.DoubleCosetRepsAndSizes(S_top, Fconj, S_bottom) - domvals = chain.from_iterable([[i] * v for i, v in enumerate(part, 1)]) - newdom = {k: v for k, v in zip(range(1, F.grade() + 1), domvals)} - for tau, _ in taus: - tHt = libgap.ConjugateGroup(Fconj, tau) - G = PermutationGroup(gap_group=libgap.Intersection(tHt, S_bottom), domain=F.domain()) - term += Parg((G, newdom)) - res += coeff * term - return res - - @staticmethod - def _embedding_coeff(part, n): - r""" - Number of embeddings of the partition ``part`` into a - list of length `n` (where holes are filled with `0`). - - EXAMPLES: - Ways to fill [0, 0, 0, 0] with [2, 1, 1]: - - [2, 1, 1, 0] - - [2, 1, 0, 1] - - [2, 0, 1, 1] - - [0, 2, 1, 1] - - [1, 2, 1, 0] - - [1, 2, 0, 1] - - [1, 0, 2, 1] - - [0, 1, 2, 1] - - [1, 1, 2, 0] - - [1, 1, 0, 2] - - [1, 0, 1, 2] - - [0, 1, 1, 2] - - So, 12 ways:: - sage: PolynomialSpecies.Element._embedding_coeff([2, 1, 1], 4) - 12 - """ - return Permutations(part).cardinality() * binomial(n, len(part)) - - def _multiplicity_handling(self, F, coeffs): - r""" - Handles cases of the form F(m1X1,m2X2,...). - coeffs is the mi. Hmc is the cardinality on each sort. - F is a PolynomialSpeciesElement. - """ - # This is supposed to be an internal method so we perform - # no domain normalizations or argument checking. - Fm = F.support()[0] - Fmc = Fm._mc - Fgap = Fm._group.gap() - # What we basically have is a specialisation of the addition - # formula, but setting X1=...=Xk=X. - res = 0 - PF = F.parent() - S_top = SymmetricGroup(Fm._tc).young_subgroup(Fmc) - for parts in cartesian_product([Partitions(k, max_length=l) for k, l in zip(Fmc, coeffs)]): - term = 0 - # parts is a tuple of partitions - part = list(chain.from_iterable(parts)) - S_bottom = SymmetricGroup(Fm._tc).young_subgroup(part) - taus = libgap.DoubleCosetRepsAndSizes(S_top, Fgap, S_bottom) - for tau, _ in taus: - tHt = libgap.ConjugateGroup(Fgap, tau) - G = PermutationGroup(gap_group=libgap.Intersection(tHt, S_bottom), domain=Fm.domain()) - term += PF((G, Fm._dompart)) - term *= prod([self._embedding_coeff(p, n) for p, n in zip(parts, coeffs)]) - res += term - return res - - def substitution(self, args): - pass \ No newline at end of file From 16ffe62ba06982a05acbd50999c461ca56aba781 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Mon, 19 Aug 2024 15:18:33 +0530 Subject: [PATCH 124/537] Modified basis() method --- src/sage/matroids/chow_ring.py | 68 +++++++++++++++++++++++----------- 1 file changed, 47 insertions(+), 21 deletions(-) diff --git a/src/sage/matroids/chow_ring.py b/src/sage/matroids/chow_ring.py index 9b42b9a32a6..04b51341b51 100644 --- a/src/sage/matroids/chow_ring.py +++ b/src/sage/matroids/chow_ring.py @@ -12,6 +12,8 @@ from sage.categories.commutative_rings import CommutativeRings from sage.misc.misc_c import prod from itertools import product +from sage.combinat.posets.posets import Poset +from sage.combinat.subset import Subsets class ChowRing(QuotientRing_generic): r""" @@ -212,31 +214,55 @@ def basis(self): monomial_basis.append(term) else: - print(ranks) - rank_diff = [] - for i in range(len(flats)): - max_pow = 0 - for j in range(i): - if flats[j] < flats[i]: - max_pow += ranks[j] - rank_diff.append(ranks[i] - max_pow) - print(rank_diff) - def generate_terms(current_term, index, max_powers, f_dict): + def generate_combinations(current_combination, index, max_powers, x_dict): + # Base case: If index equals the length of max_powers, print the current combination if index == len(max_powers): - term = self._ideal.ring().one() - term *= f_dict[i+1]**(current_term[i] for i in range(len(current_term))) - yield term + expression_terms = [x_dict[i+1] if current_combination[i] == 1 + else x_dict[i+1]**{current_combination[i]} + for i in range(len(current_combination)) if current_combination[i] != 0] + if expression_terms: + term = R.one() + for t in expression_terms: + term *= t + monomial_basis.append(term) + else: + monomial_basis.append(R.one()) return - + + # Recursive case: Iterate over the range for the current index for power in range(max_powers[index]): - current_term[index] = power - generate_terms(current_term, index + 1, max_powers, f_dict) - - current_term = [0]*len(flats) - monomial_basis = list(generate_terms(current_term, 0, rank_diff, flats_gen)) - print(monomial_basis) + current_combination[index] = power + generate_combinations(current_combination, index + 1, max_powers, x_dict) + + def m_n(i): + if flats[i] == frozenset(): + return 0 + else: + sum1 = 0 + for j in range(len(flats)): + if flats[j] < flats[i]: + sum1 += m_n(j) + + return ranks[i] - sum1 - + print(ranks) + flats = list(self._ideal.flats_generator()) + R = self._ideal.ring() + if frozenset() in flats: + flats.remove(frozenset()) + reln = lambda p,q : p < q + P = Poset((flats, reln)) + chains = P.chains() + for chain in chains: + max_powers = [] + x_dict = dict() + for F in chain: + max_powers.append(m_n(flats.index(F))) + x_dict[F] = flats_gen[F] + k = len(chain) + print(max_powers, x_dict, k) + current_combination = [0] * k + generate_combinations(current_combination, 0, max_powers, x_dict) from sage.sets.family import Family return Family([self.element_class(self, mon, reduce=False) for mon in monomial_basis]) From 4fc0ac0a68d8cf24544a3f9a51e4c4378003c8cd Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Mon, 19 Aug 2024 15:19:03 +0530 Subject: [PATCH 125/537] Modified ChowRingIdeal_nonaug.groebner_basis() --- src/sage/matroids/chow_ring_ideal.py | 50 +++++++++++++++++++--------- 1 file changed, 35 insertions(+), 15 deletions(-) diff --git a/src/sage/matroids/chow_ring_ideal.py b/src/sage/matroids/chow_ring_ideal.py index 173efaba912..c1bedad5961 100644 --- a/src/sage/matroids/chow_ring_ideal.py +++ b/src/sage/matroids/chow_ring_ideal.py @@ -12,6 +12,8 @@ from sage.sets.set import Set from sage.rings.polynomial.multi_polynomial_sequence import PolynomialSequence from sage.misc.abstract_method import abstract_method +from sage.combinat.posets.posets import Poset +from sage.combinat.subset import Subsets class ChowRingIdeal(MPolynomialIdeal): @abstract_method @@ -227,24 +229,42 @@ def groebner_basis(self): flats = list(self._flats_generator) gb = list() - R = self.ring() - for F in flats: - for G in flats: - if not (F < G or G < F): - gb.append(self._flats_generator[F]*self._flats_generator[G]) - else: - term = R.zero() - for H in flats: - if H > G: - term += self._flats_generator[H] - if term != R.zero(): - if Set(F).is_empty(): - gb.append(term**self._matroid.rank(G)) - elif F < G: - gb.append(term**(self._matroid.rank(G)-self._matroid.rank(F))) + R = self.ring() + if frozenset() in flats: + flats.remove(frozenset()) + def m_n(i): + if flats[i] == frozenset(): + return 0 + else: + return ranks[i] - sum(m_n(j) for j in range(i)) + + reln = lambda p,q : p < q + P = LatticePoset(flats) + subsets = Subsets(flats) + for subset in subsets: + if not P.subposet(subset).is_chain(): + term = R.one() + for x in subset: + term *= self._flats_generator[x] + gb.append(term) + + else: + for F in flats: + if F > P.join(list(subset)): #Getting missing argument error here + term = R.one() + for x in subset: + term *= self._flats_generator[x] + term1 = R.zero() + for G in flats: + if G >= F: + term1 += self._flats_generator[G] + if term1 != R.zero(): + gb.append(term*(term1**m_n(flats.index(subset)))) + g_basis = PolynomialSequence(R, [gb]) return g_basis + class AugmentedChowRingIdeal_fy(ChowRingIdeal): r""" From 63a5e8dd76a66c73ff3cf82a0cc191be3cbf8072 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Mon, 19 Aug 2024 15:42:56 +0530 Subject: [PATCH 126/537] Edited ChowRingIdeal_nonaug.groebner_basis() method --- src/sage/matroids/chow_ring_ideal.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/sage/matroids/chow_ring_ideal.py b/src/sage/matroids/chow_ring_ideal.py index c1bedad5961..92468e97492 100644 --- a/src/sage/matroids/chow_ring_ideal.py +++ b/src/sage/matroids/chow_ring_ideal.py @@ -12,7 +12,7 @@ from sage.sets.set import Set from sage.rings.polynomial.multi_polynomial_sequence import PolynomialSequence from sage.misc.abstract_method import abstract_method -from sage.combinat.posets.posets import Poset +from sage.combinat.posets.lattices import LatticePoset from sage.combinat.subset import Subsets class ChowRingIdeal(MPolynomialIdeal): @@ -233,13 +233,19 @@ def groebner_basis(self): if frozenset() in flats: flats.remove(frozenset()) + ranks = [self._matroid.rank(F) for F in flats] + def m_n(i): if flats[i] == frozenset(): return 0 else: - return ranks[i] - sum(m_n(j) for j in range(i)) + sum1 = 0 + for j in range(len(flats)): + if flats[j] < flats[i]: + sum1 += m_n(j) + + return ranks[i] - sum1 - reln = lambda p,q : p < q P = LatticePoset(flats) subsets = Subsets(flats) for subset in subsets: From b7f7beb3cdd8dd152e36f019c929a22d60195304 Mon Sep 17 00:00:00 2001 From: Newtech66 Date: Mon, 19 Aug 2024 16:21:41 +0530 Subject: [PATCH 127/537] Add inner_sum --- src/sage/rings/species.py | 100 ++++++++++++++++++++++++++++---------- 1 file changed, 73 insertions(+), 27 deletions(-) diff --git a/src/sage/rings/species.py b/src/sage/rings/species.py index e5e85742e77..6c745e4a365 100644 --- a/src/sage/rings/species.py +++ b/src/sage/rings/species.py @@ -273,7 +273,6 @@ def __iter__(self): [(1,2,3)] [(1,2,3), (2,3)] """ - # Is SymmetricGroup(0) directly indecomposable? n = 0 while True: for G in SymmetricGroup(n).conjugacy_classes_subgroups(): @@ -447,7 +446,7 @@ def _repr_(self): sage: A = At(G, {1: [1,2,3,4], 2: [5,6,7,8,9,10]}); A {[(1,2,3,4)(5,6)(7,8)(9,10)]: (4, 6)} """ - return "{" + f"{self._dis}: {self._mc}" + "}" + return "{" + f"{self._dis}: {self._dompart}" + "}" class AtomicSpecies(UniqueRepresentation, Parent, ElementCache): def __init__(self, k): @@ -618,7 +617,11 @@ def gen(self, x): """ if x not in self._indices: raise IndexError(f"{x} is not in the index set") - at = self._indices(x[0], x[1]) + at = None + if isinstance(x, PermutationGroup_generic): + at = self._indices(x) + else: + at = self._indices(x[0], x[1]) elm = self._cache_get(self.element_class(self, {at: ZZ.one()})) if elm._group is None: elm._group = at._dis._C @@ -865,30 +868,6 @@ def _element_constructor_(self, G, pi=None): term *= self._indices.gen(self._project(G, pi, part)) return self._from_dict({term: ZZ.one()}) - def __getitem__(self, x): - r""" - Calls _element_constructor_ on x. - - TESTS:: - - sage: P = PolynomialSpecies(1) - sage: At1 = AtomicSpecies(1) - sage: At1(SymmetricGroup(1)).rename("X") - sage: X2 = SymmetricGroup(2).young_subgroup([1, 1]) - sage: P[X2] - X^2 - sage: P2 = PolynomialSpecies(2) - sage: At2 = AtomicSpecies(2) - sage: At2(SymmetricGroup(1), {1: [1]}).rename("X") - sage: At2(SymmetricGroup(1), {2: [1]}).rename("Y") - sage: XY = (SymmetricGroup(2).young_subgroup([1, 1]), {1: [1], 2: [2]}) - sage: P2[XY] - X*Y - """ - if isinstance(x, PermutationGroup_generic): - return self._element_constructor_(x) - return self._element_constructor_(*x) - @cached_method def one_basis(self): r""" @@ -1025,3 +1004,70 @@ def is_atomic(self): True """ return self.is_molecular() and len(self.support()[0]) == 1 + + def inner_sum(self, *args): + r""" + Compute the inner sum of exercise 2.6.16 of BLL book. + + args are the compositions (in Compositions) each of which + sum to the corresponding cardinality of ``self``. The number + of args is equal to the arity of ``self``. + + EXAMPLES:: + + sage: P = PolynomialSpecies(1) + sage: C4 = P(CyclicPermutationGroup(4)) + sage: C4.inner_sum([2, 2]) # X^2Y^2 + C2(XY) + {[()]: ((1,), ())}^2*{[()]: ((), (1,))}^2 + {[(1,2)(3,4)]: ((1, 2), (3, 4))} + """ + # TODO: No checks are performed right now, must be added. + # Checks: all args in compositions, sums must match cardinalities. + + # NOTE: This method might not work correctly if self is multivariate. + # Or it might, I have not checked. Depends on the _canonicalize method. + # There are more problems actually. + + # Check for self: self is molecular and univariate. + if not self.is_molecular(): + raise ValueError("self must be molecular") + if self.parent()._k != 1: + raise ValueError("self must be univariate") + + res = 0 + # Create group of the composition + Pn = PolynomialSpecies(len(args[0])) + comp = list(chain.from_iterable(args)) + S_down = SymmetricGroup(sum(comp)).young_subgroup(comp) + for F, coeff in self.monomial_coefficients().items(): + # First, create the double coset representatives. + term = 0 + S_up = SymmetricGroup(F._tc).young_subgroup(F._mc) + taus = libgap.DoubleCosetRepsAndSizes(S_up, S_down, F._group) + for tau, _ in taus: + G = libgap.ConjugateGroup(F._group, tau) + H = libgap.Intersection(G, S_down) + grp = PermutationGroup(gap_group=H, domain=F.domain()) + dpart = {i + 1: list(range(x - comp[i] + 1, x + 1)) for i, x in enumerate(accumulate(comp))} + term += Pn(grp, dpart) + res += coeff * term + return res + + def substitution(self, *args): + r""" + Substitute M_1...M_k into self. + M_i must all have same arity and must be molecular. + """ + if len(args) != self.parent()._k: + raise ValueError("len args != k") + if not all(isinstance(arg, PolynomialSpecies.Element) for arg in args): + raise ValueError("all args not polynomial species element") + if not all(arg.is_molecular() and not arg.is_virtual() for arg in args): + raise ValueError("all args must be non-virtual molecular species") + if len(set(arg.parent()._k for arg in args)) > 1: + raise ValueError("all args must have same arity") + + res = 0 + for F, coeff in self.monomial_coefficients(): + term = 0 + + res = coeff * term From 142c09aaa17c3ba63ccc7552e843d0b27d2bdf9f Mon Sep 17 00:00:00 2001 From: Newtech66 Date: Mon, 19 Aug 2024 16:29:12 +0530 Subject: [PATCH 128/537] Doctest fixes --- src/sage/rings/species.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/sage/rings/species.py b/src/sage/rings/species.py index 6c745e4a365..9170f6a826a 100644 --- a/src/sage/rings/species.py +++ b/src/sage/rings/species.py @@ -57,11 +57,11 @@ def clear_cache(self): sage: A = AtomicSpecies(1) sage: A(SymmetricGroup(1)) - {[()]: (1,)} + {[()]: ((1,),)} sage: A(SymmetricGroup(0)) - {[]: (0,)} + {[]: ((),)} sage: A._cache - {((0,), []): [{[]: (0,)}], ((1,), [()]): [{[()]: (1,)}]} + {((0,), []): [{[]: ((),)}], ((1,), [()]): [{[()]: ((1,),)}]} sage: A.clear_cache() sage: A._cache {} @@ -384,11 +384,11 @@ def __hash__(self): sage: H = PermutationGroup([[(1,2,3,4),(5,6),(7,8),(9,10)]]); H Permutation Group with generators [(1,2,3,4)(5,6)(7,8)(9,10)] sage: A = At(G, {1: [1,2,3,4], 2: [5,6,7,8,9,10]}); A - {[(1,2,3,4)(5,6)(7,8)(9,10)]: (4, 6)} + {[(1,2,3,4)(5,6)(7,8)(9,10)]: ((5, 6, 7, 8), (9, 10, 1, 2, 3, 4))} sage: B = At(H, {1: [1,2,3,4], 2: [5,6,7,8,9,10]}); B - {[(1,2,3,4)(5,6)(7,8)(9,10)]: (4, 6)} + {[(1,2,3,4)(5,6)(7,8)(9,10)]: ((1, 2, 3, 4), (5, 6, 7, 8, 9, 10))} sage: C = At(G, {1: [1,2,5,6], 2: [3,4,7,8,9,10]}); C - {[(1,2,3,4)(5,6)(7,8)(9,10)]: (4, 6)} + {[(1,2,3,4)(5,6)(7,8)(9,10)]: ((5, 6, 7, 8), (9, 10, 1, 2, 3, 4))} sage: hash(A) == hash(B) True sage: hash(A) == hash(C) @@ -444,7 +444,7 @@ def _repr_(self): sage: G = PermutationGroup([[(1,2),(3,4),(5,6),(7,8,9,10)]]); G Permutation Group with generators [(1,2)(3,4)(5,6)(7,8,9,10)] sage: A = At(G, {1: [1,2,3,4], 2: [5,6,7,8,9,10]}); A - {[(1,2,3,4)(5,6)(7,8)(9,10)]: (4, 6)} + {[(1,2,3,4)(5,6)(7,8)(9,10)]: ((5, 6, 7, 8), (9, 10, 1, 2, 3, 4))} """ return "{" + f"{self._dis}: {self._dompart}" + "}" @@ -478,9 +478,9 @@ def an_element(self): sage: At1 = AtomicSpecies(1) sage: At2 = AtomicSpecies(2) sage: At1.an_element() - {[(1,2)]: (2,)} + {[(1,2)]: ((1, 2),)} sage: At2.an_element() - {[(1,2)(3,4)]: (2, 2)} + {[(1,2)(3,4)]: ((1, 2), (3, 4))} """ G = PermutationGroup([[(2 * i - 1, 2 * i) for i in range(1, self._k + 1)]]) m = {i: [2 * i - 1, 2 * i] for i in range(1, self._k + 1)} From 19231bee8cb97e59b2221073e5e3eb1ec271681d Mon Sep 17 00:00:00 2001 From: Newtech66 Date: Mon, 19 Aug 2024 20:07:41 +0530 Subject: [PATCH 129/537] Move things around and minor fixes --- src/sage/rings/species.py | 148 ++++++++++++++++++-------------------- 1 file changed, 68 insertions(+), 80 deletions(-) diff --git a/src/sage/rings/species.py b/src/sage/rings/species.py index 9170f6a826a..882e3cc7e63 100644 --- a/src/sage/rings/species.py +++ b/src/sage/rings/species.py @@ -57,11 +57,11 @@ def clear_cache(self): sage: A = AtomicSpecies(1) sage: A(SymmetricGroup(1)) - {[()]: ((1,),)} + {((),): ((1,),)} sage: A(SymmetricGroup(0)) - {[]: ((),)} + {(): ((),)} sage: A._cache - {((0,), []): [{[]: ((),)}], ((1,), [()]): [{[()]: ((1,),)}]} + {((0,), ()): [{(): ((),)}], ((1,), ((),)): [{((),): ((1,),)}]} sage: A.clear_cache() sage: A._cache {} @@ -132,9 +132,9 @@ def _repr_(self): sage: C = ConjugacyClassesOfDirectlyIndecomposableSubgroups() sage: G = PermutationGroup([[(1,3),(4,7)], [(2,5),(6,8)], [(1,4),(2,5),(3,7)]]) sage: C(G) - [(5,6)(7,8), (1,2)(3,4), (1,3)(2,4)(5,6)] + ((5,6)(7,8), (1,2)(3,4), (1,3)(2,4)(5,6)) """ - return f"{self._C.gens_small()}" + return f"{self._C.gens()}" def _element_key(self): r""" @@ -154,7 +154,7 @@ def _canonicalize(self): sage: C = ConjugacyClassesOfDirectlyIndecomposableSubgroups() sage: G = PermutationGroup([[(1,3),(4,7)], [(2,5),(6,8)], [(1,4),(2,5),(3,7)]]) sage: C(G) - [(5,6)(7,8), (1,2)(3,4), (1,3)(2,4)(5,6)] + ((5,6)(7,8), (1,2)(3,4), (1,3)(2,4)(5,6)) """ if self._C == SymmetricGroup(0): return @@ -211,7 +211,7 @@ def an_element(self): sage: from sage.rings.species import ConjugacyClassesOfDirectlyIndecomposableSubgroups sage: C = ConjugacyClassesOfDirectlyIndecomposableSubgroups() sage: C.an_element() - [()] + ((),) """ return self._element_constructor_(SymmetricGroup(1)) @@ -226,16 +226,16 @@ def _element_constructor_(self, x): sage: C = ConjugacyClassesOfDirectlyIndecomposableSubgroups() sage: C.clear_cache() sage: C(PermutationGroup([("a", "b", "c")])) - [(1,2,3)] + ((1,2,3),) sage: C._cache - {(3, 3, (3,)): [[(1,2,3)]]} + {(3, 3, (3,)): [((1,2,3),)]} sage: C(PermutationGroup([(1, 3, 5)], domain=[1,3,5])) - [(1,2,3)] + ((1,2,3),) sage: C(PermutationGroup([[(1,3),(4,7)],[(2,5),(6,8)], [(1,4),(2,5),(3,7)]])) - [(5,6)(7,8), (1,2)(3,4), (1,3)(2,4)(5,6)] + ((5,6)(7,8), (1,2)(3,4), (1,3)(2,4)(5,6)) sage: C._cache - {(3, 3, (3,)): [[(1,2,3)]], - (8, 8, (2, 2, 4)): [[(5,6)(7,8), (1,2)(3,4), (1,3)(2,4)(5,6)]]} + {(3, 3, (3,)): [((1,2,3),)], + (8, 8, (2, 2, 4)): [((5,6)(7,8), (1,2)(3,4), (1,3)(2,4)(5,6))]} """ if parent(x) == self: return x @@ -267,11 +267,11 @@ def __iter__(self): sage: for i in range(5): ....: print(next(iterC)) ....: - [] - [()] - [(1,2)] - [(1,2,3)] - [(1,2,3), (2,3)] + () + ((),) + ((1,2),) + ((1,2,3),) + ((2,3), (1,2,3)) """ n = 0 while True: @@ -384,11 +384,11 @@ def __hash__(self): sage: H = PermutationGroup([[(1,2,3,4),(5,6),(7,8),(9,10)]]); H Permutation Group with generators [(1,2,3,4)(5,6)(7,8)(9,10)] sage: A = At(G, {1: [1,2,3,4], 2: [5,6,7,8,9,10]}); A - {[(1,2,3,4)(5,6)(7,8)(9,10)]: ((5, 6, 7, 8), (9, 10, 1, 2, 3, 4))} + {((1,2,3,4)(5,6)(7,8)(9,10),): ((5, 6, 7, 8), (9, 10, 1, 2, 3, 4))} sage: B = At(H, {1: [1,2,3,4], 2: [5,6,7,8,9,10]}); B - {[(1,2,3,4)(5,6)(7,8)(9,10)]: ((1, 2, 3, 4), (5, 6, 7, 8, 9, 10))} + {((1,2,3,4)(5,6)(7,8)(9,10),): ((1, 2, 3, 4), (5, 6, 7, 8, 9, 10))} sage: C = At(G, {1: [1,2,5,6], 2: [3,4,7,8,9,10]}); C - {[(1,2,3,4)(5,6)(7,8)(9,10)]: ((5, 6, 7, 8), (9, 10, 1, 2, 3, 4))} + {((1,2,3,4)(5,6)(7,8)(9,10),): ((5, 6, 7, 8), (9, 10, 1, 2, 3, 4))} sage: hash(A) == hash(B) True sage: hash(A) == hash(C) @@ -444,7 +444,7 @@ def _repr_(self): sage: G = PermutationGroup([[(1,2),(3,4),(5,6),(7,8,9,10)]]); G Permutation Group with generators [(1,2)(3,4)(5,6)(7,8,9,10)] sage: A = At(G, {1: [1,2,3,4], 2: [5,6,7,8,9,10]}); A - {[(1,2,3,4)(5,6)(7,8)(9,10)]: ((5, 6, 7, 8), (9, 10, 1, 2, 3, 4))} + {((1,2,3,4)(5,6)(7,8)(9,10),): ((5, 6, 7, 8), (9, 10, 1, 2, 3, 4))} """ return "{" + f"{self._dis}: {self._dompart}" + "}" @@ -466,7 +466,6 @@ def __init__(self, k): ElementCache.__init__(self) self._k = k self._grading_set = IntegerVectors(length=k) - self._dis_ctor = ConjugacyClassesOfDirectlyIndecomposableSubgroups() @cached_method def an_element(self): @@ -478,9 +477,9 @@ def an_element(self): sage: At1 = AtomicSpecies(1) sage: At2 = AtomicSpecies(2) sage: At1.an_element() - {[(1,2)]: ((1, 2),)} + {((1,2),): ((1, 2),)} sage: At2.an_element() - {[(1,2)(3,4)]: ((1, 2), (3, 4))} + {((1,2)(3,4),): ((1, 2), (3, 4))} """ G = PermutationGroup([[(2 * i - 1, 2 * i) for i in range(1, self._k + 1)]]) m = {i: [2 * i - 1, 2 * i] for i in range(1, self._k + 1)} @@ -518,7 +517,7 @@ def _element_constructor_(self, G, pi=None): for orbit in G.orbits(): if not any(set(orbit).issubset(p) for p in pi.values()): raise ValueError(f"For each orbit of {G}, all elements must belong to the same sort") - dis_elm = self._dis_ctor(G) + dis_elm = ConjugacyClassesOfDirectlyIndecomposableSubgroups()(G) mapping = {v: i for i, v in enumerate(G.domain(), 1)} mapping2 = PermutationGroupElement([mapping[e] for o in sorted(G.orbits(), key=len, reverse=True) for e in o]).inverse() @@ -528,13 +527,6 @@ def _element_constructor_(self, G, pi=None): elm = self.element_class(self, dis_elm, tuple(dpart)) return self._cache_get(elm) - def __getitem__(self, x): - r""" - Call ``_element_constructor_`` on ``x``. - """ - # TODO: This needs to be checked. - return self._element_constructor_(*x) - def __contains__(self, x): r""" Return if ``x`` is in ``self``. @@ -779,6 +771,49 @@ def domain(self): Return the domain of ``self``. """ return FiniteEnumeratedSet(range(1, self._tc + 1)) + + def inner_sum(self, *args): + r""" + Compute the inner sum of exercise 2.6.16 of BLL book. + + args are the compositions (in Compositions) each of which + sum to the corresponding cardinality of ``self``. The number + of args is equal to the arity of ``self``. + + EXAMPLES:: + + sage: P = PolynomialSpecies(1) + sage: C4 = P(CyclicPermutationGroup(4)) + sage: C4.support()[0].inner_sum([2, 2]) # X^2Y^2 + C2(XY) + {((),): ((1,), ())}^2*{((),): ((), (1,))}^2 + {((1,2)(3,4),): ((1, 2), (3, 4))} + """ + # TODO: No checks are performed right now, must be added. + # Checks: all args in compositions, sums must match cardinalities. + + # NOTE: This method might not work correctly if self is multivariate. + # Or it might, I have not checked. Depends on the _canonicalize method. + # There are more problems actually. + # I think I need to do something with dompart. + + if self.parent()._k != 1: + raise ValueError("self must be univariate") + + res = 0 + # Create group of the composition + Pn = PolynomialSpecies(len(args[0])) + comp = list(chain.from_iterable(args)) + # Create the double coset representatives. + S_down = SymmetricGroup(sum(comp)).young_subgroup(comp) + S_up = SymmetricGroup(self._tc).young_subgroup(self._mc) + taus = libgap.DoubleCosetRepsAndSizes(S_up, S_down, self._group) + # Sum over double coset representatives. + for tau, _ in taus: + G = libgap.ConjugateGroup(self._group, tau) + H = libgap.Intersection(G, S_down) + grp = PermutationGroup(gap_group=H, domain=self.domain()) + dpart = {i + 1: list(range(x - comp[i] + 1, x + 1)) for i, x in enumerate(accumulate(comp))} + res += Pn(grp, dpart) + return res class PolynomialSpecies(CombinatorialFreeModule): @@ -1005,53 +1040,6 @@ def is_atomic(self): """ return self.is_molecular() and len(self.support()[0]) == 1 - def inner_sum(self, *args): - r""" - Compute the inner sum of exercise 2.6.16 of BLL book. - - args are the compositions (in Compositions) each of which - sum to the corresponding cardinality of ``self``. The number - of args is equal to the arity of ``self``. - - EXAMPLES:: - - sage: P = PolynomialSpecies(1) - sage: C4 = P(CyclicPermutationGroup(4)) - sage: C4.inner_sum([2, 2]) # X^2Y^2 + C2(XY) - {[()]: ((1,), ())}^2*{[()]: ((), (1,))}^2 + {[(1,2)(3,4)]: ((1, 2), (3, 4))} - """ - # TODO: No checks are performed right now, must be added. - # Checks: all args in compositions, sums must match cardinalities. - - # NOTE: This method might not work correctly if self is multivariate. - # Or it might, I have not checked. Depends on the _canonicalize method. - # There are more problems actually. - - # Check for self: self is molecular and univariate. - if not self.is_molecular(): - raise ValueError("self must be molecular") - if self.parent()._k != 1: - raise ValueError("self must be univariate") - - res = 0 - # Create group of the composition - Pn = PolynomialSpecies(len(args[0])) - comp = list(chain.from_iterable(args)) - S_down = SymmetricGroup(sum(comp)).young_subgroup(comp) - for F, coeff in self.monomial_coefficients().items(): - # First, create the double coset representatives. - term = 0 - S_up = SymmetricGroup(F._tc).young_subgroup(F._mc) - taus = libgap.DoubleCosetRepsAndSizes(S_up, S_down, F._group) - for tau, _ in taus: - G = libgap.ConjugateGroup(F._group, tau) - H = libgap.Intersection(G, S_down) - grp = PermutationGroup(gap_group=H, domain=F.domain()) - dpart = {i + 1: list(range(x - comp[i] + 1, x + 1)) for i, x in enumerate(accumulate(comp))} - term += Pn(grp, dpart) - res += coeff * term - return res - def substitution(self, *args): r""" Substitute M_1...M_k into self. From fd146bc9409f6d71101ffa3f0747aad732b5f722 Mon Sep 17 00:00:00 2001 From: Newtech66 Date: Tue, 20 Aug 2024 01:09:23 +0530 Subject: [PATCH 130/537] Add renaming patch (thanks mantepse) --- src/sage/rings/species.py | 179 ++++++++++++++++++++++++++++---------- 1 file changed, 134 insertions(+), 45 deletions(-) diff --git a/src/sage/rings/species.py b/src/sage/rings/species.py index 882e3cc7e63..bbfe5e3f0f5 100644 --- a/src/sage/rings/species.py +++ b/src/sage/rings/species.py @@ -90,6 +90,7 @@ def _cache_get(self, elm): self._cache[key] = [elm] return elm + class ConjugacyClassOfDirectlyIndecomposableSubgroups(Element): def __init__(self, parent, C): r""" @@ -448,12 +449,51 @@ def _repr_(self): """ return "{" + f"{self._dis}: {self._dompart}" + "}" + class AtomicSpecies(UniqueRepresentation, Parent, ElementCache): - def __init__(self, k): + @staticmethod + def __classcall__(cls, k, singleton_names=None): + """ + Normalize the arguments. + + TESTS:: + + sage: A1 = AtomicSpecies(1, "X") + sage: A2 = AtomicSpecies(1) + sage: A3 = AtomicSpecies(["X", "Y"]) + sage: A4 = AtomicSpecies(2, ["X", "Y"]) + sage: A1 is A2 + False + sage: A3 is A4 + True + """ + if singleton_names is None: + if k in ZZ: + k = ZZ(k) + else: + singleton_names = tuple(k) + k = len(singleton_names) + else: + k = ZZ(k) + singleton_names = tuple(singleton_names) + + if (singleton_names is not None + and (len(singleton_names) != k + or not all(isinstance(X, str) for X in singleton_names))): + raise ValueError(f"singleton_names must be a tuple of {k} strings") + + return super().__classcall__(cls, k, singleton_names) + + def __init__(self, k, singleton_names): r""" Infinite set of `k`-variate atomic species graded by integer vectors of length `k`. + INPUT: + + - ``k`` -- a non-negative integer, or an iterable of ``k`` strings + - ``singleton_names`` -- an iterable of ``k`` strings or ``None`` + TESTS:: sage: At1 = AtomicSpecies(1) @@ -466,6 +506,8 @@ def __init__(self, k): ElementCache.__init__(self) self._k = k self._grading_set = IntegerVectors(length=k) + self._singleton_names = singleton_names + self._renamed = set() # the degrees that have been renamed already @cached_method def an_element(self): @@ -524,8 +566,50 @@ def _element_constructor_(self, G, pi=None): dpart = [tuple() for _ in range(self._k)] for k, v in pi.items(): dpart[k - 1] = tuple(mapping2(mapping[x]) for x in v) - elm = self.element_class(self, dis_elm, tuple(dpart)) - return self._cache_get(elm) + elm = self._cache_get(self.element_class(self, dis_elm, tuple(dpart))) + if self._singleton_names and elm._tc not in self._renamed: + self._rename(elm._tc) + return elm + + def _rename(self, n): + from sage.groups.perm_gps.permgroup import PermutationGroup + from sage.groups.perm_gps.permgroup_named import (SymmetricGroup, + CyclicPermutationGroup, + DihedralGroup, + AlternatingGroup) + + # prevent infinite recursion in self._element_constructor_ + self._renamed.add(n) + for i in range(self._k): + if n == 1: + self(SymmetricGroup(1), {i+1: [1]}).rename(self._singleton_names[i]) + + if self._k == 1: + sort = "" + else: + sort = f"({self._singleton_names[i]})" + + if n >= 2: + self(SymmetricGroup(n), + {i+1: range(1, n+1)}).rename(f"E_{n}" + sort) + + if n >= 3: + self(CyclicPermutationGroup(n), + {i+1: range(1, n+1)}).rename(f"C_{n}" + sort) + + if n >= 4: + self(DihedralGroup(n), + {i+1: range(1, n+1)}).rename(f"P_{n}" + sort) + + if n >= 4: + self(AlternatingGroup(n), + {i+1: range(1, n+1)}).rename(f"Eo_{n}" + sort) + + if n >= 4 and not n % 2: + gens = [[(i, n-i+1) for i in range(1, n//2 + 1)], + [(i, i+1) for i in range(1, n, 2)]] + self(PermutationGroup(gens), + {i+1: range(1, n+1)}).rename(f"Pb_{n}" + sort) def __contains__(self, x): r""" @@ -569,6 +653,7 @@ def _repr_(self): Element = AtomicSpeciesElement + class MolecularSpecies(IndexedFreeAbelianMonoid, ElementCache): @staticmethod def __classcall__(cls, indices, prefix, **kwds): @@ -815,9 +900,48 @@ def inner_sum(self, *args): res += Pn(grp, dpart) return res + def substitution(self, *args): + r""" + Substitute M_1...M_k into self. + M_i must all have same arity and must be molecular. + """ + if len(args) != self.parent()._k: + raise ValueError("number of args must match arity of self") + if not all(isinstance(arg, MolecularSpecies.Element) for arg in args): + raise ValueError("all args not molecular species") + if len(set(arg.parent()._k for arg in args)) > 1: + raise ValueError("all args must have same arity") + class PolynomialSpecies(CombinatorialFreeModule): - def __init__(self, k, base_ring=ZZ): + def __classcall__(cls, k, singleton_names=None, base_ring=ZZ): + r""" + Normalize the arguments. + + TESTS:: + + sage: P1 = PolynomialSpecies(1, "X", ZZ) + sage: P2 = PolynomialSpecies(1, base_ring=ZZ) + sage: P3 = PolynomialSpecies(["X", "Y"], base_ring=ZZ) + sage: P4 = PolynomialSpecies(2, ["X", "Y"]) + sage: P1 is P2 + False + sage: P3 is P4 + True + + .. TODO:: + + Reconsider the order of the arguments. + ``singleton_names`` are not generators, and may even be + omitted, and ``base_ring`` will usually be ``ZZ``, but + maybe it would be nice to allow ``P. = + PolynomialSpecies(ZZ)`` anyway. + + """ + A = AtomicSpecies(k, singleton_names=singleton_names) + return super().__classcall__(cls, A._k, A._singleton_names, base_ring) + + def __init__(self, k, singleton_names, base_ring): r""" Ring of `k`-variate polynomial (virtual) species. @@ -829,8 +953,8 @@ def __init__(self, k, base_ring=ZZ): sage: TestSuite(P2).run() """ # should we pass a category to basis_keys? - basis_keys = MolecularSpecies(AtomicSpecies(k), - prefix='', bracket=False) + A = AtomicSpecies(k, singleton_names=singleton_names) + basis_keys = MolecularSpecies(A, prefix='', bracket=False) category = GradedAlgebrasWithBasis(base_ring).Commutative() CombinatorialFreeModule.__init__(self, base_ring, basis_keys=basis_keys, @@ -940,13 +1064,7 @@ def product_on_basis(self, H, K): EXAMPLES:: - sage: A = AtomicSpecies(1) - sage: A(SymmetricGroup(1)).rename("X") - sage: [A(SymmetricGroup(n)).rename(f"E_{n}") for n in range(2, 5)] - [None, None, None] - sage: [A(CyclicPermutationGroup(n)).rename(f"C_{n}") for n in range(3, 5)] - [None, None] - sage: P = PolynomialSpecies(1) + sage: P = PolynomialSpecies("X") sage: L1 = [P(H) for H in SymmetricGroup(3).conjugacy_classes_subgroups()] sage: L2 = [P(H) for H in SymmetricGroup(2).conjugacy_classes_subgroups()] sage: matrix([[F * G for F in L1] for G in L2]) @@ -977,12 +1095,9 @@ def is_virtual(self): TESTS:: - sage: P = PolynomialSpecies(2) - sage: At = AtomicSpecies(2) + sage: P = PolynomialSpecies(["X", "Y"]) sage: X = P(SymmetricGroup(1), {1: [1]}) sage: Y = P(SymmetricGroup(1), {2: [1]}) - sage: At(SymmetricGroup(1), {1: [1]}).rename("X") - sage: At(SymmetricGroup(1), {2: [1]}).rename("Y") sage: V = 2 * X - 3 * Y; V 2*X - 3*Y sage: V.is_virtual() @@ -998,12 +1113,9 @@ def is_molecular(self): TESTS:: - sage: P = PolynomialSpecies(2) - sage: At = AtomicSpecies(2) + sage: P = PolynomialSpecies(["X", "Y"]) sage: X = P(SymmetricGroup(1), {1: [1]}) sage: Y = P(SymmetricGroup(1), {2: [1]}) - sage: At(SymmetricGroup(1), {1: [1]}).rename("X") - sage: At(SymmetricGroup(1), {2: [1]}).rename("Y") sage: V = 2 * X - 3 * Y; V 2*X - 3*Y sage: V.is_molecular() @@ -1021,12 +1133,9 @@ def is_atomic(self): TESTS:: - sage: P = PolynomialSpecies(2) - sage: At = AtomicSpecies(2) + sage: P = PolynomialSpecies(["X", "Y"]) sage: X = P(SymmetricGroup(1), {1: [1]}) sage: Y = P(SymmetricGroup(1), {2: [1]}) - sage: At(SymmetricGroup(1), {1: [1]}).rename("X") - sage: At(SymmetricGroup(1), {2: [1]}).rename("Y") sage: V = 2 * X - 3 * Y; V 2*X - 3*Y sage: V.is_atomic() @@ -1039,23 +1148,3 @@ def is_atomic(self): True """ return self.is_molecular() and len(self.support()[0]) == 1 - - def substitution(self, *args): - r""" - Substitute M_1...M_k into self. - M_i must all have same arity and must be molecular. - """ - if len(args) != self.parent()._k: - raise ValueError("len args != k") - if not all(isinstance(arg, PolynomialSpecies.Element) for arg in args): - raise ValueError("all args not polynomial species element") - if not all(arg.is_molecular() and not arg.is_virtual() for arg in args): - raise ValueError("all args must be non-virtual molecular species") - if len(set(arg.parent()._k for arg in args)) > 1: - raise ValueError("all args must have same arity") - - res = 0 - for F, coeff in self.monomial_coefficients(): - term = 0 - - res = coeff * term From 06841b5c730adc7c1f0ed98094f328e20a32dfe5 Mon Sep 17 00:00:00 2001 From: Verrel Rievaldo Wijaya Date: Tue, 20 Aug 2024 20:42:26 +0700 Subject: [PATCH 131/537] Add ``dual_subdivision`` --- src/sage/rings/semirings/tropical_variety.py | 65 ++++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/src/sage/rings/semirings/tropical_variety.py b/src/sage/rings/semirings/tropical_variety.py index a8328ee3e48..de6a60b579c 100644 --- a/src/sage/rings/semirings/tropical_variety.py +++ b/src/sage/rings/semirings/tropical_variety.py @@ -531,6 +531,71 @@ def update_result(result): update_result(result) return result + def dual_subdivision(self): + """ + Return the dual subdivision of ``self``. + + Dual subdivision refers to a specific decomposition of the Newton + polygon associated with a tropical polynomial. The term "dual" + is used in the sense that the combinatorial structure of the + tropical variety is reflected in the dual subdivision of the + Newton polygon. Vertices of the dual subdivision correspond to + the intersection of multiple components. Edges of the dual + subdivision correspond to the individual components. + + EXAMPLES: + + Dual subdivision of a tropical curve:: + + sage: T = TropicalSemiring(QQ, use_min=False) + sage: R. = PolynomialRing(T) + sage: p1 = R(3) + R(2)*x + R(2)*y + R(3)*x*y + x^2 + y^2 + sage: tv = p1.tropical_variety() + sage: G = tv.dual_subdivision() + sage: G.plot(vertex_labels=False) + Graphics object consisting of 10 graphics primitives + + Dual subdivision of a tropical surface:: + + sage: T = TropicalSemiring(QQ) + sage: R. = PolynomialRing(T) + sage: p1 = x + y + z + x^2 + R(1) + sage: tv = p1.tropical_variety() + sage: G = tv.dual_subdivision() + sage: G.plot3d() + Graphics3d Object + + Dual subdivision of a tropical hypersurface:: + + sage: T = TropicalSemiring(QQ) + sage: R. = PolynomialRing(T) + sage: p1 = a^2 + b^2 + c^2 + d^2 + a*b*c*d + sage: tv = p1.tropical_variety() + sage: G = tv.dual_subdivision() + sage: G.plot(vertex_labels=False) + Graphics object consisting of 11 graphics primitives + + """ + from sage.graphs.graph import Graph + + G = Graph() + edges = [e for e in self._keys] + # for edge in self._keys: + # edges.append(edge) + G.add_edges(edges) + pos = {} + for vertex in G.vertices(): + pos[vertex] = list(vertex) + + if self._poly.parent().ngens() == 2: + G.layout(pos=pos, save_pos=True) + elif self._poly.parent().ngens() == 3: + G.layout(dim=3, save_pos=True) + G._pos3d = pos + else: + G.layout("spring", save_pos=True) + return G + class TropicalSurface(TropicalVariety): r""" From 67343198836d2e2382ed096a269583eeee93e82e Mon Sep 17 00:00:00 2001 From: Verrel Rievaldo Wijaya Date: Tue, 20 Aug 2024 21:04:05 +0700 Subject: [PATCH 132/537] Add ``_components_of_vertices`` and ``weight_vectors`` --- src/sage/rings/semirings/tropical_variety.py | 120 ++++++++++++++++++- 1 file changed, 117 insertions(+), 3 deletions(-) diff --git a/src/sage/rings/semirings/tropical_variety.py b/src/sage/rings/semirings/tropical_variety.py index de6a60b579c..9dbade7e52f 100644 --- a/src/sage/rings/semirings/tropical_variety.py +++ b/src/sage/rings/semirings/tropical_variety.py @@ -530,7 +530,7 @@ def update_result(result): points[i] = new_eq update_result(result) return result - + def dual_subdivision(self): """ Return the dual subdivision of ``self``. @@ -580,8 +580,6 @@ def dual_subdivision(self): G = Graph() edges = [e for e in self._keys] - # for edge in self._keys: - # edges.append(edge) G.add_edges(edges) pos = {} for vertex in G.vertices(): @@ -1074,6 +1072,122 @@ def vertices(self): vertices.add((x,y)) return vertices + def _components_of_vertices(self): + """ + Return the index of components adjacent to each vertex of ``self``. + + OUTPUT: + + A dictionary where the keys represent the vertices, and the values + are lists of tuples. Each tuple consists of the index of an + adjacent edge (component) `e_i` and a string indicating the + directionality of `e_i` relative to the vertex. The string is + either "pos" or "neg", specifying whether it is positive or + negative. + + EXAMPLES:: + + sage: T = TropicalSemiring(QQ) + sage: R. = PolynomialRing(T) + sage: p1 = R(0) + x + y + x*y + x^2*y + x*y^2 + sage: p1.tropical_variety()._components_of_vertices() + {(0, 0): [(0, 'pos'), (1, 'pos'), (2, 'pos'), (3, 'neg'), (4, 'neg')]} + sage: p2 = R(2)*x^2 + x*y + R(2)*y^2 + x + R(-1)*y + R(3) + sage: p2.tropical_variety()._components_of_vertices() + {(-2, 0): [(0, 'neg'), (1, 'pos'), (3, 'pos')], + (-1, -3): [(2, 'neg'), (4, 'pos'), (5, 'pos')], + (-1, 0): [(3, 'neg'), (4, 'neg'), (6, 'pos')], + (3, 4): [(6, 'neg'), (7, 'pos'), (8, 'pos')]} + """ + comp_vert = {} + if len(self._hypersurface) >= 3: + for i, component in enumerate(self._hypersurface): + parametric_function = component[0] + v = component[1][0].variables()[0] + interval = self._parameter_intervals()[i] + lower = interval[0].lower() + upper = interval[0].upper() + if lower != -infinity: + x = parametric_function[0].subs(v==lower) + y = parametric_function[1].subs(v==lower) + if (x,y) not in comp_vert: + comp_vert[(x,y)] = [(i, 'pos')] + else: + comp_vert[(x,y)].append((i, 'pos')) + if upper != infinity: + x = parametric_function[0].subs(v==upper) + y = parametric_function[1].subs(v==upper) + if (x,y) not in comp_vert: + comp_vert[(x,y)] = [(i, 'neg')] + else: + comp_vert[(x,y)].append((i, 'neg')) + return comp_vert + + def weight_vectors(self): + r""" + Return the weight vectors for all vertices of ``self``. + + Suppose `v` is a vertex adjacent to the edges `e_1, ldots, e_k` + with respective weights `w_1, ldots, w_k`. Every edge `e_i` is + contained in a line (component) defined by an equation with + integer coefficients. Because of this there exists a unique + integer vector `v_i=(\alpha, \beta)` in the direction of `e_i` + such that `\gcd(\alpha, \beta)=1`. Then each vertex `v` yield + the vectors `w_1v_1,ldots,w_kv_k`. These vectors will satisfy + the following balancing condition: + `\sum_{i=1}^k w_i v_i = 0`. + + OUTPUT: + + A dictionary where the keys represent the vertices, and the values + are lists of vectors. + + EXAMPLES:: + + sage: T = TropicalSemiring(QQ) + sage: R. = PolynomialRing(T) + sage: p1 = R(-2)*x^2 + R(-1)*x + R(1/2)*y + R(1/6) + sage: p1.tropical_variety().weight_vectors() + {(1, -1/2): [(0, 1), (-1, -2), (1, 1)], + (7/6, -1/3): [(-1, -1), (0, 1), (1, 0)]} + sage: p3 = R(2)*x^2 + x*y + R(2)*y^2 + x + R(-1)*y + R(3) + sage: p3.tropical_variety().weight_vectors() + {(-2, 0): [(-1, -1), (0, 1), (1, 0)], + (-1, -3): [(-1, -1), (0, 1), (1, 0)], + (-1, 0): [(-1, 0), (0, -1), (1, 1)], + (3, 4): [(-1, -1), (0, 1), (1, 0)]} + """ + from sage.calculus.functional import diff + from sage.arith.misc import gcd + from sage.rings.rational_field import QQ + from sage.modules.free_module_element import vector + + if not self._components_of_vertices(): + return {} + + # finding the base vector in the direction of each edges + temp_vectors = [] + par = self._hypersurface[0][1][0].variables()[0] + for comp in self._hypersurface: + dx = diff(comp[0][0], par) + dy = diff(comp[0][1], par) + multiplier = gcd(QQ(dx), QQ(dy)) + temp_vectors.append(vector([dx/multiplier, dy/multiplier])) + + # calculate the weight vectors of each vertex + cov = self._components_of_vertices() + result = {} + for vertex in cov: + vectors = [] + for comp in cov[vertex]: + weight = self._hypersurface[comp[0]][2] + if comp[1] == 'pos': + vectors.append(weight*temp_vectors[comp[0]]) + else: + vectors.append(weight*(-temp_vectors[comp[0]])) + result[vertex] = vectors + return result + def _parameter_intervals(self): r""" Return the intervals of each component's parameter of ``self``. From 284251b7884eeca52d360f8f659d6217d385baa7 Mon Sep 17 00:00:00 2001 From: Newtech66 Date: Wed, 21 Aug 2024 01:46:49 +0530 Subject: [PATCH 133/537] Add substitution, element_constructor for molecular species --- src/sage/rings/species.py | 148 ++++++++++++++++++++++++-------------- 1 file changed, 96 insertions(+), 52 deletions(-) diff --git a/src/sage/rings/species.py b/src/sage/rings/species.py index bbfe5e3f0f5..9ad1315c7c6 100644 --- a/src/sage/rings/species.py +++ b/src/sage/rings/species.py @@ -1,21 +1,15 @@ -from itertools import accumulate, chain, combinations -from math import prod -from sage.arith.misc import binomial -from sage.categories.cartesian_product import cartesian_product +from itertools import accumulate, chain from sage.categories.graded_algebras_with_basis import GradedAlgebrasWithBasis from sage.categories.infinite_enumerated_sets import InfiniteEnumeratedSets from sage.categories.monoids import Monoids from sage.categories.sets_with_grading import SetsWithGrading from sage.combinat.free_module import CombinatorialFreeModule from sage.combinat.integer_vector import IntegerVectors -from sage.combinat.partition import Partitions -from sage.combinat.permutation import Permutations from sage.groups.perm_gps.constructor import PermutationGroupElement from sage.groups.perm_gps.permgroup import PermutationGroup, PermutationGroup_generic from sage.groups.perm_gps.permgroup_named import SymmetricGroup from sage.libs.gap.libgap import libgap from sage.misc.cachefunc import cached_method -from sage.misc.lazy_attribute import lazy_attribute from sage.monoids.indexed_free_monoid import IndexedFreeAbelianMonoid, IndexedFreeAbelianMonoidElement, IndexedMonoid from sage.rings.integer_ring import ZZ from sage.structure.element import Element, parent @@ -665,10 +659,62 @@ def __init__(self, indices, prefix, **kwds): ElementCache.__init__(self) self._k = indices._k - # I don't think _element_constructor is ever called, so - def _element_constructor_(self, x=None): - print("molecular species element constructor is called!") - raise NotImplementedError + def _project(self, G, pi, part): + r""" + Project `G` onto a subset ``part`` of its domain. + + ``part`` must be a union of cycles, but this is not checked. + """ + restricted_gens = [[cyc for cyc in gen.cycle_tuples() if cyc[0] in part] for gen in G.gens()] + mapping = dict() + for k, v in pi.items(): + es = [e for e in v if e in part] + if es: + mapping[k] = es + return PermutationGroup(gens=restricted_gens, domain=part), mapping + + def _element_constructor_(self, G, pi=None): + r""" + Construct the `k`-variate molecular species with the given data. + + INPUT: + + - ``x`` can be any of the following: + - an element of ``self``. + - a tuple ``(H, M)`` where `H` is the permutation group + representation for the species and `M` is a ``dict`` + mapping each element of the domain of `H` to integers + in `\{ 1 \ldots k \}`, representing the set to which + the element belongs. + - if `k=1`, i.e. we are working with univariate species, + the mapping `M` may be omitted and just the group `H` + may be passed. + """ + if parent(G) == self: + if pi is not None: + raise ValueError("cannot reassign sorts to a molecular species") + return G + if not isinstance(G, PermutationGroup_generic): + raise ValueError(f"{G} must be a permutation group") + if pi is None: + if self._k == 1: + pi = {1: G.domain()} + else: + raise ValueError("the assignment of sorts to the domain elements must be provided") + if not set(pi.keys()).issubset(range(1, self._k + 1)): + raise ValueError(f"keys of pi must be in the range [1, {self._k}]") + pi = {k: set(v) for k, v in pi.items()} + if sum(len(p) for p in pi.values()) != len(G.domain()) or set.union(*[p for p in pi.values()]) != set(G.domain()): + raise ValueError("values of pi must partition the domain of G") + for orbit in G.orbits(): + if not any(set(orbit).issubset(p) for p in pi.values()): + raise ValueError(f"For each orbit of {G}, all elements must belong to the same sort") + + domain_partition = G.disjoint_direct_product_decomposition() + elm = self.one() + for part in domain_partition: + elm *= self.gen(self._project(G, pi, part)) + return elm @cached_method def one(self): @@ -875,26 +921,23 @@ def inner_sum(self, *args): # TODO: No checks are performed right now, must be added. # Checks: all args in compositions, sums must match cardinalities. - # NOTE: This method might not work correctly if self is multivariate. - # Or it might, I have not checked. Depends on the _canonicalize method. - # There are more problems actually. - # I think I need to do something with dompart. - if self.parent()._k != 1: raise ValueError("self must be univariate") res = 0 + # conjugate self._group so that [1..k] is sort 1, [k+1,..] is sort 2, so on + conj = PermutationGroupElement(list(chain.from_iterable(self._dompart))).inverse() + G = libgap.ConjugateGroup(self._group, conj) # Create group of the composition Pn = PolynomialSpecies(len(args[0])) comp = list(chain.from_iterable(args)) # Create the double coset representatives. S_down = SymmetricGroup(sum(comp)).young_subgroup(comp) S_up = SymmetricGroup(self._tc).young_subgroup(self._mc) - taus = libgap.DoubleCosetRepsAndSizes(S_up, S_down, self._group) + taus = libgap.DoubleCosetRepsAndSizes(S_up, S_down, G) # Sum over double coset representatives. for tau, _ in taus: - G = libgap.ConjugateGroup(self._group, tau) - H = libgap.Intersection(G, S_down) + H = libgap.Intersection(libgap.ConjugateGroup(G, tau), S_down) grp = PermutationGroup(gap_group=H, domain=self.domain()) dpart = {i + 1: list(range(x - comp[i] + 1, x + 1)) for i, x in enumerate(accumulate(comp))} res += Pn(grp, dpart) @@ -903,7 +946,8 @@ def inner_sum(self, *args): def substitution(self, *args): r""" Substitute M_1...M_k into self. - M_i must all have same arity and must be molecular. + M_i must all have same arity, same multicardinality, + and must be molecular. """ if len(args) != self.parent()._k: raise ValueError("number of args must match arity of self") @@ -911,6 +955,35 @@ def substitution(self, *args): raise ValueError("all args not molecular species") if len(set(arg.parent()._k for arg in args)) > 1: raise ValueError("all args must have same arity") + if len(set(arg._mc for arg in args)) > 1: + raise ValueError("all args must have same multicardinality") + + gens = [] + + # TODO: What happens if in F(G), G has a constant part? E(1+X)? + Mlist = [None for _ in range(self._group.degree())] + for i, v in enumerate(self._dompart): + for k in v: + Mlist[k - 1] = args[i] + starts = list(accumulate([M._group.degree() for M in Mlist], initial=0)) + + # gens from self + for gen in self._group.gens(): + newgen = [] + for cyc in gen.cycle_tuples(): + for k in range(1, Mlist[cyc[0] - 1]._group.degree() + 1): + newgen.append(tuple(k + starts[i - 1] for i in cyc)) + gens.append(newgen) + + # gens from M_i + dpart = {i: [] for i in range(1, args[0].parent()._k + 1)} + for start, M in zip(starts, Mlist): + for i, v in enumerate(M._dompart, 1): + dpart[i].extend([start + k for k in v]) + for gen in M._group.gens(): + gens.append([tuple(start + k for k in cyc) for cyc in gen.cycle_tuples()]) + + return args[0].parent()(PermutationGroup(gens, domain=range(1, starts[-1] + 1)), dpart) class PolynomialSpecies(CombinatorialFreeModule): @@ -970,23 +1043,9 @@ def degree_on_basis(self, m): """ return m.grade() - def _project(self, G, pi, part): - r""" - Project `G` onto a subset ``part`` of its domain. - - ``part`` must be a union of cycles, but this is not checked. - """ - restricted_gens = [[cyc for cyc in gen.cycle_tuples() if cyc[0] in part] for gen in G.gens()] - mapping = dict() - for k, v in pi.items(): - es = [e for e in v if e in part] - if es: - mapping[k] = es - return PermutationGroup(gens=restricted_gens, domain=part), mapping - def _element_constructor_(self, G, pi=None): r""" - Construct the `k`-variate molecular species with the given data. + Construct the `k`-variate polynomial species with the given data. INPUT: @@ -1005,27 +1064,12 @@ def _element_constructor_(self, G, pi=None): if pi is not None: raise ValueError("cannot reassign sorts to a polynomial species") return G - if not isinstance(G, PermutationGroup_generic): - raise ValueError(f"{G} must be a permutation group") if pi is None: if self._k == 1: - pi = {1: G.domain()} + return self._from_dict({self._indices(G): ZZ.one()}) else: raise ValueError("the assignment of sorts to the domain elements must be provided") - if not set(pi.keys()).issubset(range(1, self._k + 1)): - raise ValueError(f"keys of pi must be in the range [1, {self._k}]") - pi = {k: set(v) for k, v in pi.items()} - if sum(len(p) for p in pi.values()) != len(G.domain()) or set.union(*[p for p in pi.values()]) != set(G.domain()): - raise ValueError("values of pi must partition the domain of G") - for orbit in G.orbits(): - if not any(set(orbit).issubset(p) for p in pi.values()): - raise ValueError(f"For each orbit of {G}, all elements must belong to the same sort") - - domain_partition = G.disjoint_direct_product_decomposition() - term = self._indices.one() - for part in domain_partition: - term *= self._indices.gen(self._project(G, pi, part)) - return self._from_dict({term: ZZ.one()}) + return self._from_dict({self._indices(G, pi): ZZ.one()}) @cached_method def one_basis(self): From acc44f877ddeaec182f4c6bf354cb84d6b1b5a2e Mon Sep 17 00:00:00 2001 From: Newtech66 Date: Wed, 21 Aug 2024 13:39:39 +0530 Subject: [PATCH 134/537] Add cartesian_product and doctests --- src/sage/rings/species.py | 75 ++++++++++++++++++++++++++++++++++----- 1 file changed, 66 insertions(+), 9 deletions(-) diff --git a/src/sage/rings/species.py b/src/sage/rings/species.py index 9ad1315c7c6..c42cb3c854e 100644 --- a/src/sage/rings/species.py +++ b/src/sage/rings/species.py @@ -903,6 +903,52 @@ def domain(self): """ return FiniteEnumeratedSet(range(1, self._tc + 1)) + def cartesian_product(self, other): + r""" + Compute the cartesian product of ``self`` and ``other``. + + EXAMPLES: + + Exercise 2.1.9 from the BLL book:: + + sage: P = PolynomialSpecies(["X"]) + sage: M = P._indices + sage: C3 = M(CyclicPermutationGroup(3)) + sage: X = M(SymmetricGroup(1)) + sage: E2 = M(SymmetricGroup(2)) + sage: C3.cartesian_product(C3) # C3 x C3 = 2*C3 + 2*{((1,2,3),): ((1, 2, 3),)} + sage: (X^3).cartesian_product(C3) # X^3 x C3 = 2*X^3 + 2*{((),): ((1,),)}^3 + sage: (X*E2).cartesian_product(X*E2) # X*E2 x X*E2 = X*E2 + X^3 + {((),): ((1,),)}*{((1,2),): ((1, 2),)} + {((),): ((1,),)}^3 + """ + if not isinstance(other, MolecularSpecies.Element): + raise ValueError("other must be a molecular species") + if self.parent()._k != other.parent()._k: + raise ValueError("other must have same arity") + + Pn = PolynomialSpecies(self.parent()._k) + if self._mc != other._mc: + return Pn.zero() + # create S + S = SymmetricGroup(self._tc).young_subgroup(self._mc) + # conjugate self and other to match S + conj_self = PermutationGroupElement(list(chain.from_iterable(self._dompart))).inverse() + conj_other = PermutationGroupElement(list(chain.from_iterable(other._dompart))).inverse() + G = libgap.ConjugateGroup(self._group, conj_self) + H = libgap.ConjugateGroup(other._group, conj_other) + # create dompart + dpart = {i + 1: range(x - self._mc[i] + 1, x + 1) for i, x in enumerate(accumulate(self._mc))} + # create double coset representatives + taus = libgap.DoubleCosetRepsAndSizes(S, G, H) + # loop over representatives + res = 0 + for tau, _ in taus: + F = libgap.Intersection(libgap.ConjugateGroup(H, tau), G) + res += Pn(PermutationGroup(gap_group=F, domain=self.domain()), dpart) + return res + def inner_sum(self, *args): r""" Compute the inner sum of exercise 2.6.16 of BLL book. @@ -914,16 +960,14 @@ def inner_sum(self, *args): EXAMPLES:: sage: P = PolynomialSpecies(1) - sage: C4 = P(CyclicPermutationGroup(4)) - sage: C4.support()[0].inner_sum([2, 2]) # X^2Y^2 + C2(XY) + sage: M = P._indices + sage: C4 = M(CyclicPermutationGroup(4)) + sage: C4.inner_sum([2, 2]) # X^2Y^2 + C2(XY) {((),): ((1,), ())}^2*{((),): ((), (1,))}^2 + {((1,2)(3,4),): ((1, 2), (3, 4))} """ # TODO: No checks are performed right now, must be added. # Checks: all args in compositions, sums must match cardinalities. - if self.parent()._k != 1: - raise ValueError("self must be univariate") - res = 0 # conjugate self._group so that [1..k] is sort 1, [k+1,..] is sort 2, so on conj = PermutationGroupElement(list(chain.from_iterable(self._dompart))).inverse() @@ -939,20 +983,33 @@ def inner_sum(self, *args): for tau, _ in taus: H = libgap.Intersection(libgap.ConjugateGroup(G, tau), S_down) grp = PermutationGroup(gap_group=H, domain=self.domain()) - dpart = {i + 1: list(range(x - comp[i] + 1, x + 1)) for i, x in enumerate(accumulate(comp))} + dpart = {i + 1: range(x - comp[i] + 1, x + 1) for i, x in enumerate(accumulate(comp))} res += Pn(grp, dpart) return res - def substitution(self, *args): + def __call__(self, *args): r""" Substitute M_1...M_k into self. M_i must all have same arity, same multicardinality, and must be molecular. + + EXAMPLES:: + + sage: P = PolynomialSpecies(["X"]) + sage: M = P._indices + sage: X = M(SymmetricGroup(1)) + sage: E2 = M(SymmetricGroup(2)) + sage: E2(X) + E_2 + sage: X(E2) + E_2 + sage: E2(E2) + {((1,2,3,4), (1,4)(2,3)): ((1, 2, 3, 4),)} """ if len(args) != self.parent()._k: raise ValueError("number of args must match arity of self") if not all(isinstance(arg, MolecularSpecies.Element) for arg in args): - raise ValueError("all args not molecular species") + raise ValueError("all args must be molecular species") if len(set(arg.parent()._k for arg in args)) > 1: raise ValueError("all args must have same arity") if len(set(arg._mc for arg in args)) > 1: @@ -975,7 +1032,7 @@ def substitution(self, *args): newgen.append(tuple(k + starts[i - 1] for i in cyc)) gens.append(newgen) - # gens from M_i + # gens from M_i and dompart dpart = {i: [] for i in range(1, args[0].parent()._k + 1)} for start, M in zip(starts, Mlist): for i, v in enumerate(M._dompart, 1): From 2aa9cd0d41ed3989b6fba3c990998f53f5264798 Mon Sep 17 00:00:00 2001 From: Newtech66 Date: Wed, 21 Aug 2024 13:59:00 +0530 Subject: [PATCH 135/537] Minor changes --- src/sage/rings/species.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/sage/rings/species.py b/src/sage/rings/species.py index c42cb3c854e..2698a04036f 100644 --- a/src/sage/rings/species.py +++ b/src/sage/rings/species.py @@ -248,7 +248,7 @@ def _element_constructor_(self, x): elm = self.element_class(self, P) return self._cache_get(elm) raise ValueError(f"unable to convert {x} to {self}") - + def __iter__(self): r""" An iterator over all conjugacy classes of directly indecomposable @@ -261,7 +261,6 @@ def __iter__(self): sage: iterC = iter(C) sage: for i in range(5): ....: print(next(iterC)) - ....: () ((),) ((1,2),) @@ -902,7 +901,7 @@ def domain(self): Return the domain of ``self``. """ return FiniteEnumeratedSet(range(1, self._tc + 1)) - + def cartesian_product(self, other): r""" Compute the cartesian product of ``self`` and ``other``. @@ -1004,7 +1003,7 @@ def __call__(self, *args): sage: X(E2) E_2 sage: E2(E2) - {((1,2,3,4), (1,4)(2,3)): ((1, 2, 3, 4),)} + P_4 """ if len(args) != self.parent()._k: raise ValueError("number of args must match arity of self") From 3b6061ec0f4f0fb6cdc813d44ed048c149318824 Mon Sep 17 00:00:00 2001 From: Newtech66 Date: Wed, 21 Aug 2024 16:56:41 +0530 Subject: [PATCH 136/537] Minor changes+partial naming changes --- src/sage/rings/species.py | 115 ++++++++++++++++---------------------- 1 file changed, 47 insertions(+), 68 deletions(-) diff --git a/src/sage/rings/species.py b/src/sage/rings/species.py index 2698a04036f..4e07ef076be 100644 --- a/src/sage/rings/species.py +++ b/src/sage/rings/species.py @@ -68,9 +68,15 @@ def _cache_get(self, elm): if it doesn't exist. ``elm`` must implement the following methods: - ``_element_key`` - hashable type for dict lookup. - ``__eq__`` - to compare two elements. + - ``_element_key`` - hashable type for dict lookup. + - ``__eq__`` - to compare two elements. + Additionally, if a method ``_canonicalize`` is implemented, it is used to preprocess the element. """ + # TODO: Make _canonicalize optional. + # Possibly the following works: + # use getattr to check if name exists + # use callable to check if it is a function + # if both true, call _canonicalize key = elm._element_key() if key in self._cache: lookup = self._cache[key] @@ -445,52 +451,34 @@ def _repr_(self): class AtomicSpecies(UniqueRepresentation, Parent, ElementCache): @staticmethod - def __classcall__(cls, k, singleton_names=None): + def __classcall__(cls, names): """ Normalize the arguments. TESTS:: - sage: A1 = AtomicSpecies(1, "X") - sage: A2 = AtomicSpecies(1) - sage: A3 = AtomicSpecies(["X", "Y"]) - sage: A4 = AtomicSpecies(2, ["X", "Y"]) + sage: A1 = AtomicSpecies("X") + sage: A2 = AtomicSpecies("Y") sage: A1 is A2 False - sage: A3 is A4 - True """ - if singleton_names is None: - if k in ZZ: - k = ZZ(k) - else: - singleton_names = tuple(k) - k = len(singleton_names) - else: - k = ZZ(k) - singleton_names = tuple(singleton_names) - - if (singleton_names is not None - and (len(singleton_names) != k - or not all(isinstance(X, str) for X in singleton_names))): + if all(isinstance(X, str) for X in names): raise ValueError(f"singleton_names must be a tuple of {k} strings") return super().__classcall__(cls, k, singleton_names) - def __init__(self, k, singleton_names): + def __init__(self, names): r""" - Infinite set of `k`-variate atomic species graded by - integer vectors of length `k`. + Infinite set of multivariate atomic species. INPUT: - - ``k`` -- a non-negative integer, or an iterable of ``k`` strings - - ``singleton_names`` -- an iterable of ``k`` strings or ``None`` + - ``names`` -- an iterable of ``k`` strings TESTS:: - sage: At1 = AtomicSpecies(1) - sage: At2 = AtomicSpecies(2) + sage: At1 = AtomicSpecies(["X"]) + sage: At2 = AtomicSpecies(["X", "Y"]) sage: TestSuite(At1).run(skip="_test_graded_components") sage: TestSuite(At2).run(skip="_test_graded_components") """ @@ -642,7 +630,7 @@ def _repr_(self): sage: At2 = AtomicSpecies(2); At2 Infinite set of 2-variate atomic species """ - return f"Infinite set of {self._k}-variate atomic species" + return f"Atomic species in sorts " Element = AtomicSpeciesElement @@ -678,16 +666,10 @@ def _element_constructor_(self, G, pi=None): INPUT: - - ``x`` can be any of the following: - - an element of ``self``. - - a tuple ``(H, M)`` where `H` is the permutation group - representation for the species and `M` is a ``dict`` - mapping each element of the domain of `H` to integers - in `\{ 1 \ldots k \}`, representing the set to which - the element belongs. - - if `k=1`, i.e. we are working with univariate species, - the mapping `M` may be omitted and just the group `H` - may be passed. + - ``G`` - an element of ``self`` (in this case pi must be ``None``) + or a permutation group. + - ``pi`` - a dict mapping sorts to iterables whose union is the domain. + If `k=1`, `pi` can be omitted. """ if parent(G) == self: if pi is not None: @@ -902,9 +884,9 @@ def domain(self): """ return FiniteEnumeratedSet(range(1, self._tc + 1)) - def cartesian_product(self, other): + def hadamard_product(self, other): r""" - Compute the cartesian product of ``self`` and ``other``. + Compute the hadamard product of ``self`` and ``other``. EXAMPLES: @@ -915,19 +897,23 @@ def cartesian_product(self, other): sage: C3 = M(CyclicPermutationGroup(3)) sage: X = M(SymmetricGroup(1)) sage: E2 = M(SymmetricGroup(2)) - sage: C3.cartesian_product(C3) # C3 x C3 = 2*C3 - 2*{((1,2,3),): ((1, 2, 3),)} - sage: (X^3).cartesian_product(C3) # X^3 x C3 = 2*X^3 - 2*{((),): ((1,),)}^3 - sage: (X*E2).cartesian_product(X*E2) # X*E2 x X*E2 = X*E2 + X^3 - {((),): ((1,),)}*{((1,2),): ((1, 2),)} + {((),): ((1,),)}^3 + sage: C3.hadamard_product(C3) + 2*C_3 + sage: (X^3).hadamard_product(C3) + 2*X^3 + sage: (X*E2).hadamard_product(X*E2) + X*E_2 + X^3 """ if not isinstance(other, MolecularSpecies.Element): raise ValueError("other must be a molecular species") if self.parent()._k != other.parent()._k: raise ValueError("other must have same arity") - Pn = PolynomialSpecies(self.parent()._k) + P = self.parent() + if not P is other.parent(): + raise ValueError("the factors of a Hadamard product must be the same.") + + Pn = PolynomialSpecies(names=P._indices.names) if self._mc != other._mc: return Pn.zero() # create S @@ -942,7 +928,7 @@ def cartesian_product(self, other): # create double coset representatives taus = libgap.DoubleCosetRepsAndSizes(S, G, H) # loop over representatives - res = 0 + res = Pn.zero() for tau, _ in taus: F = libgap.Intersection(libgap.ConjugateGroup(H, tau), G) res += Pn(PermutationGroup(gap_group=F, domain=self.domain()), dpart) @@ -1043,13 +1029,13 @@ def __call__(self, *args): class PolynomialSpecies(CombinatorialFreeModule): - def __classcall__(cls, k, singleton_names=None, base_ring=ZZ): + def __classcall__(cls, names, base_ring=ZZ): r""" Normalize the arguments. TESTS:: - sage: P1 = PolynomialSpecies(1, "X", ZZ) + sage: P1 = PolynomialSpecies("X", ZZ) sage: P2 = PolynomialSpecies(1, base_ring=ZZ) sage: P3 = PolynomialSpecies(["X", "Y"], base_ring=ZZ) sage: P4 = PolynomialSpecies(2, ["X", "Y"]) @@ -1070,19 +1056,19 @@ def __classcall__(cls, k, singleton_names=None, base_ring=ZZ): A = AtomicSpecies(k, singleton_names=singleton_names) return super().__classcall__(cls, A._k, A._singleton_names, base_ring) - def __init__(self, k, singleton_names, base_ring): + def __init__(self, base_ring, names): r""" Ring of `k`-variate polynomial (virtual) species. TESTS:: - sage: P = PolynomialSpecies(1) + sage: P = PolynomialSpecies(["X"]) sage: TestSuite(P).run() - sage: P2 = PolynomialSpecies(2) + sage: P2 = PolynomialSpecies(["X", "Y"]) sage: TestSuite(P2).run() """ # should we pass a category to basis_keys? - A = AtomicSpecies(k, singleton_names=singleton_names) + A = AtomicSpecies(names=names) basis_keys = MolecularSpecies(A, prefix='', bracket=False) category = GradedAlgebrasWithBasis(base_ring).Commutative() CombinatorialFreeModule.__init__(self, base_ring, @@ -1105,16 +1091,10 @@ def _element_constructor_(self, G, pi=None): INPUT: - - ``x`` can be any of the following: - - an element of ``self``. - - a tuple ``(H, M)`` where `H` is the permutation group - representation for the species and `M` is a ``dict`` - mapping each element of the domain of `H` to integers - in `\{ 1 \ldots k \}`, representing the set to which - the element belongs. - - if `k=1`, i.e. we are working with univariate species, - the mapping `M` may be omitted and just the group `H` - may be passed. + - ``G`` - an element of ``self`` (in this case pi must be ``None``) + or a permutation group. + - ``pi`` - a dict mapping sorts to iterables whose union is the domain. + If `k=1`, `pi` can be omitted. """ if parent(G) == self: if pi is not None: @@ -1123,8 +1103,7 @@ def _element_constructor_(self, G, pi=None): if pi is None: if self._k == 1: return self._from_dict({self._indices(G): ZZ.one()}) - else: - raise ValueError("the assignment of sorts to the domain elements must be provided") + raise ValueError("the assignment of sorts to the domain elements must be provided") return self._from_dict({self._indices(G, pi): ZZ.one()}) @cached_method From 4c54733dbf5b4945165c44a47bf5c7a12120e89f Mon Sep 17 00:00:00 2001 From: Newtech66 Date: Wed, 21 Aug 2024 22:38:56 +0530 Subject: [PATCH 137/537] New renaming (thanks mantepse) + construct from group action (wip) --- src/sage/rings/species.py | 280 ++++++++++++++++++++------------------ 1 file changed, 149 insertions(+), 131 deletions(-) diff --git a/src/sage/rings/species.py b/src/sage/rings/species.py index 4e07ef076be..1dd265f3344 100644 --- a/src/sage/rings/species.py +++ b/src/sage/rings/species.py @@ -1,4 +1,5 @@ from itertools import accumulate, chain + from sage.categories.graded_algebras_with_basis import GradedAlgebrasWithBasis from sage.categories.infinite_enumerated_sets import InfiniteEnumeratedSets from sage.categories.monoids import Monoids @@ -10,12 +11,14 @@ from sage.groups.perm_gps.permgroup_named import SymmetricGroup from sage.libs.gap.libgap import libgap from sage.misc.cachefunc import cached_method -from sage.monoids.indexed_free_monoid import IndexedFreeAbelianMonoid, IndexedFreeAbelianMonoidElement, IndexedMonoid +from sage.monoids.indexed_free_monoid import (IndexedFreeAbelianMonoid, + IndexedFreeAbelianMonoidElement, + IndexedMonoid) from sage.rings.integer_ring import ZZ +from sage.sets.finite_enumerated_set import FiniteEnumeratedSet from sage.structure.element import Element, parent from sage.structure.parent import Parent from sage.structure.unique_representation import UniqueRepresentation -from sage.sets.finite_enumerated_set import FiniteEnumeratedSet GAP_FAIL = libgap.eval('fail') @@ -43,25 +46,6 @@ def __init__(self): """ self._cache = dict() - def clear_cache(self): - r""" - Clear the cache. - - EXAMPLES:: - - sage: A = AtomicSpecies(1) - sage: A(SymmetricGroup(1)) - {((),): ((1,),)} - sage: A(SymmetricGroup(0)) - {(): ((),)} - sage: A._cache - {((0,), ()): [{(): ((),)}], ((1,), ((),)): [{((),): ((1,),)}]} - sage: A.clear_cache() - sage: A._cache - {} - """ - self._cache = dict() - def _cache_get(self, elm): r""" Return the cached element, or add it @@ -225,18 +209,12 @@ def _element_constructor_(self, x): sage: from sage.rings.species import ConjugacyClassesOfDirectlyIndecomposableSubgroups sage: C = ConjugacyClassesOfDirectlyIndecomposableSubgroups() - sage: C.clear_cache() sage: C(PermutationGroup([("a", "b", "c")])) ((1,2,3),) - sage: C._cache - {(3, 3, (3,)): [((1,2,3),)]} sage: C(PermutationGroup([(1, 3, 5)], domain=[1,3,5])) ((1,2,3),) sage: C(PermutationGroup([[(1,3),(4,7)],[(2,5),(6,8)], [(1,4),(2,5),(3,7)]])) ((5,6)(7,8), (1,2)(3,4), (1,3)(2,4)(5,6)) - sage: C._cache - {(3, 3, (3,)): [((1,2,3),)], - (8, 8, (2, 2, 4)): [((5,6)(7,8), (1,2)(3,4), (1,3)(2,4)(5,6))]} """ if parent(x) == self: return x @@ -329,7 +307,7 @@ def __init__(self, parent, dis, domain_partition): TESTS:: - sage: A = AtomicSpecies(1) + sage: A = AtomicSpecies("X") sage: G = PermutationGroup([[(1,3),(4,7)], [(2,5),(6,8)], [(1,4),(2,5),(3,7)]]) sage: TestSuite(A(G)).run() """ @@ -357,7 +335,7 @@ def _canonicalize(self): EXAMPLES:: - sage: At = AtomicSpecies(2) + sage: At = AtomicSpecies("X, Y") sage: G = PermutationGroup([[(1,2),(3,4),(5,6),(7,8,9,10)]]); G Permutation Group with generators [(1,2)(3,4)(5,6)(7,8,9,10)] sage: H = PermutationGroup([[(1,2,3,4),(5,6),(7,8),(9,10)]]); H @@ -378,7 +356,7 @@ def __hash__(self): TESTS:: - sage: At = AtomicSpecies(2) + sage: At = AtomicSpecies("X, Y") sage: G = PermutationGroup([[(1,2),(3,4),(5,6),(7,8,9,10)]]); G Permutation Group with generators [(1,2)(3,4)(5,6)(7,8,9,10)] sage: H = PermutationGroup([[(1,2,3,4),(5,6),(7,8),(9,10)]]); H @@ -403,7 +381,7 @@ def __eq__(self, other): TESTS:: - sage: At = AtomicSpecies(2) + sage: At = AtomicSpecies("X, Y") sage: G = PermutationGroup([[(1,2),(3,4),(5,6),(7,8,9,10)]]); G Permutation Group with generators [(1,2)(3,4)(5,6)(7,8,9,10)] sage: H = PermutationGroup([[(1,2,3,4),(5,6),(7,8),(9,10)]]); H @@ -440,7 +418,7 @@ def _repr_(self): TESTS:: - sage: At = AtomicSpecies(2) + sage: At = AtomicSpecies("X, Y") sage: G = PermutationGroup([[(1,2),(3,4),(5,6),(7,8,9,10)]]); G Permutation Group with generators [(1,2)(3,4)(5,6)(7,8,9,10)] sage: A = At(G, {1: [1,2,3,4], 2: [5,6,7,8,9,10]}); A @@ -459,13 +437,16 @@ def __classcall__(cls, names): sage: A1 = AtomicSpecies("X") sage: A2 = AtomicSpecies("Y") + sage: A3 = AtomicSpecies("X, Y") + sage: A4 = AtomicSpecies(["X", "Y"]) sage: A1 is A2 False + sage: A3 is A4 + True """ - if all(isinstance(X, str) for X in names): - raise ValueError(f"singleton_names must be a tuple of {k} strings") - - return super().__classcall__(cls, k, singleton_names) + from sage.structure.category_object import normalize_names + names = normalize_names(-1, names) + return super().__classcall__(cls, names) def __init__(self, names): r""" @@ -483,11 +464,10 @@ def __init__(self, names): sage: TestSuite(At2).run(skip="_test_graded_components") """ category = SetsWithGrading().Infinite() - Parent.__init__(self, category=category) + Parent.__init__(self, names=names, category=category) ElementCache.__init__(self) - self._k = k - self._grading_set = IntegerVectors(length=k) - self._singleton_names = singleton_names + self._k = len(names) + self._grading_set = IntegerVectors(length=self._k) self._renamed = set() # the degrees that have been renamed already @cached_method @@ -497,10 +477,10 @@ def an_element(self): TESTS:: - sage: At1 = AtomicSpecies(1) - sage: At2 = AtomicSpecies(2) + sage: At1 = AtomicSpecies("X") + sage: At2 = AtomicSpecies("X, Y") sage: At1.an_element() - {((1,2),): ((1, 2),)} + E_2 sage: At2.an_element() {((1,2)(3,4),): ((1, 2), (3, 4))} """ @@ -548,27 +528,27 @@ def _element_constructor_(self, G, pi=None): for k, v in pi.items(): dpart[k - 1] = tuple(mapping2(mapping[x]) for x in v) elm = self._cache_get(self.element_class(self, dis_elm, tuple(dpart))) - if self._singleton_names and elm._tc not in self._renamed: + if elm._tc not in self._renamed: self._rename(elm._tc) return elm def _rename(self, n): from sage.groups.perm_gps.permgroup import PermutationGroup - from sage.groups.perm_gps.permgroup_named import (SymmetricGroup, - CyclicPermutationGroup, - DihedralGroup, - AlternatingGroup) + from sage.groups.perm_gps.permgroup_named import (AlternatingGroup, + CyclicPermutationGroup, + DihedralGroup, + SymmetricGroup) # prevent infinite recursion in self._element_constructor_ self._renamed.add(n) for i in range(self._k): if n == 1: - self(SymmetricGroup(1), {i+1: [1]}).rename(self._singleton_names[i]) + self(SymmetricGroup(1), {i+1: [1]}).rename(self._names[i]) if self._k == 1: sort = "" else: - sort = f"({self._singleton_names[i]})" + sort = f"({self._names[i]})" if n >= 2: self(SymmetricGroup(n), @@ -625,12 +605,14 @@ def _repr_(self): TESTS:: - sage: At1 = AtomicSpecies(1); At1 - Infinite set of 1-variate atomic species - sage: At2 = AtomicSpecies(2); At2 - Infinite set of 2-variate atomic species + sage: AtomicSpecies("X") + Atomic species in X + sage: AtomicSpecies("X, Y") + Atomic species in X, Y """ - return f"Atomic species in sorts " + if len(self._names) == 1: + return f"Atomic species in {self._names[0]}" + return f"Atomic species in {', '.join(self._names)}" Element = AtomicSpeciesElement @@ -667,36 +649,76 @@ def _element_constructor_(self, G, pi=None): INPUT: - ``G`` - an element of ``self`` (in this case pi must be ``None``) - or a permutation group. - - ``pi`` - a dict mapping sorts to iterables whose union is the domain. - If `k=1`, `pi` can be omitted. + or a permutation group, or a pair ``(X, a)`` consisting of a + finite set and an action. + - ``pi`` - a dict mapping sorts to iterables whose union is the + domain of ``G`` (if ``G`` is a permutation group) or `X` (if ``G``) + is a pair ``(X, a)``. If `k=1`, `pi` can be omitted. + + If `G = (X, a)`, then `X` should be a finite set and `a` an action + of `G` on `X`. + + EXAMPLES:: + + sage: P = PolynomialSpecies(["X", "Y"]) + sage: P(SymmetricGroup(4).young_subgroup([2, 2]), {1: [1,2], 2: [3,4]}) + E_2(X)*E_2(Y) + + sage: S = SymmetricGroup(4).young_subgroup([2, 2]) + sage: X = SetPartitions(4, 2) + sage: a = lambda g, x: SetPartition([[g(e) for e in b] for b in x]) + sage: P((X, a), {1: [1,2], 2: [3,4]}) + E_2(X)*E_2(Y) + E_2(X*Y) + X^2*E_2(Y) + E_2(X)*Y^2 + + TESTS:: + + sage: P = PolynomialSpecies(["X", "Y"]) + sage: M = P._indices + sage: M(CyclicPermutationGroup(4), {1: [1,2], 2:[3,4]}) + Traceback (most recent call last): + ... + ValueError: For each orbit of Cyclic group of order 4 as a permutation group, all elements must belong to the same sort """ if parent(G) == self: if pi is not None: raise ValueError("cannot reassign sorts to a molecular species") return G - if not isinstance(G, PermutationGroup_generic): - raise ValueError(f"{G} must be a permutation group") + if isinstance(G, PermutationGroup_generic): + if pi is None: + if self._k == 1: + pi = {1: G.domain()} + else: + raise ValueError("the assignment of sorts to the domain elements must be provided") + if not set(pi.keys()).issubset(range(1, self._k + 1)): + raise ValueError(f"keys of pi must be in the range [1, {self._k}]") + pi = {k: set(v) for k, v in pi.items()} + if sum(len(p) for p in pi.values()) != len(G.domain()) or set.union(*[p for p in pi.values()]) != set(G.domain()): + raise ValueError("values of pi must partition the domain of G") + for orbit in G.orbits(): + if not any(set(orbit).issubset(p) for p in pi.values()): + raise ValueError(f"For each orbit of {G}, all elements must belong to the same sort") + + domain_partition = G.disjoint_direct_product_decomposition() + elm = self.one() + for part in domain_partition: + elm *= self.gen(self._project(G, pi, part)) + return elm + # If not a permutation group, assume input is (X, a) + X, a = G if pi is None: if self._k == 1: - pi = {1: G.domain()} + pi = {1: X} else: raise ValueError("the assignment of sorts to the domain elements must be provided") if not set(pi.keys()).issubset(range(1, self._k + 1)): raise ValueError(f"keys of pi must be in the range [1, {self._k}]") pi = {k: set(v) for k, v in pi.items()} - if sum(len(p) for p in pi.values()) != len(G.domain()) or set.union(*[p for p in pi.values()]) != set(G.domain()): + if sum(len(p) for p in pi.values()) != len(G.domain()) or set.union(*[p for p in pi.values()]) != set(X): raise ValueError("values of pi must partition the domain of G") for orbit in G.orbits(): if not any(set(orbit).issubset(p) for p in pi.values()): raise ValueError(f"For each orbit of {G}, all elements must belong to the same sort") - domain_partition = G.disjoint_direct_product_decomposition() - elm = self.one() - for part in domain_partition: - elm *= self.gen(self._project(G, pi, part)) - return elm - @cached_method def one(self): r""" @@ -704,7 +726,7 @@ def one(self): EXAMPLES:: - sage: P = PolynomialSpecies(2) + sage: P = PolynomialSpecies(ZZ, "X, Y") sage: P._indices.one() 1 """ @@ -853,7 +875,7 @@ def _canonicalize(self): EXAMPLES:: - sage: P = PolynomialSpecies(2) + sage: P = PolynomialSpecies(ZZ, "X, Y") sage: G = PermutationGroup([[(1,2),(3,4),(5,6),(7,8,9,10)]]); G Permutation Group with generators [(1,2)(3,4)(5,6)(7,8,9,10)] sage: H = PermutationGroup([[(1,2,3,4),(5,6),(7,8),(9,10)]]); H @@ -892,7 +914,7 @@ def hadamard_product(self, other): Exercise 2.1.9 from the BLL book:: - sage: P = PolynomialSpecies(["X"]) + sage: P = PolynomialSpecies(ZZ, ["X"]) sage: M = P._indices sage: C3 = M(CyclicPermutationGroup(3)) sage: X = M(SymmetricGroup(1)) @@ -904,16 +926,11 @@ def hadamard_product(self, other): sage: (X*E2).hadamard_product(X*E2) X*E_2 + X^3 """ - if not isinstance(other, MolecularSpecies.Element): - raise ValueError("other must be a molecular species") - if self.parent()._k != other.parent()._k: - raise ValueError("other must have same arity") - P = self.parent() - if not P is other.parent(): + if P is not other.parent(): raise ValueError("the factors of a Hadamard product must be the same.") - - Pn = PolynomialSpecies(names=P._indices.names) + Pn = PolynomialSpecies(ZZ, P._indices._names) + if self._mc != other._mc: return Pn.zero() # create S @@ -934,31 +951,40 @@ def hadamard_product(self, other): res += Pn(PermutationGroup(gap_group=F, domain=self.domain()), dpart) return res - def inner_sum(self, *args): + def inner_sum(self, base_ring, names, *args): r""" Compute the inner sum of exercise 2.6.16 of BLL book. - args are the compositions (in Compositions) each of which - sum to the corresponding cardinality of ``self``. The number - of args is equal to the arity of ``self``. + INPUT: + + - ``base_ring``, the base ring of the result + + - ``names``, the names of the result + + - ``args``, the sequence of compositions, each of + which sums to the corresponding cardinality of + ``self``. The number of ``args`` is equal to the + arity of ``self``. EXAMPLES:: - sage: P = PolynomialSpecies(1) + sage: P = PolynomialSpecies(ZZ, "X") sage: M = P._indices sage: C4 = M(CyclicPermutationGroup(4)) - sage: C4.inner_sum([2, 2]) # X^2Y^2 + C2(XY) - {((),): ((1,), ())}^2*{((),): ((), (1,))}^2 + {((1,2)(3,4),): ((1, 2), (3, 4))} + sage: C4.inner_sum(ZZ, "X, Y", [2, 2]) # X^2Y^2 + C2(XY) + {((1,2)(3,4),): ((1, 2), (3, 4))} + X^2*Y^2 + """ # TODO: No checks are performed right now, must be added. # Checks: all args in compositions, sums must match cardinalities. - res = 0 + # Create group of the composition + Pn = PolynomialSpecies(base_ring, names) + res = Pn.zero() # conjugate self._group so that [1..k] is sort 1, [k+1,..] is sort 2, so on conj = PermutationGroupElement(list(chain.from_iterable(self._dompart))).inverse() G = libgap.ConjugateGroup(self._group, conj) - # Create group of the composition - Pn = PolynomialSpecies(len(args[0])) + comp = list(chain.from_iterable(args)) # Create the double coset representatives. S_down = SymmetricGroup(sum(comp)).young_subgroup(comp) @@ -980,7 +1006,7 @@ def __call__(self, *args): EXAMPLES:: - sage: P = PolynomialSpecies(["X"]) + sage: P = PolynomialSpecies(ZZ, ["X"]) sage: M = P._indices sage: X = M(SymmetricGroup(1)) sage: E2 = M(SymmetricGroup(2)) @@ -1029,32 +1055,23 @@ def __call__(self, *args): class PolynomialSpecies(CombinatorialFreeModule): - def __classcall__(cls, names, base_ring=ZZ): + def __classcall__(cls, base_ring, names): r""" Normalize the arguments. TESTS:: - sage: P1 = PolynomialSpecies("X", ZZ) - sage: P2 = PolynomialSpecies(1, base_ring=ZZ) - sage: P3 = PolynomialSpecies(["X", "Y"], base_ring=ZZ) - sage: P4 = PolynomialSpecies(2, ["X", "Y"]) + sage: P1 = PolynomialSpecies(ZZ, "X, Y") + sage: P2 = PolynomialSpecies(ZZ, "X, Y") + sage: P3 = PolynomialSpecies(ZZ, ["X", "Z"]) sage: P1 is P2 - False - sage: P3 is P4 True - - .. TODO:: - - Reconsider the order of the arguments. - ``singleton_names`` are not generators, and may even be - omitted, and ``base_ring`` will usually be ``ZZ``, but - maybe it would be nice to allow ``P. = - PolynomialSpecies(ZZ)`` anyway. - + sage: P1 is P3 + False """ - A = AtomicSpecies(k, singleton_names=singleton_names) - return super().__classcall__(cls, A._k, A._singleton_names, base_ring) + from sage.structure.category_object import normalize_names + names = normalize_names(-1, names) + return super().__classcall__(cls, base_ring, names) def __init__(self, base_ring, names): r""" @@ -1062,21 +1079,21 @@ def __init__(self, base_ring, names): TESTS:: - sage: P = PolynomialSpecies(["X"]) + sage: P = PolynomialSpecies(ZZ, "X") sage: TestSuite(P).run() - sage: P2 = PolynomialSpecies(["X", "Y"]) + sage: P2 = PolynomialSpecies(ZZ, "X, Y") sage: TestSuite(P2).run() """ # should we pass a category to basis_keys? - A = AtomicSpecies(names=names) + A = AtomicSpecies(names) basis_keys = MolecularSpecies(A, prefix='', bracket=False) category = GradedAlgebrasWithBasis(base_ring).Commutative() CombinatorialFreeModule.__init__(self, base_ring, - basis_keys=basis_keys, - category=category, - element_class=self.Element, - prefix='', bracket=False) - self._k = k + basis_keys=basis_keys, + category=category, + element_class=self.Element, + prefix='', bracket=False) + self._k = len(names) self._atomic_basis = basis_keys.indices() def degree_on_basis(self, m): @@ -1114,10 +1131,10 @@ def one_basis(self): EXAMPLES:: - sage: P = PolynomialSpecies(1) + sage: P = PolynomialSpecies(ZZ, "X") sage: P.one_basis() 1 - sage: P2 = PolynomialSpecies(2) + sage: P2 = PolynomialSpecies(ZZ, "X, Y") sage: P2.one_basis() 1 """ @@ -1128,10 +1145,10 @@ def an_element(self): """ Return an element of ``self``. - sage: P = PolynomialSpecies(1) + sage: P = PolynomialSpecies(ZZ, "X") sage: P.an_element() 1 - sage: P2 = PolynomialSpecies(2) + sage: P2 = PolynomialSpecies(ZZ, "X, Y") sage: P2.an_element() 1 """ @@ -1143,7 +1160,7 @@ def product_on_basis(self, H, K): EXAMPLES:: - sage: P = PolynomialSpecies("X") + sage: P = PolynomialSpecies(ZZ, "X") sage: L1 = [P(H) for H in SymmetricGroup(3).conjugacy_classes_subgroups()] sage: L2 = [P(H) for H in SymmetricGroup(2).conjugacy_classes_subgroups()] sage: matrix([[F * G for F in L1] for G in L2]) @@ -1158,14 +1175,15 @@ def _repr_(self): EXAMPLES:: - sage: P = PolynomialSpecies(1) - sage: P - Ring of 1-variate virtual species - sage: P2 = PolynomialSpecies(2) - sage: P2 - Ring of 2-variate virtual species + sage: PolynomialSpecies(ZZ, "X") + Polynomial species in X over Integer Ring + sage: PolynomialSpecies(ZZ, "X, Y") + Polynomial species in X, Y over Integer Ring """ - return f"Ring of {self._k}-variate virtual species" + names = self._indices._indices._names + if len(names) == 1: + return f"Polynomial species in {names[0]} over {self.base_ring()}" + return f"Polynomial species in {', '.join(names)} over {self.base_ring()}" class Element(CombinatorialFreeModule.Element): def is_virtual(self): @@ -1174,7 +1192,7 @@ def is_virtual(self): TESTS:: - sage: P = PolynomialSpecies(["X", "Y"]) + sage: P = PolynomialSpecies(ZZ, ["X", "Y"]) sage: X = P(SymmetricGroup(1), {1: [1]}) sage: Y = P(SymmetricGroup(1), {2: [1]}) sage: V = 2 * X - 3 * Y; V @@ -1192,7 +1210,7 @@ def is_molecular(self): TESTS:: - sage: P = PolynomialSpecies(["X", "Y"]) + sage: P = PolynomialSpecies(ZZ, ["X", "Y"]) sage: X = P(SymmetricGroup(1), {1: [1]}) sage: Y = P(SymmetricGroup(1), {2: [1]}) sage: V = 2 * X - 3 * Y; V @@ -1212,7 +1230,7 @@ def is_atomic(self): TESTS:: - sage: P = PolynomialSpecies(["X", "Y"]) + sage: P = PolynomialSpecies(ZZ, ["X", "Y"]) sage: X = P(SymmetricGroup(1), {1: [1]}) sage: Y = P(SymmetricGroup(1), {2: [1]}) sage: V = 2 * X - 3 * Y; V From 8b8c5cc6110865c4391a8b741d71561df1688677 Mon Sep 17 00:00:00 2001 From: Verrel Rievaldo Wijaya Date: Thu, 22 Aug 2024 02:42:41 +0700 Subject: [PATCH 138/537] Add ``is_smooth``, ``is_simple``, ``genus``, ``contribution`` --- src/sage/rings/semirings/tropical_variety.py | 128 +++++++++++++++++++ 1 file changed, 128 insertions(+) diff --git a/src/sage/rings/semirings/tropical_variety.py b/src/sage/rings/semirings/tropical_variety.py index 9dbade7e52f..df507b828cd 100644 --- a/src/sage/rings/semirings/tropical_variety.py +++ b/src/sage/rings/semirings/tropical_variety.py @@ -1188,6 +1188,134 @@ def weight_vectors(self): result[vertex] = vectors return result + def is_smooth(self): + r""" + Return ``True`` if ``self`` is smooth and ``False`` otherwise. + + Suppose `C` is a tropical curve of degree `d`. A tropical curve + `C` is smooth if the dual subdivision of `C` consists of `d^2` + triangles each having unit area `1/2`. This is equivalent with + `C` having `d^2` vertices. These vertices are necessarily + trivalent (has three adjacent edges). + + EXAMPLES:: + + sage: T = TropicalSemiring(QQ) + sage: R. = PolynomialRing(T) + sage: p1 = x^2 + x + R(1) + sage: p1.tropical_variety().is_smooth() + False + sage: p2 = R(2)*x^2 + x*y + R(2)*y^2 + x + R(-1)*y + R(3) + sage: p2.tropical_variety().is_smooth() + True + """ + if len(self.vertices()) == self._poly.degree()**2: + return True + return False + + def is_simple(self): + r""" + Return ``True`` if ``self`` is simple and ``False`` otherwise. + + A tropical curve `C` is called simple if each vertex is either + trivalent or is locally the intersection of two line segments. + Equivalently, `C` is simple if the corresponding subdivision + consists only of triangles and parallelograms. + + EXAMPLES:: + + sage: T = TropicalSemiring(QQ) + sage: R. = PolynomialRing(T) + sage: p1 = R(0) + x + y + x*y + x^2*y + x*y^2 + sage: p1.tropical_variety().is_simple() + False + sage: p2 = R(2)*x^2 + x*y + R(2)*y^2 + x + R(-1)*y + R(3) + sage: p2.tropical_variety().is_simple() + True + """ + vov = self.weight_vectors() + for vertex in self.vertices(): + if len(vov[vertex]) > 4: + return False + elif len(vov[vertex]) == 4: + for v in vov[vertex]: + if -v not in vov[vertex]: + return False + return True + + def genus(self): + r""" + Return the genus of ``self``. + + Let `t(C)` be the number of trivalent vertices, and let `r(C)` be + the number of unbounded edges of `C`. The genus of simple tropical + curve `C` is defined by the formula: + `g(C) = \frac{1}{2}t(C) - \frac{1}{2}r(C) + 1`. + + EXAMPLES:: + + sage: T = TropicalSemiring(QQ) + sage: R. = PolynomialRing(T) + sage: p1 = x^2 + y^2 + x*y + sage: p1.tropical_variety().genus() + 1 + sage: p2 = R(2)*x^2 + x*y + R(2)*y^2 + x + R(-1)*y + R(3) + sage: p2.tropical_variety().genus() + 0 + """ + if not self.is_simple(): + raise ValueError("tropical curve is not simple") + trivalent = 0 # number of trivalent vertices + for vectors in self.weight_vectors().values(): + if len(vectors) == 3: + trivalent += 1 + unbounded = 0 # number of unbounded edges + for component in self._hypersurface: + if len(component[1]) == 1: + unbounded += 1 + return trivalent//2 - unbounded//2 + 1 + + def contribution(self): + r""" + Return the contribution of ``self``. + + The contribution of a simple curve `C` is defined as the product + of the normalized areas of all triangles in the corresponding + dual subdivision. We just multiply positive integers attached to + the trivalent vertices. The contribution of a trivalent vertex + equals `w_1w_2|\det(v_1,v_2)|`, with `w_i` are the weights of + the adjacent edges and `v_i` are their weight vectors. That + formula is independent of the choice made because of the + balancing condition `w_1v_1+w_2v_2+w_3v_3=0`. + + EXAMPLES:: + + sage: T = TropicalSemiring(QQ) + sage: R. = PolynomialRing(T) + sage: p1 = R(2)*x^2 + x*y + R(2)*y^2 + x + R(-1)*y + R(3) + sage: p1.tropical_variety().contribution() + 1 + sage: p2 = R(-1/3)*x^2 + R(1)*x*y + R(1)*y^2 + R(-1/3)*x + R(1/3) + sage: p2.tropical_variety().contribution() + 16 + """ + if not self.is_simple(): + raise ValueError("tropical curve is not simple") + result = 1 + voc = self._components_of_vertices() + vov = self.weight_vectors() + for vertex in vov: + if len(vov[vertex]) == 3: + u1 = vov[vertex][0] + u2 = vov[vertex][1] + index1 = voc[vertex][0][0] + index2 = voc[vertex][1][0] + w1 = self._hypersurface[index1][2] + w2 = self._hypersurface[index2][2] + det = u1[0]*u2[1] - u1[1]*u2[0] + result *= w1 * w2 * abs(det) + return result + def _parameter_intervals(self): r""" Return the intervals of each component's parameter of ``self``. From f8e8bb2791932db717fd8a09b21dd2dab14310db Mon Sep 17 00:00:00 2001 From: Newtech66 Date: Thu, 22 Aug 2024 01:21:32 +0530 Subject: [PATCH 139/537] Construct from group action (complete, added to MolecularSpecies and PolynomialSpecies) --- src/sage/rings/species.py | 77 +++++++++++++++++++++++++-------------- 1 file changed, 49 insertions(+), 28 deletions(-) diff --git a/src/sage/rings/species.py b/src/sage/rings/species.py index 1dd265f3344..f632acf0372 100644 --- a/src/sage/rings/species.py +++ b/src/sage/rings/species.py @@ -510,12 +510,9 @@ def _element_constructor_(self, G, pi=None): pi = {1: G.domain()} else: raise ValueError("the assignment of sorts to the domain elements must be provided") - if any(len(set(v)) != len(v) for v in pi.values()): - raise ValueError("each sort must contain distinct elements") - pi = {k: set(v) for k, v in pi.items()} if not set(pi.keys()).issubset(range(1, self._k + 1)): raise ValueError(f"keys of pi must be in the range [1, {self._k}]") - if sum(len(p) for p in pi.values()) != len(G.domain()) or set.union(*[p for p in pi.values()]) != set(G.domain()): + if sum(len(p) for p in pi.values()) != len(G.domain()) or set(chain.from_iterable(pi.values())) != set(G.domain()): raise ValueError("values of pi must partition the domain of G") for orbit in G.orbits(): if not any(set(orbit).issubset(p) for p in pi.values()): @@ -591,8 +588,7 @@ def __contains__(self, x): raise ValueError(f"{G} must be a permutation group") if not set(pi.keys()).issubset(range(1, self._k + 1)): raise ValueError(f"keys of pi must be in the range [1, {self._k}]") - pi = {k: set(v) for k, v in pi.items()} - if sum(len(p) for p in pi.values()) != len(G.domain()) or set.union(*[p for p in pi.values()]) != set(G.domain()): + if sum(len(p) for p in pi.values()) != len(G.domain()) or set(chain.from_iterable(pi.values())) != set(G.domain()): raise ValueError("values of pi must partition the domain of G") for orbit in G.orbits(): if not any(set(orbit).issubset(p) for p in pi.values()): @@ -655,26 +651,25 @@ def _element_constructor_(self, G, pi=None): domain of ``G`` (if ``G`` is a permutation group) or `X` (if ``G``) is a pair ``(X, a)``. If `k=1`, `pi` can be omitted. - If `G = (X, a)`, then `X` should be a finite set and `a` an action - of `G` on `X`. + If `G = (X, a)`, then `X` should be a finite set and `a` a transitive + action of `G` on `X`. EXAMPLES:: - sage: P = PolynomialSpecies(["X", "Y"]) + sage: P = PolynomialSpecies(ZZ, ["X", "Y"]) sage: P(SymmetricGroup(4).young_subgroup([2, 2]), {1: [1,2], 2: [3,4]}) E_2(X)*E_2(Y) - sage: S = SymmetricGroup(4).young_subgroup([2, 2]) sage: X = SetPartitions(4, 2) sage: a = lambda g, x: SetPartition([[g(e) for e in b] for b in x]) sage: P((X, a), {1: [1,2], 2: [3,4]}) - E_2(X)*E_2(Y) + E_2(X*Y) + X^2*E_2(Y) + E_2(X)*Y^2 + X^2*E_2(Y) + X^2*Y^2 + E_2(X)*Y^2 + E_2(X)*E_2(Y) TESTS:: - sage: P = PolynomialSpecies(["X", "Y"]) + sage: P = PolynomialSpecies(ZZ, ["X", "Y"]) sage: M = P._indices - sage: M(CyclicPermutationGroup(4), {1: [1,2], 2:[3,4]}) + sage: M(CyclicPermutationGroup(4), {1: [1,2], 2: [3,4]}) Traceback (most recent call last): ... ValueError: For each orbit of Cyclic group of order 4 as a permutation group, all elements must belong to the same sort @@ -691,19 +686,17 @@ def _element_constructor_(self, G, pi=None): raise ValueError("the assignment of sorts to the domain elements must be provided") if not set(pi.keys()).issubset(range(1, self._k + 1)): raise ValueError(f"keys of pi must be in the range [1, {self._k}]") - pi = {k: set(v) for k, v in pi.items()} - if sum(len(p) for p in pi.values()) != len(G.domain()) or set.union(*[p for p in pi.values()]) != set(G.domain()): - raise ValueError("values of pi must partition the domain of G") + if sum(len(p) for p in pi.values()) != len(G.domain()) or set(chain.from_iterable(pi.values())) != set(G.domain()): + raise ValueError("values of pi must partition X") for orbit in G.orbits(): if not any(set(orbit).issubset(p) for p in pi.values()): raise ValueError(f"For each orbit of {G}, all elements must belong to the same sort") - domain_partition = G.disjoint_direct_product_decomposition() elm = self.one() for part in domain_partition: elm *= self.gen(self._project(G, pi, part)) return elm - # If not a permutation group, assume input is (X, a) + # Assume G is a tuple (X, a) X, a = G if pi is None: if self._k == 1: @@ -712,12 +705,17 @@ def _element_constructor_(self, G, pi=None): raise ValueError("the assignment of sorts to the domain elements must be provided") if not set(pi.keys()).issubset(range(1, self._k + 1)): raise ValueError(f"keys of pi must be in the range [1, {self._k}]") - pi = {k: set(v) for k, v in pi.items()} - if sum(len(p) for p in pi.values()) != len(G.domain()) or set.union(*[p for p in pi.values()]) != set(X): - raise ValueError("values of pi must partition the domain of G") - for orbit in G.orbits(): - if not any(set(orbit).issubset(p) for p in pi.values()): - raise ValueError(f"For each orbit of {G}, all elements must belong to the same sort") + # Make iteration over values of pi deterministic + pi = {k: list(v) for k, v in pi.items()} + # Create group + # TODO: Is this correct? + S = SymmetricGroup(list(chain.from_iterable(pi.values()))).young_subgroup([len(v) for v in pi.values()]) + H = PermutationGroup(S.gens(), action=a, domain=X) + if len(H.orbits()) > 1: + # Then it is not transitive + raise ValueError("Action is not transitive") + stabG = PermutationGroup([g for g in S.gens() if a(g, H.orbits()[0][0]) == H.orbits()[0][0]], domain=S.domain()) + return self(stabG, pi) @cached_method def one(self): @@ -1094,7 +1092,6 @@ def __init__(self, base_ring, names): element_class=self.Element, prefix='', bracket=False) self._k = len(names) - self._atomic_basis = basis_keys.indices() def degree_on_basis(self, m): r""" @@ -1112,16 +1109,40 @@ def _element_constructor_(self, G, pi=None): or a permutation group. - ``pi`` - a dict mapping sorts to iterables whose union is the domain. If `k=1`, `pi` can be omitted. + + If `G = (X, a)`, then `X` should be a finite set and `a` an action of + `G` on `X`. """ if parent(G) == self: if pi is not None: raise ValueError("cannot reassign sorts to a polynomial species") return G + if isinstance(G, PermutationGroup_generic): + if pi is None: + if self._k == 1: + return self._from_dict({self._indices(G): ZZ.one()}) + raise ValueError("the assignment of sorts to the domain elements must be provided") + return self._from_dict({self._indices(G, pi): ZZ.one()}) + # Assume G is a tuple (X, a) + X, a = G if pi is None: if self._k == 1: - return self._from_dict({self._indices(G): ZZ.one()}) - raise ValueError("the assignment of sorts to the domain elements must be provided") - return self._from_dict({self._indices(G, pi): ZZ.one()}) + pi = {1: X} + else: + raise ValueError("the assignment of sorts to the domain elements must be provided") + if not set(pi.keys()).issubset(range(1, self._k + 1)): + raise ValueError(f"keys of pi must be in the range [1, {self._k}]") + # Make iteration over values of pi deterministic + pi = {k: list(v) for k, v in pi.items()} + # Create group + # TODO: Is this correct? + S = SymmetricGroup(list(chain.from_iterable(pi.values()))).young_subgroup([len(v) for v in pi.values()]) + H = PermutationGroup(S.gens(), action=a, domain=X) + res = self.zero() + for orbit in H.orbits(): + stabG = PermutationGroup([g for g in S.gens() if a(g, orbit[0]) == orbit[0]], domain=S.domain()) + res += self._from_dict({self._indices(stabG, pi): ZZ.one()}) + return res @cached_method def one_basis(self): From 5c9e8d1b7ae9c0bf9786336a36c92b332cbc97fa Mon Sep 17 00:00:00 2001 From: Verrel Rievaldo Wijaya Date: Thu, 22 Aug 2024 03:10:17 +0700 Subject: [PATCH 140/537] Add ``weight_vectors`` in tropical surface --- src/sage/rings/semirings/tropical_variety.py | 137 +++++++++++++++++++ 1 file changed, 137 insertions(+) diff --git a/src/sage/rings/semirings/tropical_variety.py b/src/sage/rings/semirings/tropical_variety.py index df507b828cd..0a6c00349c6 100644 --- a/src/sage/rings/semirings/tropical_variety.py +++ b/src/sage/rings/semirings/tropical_variety.py @@ -952,6 +952,143 @@ def _repr_(self): Tropical surface of 0*x^4 + 0*z^2 """ return f"Tropical surface of {self._poly}" + + def weight_vectors(self): + r""" + Return the weight vectors for each edge of ``self``. + + Suppose `L` is an edge adjacent to the surface `S_1, ldots, S_k` + with respective weights `w_1, ldots, w_k`. This edge `L` has + a direction vector `d=[d_1,d_2,d_3]`. Each surface + `S_1, ldots, S_k` has a normal vector `n_1, \ldots, n_k`. + Make sure that the normal vector is scale to an integer vector + `n_k=(\alpha, \beta, \gamma)` such that + `\gcd(\alpha, \beta, \gamma)=1`. The weight vector of a surface + with respect to line `L` can be calculated with + `v_k=w_k \cdot (d\times n_k). These vectors will satisfy + the following balancing condition: + `\sum_{i=1}^k v_k = 0`. + + OUTPUT: + + A dictionary where the keys represent the vertices, and the values + are lists of vectors. + + EXAMPLES:: + + sage: T = TropicalSemiring(QQ) + sage: R. = PolynomialRing(T) + sage: p1 = x^2 + y^2 + z^3 + sage: tv1 = p1.tropical_variety() + sage: tv1.weight_vectors() + [[((3/2*t2, 3/2*t2, t2), {t2 < +Infinity}), + [(-2, -2, 6), (-9/2, 13/2, -3), (13/2, -9/2, -3)]]] + + sage: p2 = x + y + z + x^2 + R(1) + sage: tv2 = p2.tropical_variety() + sage: tv2.weight_vectors() + [[((t2, t2, t2), {0 <= t2, t2 <= 1}), [(-1, -1, 2), (-1, 2, -1), (2, -1, -1)]], + [((0, 0, t2), {0 <= t2}), [(-1, -1, 0), (0, -1, 0), (1, 2, 0)]], + [((1, 1, t2), {1 <= t2}), [(1, 1, 0), (0, -1, 0), (-1, 0, 0)]], + [((0, t2, 0), {0 <= t2}), [(1, 0, 1), (0, 0, 1), (-1, 0, -2)]], + [((1, t2, 1), {1 <= t2}), [(-1, 0, -1), (0, 0, 1), (1, 0, 0)]], + [((t1, 1, 1), {1 <= t1}), [(0, -1, -1), (0, 0, 1), (0, 1, 0)]], + [((t1, 2*t1, 2*t1), {t1 <= 0}), [(4, -1, -1), (-2, -4, 5), (-2, 5, -4)]]] + """ + from sage.symbolic.ring import SR + from sage.symbolic.relation import solve + from sage.calculus.functional import diff + from sage.arith.misc import gcd + from sage.rings.rational_field import QQ + from sage.modules.free_module_element import vector + + t = SR.var('t') + CI = self._components_intersection() + unique_line = set() + index_line = {} + line_comps = {} + index = 0 + + # Identify the distinct line of intersection and determine which + # components contain this line. + for i, lines in CI.items(): + for line in lines: + v1 = next(iter(line[1])).variables()[0] + eqn = line[0] + is_unique = True + for uniq in unique_line: + subs_index = -1 + for j in range(3): + if eqn[j] != uniq[j]: + subs_index = j + break + if subs_index == -1: + new_line = eqn + is_unique = False + break + eq1 = eqn[subs_index].subs(v1 == t) + eq2 = uniq[subs_index] + temp_sol = solve(eq1 == eq2, t) + if temp_sol: + temp_sol = temp_sol[0].rhs() + if not temp_sol.is_numeric(): + new_line = [] + for l in eqn: + new_line.append(l.subs(v1 == temp_sol)) + if tuple(new_line) in unique_line: + is_unique = False + break + if is_unique: + unique_line.add(eqn) + index_line[index] = line + line_comps[index] = [i] + index += 1 + else: + match_key = [k for k, v in index_line.items() if v[0] == tuple(new_line)][0] + line_comps[match_key].append(i) + + WV = {i: [] for i in range(len(line_comps))} + for k, v in line_comps.items(): + + # Calculate direction vector of the line + dir_vec = [] + line = index_line[k][0] + for l in line: + if l.variables(): + vpar = l.variables()[0] + break + for l in line: + dir_vec.append(QQ(diff(l, vpar))) + dir_vec = vector(dir_vec) + + # Calculate the outgoing normal vector of each surface in the + # direction of the line + for i in v: + surface = self._hypersurface[i][0] + vec1, vec2 = [], [] + for s in surface: + vec1.append(QQ(diff(s, self._vars[0]))) + vec2.append(QQ(diff(s, self._vars[1]))) + vector1 = vector(vec1) + vector2 = vector(vec2) + nor_vec = vector1.cross_product(vector2) + nor_vec *= 1/gcd(nor_vec) + weight_vec = nor_vec.cross_product(dir_vec) + weight_vec = vector([QQ(w) for w in weight_vec]) + order = self._hypersurface[i][2] + weight_vec *= order + WV[k].append(weight_vec) + for i in range(len(WV[k])): + test_vectors = [v for v in WV[k]] + test_vectors[i] = -test_vectors[i] + if sum(test_vectors) == vector([0,0,0]): + WV[k] = test_vectors + break + + result = [] + for k, v in WV.items(): + result.append([index_line[k], v]) + return result class TropicalCurve(TropicalVariety): From 010149c3e2c97d0df868787cb1b66c7ecd72549b Mon Sep 17 00:00:00 2001 From: Verrel Rievaldo Wijaya Date: Thu, 22 Aug 2024 22:43:58 +0700 Subject: [PATCH 141/537] Add ``PLOT`` section in dual subdvision and add one reference --- src/doc/en/reference/references/index.rst | 3 ++ src/sage/rings/semirings/tropical_variety.py | 43 +++++++++++++++++--- 2 files changed, 41 insertions(+), 5 deletions(-) diff --git a/src/doc/en/reference/references/index.rst b/src/doc/en/reference/references/index.rst index d7fe85422ba..88702eecdc7 100644 --- a/src/doc/en/reference/references/index.rst +++ b/src/doc/en/reference/references/index.rst @@ -4648,6 +4648,9 @@ REFERENCES: University Press, New York, 1995, With contributions by A. Zelevinsky, Oxford Science Publications. +.. [Mac2015] Diane Maclagan and Bernd Sturmfels, *Introduction to + Tropical Geometry*, American Mathematical Society, 2015. + .. [MagmaHGM] *Hypergeometric motives* in Magma, http://magma.maths.usyd.edu.au/~watkins/papers/HGM-chapter.pdf diff --git a/src/sage/rings/semirings/tropical_variety.py b/src/sage/rings/semirings/tropical_variety.py index 0a6c00349c6..25df68ce78d 100644 --- a/src/sage/rings/semirings/tropical_variety.py +++ b/src/sage/rings/semirings/tropical_variety.py @@ -12,6 +12,7 @@ REFERENCES: - [Bru2014]_ +- [Mac2015]_ - [Fil2017]_ """ @@ -555,6 +556,17 @@ def dual_subdivision(self): sage: G.plot(vertex_labels=False) Graphics object consisting of 10 graphics primitives + .. PLOT:: + :width: 300 px + + T = TropicalSemiring(QQ, use_min=False) + R = PolynomialRing(T, ('x,y')) + x, y = R.gen(), R.gen(1) + p1 = R(3) + R(2)*x + R(2)*y + R(3)*x*y + x**2 + y**2 + tv = p1.tropical_variety() + G = tv.dual_subdivision() + sphinx_plot(G.plot(vertex_labels=False)) + Dual subdivision of a tropical surface:: sage: T = TropicalSemiring(QQ) @@ -565,6 +577,17 @@ def dual_subdivision(self): sage: G.plot3d() Graphics3d Object + .. PLOT:: + :width: 300 px + + T = TropicalSemiring(QQ, use_min=False) + R = PolynomialRing(T, ('x,y,z')) + x, y, z = R.gen(), R.gen(1), R.gen(2) + p1 = x + y + z + x**2 + R(1) + tv = p1.tropical_variety() + G = tv.dual_subdivision() + sphinx_plot(G.plot3d()) + Dual subdivision of a tropical hypersurface:: sage: T = TropicalSemiring(QQ) @@ -575,6 +598,16 @@ def dual_subdivision(self): sage: G.plot(vertex_labels=False) Graphics object consisting of 11 graphics primitives + .. PLOT:: + :width: 300 px + + T = TropicalSemiring(QQ, use_min=False) + R = PolynomialRing(T, ('a,b,c,d')) + a, b, c, d = R.gen(), R.gen(1), R.gen(2), R.gen(3) + p1 = a**2 + b**2 + c**2 + d**2 + a*b*c*d + tv = p1.tropical_variety() + G = tv.dual_subdivision() + sphinx_plot(G.plot(vertex_labels=False)) """ from sage.graphs.graph import Graph @@ -965,9 +998,8 @@ def weight_vectors(self): `n_k=(\alpha, \beta, \gamma)` such that `\gcd(\alpha, \beta, \gamma)=1`. The weight vector of a surface with respect to line `L` can be calculated with - `v_k=w_k \cdot (d\times n_k). These vectors will satisfy - the following balancing condition: - `\sum_{i=1}^k v_k = 0`. + `v_k=d\times n_k. These vectors will satisfy the following + balancing condition: `\sum_{i=1}^k w_k v_k = 0`. OUTPUT: @@ -1287,8 +1319,9 @@ def weight_vectors(self): sage: p1.tropical_variety().weight_vectors() {(1, -1/2): [(0, 1), (-1, -2), (1, 1)], (7/6, -1/3): [(-1, -1), (0, 1), (1, 0)]} - sage: p3 = R(2)*x^2 + x*y + R(2)*y^2 + x + R(-1)*y + R(3) - sage: p3.tropical_variety().weight_vectors() + + sage: p2 = R(2)*x^2 + x*y + R(2)*y^2 + x + R(-1)*y + R(3) + sage: p2.tropical_variety().weight_vectors() {(-2, 0): [(-1, -1), (0, 1), (1, 0)], (-1, -3): [(-1, -1), (0, 1), (1, 0)], (-1, 0): [(-1, 0), (0, -1), (1, 1)], From 238eae19a3d13e685623c031f707a057100c159f Mon Sep 17 00:00:00 2001 From: Newtech66 Date: Fri, 23 Aug 2024 02:13:01 +0530 Subject: [PATCH 142/537] Edits to error checking and messages --- src/sage/rings/species.py | 39 ++++++++++++++------------------------- 1 file changed, 14 insertions(+), 25 deletions(-) diff --git a/src/sage/rings/species.py b/src/sage/rings/species.py index f632acf0372..e58cd441dc4 100644 --- a/src/sage/rings/species.py +++ b/src/sage/rings/species.py @@ -511,12 +511,12 @@ def _element_constructor_(self, G, pi=None): else: raise ValueError("the assignment of sorts to the domain elements must be provided") if not set(pi.keys()).issubset(range(1, self._k + 1)): - raise ValueError(f"keys of pi must be in the range [1, {self._k}]") + raise ValueError(f"keys of pi (={pi.keys()}) must be in the range [1, {self._k}]") if sum(len(p) for p in pi.values()) != len(G.domain()) or set(chain.from_iterable(pi.values())) != set(G.domain()): - raise ValueError("values of pi must partition the domain of G") + raise ValueError(f"values of pi (={pi.values()}) must partition the domain of G (={G.domain()})") for orbit in G.orbits(): if not any(set(orbit).issubset(p) for p in pi.values()): - raise ValueError(f"For each orbit of {G}, all elements must belong to the same sort") + raise ValueError(f"All elements of orbit {orbit} must have the same sort") dis_elm = ConjugacyClassesOfDirectlyIndecomposableSubgroups()(G) mapping = {v: i for i, v in enumerate(G.domain(), 1)} mapping2 = PermutationGroupElement([mapping[e] for o in sorted(G.orbits(), key=len, reverse=True) @@ -654,17 +654,6 @@ def _element_constructor_(self, G, pi=None): If `G = (X, a)`, then `X` should be a finite set and `a` a transitive action of `G` on `X`. - EXAMPLES:: - - sage: P = PolynomialSpecies(ZZ, ["X", "Y"]) - sage: P(SymmetricGroup(4).young_subgroup([2, 2]), {1: [1,2], 2: [3,4]}) - E_2(X)*E_2(Y) - - sage: X = SetPartitions(4, 2) - sage: a = lambda g, x: SetPartition([[g(e) for e in b] for b in x]) - sage: P((X, a), {1: [1,2], 2: [3,4]}) - X^2*E_2(Y) + X^2*Y^2 + E_2(X)*Y^2 + E_2(X)*E_2(Y) - TESTS:: sage: P = PolynomialSpecies(ZZ, ["X", "Y"]) @@ -684,13 +673,6 @@ def _element_constructor_(self, G, pi=None): pi = {1: G.domain()} else: raise ValueError("the assignment of sorts to the domain elements must be provided") - if not set(pi.keys()).issubset(range(1, self._k + 1)): - raise ValueError(f"keys of pi must be in the range [1, {self._k}]") - if sum(len(p) for p in pi.values()) != len(G.domain()) or set(chain.from_iterable(pi.values())) != set(G.domain()): - raise ValueError("values of pi must partition X") - for orbit in G.orbits(): - if not any(set(orbit).issubset(p) for p in pi.values()): - raise ValueError(f"For each orbit of {G}, all elements must belong to the same sort") domain_partition = G.disjoint_direct_product_decomposition() elm = self.one() for part in domain_partition: @@ -703,8 +685,6 @@ def _element_constructor_(self, G, pi=None): pi = {1: X} else: raise ValueError("the assignment of sorts to the domain elements must be provided") - if not set(pi.keys()).issubset(range(1, self._k + 1)): - raise ValueError(f"keys of pi must be in the range [1, {self._k}]") # Make iteration over values of pi deterministic pi = {k: list(v) for k, v in pi.items()} # Create group @@ -1112,6 +1092,17 @@ def _element_constructor_(self, G, pi=None): If `G = (X, a)`, then `X` should be a finite set and `a` an action of `G` on `X`. + + EXAMPLES:: + + sage: P = PolynomialSpecies(ZZ, ["X", "Y"]) + sage: P(SymmetricGroup(4).young_subgroup([2, 2]), {1: [1,2], 2: [3,4]}) + E_2(X)*E_2(Y) + + sage: X = SetPartitions(4, 2) + sage: a = lambda g, x: SetPartition([[g(e) for e in b] for b in x]) + sage: P((X, a), {1: [1,2], 2: [3,4]}) + X^2*E_2(Y) + X^2*Y^2 + E_2(X)*Y^2 + E_2(X)*E_2(Y) """ if parent(G) == self: if pi is not None: @@ -1130,8 +1121,6 @@ def _element_constructor_(self, G, pi=None): pi = {1: X} else: raise ValueError("the assignment of sorts to the domain elements must be provided") - if not set(pi.keys()).issubset(range(1, self._k + 1)): - raise ValueError(f"keys of pi must be in the range [1, {self._k}]") # Make iteration over values of pi deterministic pi = {k: list(v) for k, v in pi.items()} # Create group From 7a38ab771d4b9f9b279de875bc47992b21970451 Mon Sep 17 00:00:00 2001 From: Newtech66 Date: Fri, 23 Aug 2024 02:26:52 +0530 Subject: [PATCH 143/537] More minor changes --- src/sage/rings/species.py | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/src/sage/rings/species.py b/src/sage/rings/species.py index e58cd441dc4..595582c4863 100644 --- a/src/sage/rings/species.py +++ b/src/sage/rings/species.py @@ -587,12 +587,12 @@ def __contains__(self, x): if not isinstance(G, PermutationGroup_generic): raise ValueError(f"{G} must be a permutation group") if not set(pi.keys()).issubset(range(1, self._k + 1)): - raise ValueError(f"keys of pi must be in the range [1, {self._k}]") + raise ValueError(f"keys of pi (={pi.keys()}) must be in the range [1, {self._k}]") if sum(len(p) for p in pi.values()) != len(G.domain()) or set(chain.from_iterable(pi.values())) != set(G.domain()): - raise ValueError("values of pi must partition the domain of G") + raise ValueError(f"values of pi (={pi.values()}) must partition the domain of G (={G.domain()})") for orbit in G.orbits(): if not any(set(orbit).issubset(p) for p in pi.values()): - raise ValueError(f"For each orbit of {G}, all elements must belong to the same sort") + raise ValueError(f"All elements of orbit {orbit} must have the same sort") return len(G.disjoint_direct_product_decomposition()) <= 1 def _repr_(self): @@ -685,11 +685,12 @@ def _element_constructor_(self, G, pi=None): pi = {1: X} else: raise ValueError("the assignment of sorts to the domain elements must be provided") - # Make iteration over values of pi deterministic - pi = {k: list(v) for k, v in pi.items()} + L = [None for _ in range(self._k)] + for k, v in pi.items(): + L[k - 1] = list(v) # Create group # TODO: Is this correct? - S = SymmetricGroup(list(chain.from_iterable(pi.values()))).young_subgroup([len(v) for v in pi.values()]) + S = SymmetricGroup(list(chain.from_iterable(L))).young_subgroup([len(v) for v in L]) H = PermutationGroup(S.gens(), action=a, domain=X) if len(H.orbits()) > 1: # Then it is not transitive @@ -906,7 +907,7 @@ def hadamard_product(self, other): """ P = self.parent() if P is not other.parent(): - raise ValueError("the factors of a Hadamard product must be the same.") + raise ValueError("the factors of a Hadamard product must be the same") Pn = PolynomialSpecies(ZZ, P._indices._names) if self._mc != other._mc: @@ -929,6 +930,12 @@ def hadamard_product(self, other): res += Pn(PermutationGroup(gap_group=F, domain=self.domain()), dpart) return res + def point(self): + r""" + Return the pointing of ``self``. + """ + pass + def inner_sum(self, base_ring, names, *args): r""" Compute the inner sum of exercise 2.6.16 of BLL book. @@ -1122,10 +1129,12 @@ def _element_constructor_(self, G, pi=None): else: raise ValueError("the assignment of sorts to the domain elements must be provided") # Make iteration over values of pi deterministic - pi = {k: list(v) for k, v in pi.items()} + L = [None for _ in range(self._k)] + for k, v in pi.items(): + L[k - 1] = list(v) # Create group # TODO: Is this correct? - S = SymmetricGroup(list(chain.from_iterable(pi.values()))).young_subgroup([len(v) for v in pi.values()]) + S = SymmetricGroup(list(chain.from_iterable(L))).young_subgroup([len(v) for v in L]) H = PermutationGroup(S.gens(), action=a, domain=X) res = self.zero() for orbit in H.orbits(): From 3f1641af2a3baeeaeb8c27348a9df02043d7918b Mon Sep 17 00:00:00 2001 From: Verrel Rievaldo Wijaya Date: Fri, 23 Aug 2024 16:41:21 +0700 Subject: [PATCH 144/537] Add ``TESTS`` to genus and contribution --- src/sage/rings/semirings/tropical_variety.py | 24 ++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/src/sage/rings/semirings/tropical_variety.py b/src/sage/rings/semirings/tropical_variety.py index 25df68ce78d..f31496ee1fe 100644 --- a/src/sage/rings/semirings/tropical_variety.py +++ b/src/sage/rings/semirings/tropical_variety.py @@ -1432,9 +1432,19 @@ def genus(self): sage: p2 = R(2)*x^2 + x*y + R(2)*y^2 + x + R(-1)*y + R(3) sage: p2.tropical_variety().genus() 0 + + TESTS:: + + sage: T = TropicalSemiring(QQ) + sage: R. = PolynomialRing(T) + sage: p1 = R(0) + y + x^2*y + x*y^2 + sage: p1.tropical_variety().genus() + Traceback (most recent call last): + ... + ValueError: Tropical curve of 0*x^2*y + 0*x*y^2 + 0*y + 0 is not simple """ if not self.is_simple(): - raise ValueError("tropical curve is not simple") + raise ValueError(f"{self} is not simple") trivalent = 0 # number of trivalent vertices for vectors in self.weight_vectors().values(): if len(vectors) == 3: @@ -1468,9 +1478,19 @@ def contribution(self): sage: p2 = R(-1/3)*x^2 + R(1)*x*y + R(1)*y^2 + R(-1/3)*x + R(1/3) sage: p2.tropical_variety().contribution() 16 + + TESTS:: + + sage: T = TropicalSemiring(QQ) + sage: R. = PolynomialRing(T) + sage: p1 = R(0) + x + x^2*y + x*y^2 + sage: p1.tropical_variety().contribution() + Traceback (most recent call last): + ... + ValueError: Tropical curve of 0*x^2*y + 0*x*y^2 + 0*x + 0 is not simple """ if not self.is_simple(): - raise ValueError("tropical curve is not simple") + raise ValueError(f"{self} is not simple") result = 1 voc = self._components_of_vertices() vov = self.weight_vectors() From 4795639815688cfc0200da52c14f80d269471a10 Mon Sep 17 00:00:00 2001 From: Verrel Rievaldo Wijaya Date: Fri, 23 Aug 2024 21:55:56 +0700 Subject: [PATCH 145/537] Small fix on style and white spaces --- src/sage/rings/semirings/tropical_variety.py | 28 ++++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/sage/rings/semirings/tropical_variety.py b/src/sage/rings/semirings/tropical_variety.py index f31496ee1fe..560b8b76a33 100644 --- a/src/sage/rings/semirings/tropical_variety.py +++ b/src/sage/rings/semirings/tropical_variety.py @@ -531,7 +531,7 @@ def update_result(result): points[i] = new_eq update_result(result) return result - + def dual_subdivision(self): """ Return the dual subdivision of ``self``. @@ -935,7 +935,7 @@ def plot(self, color='random'): p1 = x + z sphinx_plot(p1.tropical_variety().plot()) - A tropical surface with multiple cell that exhibit complex and + A tropical surface with multiple cells that exhibit complex and intriguing geometric structures:: sage: p2 = x^2 + x + y + z + R(1) @@ -985,7 +985,7 @@ def _repr_(self): Tropical surface of 0*x^4 + 0*z^2 """ return f"Tropical surface of {self._poly}" - + def weight_vectors(self): r""" Return the weight vectors for each edge of ``self``. @@ -1058,7 +1058,7 @@ def weight_vectors(self): new_line = eqn is_unique = False break - eq1 = eqn[subs_index].subs(v1 == t) + eq1 = eqn[subs_index].subs(**{str(v1): t}) eq2 = uniq[subs_index] temp_sol = solve(eq1 == eq2, t) if temp_sol: @@ -1066,7 +1066,7 @@ def weight_vectors(self): if not temp_sol.is_numeric(): new_line = [] for l in eqn: - new_line.append(l.subs(v1 == temp_sol)) + new_line.append(l.subs(**{str(v1): temp_sol})) if tuple(new_line) in unique_line: is_unique = False break @@ -1247,11 +1247,11 @@ def _components_of_vertices(self): OUTPUT: - A dictionary where the keys represent the vertices, and the values - are lists of tuples. Each tuple consists of the index of an - adjacent edge (component) `e_i` and a string indicating the - directionality of `e_i` relative to the vertex. The string is - either "pos" or "neg", specifying whether it is positive or + A dictionary where the keys represent the vertices, and the + values are lists of tuples. Each tuple consists of the index + of an adjacent edge (component) `e_i` and a string indicating + the directionality of `e_i` relative to the vertex. The string + is either "pos" or "neg", specifying whether it is positive or negative. EXAMPLES:: @@ -1277,15 +1277,15 @@ def _components_of_vertices(self): lower = interval[0].lower() upper = interval[0].upper() if lower != -infinity: - x = parametric_function[0].subs(v==lower) - y = parametric_function[1].subs(v==lower) + 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, 'pos')] else: comp_vert[(x,y)].append((i, 'pos')) if upper != infinity: - x = parametric_function[0].subs(v==upper) - y = parametric_function[1].subs(v==upper) + 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, 'neg')] else: From f1e10fc6439eb494ee2b34f92763841c7f7e5dca Mon Sep 17 00:00:00 2001 From: Newtech66 Date: Sun, 25 Aug 2024 03:09:29 +0530 Subject: [PATCH 146/537] Added functorial composition for univariate molecular species --- src/sage/rings/species.py | 79 +++++++++++++++++++++++++++++++++++---- 1 file changed, 72 insertions(+), 7 deletions(-) diff --git a/src/sage/rings/species.py b/src/sage/rings/species.py index 595582c4863..3b135516a5d 100644 --- a/src/sage/rings/species.py +++ b/src/sage/rings/species.py @@ -4,6 +4,7 @@ from sage.categories.infinite_enumerated_sets import InfiniteEnumeratedSets from sage.categories.monoids import Monoids from sage.categories.sets_with_grading import SetsWithGrading +from sage.categories.cartesian_product import cartesian_product from sage.combinat.free_module import CombinatorialFreeModule from sage.combinat.integer_vector import IntegerVectors from sage.groups.perm_gps.constructor import PermutationGroupElement @@ -661,7 +662,7 @@ def _element_constructor_(self, G, pi=None): sage: M(CyclicPermutationGroup(4), {1: [1,2], 2: [3,4]}) Traceback (most recent call last): ... - ValueError: For each orbit of Cyclic group of order 4 as a permutation group, all elements must belong to the same sort + ValueError: All elements of orbit (1, 2, 3, 4) must have the same sort """ if parent(G) == self: if pi is not None: @@ -930,11 +931,75 @@ def hadamard_product(self, other): res += Pn(PermutationGroup(gap_group=F, domain=self.domain()), dpart) return res - def point(self): + def functorial_composition(self, other): r""" - Return the pointing of ``self``. + Return the functorial composition of ``self`` with ``other``. + Currrent this only works for univariate molecular species only. + + TESTS:: + + sage: P = PolynomialSpecies(ZZ, ["X"]) + sage: M = P._indices + sage: E = [None] + [M(SymmetricGroup(n)) for n in range(1, 4)] + sage: E[2].functorial_composition(E[2]) + E_4 + sage: E[1].functorial_composition(E[1]) + X + sage: E[1].functorial_composition(E[2]) + E_2 + sage: E[2].functorial_composition(E[1]) + X + sage: E[3].functorial_composition(E[2]) + E_8 + sage: E[2].functorial_composition(E[3]) + E_9 """ - pass + if not isinstance(other, MolecularSpecies.Element): + raise ValueError(f"{other} must be a molecular species") + if other.parent()._k > 1: + raise ValueError(f"{other} must be univariate") + if self.parent()._k > 1: + raise ValueError(f"{self} must be univariate") + + gens = [] + dpart = {1: range(1, other.grade() ** self.grade() + 1)} + + def to_number(l): + B = ZZ.one() # ZZ.one or 1? + R = 0 # Just 0 is fine? + for e in reversed(l): + R += e * B + B *= other.grade() + return R + + # it is a base other.grade() representation + for pre in cartesian_product([range(other.grade())]*self.grade()): + pre_n = to_number(pre) + 1 + # gens from self + for gen in self._group.gens(): + # gen swaps around the numbers in pre + im = gen(list(pre)) + im_n = to_number(im) + 1 + if pre_n == im_n: + continue + gens.append([tuple([pre_n, im_n])]) + print('after self',gens) + + # gens from other + for gen in other._group.gens(): + for pre in cartesian_product([range(other.grade())]*self.grade()): + pre_n = to_number(pre) + 1 + for i in range(self.grade()): + im_n = pre_n - pre[-i-1] * other.grade() ** i + (gen(pre[-i-1] + 1) - 1) * other.grade() ** i + if pre_n == im_n: + continue + gens.append([tuple([pre_n, im_n])]) + print('after others',gens) + + G = PermutationGroup(gens,domain=range(1, other.grade() ** self.grade() + 1)) + print('G',G) + print('dompart',dpart) + return other.parent()(G, dpart) def inner_sum(self, base_ring, names, *args): r""" @@ -1014,17 +1079,17 @@ def __call__(self, *args): gens = [] # TODO: What happens if in F(G), G has a constant part? E(1+X)? - Mlist = [None for _ in range(self._group.degree())] + Mlist = [None for _ in range(self.grade())] for i, v in enumerate(self._dompart): for k in v: Mlist[k - 1] = args[i] - starts = list(accumulate([M._group.degree() for M in Mlist], initial=0)) + starts = list(accumulate([M.grade() for M in Mlist], initial=0)) # gens from self for gen in self._group.gens(): newgen = [] for cyc in gen.cycle_tuples(): - for k in range(1, Mlist[cyc[0] - 1]._group.degree() + 1): + for k in range(1, Mlist[cyc[0] - 1].grade() + 1): newgen.append(tuple(k + starts[i - 1] for i in cyc)) gens.append(newgen) From a601cbdd44670ab8c3de1d08d044ab7a9b4717cb Mon Sep 17 00:00:00 2001 From: Verrel Rievaldo Wijaya Date: Sun, 25 Aug 2024 13:47:40 +0700 Subject: [PATCH 147/537] Refactor ``vertices`` in tropical curve --- src/sage/rings/semirings/tropical_variety.py | 37 ++++++-------------- 1 file changed, 10 insertions(+), 27 deletions(-) diff --git a/src/sage/rings/semirings/tropical_variety.py b/src/sage/rings/semirings/tropical_variety.py index 560b8b76a33..03e961623d4 100644 --- a/src/sage/rings/semirings/tropical_variety.py +++ b/src/sage/rings/semirings/tropical_variety.py @@ -265,7 +265,7 @@ def __init__(self, poly): temp_order.append(order) temp_keys.append(keys) - # Changing all the operator symbol to be <= or >= + # Changing all the operator's symbol to <= or >= self._keys = [] components = [] dim_param = 0 @@ -1223,25 +1223,9 @@ def vertices(self): """ if len(self._hypersurface) < 3: return set() + return set(self._vertices_components().keys()) - vertices = set() - for i, component in enumerate(self._hypersurface): - parametric_function = component[0] - var = component[1][0].variables()[0] - interval = self._parameter_intervals()[i] - lower = interval[0].lower() - upper = interval[0].upper() - if lower != -infinity: - x = parametric_function[0].subs(**{str(var): lower}) - y = parametric_function[1].subs(**{str(var): lower}) - vertices.add((x,y)) - if upper != infinity: - x = parametric_function[0].subs(**{str(var): upper}) - y = parametric_function[1].subs(**{str(var): upper}) - vertices.add((x,y)) - return vertices - - def _components_of_vertices(self): + def _vertices_components(self): """ Return the index of components adjacent to each vertex of ``self``. @@ -1259,10 +1243,10 @@ def _components_of_vertices(self): sage: T = TropicalSemiring(QQ) sage: R. = PolynomialRing(T) sage: p1 = R(0) + x + y + x*y + x^2*y + x*y^2 - sage: p1.tropical_variety()._components_of_vertices() + sage: p1.tropical_variety()._vertices_components() {(0, 0): [(0, 'pos'), (1, 'pos'), (2, 'pos'), (3, 'neg'), (4, 'neg')]} sage: p2 = R(2)*x^2 + x*y + R(2)*y^2 + x + R(-1)*y + R(3) - sage: p2.tropical_variety()._components_of_vertices() + sage: p2.tropical_variety()._vertices_components() {(-2, 0): [(0, 'neg'), (1, 'pos'), (3, 'pos')], (-1, -3): [(2, 'neg'), (4, 'pos'), (5, 'pos')], (-1, 0): [(3, 'neg'), (4, 'neg'), (6, 'pos')], @@ -1329,13 +1313,12 @@ def weight_vectors(self): """ from sage.calculus.functional import diff from sage.arith.misc import gcd - from sage.rings.rational_field import QQ from sage.modules.free_module_element import vector - if not self._components_of_vertices(): + if not self._vertices_components(): return {} - # finding the base vector in the direction of each edges + # Finding the base vector in the direction of each edge temp_vectors = [] par = self._hypersurface[0][1][0].variables()[0] for comp in self._hypersurface: @@ -1344,8 +1327,8 @@ def weight_vectors(self): multiplier = gcd(QQ(dx), QQ(dy)) temp_vectors.append(vector([dx/multiplier, dy/multiplier])) - # calculate the weight vectors of each vertex - cov = self._components_of_vertices() + # Calculate the weight vectors of each vertex + cov = self._vertices_components() result = {} for vertex in cov: vectors = [] @@ -1492,7 +1475,7 @@ def contribution(self): if not self.is_simple(): raise ValueError(f"{self} is not simple") result = 1 - voc = self._components_of_vertices() + voc = self._vertices_components() vov = self.weight_vectors() for vertex in vov: if len(vov[vertex]) == 3: From 2e8592c1e6c487867567797bc17828debb3cd230 Mon Sep 17 00:00:00 2001 From: Verrel Rievaldo Wijaya Date: Sun, 25 Aug 2024 18:49:19 +0700 Subject: [PATCH 148/537] Move ``weight_vectors`` from ``TropicalSurface`` to ``TropicalVariety`` --- .../rings/semirings/tropical_mpolynomial.py | 2 +- src/sage/rings/semirings/tropical_variety.py | 354 +++++++++++------- 2 files changed, 211 insertions(+), 145 deletions(-) diff --git a/src/sage/rings/semirings/tropical_mpolynomial.py b/src/sage/rings/semirings/tropical_mpolynomial.py index a482e097f89..50b15f45776 100644 --- a/src/sage/rings/semirings/tropical_mpolynomial.py +++ b/src/sage/rings/semirings/tropical_mpolynomial.py @@ -284,7 +284,7 @@ def plot3d(self, color='random'): T = self.parent().base() R = self.base_ring().base_ring() - # Finding the point of curve that touch the edge of the axes + # Find the point of curve that touch the edge of the axes for comp in tv.components(): if len(comp[1]) == 1: valid_int = RealSet(comp[1][0]) diff --git a/src/sage/rings/semirings/tropical_variety.py b/src/sage/rings/semirings/tropical_variety.py index 03e961623d4..fad657ee871 100644 --- a/src/sage/rings/semirings/tropical_variety.py +++ b/src/sage/rings/semirings/tropical_variety.py @@ -27,9 +27,11 @@ # **************************************************************************** from sage.structure.sage_object import SageObject -from sage.rings.infinity import infinity 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""" A tropical variety in `\RR^n`. @@ -478,6 +480,7 @@ def update_result(result): sol_param_sim.add(eqn.lhs() >= eqn.rhs()) else: sol_param_sim.add(sol) + # Checking there are no conditions with the same variables # that use the <= and >= operators simultaneously unique_sol_param = set() @@ -627,6 +630,205 @@ def dual_subdivision(self): G.layout("spring", save_pos=True) return G + def weight_vectors(self): + r""" + Return the weight vectors for each unique intesection of + components of ``self``. + + Assume ``self`` is a `n`-dimensional tropical variety. + Suppose `L` is an intersection adjacent to the components + `S_1, ldots, S_k` with respective weights `w_1, ldots, w_k`. + This `L` is a linear structure in `\RR^{n-1}` and has `n-1` + direction vectors `d_1,d_2,\dots, d_{n-1}`. Each component + `S_1, ldots, S_k` has a normal vector `n_1, \ldots, n_k`. + Make sure that the normal vector is scale to an integer vector + such that the greatest common divisor of its elements is 1. + + The weight vector of a component `S_i` with respect to `L` + can be found by calculating the cross product between direction + vectors of `L` and normal vector `n_i`.These vectors will + satisfy the following balancing condition: + `\sum_{i=1}^k w_k v_k = 0`. + + OUTPUT: + + A tuple of two dictionaries: + - The first dictionary contains equations representing the + intersections. + - The second dictionary contains lists of vectors. + + EXAMPLES: + + Weight vectors of tropical surface:: + + sage: T = TropicalSemiring(QQ) + sage: R. = PolynomialRing(T) + sage: p = x^2 + R(-1)*y + z + R(1) + sage: tv = p.tropical_variety() + sage: tv.weight_vectors() + ({0: ((1/2*u2, u2 + 1, u2), {u2 <= 1}), + 1: ((1/2, 2, u2), {1 <= u2}), + 2: ((1/2, u2, 1), {2 <= u2}), + 3: ((u1, 2, 1), {(1/2) <= u1})}, + {0: [(1, 2, -5/2), (1, -5/2, 2), (-2, 1/2, 1/2)], + 1: [(-1, -2, 0), (0, 2, 0), (1, 0, 0)], + 2: [(1, 0, 2), (0, 0, -2), (-1, 0, 0)], + 3: [(0, 1, 1), (0, 0, -1), (0, -1, 0)]}) + + Weight vectors of tropical hypersurface:: + + sage: T = TropicalSemiring(QQ) + sage: R. = PolynomialRing(T) + sage: p1 = R(2)*a*b + R(3)*a*c + R(-1)*c^2 + R(-1/3)*a*d + sage: tv = p1.tropical_variety() + sage: tv.weight_vectors() + ({0: ((u1, u3 - 7/3, u3 - 10/3, u3), {u1 <= u3 - 22/3}), + 1: ((u2 - 4, u2 + 1, u2, u3), {u2 <= u3 - 10/3}), + 2: ((2*u1 - u3 - 2/3, u3 - 7/3, u1, u3), {u3 - 10/3 <= u1}), + 3: ((u3 - 22/3, u2, u3 - 10/3, u3), {u3 - 7/3 <= u2})}, + {0: [(0, 1, 1, -2), (0, 1, -2, 1), (0, -2, 1, 1)], + 1: [(-2, 1, 1, 0), (3, -3, 0, 0), (-1, 2, -1, 0)], + 2: [(-1, 5, 2, -6), (2, 1, -4, 1), (-1, -6, 2, 5)], + 3: [(-1, 0, -1, 2), (-2, 0, 1, 1), (3, 0, 0, -3)]}) + """ + from sage.symbolic.ring import SR + from sage.symbolic.relation import solve + from sage.calculus.functional import diff + from sage.arith.misc import gcd + from sage.matrix.constructor import matrix + from sage.modules.free_module_element import vector, zero_vector + + 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)} + CI = self._components_intersection() + unique_line = set() + index_line = {} + line_comps = {} + index = 0 + + # Find the unique intersection between multiple components and + # the indices of the components containing this intersection. + for i, lines in CI.items(): + for line in lines: + eqn = line[0] + is_unique = True + for uniq in unique_line: + subs_index = -1 + for j in range(dim): + if eqn[j] != uniq[j]: + subs_index = j + break + if subs_index == -1: + new_line = eqn + is_unique = False + break + subs_dict = {} + while len(subs_dict) != dim-2 and subs_index < dim: + eq1 = eqn[subs_index].subs(subs_dict) + vib = None + for unk in eq1.variables(): + if unk not in subs_dict: + if unk in t_vars: + vib = unk + break + if vib: + eq1 = eq1.subs(**{str(vib): t}) + eq2 = uniq[subs_index] + temp_sol = solve(eq1 == eq2, t) + if temp_sol: + temp_sol = temp_sol[0].rhs() + if not temp_sol.is_numeric(): + subs_dict[vib] = temp_sol + subs_index += 1 + if subs_dict: + new_line = [] + for l in eqn: + for key, value in subs_dict.items(): + l = l.subs(key == value) + new_line.append(l) + if tuple(new_line) in unique_line: + is_unique = False + break + if is_unique: + new_eqn = [eq.subs(convert_tu) for eq in eqn] + new_eqn = tuple(new_eqn) + cdns = line[1] + new_cdn = [cdn.subs(convert_tu) for cdn in cdns] + new_cdn = set(new_cdn) + unique_line.add(new_eqn) + index_line[index] = tuple([new_eqn, new_cdn]) + line_comps[index] = [i] + index += 1 + else: + match_key = [k for k, v in index_line.items() if v[0] == tuple(new_line)][0] + line_comps[match_key].append(i) + + WV = {i: [] for i in range(len(line_comps))} + for k, index in line_comps.items(): + + # Calculate direction vector of the line + dir_vecs = [] + line = index_line[k][0] + all_var = set() + for l in line: + 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 = vector(par_drv) + dir_vecs.append(par_drv) + + # Calculate the outgoing normal vector of each surface in the + # direction of the line + for i in index: + 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 = vector(temp_vec) + drv_vectors.append(temp_vec) + temp = [t_vars] + for vec in drv_vectors: + temp.append(vec) + 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))) + 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.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))) + weight_vec = vector(temp_weight) + order = self._hypersurface[i][2] + weight_vec *= order + WV[k].append(weight_vec) + + for i in range(len(WV[k])): + test_vectors = [v for v in WV[k]] + test_vectors[i] = -test_vectors[i] + if sum(test_vectors) == zero_vector(QQ, dim): + WV[k] = test_vectors + break + + return index_line, WV + class TropicalSurface(TropicalVariety): r""" @@ -742,7 +944,7 @@ def _axes(self): v_set = v_set.union(temp_v) axes = [[min(u_set)-1, max(u_set)+1], [min(v_set)-1, max(v_set)+1]] - # Finding the z-axis + # Calculate the z-axis step = 10 du = (axes[0][1]-axes[0][0]) / step dv = (axes[1][1]-axes[1][0]) / step @@ -807,9 +1009,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.sets.real_set import RealSet from sage.symbolic.relation import solve - from sage.rings.rational_field import QQ + from sage.sets.real_set import RealSet poly_verts = {i: set() for i in range(self.number_of_components())} axes = self._axes() @@ -817,7 +1018,7 @@ def _polygon_vertices(self): vars = self._vars comps_int = self._components_intersection() - # Finding the inside vertices + # Find the inside vertices (intersection of components) for index, lines in comps_int.items(): for line in lines: v = list(line[1])[0].variables()[0] @@ -896,7 +1097,8 @@ def find_edge_vertices(i): sol1 = solve(point >= axes[i][0], pv) sol2 = solve(point <= axes[i][1], pv) is_doublevar = True - # Finding the edge vertices (those that touch the axes) + + # Find the edge vertices (those that touch the axes) find_edge_vertices(0) # t1 fixed find_edge_vertices(1) # t2 fixed return poly_verts @@ -986,142 +1188,6 @@ def _repr_(self): """ return f"Tropical surface of {self._poly}" - def weight_vectors(self): - r""" - Return the weight vectors for each edge of ``self``. - - Suppose `L` is an edge adjacent to the surface `S_1, ldots, S_k` - with respective weights `w_1, ldots, w_k`. This edge `L` has - a direction vector `d=[d_1,d_2,d_3]`. Each surface - `S_1, ldots, S_k` has a normal vector `n_1, \ldots, n_k`. - Make sure that the normal vector is scale to an integer vector - `n_k=(\alpha, \beta, \gamma)` such that - `\gcd(\alpha, \beta, \gamma)=1`. The weight vector of a surface - with respect to line `L` can be calculated with - `v_k=d\times n_k. These vectors will satisfy the following - balancing condition: `\sum_{i=1}^k w_k v_k = 0`. - - OUTPUT: - - A dictionary where the keys represent the vertices, and the values - are lists of vectors. - - EXAMPLES:: - - sage: T = TropicalSemiring(QQ) - sage: R. = PolynomialRing(T) - sage: p1 = x^2 + y^2 + z^3 - sage: tv1 = p1.tropical_variety() - sage: tv1.weight_vectors() - [[((3/2*t2, 3/2*t2, t2), {t2 < +Infinity}), - [(-2, -2, 6), (-9/2, 13/2, -3), (13/2, -9/2, -3)]]] - - sage: p2 = x + y + z + x^2 + R(1) - sage: tv2 = p2.tropical_variety() - sage: tv2.weight_vectors() - [[((t2, t2, t2), {0 <= t2, t2 <= 1}), [(-1, -1, 2), (-1, 2, -1), (2, -1, -1)]], - [((0, 0, t2), {0 <= t2}), [(-1, -1, 0), (0, -1, 0), (1, 2, 0)]], - [((1, 1, t2), {1 <= t2}), [(1, 1, 0), (0, -1, 0), (-1, 0, 0)]], - [((0, t2, 0), {0 <= t2}), [(1, 0, 1), (0, 0, 1), (-1, 0, -2)]], - [((1, t2, 1), {1 <= t2}), [(-1, 0, -1), (0, 0, 1), (1, 0, 0)]], - [((t1, 1, 1), {1 <= t1}), [(0, -1, -1), (0, 0, 1), (0, 1, 0)]], - [((t1, 2*t1, 2*t1), {t1 <= 0}), [(4, -1, -1), (-2, -4, 5), (-2, 5, -4)]]] - """ - from sage.symbolic.ring import SR - from sage.symbolic.relation import solve - from sage.calculus.functional import diff - from sage.arith.misc import gcd - from sage.rings.rational_field import QQ - from sage.modules.free_module_element import vector - - t = SR.var('t') - CI = self._components_intersection() - unique_line = set() - index_line = {} - line_comps = {} - index = 0 - - # Identify the distinct line of intersection and determine which - # components contain this line. - for i, lines in CI.items(): - for line in lines: - v1 = next(iter(line[1])).variables()[0] - eqn = line[0] - is_unique = True - for uniq in unique_line: - subs_index = -1 - for j in range(3): - if eqn[j] != uniq[j]: - subs_index = j - break - if subs_index == -1: - new_line = eqn - is_unique = False - break - eq1 = eqn[subs_index].subs(**{str(v1): t}) - eq2 = uniq[subs_index] - temp_sol = solve(eq1 == eq2, t) - if temp_sol: - temp_sol = temp_sol[0].rhs() - if not temp_sol.is_numeric(): - new_line = [] - for l in eqn: - new_line.append(l.subs(**{str(v1): temp_sol})) - if tuple(new_line) in unique_line: - is_unique = False - break - if is_unique: - unique_line.add(eqn) - index_line[index] = line - line_comps[index] = [i] - index += 1 - else: - match_key = [k for k, v in index_line.items() if v[0] == tuple(new_line)][0] - line_comps[match_key].append(i) - - WV = {i: [] for i in range(len(line_comps))} - for k, v in line_comps.items(): - - # Calculate direction vector of the line - dir_vec = [] - line = index_line[k][0] - for l in line: - if l.variables(): - vpar = l.variables()[0] - break - for l in line: - dir_vec.append(QQ(diff(l, vpar))) - dir_vec = vector(dir_vec) - - # Calculate the outgoing normal vector of each surface in the - # direction of the line - for i in v: - surface = self._hypersurface[i][0] - vec1, vec2 = [], [] - for s in surface: - vec1.append(QQ(diff(s, self._vars[0]))) - vec2.append(QQ(diff(s, self._vars[1]))) - vector1 = vector(vec1) - vector2 = vector(vec2) - nor_vec = vector1.cross_product(vector2) - nor_vec *= 1/gcd(nor_vec) - weight_vec = nor_vec.cross_product(dir_vec) - weight_vec = vector([QQ(w) for w in weight_vec]) - order = self._hypersurface[i][2] - weight_vec *= order - WV[k].append(weight_vec) - for i in range(len(WV[k])): - test_vectors = [v for v in WV[k]] - test_vectors[i] = -test_vectors[i] - if sum(test_vectors) == vector([0,0,0]): - WV[k] = test_vectors - break - - result = [] - for k, v in WV.items(): - result.append([index_line[k], v]) - return result - class TropicalCurve(TropicalVariety): r""" @@ -1312,13 +1378,13 @@ def weight_vectors(self): (3, 4): [(-1, -1), (0, 1), (1, 0)]} """ from sage.calculus.functional import diff - from sage.arith.misc import gcd from sage.modules.free_module_element import vector + from sage.arith.misc import gcd if not self._vertices_components(): return {} - # Finding the base vector in the direction of each edge + # Calculate the base vector in the direction of each edge temp_vectors = [] par = self._hypersurface[0][1][0].variables()[0] for comp in self._hypersurface: From 96a0f4cdffb401933a00a498101573be9bf8994f Mon Sep 17 00:00:00 2001 From: Verrel Rievaldo Wijaya Date: Sun, 25 Aug 2024 19:17:03 +0700 Subject: [PATCH 149/537] Small fix on example --- src/sage/rings/semirings/tropical_variety.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/sage/rings/semirings/tropical_variety.py b/src/sage/rings/semirings/tropical_variety.py index fad657ee871..4b11043bebe 100644 --- a/src/sage/rings/semirings/tropical_variety.py +++ b/src/sage/rings/semirings/tropical_variety.py @@ -686,10 +686,10 @@ def weight_vectors(self): 1: ((u2 - 4, u2 + 1, u2, u3), {u2 <= u3 - 10/3}), 2: ((2*u1 - u3 - 2/3, u3 - 7/3, u1, u3), {u3 - 10/3 <= u1}), 3: ((u3 - 22/3, u2, u3 - 10/3, u3), {u3 - 7/3 <= u2})}, - {0: [(0, 1, 1, -2), (0, 1, -2, 1), (0, -2, 1, 1)], - 1: [(-2, 1, 1, 0), (3, -3, 0, 0), (-1, 2, -1, 0)], - 2: [(-1, 5, 2, -6), (2, 1, -4, 1), (-1, -6, 2, 5)], - 3: [(-1, 0, -1, 2), (-2, 0, 1, 1), (3, 0, 0, -3)]}) + {0: [(0, -1, -1, 2), (0, -1, 2, -1), (0, 2, -1, -1)], + 1: [(2, -1, -1, 0), (-3, 3, 0, 0), (1, -2, 1, 0)], + 2: [(1, -5, -2, 6), (-2, -1, 4, -1), (1, 6, -2, -5)], + 3: [(1, 0, 1, -2), (2, 0, -1, -1), (-3, 0, 0, 3)]}) """ from sage.symbolic.ring import SR from sage.symbolic.relation import solve From ec4307da18e3973e81d9ff98fa1e4ab7a088c43e Mon Sep 17 00:00:00 2001 From: Verrel Rievaldo Wijaya Date: Sun, 25 Aug 2024 19:56:47 +0700 Subject: [PATCH 150/537] Another fix --- src/sage/rings/semirings/tropical_variety.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/sage/rings/semirings/tropical_variety.py b/src/sage/rings/semirings/tropical_variety.py index 4b11043bebe..cd2d9bc84b5 100644 --- a/src/sage/rings/semirings/tropical_variety.py +++ b/src/sage/rings/semirings/tropical_variety.py @@ -683,13 +683,13 @@ def weight_vectors(self): sage: tv = p1.tropical_variety() sage: tv.weight_vectors() ({0: ((u1, u3 - 7/3, u3 - 10/3, u3), {u1 <= u3 - 22/3}), - 1: ((u2 - 4, u2 + 1, u2, u3), {u2 <= u3 - 10/3}), - 2: ((2*u1 - u3 - 2/3, u3 - 7/3, u1, u3), {u3 - 10/3 <= u1}), - 3: ((u3 - 22/3, u2, u3 - 10/3, u3), {u3 - 7/3 <= u2})}, - {0: [(0, -1, -1, 2), (0, -1, 2, -1), (0, 2, -1, -1)], - 1: [(2, -1, -1, 0), (-3, 3, 0, 0), (1, -2, 1, 0)], - 2: [(1, -5, -2, 6), (-2, -1, 4, -1), (1, 6, -2, -5)], - 3: [(1, 0, 1, -2), (2, 0, -1, -1), (-3, 0, 0, 3)]}) + 1: ((u2 - 4, u2 + 1, u2, u3), {u2 <= u3 - 10/3}), + 2: ((2*u1 - u3 - 2/3, u3 - 7/3, u1, u3), {u3 - 10/3 <= u1}), + 3: ((u3 - 22/3, u2, u3 - 10/3, u3), {u3 - 7/3 <= u2})}, + {0: [(0, 1, 1, -2), (0, 1, -2, 1), (0, -2, 1, 1)], + 1: [(-2, 1, 1, 0), (3, -3, 0, 0), (-1, 2, -1, 0)], + 2: [(-1, 5, 2, -6), (2, 1, -4, 1), (-1, -6, 2, 5)], + 3: [(-1, 0, -1, 2), (-2, 0, 1, 1), (3, 0, 0, -3)]}) """ from sage.symbolic.ring import SR from sage.symbolic.relation import solve From dd3fc7b6c2b31d96e4077c366bdc43c0abe70705 Mon Sep 17 00:00:00 2001 From: Newtech66 Date: Sun, 25 Aug 2024 23:34:49 +0530 Subject: [PATCH 151/537] remove functorial_composition and change molecular species grading --- src/sage/rings/species.py | 83 +++------------------------------------ 1 file changed, 6 insertions(+), 77 deletions(-) diff --git a/src/sage/rings/species.py b/src/sage/rings/species.py index 3b135516a5d..0f2fed08f31 100644 --- a/src/sage/rings/species.py +++ b/src/sage/rings/species.py @@ -4,7 +4,6 @@ from sage.categories.infinite_enumerated_sets import InfiniteEnumeratedSets from sage.categories.monoids import Monoids from sage.categories.sets_with_grading import SetsWithGrading -from sage.categories.cartesian_product import cartesian_product from sage.combinat.free_module import CombinatorialFreeModule from sage.combinat.integer_vector import IntegerVectors from sage.groups.perm_gps.constructor import PermutationGroupElement @@ -773,10 +772,10 @@ def _elmmul(self, elm1, elm2): elm1._group_constructor() if elm2._group is None: elm2._group_constructor() - if elm1.grade() == 0: + if elm1._tc == 0: self._assign_group_info(elm2) return - if elm2.grade() == 0: + if elm2._tc == 0: self._assign_group_info(elm1) return self._mc = tuple(elm1._mc[i] + elm2._mc[i] for i in range(self.parent()._k)) @@ -878,7 +877,7 @@ def grade(self): r""" Return the grade of ``self``. """ - return self._tc + return self._mc def domain(self): r""" @@ -931,76 +930,6 @@ def hadamard_product(self, other): res += Pn(PermutationGroup(gap_group=F, domain=self.domain()), dpart) return res - def functorial_composition(self, other): - r""" - Return the functorial composition of ``self`` with ``other``. - Currrent this only works for univariate molecular species only. - - TESTS:: - - sage: P = PolynomialSpecies(ZZ, ["X"]) - sage: M = P._indices - sage: E = [None] + [M(SymmetricGroup(n)) for n in range(1, 4)] - sage: E[2].functorial_composition(E[2]) - E_4 - sage: E[1].functorial_composition(E[1]) - X - sage: E[1].functorial_composition(E[2]) - E_2 - sage: E[2].functorial_composition(E[1]) - X - sage: E[3].functorial_composition(E[2]) - E_8 - sage: E[2].functorial_composition(E[3]) - E_9 - """ - if not isinstance(other, MolecularSpecies.Element): - raise ValueError(f"{other} must be a molecular species") - if other.parent()._k > 1: - raise ValueError(f"{other} must be univariate") - if self.parent()._k > 1: - raise ValueError(f"{self} must be univariate") - - gens = [] - dpart = {1: range(1, other.grade() ** self.grade() + 1)} - - def to_number(l): - B = ZZ.one() # ZZ.one or 1? - R = 0 # Just 0 is fine? - for e in reversed(l): - R += e * B - B *= other.grade() - return R - - # it is a base other.grade() representation - for pre in cartesian_product([range(other.grade())]*self.grade()): - pre_n = to_number(pre) + 1 - # gens from self - for gen in self._group.gens(): - # gen swaps around the numbers in pre - im = gen(list(pre)) - im_n = to_number(im) + 1 - if pre_n == im_n: - continue - gens.append([tuple([pre_n, im_n])]) - print('after self',gens) - - # gens from other - for gen in other._group.gens(): - for pre in cartesian_product([range(other.grade())]*self.grade()): - pre_n = to_number(pre) + 1 - for i in range(self.grade()): - im_n = pre_n - pre[-i-1] * other.grade() ** i + (gen(pre[-i-1] + 1) - 1) * other.grade() ** i - if pre_n == im_n: - continue - gens.append([tuple([pre_n, im_n])]) - print('after others',gens) - - G = PermutationGroup(gens,domain=range(1, other.grade() ** self.grade() + 1)) - print('G',G) - print('dompart',dpart) - return other.parent()(G, dpart) - def inner_sum(self, base_ring, names, *args): r""" Compute the inner sum of exercise 2.6.16 of BLL book. @@ -1079,17 +1008,17 @@ def __call__(self, *args): gens = [] # TODO: What happens if in F(G), G has a constant part? E(1+X)? - Mlist = [None for _ in range(self.grade())] + Mlist = [None for _ in range(self._tc)] for i, v in enumerate(self._dompart): for k in v: Mlist[k - 1] = args[i] - starts = list(accumulate([M.grade() for M in Mlist], initial=0)) + starts = list(accumulate([M._tc for M in Mlist], initial=0)) # gens from self for gen in self._group.gens(): newgen = [] for cyc in gen.cycle_tuples(): - for k in range(1, Mlist[cyc[0] - 1].grade() + 1): + for k in range(1, Mlist[cyc[0] - 1]._tc + 1): newgen.append(tuple(k + starts[i - 1] for i in cyc)) gens.append(newgen) From 700b925d5ab70dc21383d3d5f9b96a4a3318344f Mon Sep 17 00:00:00 2001 From: Newtech66 Date: Mon, 26 Aug 2024 02:01:51 +0530 Subject: [PATCH 152/537] Replace tuple with frozenset for dompart --- src/sage/rings/species.py | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/sage/rings/species.py b/src/sage/rings/species.py index 0f2fed08f31..ac07d6861d2 100644 --- a/src/sage/rings/species.py +++ b/src/sage/rings/species.py @@ -338,8 +338,6 @@ def _canonicalize(self): sage: At = AtomicSpecies("X, Y") sage: G = PermutationGroup([[(1,2),(3,4),(5,6),(7,8,9,10)]]); G Permutation Group with generators [(1,2)(3,4)(5,6)(7,8,9,10)] - sage: H = PermutationGroup([[(1,2,3,4),(5,6),(7,8),(9,10)]]); H - Permutation Group with generators [(1,2,3,4)(5,6)(7,8)(9,10)] sage: A = At(G, {1: [1,2,3,4], 2: [5,6,7,8,9,10]}) sage: A._dompart ((5, 6, 7, 8), (9, 10, 1, 2, 3, 4)) @@ -404,8 +402,8 @@ def __eq__(self, other): for i in range(self.parent()._k): if len(self._dompart[i]) != len(other._dompart[i]): return False - selflist.extend(self._dompart[i]) - otherlist.extend(other._dompart[i]) + selflist.extend(sorted(list(self._dompart[i]))) + otherlist.extend(sorted(list(other._dompart[i]))) mapping = libgap.MappingPermListList(selflist, otherlist) G = PermutationGroup(gap_group=libgap.ConjugateGroup(self._dis._C, mapping), domain=self._dis._C.domain()) @@ -521,9 +519,9 @@ def _element_constructor_(self, G, pi=None): mapping = {v: i for i, v in enumerate(G.domain(), 1)} mapping2 = PermutationGroupElement([mapping[e] for o in sorted(G.orbits(), key=len, reverse=True) for e in o]).inverse() - dpart = [tuple() for _ in range(self._k)] + dpart = [frozenset() for _ in range(self._k)] for k, v in pi.items(): - dpart[k - 1] = tuple(mapping2(mapping[x]) for x in v) + dpart[k - 1] = frozenset(mapping2(mapping[x]) for x in v) elm = self._cache_get(self.element_class(self, dis_elm, tuple(dpart))) if elm._tc not in self._renamed: self._rename(elm._tc) @@ -797,7 +795,7 @@ def _elmmul(self, elm1, elm2): self._group = PermutationGroup(gens, domain=range(1, elm1._tc + elm2._tc + 1)) self._dompart = list(elm1._dompart) for i in range(elm2.parent()._k): - self._dompart[i] = tuple(list(self._dompart[i]) + [elm1._tc + e for e in elm2._dompart[i]]) + self._dompart[i] = frozenset(list(self._dompart[i]) + [elm1._tc + e for e in elm2._dompart[i]]) self._dompart = tuple(self._dompart) def __floordiv__(self, elt): @@ -871,7 +869,7 @@ def _canonicalize(self): sorted_orbits = sorted([sorted(orbit) for orbit in self._group.orbits()], key=len, reverse=True) pi = PermutationGroupElement(list(chain.from_iterable(sorted_orbits))).inverse() self._group = PermutationGroup(gap_group=libgap.ConjugateGroup(self._group, pi)) - self._dompart = tuple(tuple(pi(k) for k in v) for v in self._dompart) + self._dompart = tuple(frozenset(pi(k) for k in v) for v in self._dompart) def grade(self): r""" From 0d07b869d8d41290d65adf7b065a409fbb4b522f Mon Sep 17 00:00:00 2001 From: Newtech66 Date: Mon, 26 Aug 2024 02:04:20 +0530 Subject: [PATCH 153/537] fix doctests --- src/sage/rings/species.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/sage/rings/species.py b/src/sage/rings/species.py index ac07d6861d2..77cc7dcd32d 100644 --- a/src/sage/rings/species.py +++ b/src/sage/rings/species.py @@ -340,10 +340,10 @@ def _canonicalize(self): Permutation Group with generators [(1,2)(3,4)(5,6)(7,8,9,10)] sage: A = At(G, {1: [1,2,3,4], 2: [5,6,7,8,9,10]}) sage: A._dompart - ((5, 6, 7, 8), (9, 10, 1, 2, 3, 4)) + (frozenset({5, 6, 7, 8}), frozenset({1, 2, 3, 4, 9, 10})) sage: C = At(G, {1: [1,2,5,6], 2: [3,4,7,8,9,10]}) sage: C._dompart - ((5, 6, 7, 8), (9, 10, 1, 2, 3, 4)) + (frozenset({5, 6, 7, 8}), frozenset({1, 2, 3, 4, 9, 10})) """ # The canonicalization is done in the element constructor. pass @@ -360,11 +360,11 @@ def __hash__(self): sage: H = PermutationGroup([[(1,2,3,4),(5,6),(7,8),(9,10)]]); H Permutation Group with generators [(1,2,3,4)(5,6)(7,8)(9,10)] sage: A = At(G, {1: [1,2,3,4], 2: [5,6,7,8,9,10]}); A - {((1,2,3,4)(5,6)(7,8)(9,10),): ((5, 6, 7, 8), (9, 10, 1, 2, 3, 4))} + {((1,2,3,4)(5,6)(7,8)(9,10),): (frozenset({8, 5, 6, 7}), frozenset({1, 2, 3, 4, 9, 10}))} sage: B = At(H, {1: [1,2,3,4], 2: [5,6,7,8,9,10]}); B - {((1,2,3,4)(5,6)(7,8)(9,10),): ((1, 2, 3, 4), (5, 6, 7, 8, 9, 10))} + {((1,2,3,4)(5,6)(7,8)(9,10),): (frozenset({1, 2, 3, 4}), frozenset({5, 6, 7, 8, 9, 10}))} sage: C = At(G, {1: [1,2,5,6], 2: [3,4,7,8,9,10]}); C - {((1,2,3,4)(5,6)(7,8)(9,10),): ((5, 6, 7, 8), (9, 10, 1, 2, 3, 4))} + {((1,2,3,4)(5,6)(7,8)(9,10),): (frozenset({8, 5, 6, 7}), frozenset({1, 2, 3, 4, 9, 10}))} sage: hash(A) == hash(B) True sage: hash(A) == hash(C) @@ -420,7 +420,7 @@ def _repr_(self): sage: G = PermutationGroup([[(1,2),(3,4),(5,6),(7,8,9,10)]]); G Permutation Group with generators [(1,2)(3,4)(5,6)(7,8,9,10)] sage: A = At(G, {1: [1,2,3,4], 2: [5,6,7,8,9,10]}); A - {((1,2,3,4)(5,6)(7,8)(9,10),): ((5, 6, 7, 8), (9, 10, 1, 2, 3, 4))} + {((1,2,3,4)(5,6)(7,8)(9,10),): (frozenset({8, 5, 6, 7}), frozenset({1, 2, 3, 4, 9, 10}))} """ return "{" + f"{self._dis}: {self._dompart}" + "}" @@ -480,7 +480,7 @@ def an_element(self): sage: At1.an_element() E_2 sage: At2.an_element() - {((1,2)(3,4),): ((1, 2), (3, 4))} + {((1,2)(3,4),): (frozenset({1, 2}), frozenset({3, 4}))} """ G = PermutationGroup([[(2 * i - 1, 2 * i) for i in range(1, self._k + 1)]]) m = {i: [2 * i - 1, 2 * i] for i in range(1, self._k + 1)} @@ -859,10 +859,10 @@ def _canonicalize(self): Permutation Group with generators [(1,2,3,4)(5,6)(7,8)(9,10)] sage: A = P(G, {1: [1,2,3,4], 2: [5,6,7,8,9,10]}) sage: A.support()[0]._dompart - ((5, 6, 7, 8), (9, 10, 1, 2, 3, 4)) + (frozenset({5, 6, 7, 8}), frozenset({1, 2, 3, 4, 9, 10})) sage: C = P(G, {1: [1,2,5,6], 2: [3,4,7,8,9,10]}) sage: C.support()[0]._dompart - ((5, 6, 7, 8), (9, 10, 1, 2, 3, 4)) + (frozenset({5, 6, 7, 8}), frozenset({1, 2, 3, 4, 9, 10})) """ if self._group is None or self._group == SymmetricGroup(0): return @@ -949,7 +949,7 @@ def inner_sum(self, base_ring, names, *args): sage: M = P._indices sage: C4 = M(CyclicPermutationGroup(4)) sage: C4.inner_sum(ZZ, "X, Y", [2, 2]) # X^2Y^2 + C2(XY) - {((1,2)(3,4),): ((1, 2), (3, 4))} + X^2*Y^2 + {((1,2)(3,4),): (frozenset({1, 2}), frozenset({3, 4}))} + X^2*Y^2 """ # TODO: No checks are performed right now, must be added. From 35b1703bb9a9397d0b2bbe12b785118c9c077540 Mon Sep 17 00:00:00 2001 From: Newtech66 Date: Mon, 26 Aug 2024 03:20:56 +0530 Subject: [PATCH 154/537] Add doctests --- src/sage/rings/species.py | 155 +++++++++++++++++++++++++++++++++++--- 1 file changed, 145 insertions(+), 10 deletions(-) diff --git a/src/sage/rings/species.py b/src/sage/rings/species.py index 77cc7dcd32d..35220ee6490 100644 --- a/src/sage/rings/species.py +++ b/src/sage/rings/species.py @@ -54,7 +54,20 @@ def _cache_get(self, elm): ``elm`` must implement the following methods: - ``_element_key`` - hashable type for dict lookup. - ``__eq__`` - to compare two elements. - Additionally, if a method ``_canonicalize`` is implemented, it is used to preprocess the element. + - ``_canonicalize`` - to preprocess the element. + + TESTS:: + + sage: P = PolynomialSpecies(ZZ, "X, Y") + sage: M = P._indices + sage: G = PermutationGroup([[(1,2),(3,4),(5,6),(7,8,9,10)]]); G + Permutation Group with generators [(1,2)(3,4)(5,6)(7,8,9,10)] + sage: A = M(G, {1: [1,2,3,4], 2: [5,6,7,8,9,10]}); A + sage: C = M(G, {1: [1,2,5,6], 2: [3,4,7,8,9,10]}); C + sage: from sage.rings.species import ElementCache + sage: E = ElementCache() + sage: E._cache_get(A) + sage: E._cache_get(C) """ # TODO: Make _canonicalize optional. # Possibly the following works: @@ -124,6 +137,13 @@ def _repr_(self): def _element_key(self): r""" Return the cache lookup key for ``self``. + + TESTS:: + + sage: from sage.rings.species import ConjugacyClassesOfDirectlyIndecomposableSubgroups + sage: C = ConjugacyClassesOfDirectlyIndecomposableSubgroups() + sage: G = PermutationGroup([[(1,3),(4,7)], [(2,5),(6,8)], [(1,4),(2,5),(3,7)]]) + sage: C(G)._element_key() """ return self._C.degree(), self._C.order(), tuple(len(orbit) for orbit in sorted(self._C.orbits(), key=len)) @@ -324,6 +344,14 @@ def __init__(self, parent, dis, domain_partition): def _element_key(self): r""" Return the cache lookup key for ``self``. + + TESTS:: + + sage: At = AtomicSpecies("X, Y") + sage: G = PermutationGroup([[(1,2),(3,4),(5,6),(7,8,9,10)]]); G + Permutation Group with generators [(1,2)(3,4)(5,6)(7,8,9,10)] + sage: A = At(G, {1: [1,2,3,4], 2: [5,6,7,8,9,10]}); A + sage: A._element_key() """ return self._mc, self._dis @@ -528,6 +556,29 @@ def _element_constructor_(self, G, pi=None): return elm def _rename(self, n): + r""" + Names for common species. + + EXAMPLES:: + + sage: P = PolynomialSpecies(ZZ, ["X", "Y"]) + sage: P(SymmetricGroup(4), {1: range(1, 5)}) + E_4(X) + sage: P(SymmetricGroup(4), {2: range(1, 5)}) + E_4(Y) + sage: P(CyclicPermutationGroup(4), {1: range(1, 5)}) + C_4(X) + sage: P(CyclicPermutationGroup(4), {2: range(1, 5)}) + C_4(Y) + sage: P(DihedralGroup(4), {1: range(1, 5)}) + P_4(X) + sage: P(DihedralGroup(4), {2: range(1, 5)}) + P_4(Y) + sage: P(AlternatingGroup(4), {1: range(1, 5)}) + Eo_4(X) + sage: P(AlternatingGroup(4), {2: range(1, 5)}) + Eo_4(Y) + """ from sage.groups.perm_gps.permgroup import PermutationGroup from sage.groups.perm_gps.permgroup_named import (AlternatingGroup, CyclicPermutationGroup, @@ -570,6 +621,14 @@ def _rename(self, n): def __contains__(self, x): r""" Return if ``x`` is in ``self``. + + TESTS:: + + sage: A = AtomicSpecies("X") + sage: G = PermutationGroup([[(1,2)], [(3,4)]]); G + sage: G.disjoint_direct_product_decomposition() + sage: G in A + False """ if parent(x) == self: return True @@ -613,11 +672,25 @@ def _repr_(self): class MolecularSpecies(IndexedFreeAbelianMonoid, ElementCache): @staticmethod - def __classcall__(cls, indices, prefix, **kwds): + def __classcall__(cls, indices, prefix=None, **kwds): return super(IndexedMonoid, cls).__classcall__(cls, indices, prefix, **kwds) - def __init__(self, indices, prefix, **kwds): - category = Monoids() & InfiniteEnumeratedSets() + def __init__(self, indices, prefix=None, **kwds): + r""" + Infinite set of multivariate molecular species. + + INPUT: + + - ``indices`` -- the underlying set of atomic species indexing the monoid + + TESTS:: + + sage: P1 = PolynomialSpecies(ZZ, "X") + sage: P2 = PolynomialSpecies(ZZ, ["X", "Y"]) + sage: TestSuite(P1._indices).run(skip="_test_graded_components") + sage: TestSuite(P2._indices).run(skip="_test_graded_components") + """ + category = Monoids() & SetsWithGrading().Infinite() IndexedFreeAbelianMonoid.__init__(self, indices, prefix=prefix, category=category, **kwds) ElementCache.__init__(self) self._k = indices._k @@ -627,6 +700,16 @@ def _project(self, G, pi, part): Project `G` onto a subset ``part`` of its domain. ``part`` must be a union of cycles, but this is not checked. + + TESTS:: + + sage: P = PolynomialSpecies(ZZ, ["X", "Y"]) + sage: M = P._indices + sage: G = PermutationGroup([[(1,2),(3,4)], [(5,6)]]); G + sage: parts = G.disjoint_direct_product_decomposition(); parts + sage: pi = {1: [1,2,3,4], 2: [5,6]} + sage: M._project(G, pi, parts[0]) + sage: M._project(G, pi, parts[1]) """ restricted_gens = [[cyc for cyc in gen.cycle_tuples() if cyc[0] in part] for gen in G.gens()] mapping = dict() @@ -732,9 +815,27 @@ def gen(self, x): elm._mc = at._mc elm._tc = at._tc return elm + + def _repr_(self): + r""" + Return a string representation of ``self``. + + TESTS:: + + sage: PolynomialSpecies(ZZ, "X")._indices + Molecular species in X + sage: PolynomialSpecies(ZZ, "X, Y")._indices + Molecular species in X, Y + """ + if len(self._indices._names) == 1: + return f"Molecular species in {self._indices._names[0]}" + return f"Molecular species in {', '.join(self._indices._names)}" class Element(IndexedFreeAbelianMonoidElement): def __init__(self, F, x): + r""" + Initialize a molecular species with no group information. + """ super().__init__(F, x) self._group = None self._dompart = None @@ -830,6 +931,15 @@ def _elmexp(self, other, n): def __pow__(self, n): r""" Raise ``self`` to the power of ``n``. + + TESTS:: + + sage: P = PolynomialSpecies(ZZ, "X") + sage: M = P._indices + sage: E2 = M(SymmetricGroup(2), {1: [1,2]}) + sage: (E2._group, E2._dompart, E2._mc, E2._tc) + sage: E2_3 = E2 ^ 3 + sage: (E2_3._group, E2_3._dompart, E2_3._mc, E2_3._tc) """ res = super().__pow__(n) elm = self.parent()._cache_get(res) @@ -841,6 +951,14 @@ def __pow__(self, n): def _element_key(self): r""" Return the cache lookup key for ``self``. + + TESTS:: + + sage: P = PolynomialSpecies(ZZ, "X") + sage: M = P._indices + sage: E2 = M(SymmetricGroup(2), {1: [1,2]}) + sage: E2._element_key() + E_2 """ return self @@ -853,15 +971,14 @@ def _canonicalize(self): EXAMPLES:: sage: P = PolynomialSpecies(ZZ, "X, Y") + sage: M = P._indices sage: G = PermutationGroup([[(1,2),(3,4),(5,6),(7,8,9,10)]]); G Permutation Group with generators [(1,2)(3,4)(5,6)(7,8,9,10)] - sage: H = PermutationGroup([[(1,2,3,4),(5,6),(7,8),(9,10)]]); H - Permutation Group with generators [(1,2,3,4)(5,6)(7,8)(9,10)] - sage: A = P(G, {1: [1,2,3,4], 2: [5,6,7,8,9,10]}) - sage: A.support()[0]._dompart + sage: A = M(G, {1: [1,2,3,4], 2: [5,6,7,8,9,10]}) + sage: A._dompart (frozenset({5, 6, 7, 8}), frozenset({1, 2, 3, 4, 9, 10})) - sage: C = P(G, {1: [1,2,5,6], 2: [3,4,7,8,9,10]}) - sage: C.support()[0]._dompart + sage: C = M(G, {1: [1,2,5,6], 2: [3,4,7,8,9,10]}) + sage: C._dompart (frozenset({5, 6, 7, 8}), frozenset({1, 2, 3, 4, 9, 10})) """ if self._group is None or self._group == SymmetricGroup(0): @@ -874,12 +991,30 @@ def _canonicalize(self): def grade(self): r""" Return the grade of ``self``. + + EXAMPLES:: + + sage: P = PolynomialSpecies(ZZ, "X, Y") + sage: M = P._indices + sage: G = PermutationGroup([[(1,2),(3,4),(5,6),(7,8,9,10)]]); G + Permutation Group with generators [(1,2)(3,4)(5,6)(7,8,9,10)] + sage: A = M(G, {1: [1,2,3,4], 2: [5,6,7,8,9,10]}); A + sage: A.grade() """ return self._mc def domain(self): r""" Return the domain of ``self``. + + EXAMPLES:: + + sage: P = PolynomialSpecies(ZZ, "X, Y") + sage: M = P._indices + sage: G = PermutationGroup([[(1,2),(3,4),(5,6),(7,8,9,10)]]); G + Permutation Group with generators [(1,2)(3,4)(5,6)(7,8,9,10)] + sage: A = M(G, {1: [1,2,3,4], 2: [5,6,7,8,9,10]}); A + sage: A.domain() """ return FiniteEnumeratedSet(range(1, self._tc + 1)) From 853b40315f76aaa17fe7f0597d0fb50179852a27 Mon Sep 17 00:00:00 2001 From: Newtech66 Date: Mon, 26 Aug 2024 03:22:44 +0530 Subject: [PATCH 155/537] run doctest fixer --- src/sage/rings/species.py | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/sage/rings/species.py b/src/sage/rings/species.py index 35220ee6490..1d77afe6818 100644 --- a/src/sage/rings/species.py +++ b/src/sage/rings/species.py @@ -63,11 +63,15 @@ def _cache_get(self, elm): sage: G = PermutationGroup([[(1,2),(3,4),(5,6),(7,8,9,10)]]); G Permutation Group with generators [(1,2)(3,4)(5,6)(7,8,9,10)] sage: A = M(G, {1: [1,2,3,4], 2: [5,6,7,8,9,10]}); A + {((1,2,3,4)(5,6)(7,8)(9,10),): (frozenset({8, 5, 6, 7}), frozenset({1, 2, 3, 4, 9, 10}))} sage: C = M(G, {1: [1,2,5,6], 2: [3,4,7,8,9,10]}); C + {((1,2,3,4)(5,6)(7,8)(9,10),): (frozenset({8, 5, 6, 7}), frozenset({1, 2, 3, 4, 9, 10}))} sage: from sage.rings.species import ElementCache sage: E = ElementCache() sage: E._cache_get(A) + {((1,2,3,4)(5,6)(7,8)(9,10),): (frozenset({8, 5, 6, 7}), frozenset({1, 2, 3, 4, 9, 10}))} sage: E._cache_get(C) + {((1,2,3,4)(5,6)(7,8)(9,10),): (frozenset({8, 5, 6, 7}), frozenset({1, 2, 3, 4, 9, 10}))} """ # TODO: Make _canonicalize optional. # Possibly the following works: @@ -144,6 +148,7 @@ def _element_key(self): sage: C = ConjugacyClassesOfDirectlyIndecomposableSubgroups() sage: G = PermutationGroup([[(1,3),(4,7)], [(2,5),(6,8)], [(1,4),(2,5),(3,7)]]) sage: C(G)._element_key() + (8, 8, (2, 2, 4)) """ return self._C.degree(), self._C.order(), tuple(len(orbit) for orbit in sorted(self._C.orbits(), key=len)) @@ -351,7 +356,9 @@ def _element_key(self): sage: G = PermutationGroup([[(1,2),(3,4),(5,6),(7,8,9,10)]]); G Permutation Group with generators [(1,2)(3,4)(5,6)(7,8,9,10)] sage: A = At(G, {1: [1,2,3,4], 2: [5,6,7,8,9,10]}); A + {((1,2,3,4)(5,6)(7,8)(9,10),): (frozenset({8, 5, 6, 7}), frozenset({1, 2, 3, 4, 9, 10}))} sage: A._element_key() + ((4, 6), ((1,2,3,4)(5,6)(7,8)(9,10),)) """ return self._mc, self._dis @@ -626,7 +633,9 @@ def __contains__(self, x): sage: A = AtomicSpecies("X") sage: G = PermutationGroup([[(1,2)], [(3,4)]]); G + Permutation Group with generators [(3,4), (1,2)] sage: G.disjoint_direct_product_decomposition() + {{1, 2}, {3, 4}} sage: G in A False """ @@ -706,10 +715,14 @@ def _project(self, G, pi, part): sage: P = PolynomialSpecies(ZZ, ["X", "Y"]) sage: M = P._indices sage: G = PermutationGroup([[(1,2),(3,4)], [(5,6)]]); G + Permutation Group with generators [(5,6), (1,2)(3,4)] sage: parts = G.disjoint_direct_product_decomposition(); parts + {{1, 2, 3, 4}, {5, 6}} sage: pi = {1: [1,2,3,4], 2: [5,6]} sage: M._project(G, pi, parts[0]) + (Permutation Group with generators [(), (1,2)(3,4)], {1: [1, 2, 3, 4]}) sage: M._project(G, pi, parts[1]) + (Permutation Group with generators [(), (5,6)], {2: [5, 6]}) """ restricted_gens = [[cyc for cyc in gen.cycle_tuples() if cyc[0] in part] for gen in G.gens()] mapping = dict() @@ -938,8 +951,13 @@ def __pow__(self, n): sage: M = P._indices sage: E2 = M(SymmetricGroup(2), {1: [1,2]}) sage: (E2._group, E2._dompart, E2._mc, E2._tc) + (Permutation Group with generators [(1,2)], (frozenset({1, 2}),), (2,), 2) sage: E2_3 = E2 ^ 3 sage: (E2_3._group, E2_3._dompart, E2_3._mc, E2_3._tc) + (Permutation Group with generators [(5,6), (3,4), (1,2)], + (frozenset({1, 2, 3, 4, 5, 6}),), + (6,), + 6) """ res = super().__pow__(n) elm = self.parent()._cache_get(res) @@ -999,7 +1017,9 @@ def grade(self): sage: G = PermutationGroup([[(1,2),(3,4),(5,6),(7,8,9,10)]]); G Permutation Group with generators [(1,2)(3,4)(5,6)(7,8,9,10)] sage: A = M(G, {1: [1,2,3,4], 2: [5,6,7,8,9,10]}); A + {((1,2,3,4)(5,6)(7,8)(9,10),): (frozenset({8, 5, 6, 7}), frozenset({1, 2, 3, 4, 9, 10}))} sage: A.grade() + (4, 6) """ return self._mc @@ -1014,7 +1034,9 @@ def domain(self): sage: G = PermutationGroup([[(1,2),(3,4),(5,6),(7,8,9,10)]]); G Permutation Group with generators [(1,2)(3,4)(5,6)(7,8,9,10)] sage: A = M(G, {1: [1,2,3,4], 2: [5,6,7,8,9,10]}); A + {((1,2,3,4)(5,6)(7,8)(9,10),): (frozenset({8, 5, 6, 7}), frozenset({1, 2, 3, 4, 9, 10}))} sage: A.domain() + {1, 2, 3, 4, 5, 6, 7, 8, 9, 10} """ return FiniteEnumeratedSet(range(1, self._tc + 1)) From 401ad51e6b1f15684419960778f35870f1e72aa9 Mon Sep 17 00:00:00 2001 From: Verrel Rievaldo Wijaya Date: Mon, 26 Aug 2024 12:17:02 +0700 Subject: [PATCH 156/537] Fix docstring in ``weight_vectors`` --- src/sage/rings/semirings/tropical_variety.py | 24 +++++++++----------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/src/sage/rings/semirings/tropical_variety.py b/src/sage/rings/semirings/tropical_variety.py index cd2d9bc84b5..d77cde29d47 100644 --- a/src/sage/rings/semirings/tropical_variety.py +++ b/src/sage/rings/semirings/tropical_variety.py @@ -643,19 +643,17 @@ def weight_vectors(self): `S_1, ldots, S_k` has a normal vector `n_1, \ldots, n_k`. Make sure that the normal vector is scale to an integer vector such that the greatest common divisor of its elements is 1. - + The weight vector of a component `S_i` with respect to `L` can be found by calculating the cross product between direction vectors of `L` and normal vector `n_i`.These vectors will - satisfy the following balancing condition: - `\sum_{i=1}^k w_k v_k = 0`. + satisfy the balancing condition `\sum_{i=1}^k w_k v_k = 0`. OUTPUT: - A tuple of two dictionaries: - - The first dictionary contains equations representing the - intersections. - - The second dictionary contains lists of vectors. + A tuple of two dictionaries. The first dictionary contains + equations representing the intersections. The second dictionary + contains lists of vectors. EXAMPLES: @@ -683,13 +681,13 @@ def weight_vectors(self): sage: tv = p1.tropical_variety() sage: tv.weight_vectors() ({0: ((u1, u3 - 7/3, u3 - 10/3, u3), {u1 <= u3 - 22/3}), - 1: ((u2 - 4, u2 + 1, u2, u3), {u2 <= u3 - 10/3}), - 2: ((2*u1 - u3 - 2/3, u3 - 7/3, u1, u3), {u3 - 10/3 <= u1}), - 3: ((u3 - 22/3, u2, u3 - 10/3, u3), {u3 - 7/3 <= u2})}, + 1: ((u2 - 4, u2 + 1, u2, u3), {u2 <= u3 - 10/3}), + 2: ((2*u1 - u3 - 2/3, u3 - 7/3, u1, u3), {u3 - 10/3 <= u1}), + 3: ((u3 - 22/3, u2, u3 - 10/3, u3), {u3 - 7/3 <= u2})}, {0: [(0, 1, 1, -2), (0, 1, -2, 1), (0, -2, 1, 1)], - 1: [(-2, 1, 1, 0), (3, -3, 0, 0), (-1, 2, -1, 0)], - 2: [(-1, 5, 2, -6), (2, 1, -4, 1), (-1, -6, 2, 5)], - 3: [(-1, 0, -1, 2), (-2, 0, 1, 1), (3, 0, 0, -3)]}) + 1: [(-2, 1, 1, 0), (3, -3, 0, 0), (-1, 2, -1, 0)], + 2: [(-1, 5, 2, -6), (2, 1, -4, 1), (-1, -6, 2, 5)], + 3: [(-1, 0, -1, 2), (-2, 0, 1, 1), (3, 0, 0, -3)]}) """ from sage.symbolic.ring import SR from sage.symbolic.relation import solve From e7dcaef563d6bd03634b5699b5e7a704f43ad10e Mon Sep 17 00:00:00 2001 From: Newtech66 Date: Mon, 26 Aug 2024 10:55:04 +0530 Subject: [PATCH 157/537] some more doctests --- src/sage/rings/species.py | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/src/sage/rings/species.py b/src/sage/rings/species.py index 1d77afe6818..3cae2094279 100644 --- a/src/sage/rings/species.py +++ b/src/sage/rings/species.py @@ -813,6 +813,19 @@ def one(self): def gen(self, x): r""" Create the molecular species from an atomic species. + + EXAMPLES:: + + sage: P = PolynomialSpecies(ZZ, "X, Y") + sage: At = AtomicSpecies("X, Y") + sage: G = PermutationGroup([[(1,2),(3,4)]]); G + sage: pi = {1: [1,2], 2: [3,4]} + sage: E2XY = At(G, pi) + sage: At(G, pi).rename("E_2(XY)"); E2XY + E_2(XY) + sage: m = P._indices.gen((G, pi)); m + E_2(XY) + sage: type(m) """ if x not in self._indices: raise IndexError(f"{x} is not in the index set") @@ -918,6 +931,17 @@ def __floordiv__(self, elt): def _mul_(self, other): r""" Multiply ``self`` by ``other``. + + TESTS:: + + sage: P = PolynomialSpecies(ZZ, "X, Y") + sage: M = P._indices + sage: E2X = M(SymmetricGroup(2), {1: [1,2]}); E2X + sage: (E2X._group, E2X._dompart, E2X._mc, E2X._tc) + sage: E2Y = M(SymmetricGroup(2), {2: [1,2]}); E2Y + sage: (E2Y._group, E2Y._dompart, E2Y._mc, E2Y._tc) + sage: E2XE2Y = E2X * E2Y; E2XE2Y + sage: (E2XE2Y._group, E2XE2Y._dompart, E2XE2Y._mc, E2XE2Y._tc) """ res = super()._mul_(other) elm = self.parent()._cache_get(res) @@ -1232,6 +1256,18 @@ def __init__(self, base_ring, names): def degree_on_basis(self, m): r""" Return the degree of the molecular species indexed by ``m``. + + EXAMPLES:: + + sage: P = PolynomialSpecies(ZZ, ["X", "Y"]) + sage: E4X = P(SymmetricGroup(4), {1: range(1, 5)}); E4X + E_4(X) + sage: E4Y = P(SymmetricGroup(4), {2: range(1, 5)}); E4Y + E_4(Y) + sage: P.degree_on_basis(E4X.support()[0]) + (4, 0) + sage: P.degree_on_basis(E4Y.support()[0]) + (0, 4) """ return m.grade() From 046aa23d6873fddcb569c324854ab0d1eea815de Mon Sep 17 00:00:00 2001 From: Newtech66 Date: Mon, 26 Aug 2024 10:56:36 +0530 Subject: [PATCH 158/537] run doctest fixer --- src/sage/rings/species.py | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/src/sage/rings/species.py b/src/sage/rings/species.py index 3cae2094279..a4625cd6182 100644 --- a/src/sage/rings/species.py +++ b/src/sage/rings/species.py @@ -819,6 +819,7 @@ def gen(self, x): sage: P = PolynomialSpecies(ZZ, "X, Y") sage: At = AtomicSpecies("X, Y") sage: G = PermutationGroup([[(1,2),(3,4)]]); G + Permutation Group with generators [(1,2)(3,4)] sage: pi = {1: [1,2], 2: [3,4]} sage: E2XY = At(G, pi) sage: At(G, pi).rename("E_2(XY)"); E2XY @@ -826,6 +827,7 @@ def gen(self, x): sage: m = P._indices.gen((G, pi)); m E_2(XY) sage: type(m) + """ if x not in self._indices: raise IndexError(f"{x} is not in the index set") @@ -937,11 +939,26 @@ def _mul_(self, other): sage: P = PolynomialSpecies(ZZ, "X, Y") sage: M = P._indices sage: E2X = M(SymmetricGroup(2), {1: [1,2]}); E2X + E_2(X) sage: (E2X._group, E2X._dompart, E2X._mc, E2X._tc) + (Permutation Group with generators [(1,2)], + (frozenset({1, 2}), frozenset()), + (2, 0), + 2) sage: E2Y = M(SymmetricGroup(2), {2: [1,2]}); E2Y + E_2(Y) sage: (E2Y._group, E2Y._dompart, E2Y._mc, E2Y._tc) + (Permutation Group with generators [(1,2)], + (frozenset(), frozenset({1, 2})), + (0, 2), + 2) sage: E2XE2Y = E2X * E2Y; E2XE2Y + E_2(X)*E_2(Y) sage: (E2XE2Y._group, E2XE2Y._dompart, E2XE2Y._mc, E2XE2Y._tc) + (Permutation Group with generators [(3,4), (1,2)], + (frozenset({1, 2}), frozenset({3, 4})), + (2, 2), + 4) """ res = super()._mul_(other) elm = self.parent()._cache_get(res) @@ -1130,7 +1147,7 @@ def inner_sum(self, base_ring, names, *args): sage: M = P._indices sage: C4 = M(CyclicPermutationGroup(4)) sage: C4.inner_sum(ZZ, "X, Y", [2, 2]) # X^2Y^2 + C2(XY) - {((1,2)(3,4),): (frozenset({1, 2}), frozenset({3, 4}))} + X^2*Y^2 + E_2(XY) + X^2*Y^2 """ # TODO: No checks are performed right now, must be added. From 125771fef59f1837d0dd8771393dd02a0b61707a Mon Sep 17 00:00:00 2001 From: Newtech66 Date: Mon, 26 Aug 2024 11:03:54 +0530 Subject: [PATCH 159/537] pycodestyle fix --- src/sage/rings/species.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/rings/species.py b/src/sage/rings/species.py index a4625cd6182..1c453a87ea5 100644 --- a/src/sage/rings/species.py +++ b/src/sage/rings/species.py @@ -843,7 +843,7 @@ def gen(self, x): elm._mc = at._mc elm._tc = at._tc return elm - + def _repr_(self): r""" Return a string representation of ``self``. From 2cedfcb21a196bc7143e7b939a1444e5caefd783 Mon Sep 17 00:00:00 2001 From: Newtech66 Date: Mon, 26 Aug 2024 15:59:50 +0530 Subject: [PATCH 160/537] change AtomicSpeciesElement _repr_ and remove multicardinality check in MolecularSpecies __call__ --- src/sage/rings/species.py | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/src/sage/rings/species.py b/src/sage/rings/species.py index 1c453a87ea5..f8fa223981c 100644 --- a/src/sage/rings/species.py +++ b/src/sage/rings/species.py @@ -455,9 +455,13 @@ def _repr_(self): sage: G = PermutationGroup([[(1,2),(3,4),(5,6),(7,8,9,10)]]); G Permutation Group with generators [(1,2)(3,4)(5,6)(7,8,9,10)] sage: A = At(G, {1: [1,2,3,4], 2: [5,6,7,8,9,10]}); A - {((1,2,3,4)(5,6)(7,8)(9,10),): (frozenset({8, 5, 6, 7}), frozenset({1, 2, 3, 4, 9, 10}))} + {((1,2,3,4)(5,6)(7,8)(9,10),): ({5, 6, 7, 8}, {1, 2, 3, 4, 9, 10})} + sage: A = At(G, {2: [1,2,3,4,5,6,7,8,9,10]}); A + {((1,2,3,4)(5,6)(7,8)(9,10),): ({}, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10})} """ - return "{" + f"{self._dis}: {self._dompart}" + "}" + dompart = ', '.join("{" + repr(sorted(b))[1:-1] + "}" + for b in self._dompart) + return "{" + f"{self._dis}: ({dompart})" + "}" class AtomicSpecies(UniqueRepresentation, Parent, ElementCache): @@ -1176,8 +1180,7 @@ def inner_sum(self, base_ring, names, *args): def __call__(self, *args): r""" Substitute M_1...M_k into self. - M_i must all have same arity, same multicardinality, - and must be molecular. + M_i must all have same arity and must be molecular. EXAMPLES:: @@ -1191,6 +1194,12 @@ def __call__(self, *args): E_2 sage: E2(E2) P_4 + + sage: P = PolynomialSpecies(ZZ, ["X","Y"]) + sage: M = P._indices + sage: X = M(SymmetricGroup(1), {1:[1]}) + sage: Y = M(SymmetricGroup(1), {2:[1]}) + sage: (X*Y)(X, Y^2) """ if len(args) != self.parent()._k: raise ValueError("number of args must match arity of self") @@ -1198,8 +1207,6 @@ def __call__(self, *args): raise ValueError("all args must be molecular species") if len(set(arg.parent()._k for arg in args)) > 1: raise ValueError("all args must have same arity") - if len(set(arg._mc for arg in args)) > 1: - raise ValueError("all args must have same multicardinality") gens = [] From 29bb7eb6cd9d6b02bad08c4e9ef8d13d5dea9ea6 Mon Sep 17 00:00:00 2001 From: Newtech66 Date: Mon, 26 Aug 2024 16:08:00 +0530 Subject: [PATCH 161/537] Get rid of some calls to libgap ConjugateGroup without passing domain and use gens_small in ConjugacyClassOfSubgroups _canonicalize --- src/sage/rings/species.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/rings/species.py b/src/sage/rings/species.py index f8fa223981c..43123503cc0 100644 --- a/src/sage/rings/species.py +++ b/src/sage/rings/species.py @@ -170,7 +170,7 @@ def _canonicalize(self): return sorted_orbits = sorted([sorted(orbit) for orbit in self._C.orbits()], key=len, reverse=True) pi = PermutationGroupElement(list(chain.from_iterable(sorted_orbits))).inverse() - self._C = PermutationGroup(gap_group=libgap.ConjugateGroup(self._C, pi)) + self._C = PermutationGroup(self._C.gens_small(), domain=self._C.domain()).conjugate(pi) def __eq__(self, other): r""" @@ -1048,7 +1048,7 @@ def _canonicalize(self): return sorted_orbits = sorted([sorted(orbit) for orbit in self._group.orbits()], key=len, reverse=True) pi = PermutationGroupElement(list(chain.from_iterable(sorted_orbits))).inverse() - self._group = PermutationGroup(gap_group=libgap.ConjugateGroup(self._group, pi)) + self._group = self._group.conjugate(pi) self._dompart = tuple(frozenset(pi(k) for k in v) for v in self._dompart) def grade(self): From 696f0e12786e6473158e30c9ffc8e3dce0096591 Mon Sep 17 00:00:00 2001 From: Newtech66 Date: Mon, 26 Aug 2024 16:08:53 +0530 Subject: [PATCH 162/537] run doctest fixer --- src/sage/rings/species.py | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/src/sage/rings/species.py b/src/sage/rings/species.py index 43123503cc0..a58fe1ef57a 100644 --- a/src/sage/rings/species.py +++ b/src/sage/rings/species.py @@ -63,15 +63,15 @@ def _cache_get(self, elm): sage: G = PermutationGroup([[(1,2),(3,4),(5,6),(7,8,9,10)]]); G Permutation Group with generators [(1,2)(3,4)(5,6)(7,8,9,10)] sage: A = M(G, {1: [1,2,3,4], 2: [5,6,7,8,9,10]}); A - {((1,2,3,4)(5,6)(7,8)(9,10),): (frozenset({8, 5, 6, 7}), frozenset({1, 2, 3, 4, 9, 10}))} + {((1,2,3,4)(5,6)(7,8)(9,10),): ({5, 6, 7, 8}, {1, 2, 3, 4, 9, 10})} sage: C = M(G, {1: [1,2,5,6], 2: [3,4,7,8,9,10]}); C - {((1,2,3,4)(5,6)(7,8)(9,10),): (frozenset({8, 5, 6, 7}), frozenset({1, 2, 3, 4, 9, 10}))} + {((1,2,3,4)(5,6)(7,8)(9,10),): ({5, 6, 7, 8}, {1, 2, 3, 4, 9, 10})} sage: from sage.rings.species import ElementCache sage: E = ElementCache() sage: E._cache_get(A) - {((1,2,3,4)(5,6)(7,8)(9,10),): (frozenset({8, 5, 6, 7}), frozenset({1, 2, 3, 4, 9, 10}))} + {((1,2,3,4)(5,6)(7,8)(9,10),): ({5, 6, 7, 8}, {1, 2, 3, 4, 9, 10})} sage: E._cache_get(C) - {((1,2,3,4)(5,6)(7,8)(9,10),): (frozenset({8, 5, 6, 7}), frozenset({1, 2, 3, 4, 9, 10}))} + {((1,2,3,4)(5,6)(7,8)(9,10),): ({5, 6, 7, 8}, {1, 2, 3, 4, 9, 10})} """ # TODO: Make _canonicalize optional. # Possibly the following works: @@ -356,7 +356,7 @@ def _element_key(self): sage: G = PermutationGroup([[(1,2),(3,4),(5,6),(7,8,9,10)]]); G Permutation Group with generators [(1,2)(3,4)(5,6)(7,8,9,10)] sage: A = At(G, {1: [1,2,3,4], 2: [5,6,7,8,9,10]}); A - {((1,2,3,4)(5,6)(7,8)(9,10),): (frozenset({8, 5, 6, 7}), frozenset({1, 2, 3, 4, 9, 10}))} + {((1,2,3,4)(5,6)(7,8)(9,10),): ({5, 6, 7, 8}, {1, 2, 3, 4, 9, 10})} sage: A._element_key() ((4, 6), ((1,2,3,4)(5,6)(7,8)(9,10),)) """ @@ -395,11 +395,11 @@ def __hash__(self): sage: H = PermutationGroup([[(1,2,3,4),(5,6),(7,8),(9,10)]]); H Permutation Group with generators [(1,2,3,4)(5,6)(7,8)(9,10)] sage: A = At(G, {1: [1,2,3,4], 2: [5,6,7,8,9,10]}); A - {((1,2,3,4)(5,6)(7,8)(9,10),): (frozenset({8, 5, 6, 7}), frozenset({1, 2, 3, 4, 9, 10}))} + {((1,2,3,4)(5,6)(7,8)(9,10),): ({5, 6, 7, 8}, {1, 2, 3, 4, 9, 10})} sage: B = At(H, {1: [1,2,3,4], 2: [5,6,7,8,9,10]}); B - {((1,2,3,4)(5,6)(7,8)(9,10),): (frozenset({1, 2, 3, 4}), frozenset({5, 6, 7, 8, 9, 10}))} + {((1,2,3,4)(5,6)(7,8)(9,10),): ({1, 2, 3, 4}, {5, 6, 7, 8, 9, 10})} sage: C = At(G, {1: [1,2,5,6], 2: [3,4,7,8,9,10]}); C - {((1,2,3,4)(5,6)(7,8)(9,10),): (frozenset({8, 5, 6, 7}), frozenset({1, 2, 3, 4, 9, 10}))} + {((1,2,3,4)(5,6)(7,8)(9,10),): ({5, 6, 7, 8}, {1, 2, 3, 4, 9, 10})} sage: hash(A) == hash(B) True sage: hash(A) == hash(C) @@ -519,7 +519,7 @@ def an_element(self): sage: At1.an_element() E_2 sage: At2.an_element() - {((1,2)(3,4),): (frozenset({1, 2}), frozenset({3, 4}))} + {((1,2)(3,4),): ({1, 2}, {3, 4})} """ G = PermutationGroup([[(2 * i - 1, 2 * i) for i in range(1, self._k + 1)]]) m = {i: [2 * i - 1, 2 * i] for i in range(1, self._k + 1)} @@ -1062,7 +1062,7 @@ def grade(self): sage: G = PermutationGroup([[(1,2),(3,4),(5,6),(7,8,9,10)]]); G Permutation Group with generators [(1,2)(3,4)(5,6)(7,8,9,10)] sage: A = M(G, {1: [1,2,3,4], 2: [5,6,7,8,9,10]}); A - {((1,2,3,4)(5,6)(7,8)(9,10),): (frozenset({8, 5, 6, 7}), frozenset({1, 2, 3, 4, 9, 10}))} + {((1,2,3,4)(5,6)(7,8)(9,10),): ({5, 6, 7, 8}, {1, 2, 3, 4, 9, 10})} sage: A.grade() (4, 6) """ @@ -1079,7 +1079,7 @@ def domain(self): sage: G = PermutationGroup([[(1,2),(3,4),(5,6),(7,8,9,10)]]); G Permutation Group with generators [(1,2)(3,4)(5,6)(7,8,9,10)] sage: A = M(G, {1: [1,2,3,4], 2: [5,6,7,8,9,10]}); A - {((1,2,3,4)(5,6)(7,8)(9,10),): (frozenset({8, 5, 6, 7}), frozenset({1, 2, 3, 4, 9, 10}))} + {((1,2,3,4)(5,6)(7,8)(9,10),): ({5, 6, 7, 8}, {1, 2, 3, 4, 9, 10})} sage: A.domain() {1, 2, 3, 4, 5, 6, 7, 8, 9, 10} """ @@ -1200,6 +1200,7 @@ def __call__(self, *args): sage: X = M(SymmetricGroup(1), {1:[1]}) sage: Y = M(SymmetricGroup(1), {2:[1]}) sage: (X*Y)(X, Y^2) + X*Y^2 """ if len(args) != self.parent()._k: raise ValueError("number of args must match arity of self") From 44a0b9bf087c70492330c2518b9abc6afb81fb0e Mon Sep 17 00:00:00 2001 From: Newtech66 Date: Mon, 26 Aug 2024 20:06:53 +0530 Subject: [PATCH 163/537] Working composition (thanks mantepse) --- src/sage/rings/species.py | 345 +++++++++++++++++++++++++++++++------- 1 file changed, 286 insertions(+), 59 deletions(-) diff --git a/src/sage/rings/species.py b/src/sage/rings/species.py index a58fe1ef57a..01210e0f757 100644 --- a/src/sage/rings/species.py +++ b/src/sage/rings/species.py @@ -1,19 +1,24 @@ from itertools import accumulate, chain +from sage.arith.misc import multinomial from sage.categories.graded_algebras_with_basis import GradedAlgebrasWithBasis from sage.categories.infinite_enumerated_sets import InfiniteEnumeratedSets from sage.categories.monoids import Monoids +from sage.categories.sets_cat import cartesian_product from sage.categories.sets_with_grading import SetsWithGrading from sage.combinat.free_module import CombinatorialFreeModule from sage.combinat.integer_vector import IntegerVectors +from sage.combinat.partition import Partitions from sage.groups.perm_gps.constructor import PermutationGroupElement from sage.groups.perm_gps.permgroup import PermutationGroup, PermutationGroup_generic from sage.groups.perm_gps.permgroup_named import SymmetricGroup from sage.libs.gap.libgap import libgap from sage.misc.cachefunc import cached_method +from sage.misc.misc_c import prod from sage.monoids.indexed_free_monoid import (IndexedFreeAbelianMonoid, IndexedFreeAbelianMonoidElement, IndexedMonoid) +from sage.functions.other import binomial from sage.rings.integer_ring import ZZ from sage.sets.finite_enumerated_set import FiniteEnumeratedSet from sage.structure.element import Element, parent @@ -168,7 +173,8 @@ def _canonicalize(self): """ if self._C == SymmetricGroup(0): return - sorted_orbits = sorted([sorted(orbit) for orbit in self._C.orbits()], key=len, reverse=True) + sorted_orbits = sorted((sorted(orbit) for orbit in self._C.orbits()), + key=len, reverse=True) pi = PermutationGroupElement(list(chain.from_iterable(sorted_orbits))).inverse() self._C = PermutationGroup(self._C.gens_small(), domain=self._C.domain()).conjugate(pi) @@ -346,6 +352,12 @@ def __init__(self, parent, dis, domain_partition): self._mc = tuple(len(v) for v in self._dompart) self._tc = sum(self._mc) + def grade(self): + r""" + Return the grade of ``self``. + """ + return self._mc + def _element_key(self): r""" Return the cache lookup key for ``self``. @@ -724,11 +736,13 @@ def _project(self, G, pi, part): {{1, 2, 3, 4}, {5, 6}} sage: pi = {1: [1,2,3,4], 2: [5,6]} sage: M._project(G, pi, parts[0]) - (Permutation Group with generators [(), (1,2)(3,4)], {1: [1, 2, 3, 4]}) + (Permutation Group with generators [(1,2)(3,4)], {1: [1, 2, 3, 4]}) sage: M._project(G, pi, parts[1]) - (Permutation Group with generators [(), (5,6)], {2: [5, 6]}) + (Permutation Group with generators [(5,6)], {2: [5, 6]}) """ - restricted_gens = [[cyc for cyc in gen.cycle_tuples() if cyc[0] in part] for gen in G.gens()] + restricted_gens = [[cyc for cyc in gen.cycle_tuples() if cyc[0] in part] + for gen in G.gens()] + restricted_gens = [gen for gen in restricted_gens if gen] mapping = dict() for k, v in pi.items(): es = [e for e in v if e in part] @@ -832,11 +846,15 @@ def gen(self, x): E_2(XY) sage: type(m) + + sage: M = P._indices + sage: m = M(SymmetricGroup(6).young_subgroup([2, 2, 2]), {1: [1,2], 2: [3,4,5,6]}) + sage: list(m) + [(E_2(X), 1), (E_2(Y), 2)] """ if x not in self._indices: raise IndexError(f"{x} is not in the index set") - at = None - if isinstance(x, PermutationGroup_generic): + if isinstance(x, (PermutationGroup_generic, AtomicSpecies.Element)): at = self._indices(x) else: at = self._indices(x[0], x[1]) @@ -1085,52 +1103,7 @@ def domain(self): """ return FiniteEnumeratedSet(range(1, self._tc + 1)) - def hadamard_product(self, other): - r""" - Compute the hadamard product of ``self`` and ``other``. - - EXAMPLES: - - Exercise 2.1.9 from the BLL book:: - - sage: P = PolynomialSpecies(ZZ, ["X"]) - sage: M = P._indices - sage: C3 = M(CyclicPermutationGroup(3)) - sage: X = M(SymmetricGroup(1)) - sage: E2 = M(SymmetricGroup(2)) - sage: C3.hadamard_product(C3) - 2*C_3 - sage: (X^3).hadamard_product(C3) - 2*X^3 - sage: (X*E2).hadamard_product(X*E2) - X*E_2 + X^3 - """ - P = self.parent() - if P is not other.parent(): - raise ValueError("the factors of a Hadamard product must be the same") - Pn = PolynomialSpecies(ZZ, P._indices._names) - - if self._mc != other._mc: - return Pn.zero() - # create S - S = SymmetricGroup(self._tc).young_subgroup(self._mc) - # conjugate self and other to match S - conj_self = PermutationGroupElement(list(chain.from_iterable(self._dompart))).inverse() - conj_other = PermutationGroupElement(list(chain.from_iterable(other._dompart))).inverse() - G = libgap.ConjugateGroup(self._group, conj_self) - H = libgap.ConjugateGroup(other._group, conj_other) - # create dompart - dpart = {i + 1: range(x - self._mc[i] + 1, x + 1) for i, x in enumerate(accumulate(self._mc))} - # create double coset representatives - taus = libgap.DoubleCosetRepsAndSizes(S, G, H) - # loop over representatives - res = Pn.zero() - for tau, _ in taus: - F = libgap.Intersection(libgap.ConjugateGroup(H, tau), G) - res += Pn(PermutationGroup(gap_group=F, domain=self.domain()), dpart) - return res - - def inner_sum(self, base_ring, names, *args): + def compose_with_singletons(self, base_ring, names, args): r""" Compute the inner sum of exercise 2.6.16 of BLL book. @@ -1138,7 +1111,7 @@ def inner_sum(self, base_ring, names, *args): - ``base_ring``, the base ring of the result - - ``names``, the names of the result + - ``names``, the (flat) list of names of the result - ``args``, the sequence of compositions, each of which sums to the corresponding cardinality of @@ -1150,12 +1123,20 @@ def inner_sum(self, base_ring, names, *args): sage: P = PolynomialSpecies(ZZ, "X") sage: M = P._indices sage: C4 = M(CyclicPermutationGroup(4)) - sage: C4.inner_sum(ZZ, "X, Y", [2, 2]) # X^2Y^2 + C2(XY) + sage: C4.compose_with_singletons(ZZ, "X, Y", [[2, 2]]) # X^2Y^2 + C2(XY) E_2(XY) + X^2*Y^2 + sage: P = PolynomialSpecies(ZZ, ["X", "Y"]) + sage: M = P._indices + sage: F = M(PermutationGroup([[(1,2,3), (4,5,6)]]), {1: [1,2,3], 2: [4,5,6]}) + sage: F + {((1,2,3)(4,5,6),): ({1, 2, 3}, {4, 5, 6})} + sage: F.compose_with_singletons(ZZ, "X1, X2, X3, Y1, Y2", [[1, 1, 1], [2, 1]]) + 6*X1*X2*X3*Y1^2*Y2 + """ # TODO: No checks are performed right now, must be added. - # Checks: all args in compositions, sums must match cardinalities. + # Checks: all args in Compositions, sums must match cardinalities. # Create group of the composition Pn = PolynomialSpecies(base_ring, names) @@ -1165,6 +1146,7 @@ def inner_sum(self, base_ring, names, *args): G = libgap.ConjugateGroup(self._group, conj) comp = list(chain.from_iterable(args)) + dpart = {i + 1: range(x - comp[i] + 1, x + 1) for i, x in enumerate(accumulate(comp))} # Create the double coset representatives. S_down = SymmetricGroup(sum(comp)).young_subgroup(comp) S_up = SymmetricGroup(self._tc).young_subgroup(self._mc) @@ -1173,7 +1155,6 @@ def inner_sum(self, base_ring, names, *args): for tau, _ in taus: H = libgap.Intersection(libgap.ConjugateGroup(G, tau), S_down) grp = PermutationGroup(gap_group=H, domain=self.domain()) - dpart = {i + 1: range(x - comp[i] + 1, x + 1) for i, x in enumerate(accumulate(comp))} res += Pn(grp, dpart) return res @@ -1201,6 +1182,16 @@ def __call__(self, *args): sage: Y = M(SymmetricGroup(1), {2:[1]}) sage: (X*Y)(X, Y^2) X*Y^2 + + A multivariate example:: + + sage: M1 = PolynomialSpecies(QQ, "X")._indices + sage: M2 = PolynomialSpecies(QQ, "X, Y")._indices + sage: C3 = M1(CyclicPermutationGroup(3)) + sage: X = M2(SymmetricGroup(1), {1: [1]}) + sage: Y = M2(SymmetricGroup(1), {2: [1]}) + sage: C3(X*Y) + {((1,2,3)(4,5,6),): ({1, 2, 3}, {4, 5, 6})} """ if len(args) != self.parent()._k: raise ValueError("number of args must match arity of self") @@ -1290,11 +1281,11 @@ def degree_on_basis(self, m): sage: E4Y = P(SymmetricGroup(4), {2: range(1, 5)}); E4Y E_4(Y) sage: P.degree_on_basis(E4X.support()[0]) - (4, 0) + 4 sage: P.degree_on_basis(E4Y.support()[0]) - (0, 4) + 4 """ - return m.grade() + return m._tc def _element_constructor_(self, G, pi=None): r""" @@ -1414,7 +1405,73 @@ def _repr_(self): return f"Polynomial species in {names[0]} over {self.base_ring()}" return f"Polynomial species in {', '.join(names)} over {self.base_ring()}" + def exponential(self, multiplicities, degrees): + r""" + Return `E(\sum_i m_i X_i)` in the specified degrees. + + EXAMPLES:: + + sage: P = PolynomialSpecies(QQ, ["X"]) + sage: P.exponential([3/2], [7]) + 3/4*X*E_6 + 3/4*E_2*E_5 + 3/4*E_3*E_4 + 3/2*E_7 - 3/16*X^2*E_5 + - 3/8*X*E_2*E_4 - 3/16*X*E_3^2 - 3/16*E_2^2*E_3 + 3/32*X^3*E_4 + + 9/32*X^2*E_2*E_3 + 3/32*X*E_2^3 - 15/256*X^4*E_3 - 15/128*X^3*E_2^2 + + 21/512*X^5*E_2 - 9/2048*X^7 + + TESTS:: + + sage: from sage.rings.lazy_species import LazySpecies + sage: L = LazySpecies(QQ, "X") + sage: E = L(lambda n: SymmetricGroup(n)) + + sage: c = 3/2; all((E^c)[i] == P.exponential([c], [i]) for i in range(6)) + True + + sage: c = -5/3; all((E^c)[i] == P.exponential([c], [i]) for i in range(6)) + True + + sage: c = 0; all((E^c)[i] == P.exponential([c], [i]) for i in range(6)) + True + + sage: c = 1; all((E^c)[i] == P.exponential([c], [i]) for i in range(6)) + True + + sage: c = -1; all((E^c)[i] == P.exponential([c], [i]) for i in range(6)) + True + + """ + def power(s, mu_exp): + return prod(self(SymmetricGroup(i), {s: range(1, i+1)}) ** m + for i, m in enumerate(mu_exp, 1)) + + def factor(s, c, d): + return sum(binomial(c, j) + * sum(multinomial(mu_exp := mu.to_exp()) + * power(s, mu_exp) + for mu in Partitions(d, length=j)) + for j in range(d+1)) + + return prod(factor(s+1, multiplicities[s], degrees[s]) + for s in range(self._k)) + class Element(CombinatorialFreeModule.Element): + def is_constant(self): + """ + Return ``True`` if this is a constant polynomial species. + + EXAMPLES:: + + sage: P = PolynomialSpecies(ZZ, ["X", "Y"]) + sage: X = P(SymmetricGroup(1), {1: [1]}) + sage: X.is_constant() + False + sage: (3*P.one()).is_constant() + True + sage: P(0).is_constant() + True + """ + return self.is_zero() or not self.degree() + def is_virtual(self): r""" Return if ``self`` is a virtual species. @@ -1474,3 +1531,173 @@ def is_atomic(self): True """ return self.is_molecular() and len(self.support()[0]) == 1 + + def hadamard_product(self, other): + r""" + Compute the hadamard product of ``self`` and ``other``. + + EXAMPLES: + + Exercise 2.1.9 from the BLL book:: + + sage: P = PolynomialSpecies(ZZ, ["X"]) + sage: C3 = P(CyclicPermutationGroup(3)) + sage: X = P(SymmetricGroup(1)) + sage: E2 = P(SymmetricGroup(2)) + sage: C3.hadamard_product(C3) + 2*C_3 + sage: (X^3).hadamard_product(C3) + 2*X^3 + sage: (X*E2).hadamard_product(X*E2) + X*E_2 + X^3 + + TESTS:: + + sage: C3.hadamard_product(-C3) + -2*C_3 + """ + P = self.parent() + if P is not other.parent(): + raise ValueError("the factors of a Hadamard product must be the same") + + res = P.zero() + # we should first collect matching multicardinalities. + for L, c in self: + S = SymmetricGroup(L._tc).young_subgroup(L._mc) + # conjugate L and R to match S + conj_L = PermutationGroupElement(list(chain.from_iterable(L._dompart))).inverse() + G = libgap.ConjugateGroup(L._group, conj_L) + dpart = {i + 1: range(x - L._mc[i] + 1, x + 1) for i, x in enumerate(accumulate(L._mc))} + for R, d in other: + if L._mc != R._mc: + continue + conj_R = PermutationGroupElement(list(chain.from_iterable(R._dompart))).inverse() + H = libgap.ConjugateGroup(R._group, conj_R) + taus = libgap.DoubleCosetRepsAndSizes(S, G, H) + # loop over representatives + new = P.zero() + for tau, _ in taus: + F = libgap.Intersection(libgap.ConjugateGroup(H, tau), G) + new += P(PermutationGroup(gap_group=F, domain=L.domain()), dpart) + res += c * d * new + + return res + + def compose_with_weighted_singletons(self, base_ring, names, multiplicities, degrees): + r""" + Compute the composition with + `(\sum_j m_{1,j} X_{1,j}, \sum_j m_{2,j} X_{2,j}, \dots)` + in the specified degrees. + + The `k`-sort species ``self`` should be homogeneous. + + INPUT: + + - ``names``, the (flat) list of names of the result + + - ``multiplicities``, a (flat) list of constants + + - ``degrees``, a `k`-tuple of compositions `c_1, + \dots, c_k`, such that the size of `c_i` is the + degree of self in sort `i`. + + EXAMPLES: + + Equation (2.5.41):: + + sage: P = PolynomialSpecies(ZZ, ["X"]) + sage: E2 = P(SymmetricGroup(2)) + sage: E2.compose_with_weighted_singletons(ZZ, ["X"], [-1], [[2]]) + -E_2 + X^2 + + sage: C4 = P(CyclicPermutationGroup(4)) + sage: C4.compose_with_weighted_singletons(ZZ, ["X"], [-1], [[4]]) + {((1,2)(3,4),): ({1, 2, 3, 4})} - C_4 + + Exercise (2.5.17):: + + sage: C4.compose_with_weighted_singletons(ZZ, ["X", "Y"], [1, 1], [[2, 2]]) + E_2(XY) + X^2*Y^2 + sage: C4.compose_with_weighted_singletons(ZZ, ["X", "Y"], [1, 1], [[3, 1]]) + X^3*Y + sage: C4.compose_with_weighted_singletons(ZZ, ["X", "Y"], [1, 1], [[4, 0]]) + C_4(X) + + Auger et al., Equation (4.60):: + + sage: C4.compose_with_weighted_singletons(ZZ, ["X", "Y"], [1, -1], [[2, 2]]) + -E_2(XY) + 2*X^2*Y^2 + + TESTS:: + + sage: (C4+E2^2).compose_with_weighted_singletons(ZZ, ["X"], [-1], [[4]]) + {((1,2)(3,4),): ({1, 2, 3, 4})} - C_4 - 2*X^2*E_2 + E_2^2 + X^4 + + """ + P = self.parent() + if not self.support(): + return P.zero() + if not self.is_homogeneous(): + raise ValueError("element is not homogeneous") + + left = sum(c * M.compose_with_singletons(P.base_ring(), + names, + degrees) + for M, c in self) + P = left.parent() + right = P.exponential(multiplicities, + list(chain.from_iterable(degrees))) + return left.hadamard_product(right) + + def __call__(self, *args): + """ + + EXAMPLES:: + + sage: P = PolynomialSpecies(ZZ, ["X"]) + sage: X = P(SymmetricGroup(1)) + sage: E2 = P(SymmetricGroup(2)) + sage: E2(-X) + -E_2 + X^2 + sage: E2(X^2) + {((1,2)(3,4),): ({1, 2, 3, 4})} + + sage: E2(X + X^2) + E_2 + X^3 + {((1,2)(3,4),): ({1, 2, 3, 4})} + + sage: P2 = PolynomialSpecies(ZZ, ["X", "Y"]) + sage: X = P2(SymmetricGroup(1), {1:[1]}) + sage: Y = P2(SymmetricGroup(1), {2:[1]}) + sage: E2(X + Y) + E_2(Y) + X*Y + E_2(X) + + sage: E2(X*Y)(E2(X), E2(Y)) + {((7,8), (5,6), (3,4), (1,2), (1,3)(2,4)(5,7)(6,8)): ({1, 2, 3, 4}, {5, 6, 7, 8})} + + """ + P = self.parent() + if not self.support(): + return P.zero() + P0 = args[0].parent() + assert all(P0 == arg.parent() for arg in args), "all parents must be the same" + R = P.base_ring() + args = [sorted(g, key=lambda x: x[0]._mc) + for g in args] + multiplicities = [[c for _, c in g] for g in args] + molecules = [[M for M, _ in g] for g in args] + F_degrees = sorted(set(M._mc for M, _ in self)) + + result = P0.zero() + for n in F_degrees: + F = P.sum_of_terms((M, c) for M, c in self if M._mc == n) + for degrees in cartesian_product([IntegerVectors(n_i, length=len(arg)) + for n_i, arg in zip(n, args)]): + # each degree is a weak composition of the degree of F in sort i + names = ["X%s" % i for i in range(sum(len(arg) for arg in args))] + FX = F.compose_with_weighted_singletons(R, names, + list(chain.from_iterable(multiplicities)), + degrees) + FG = [(M(*list(chain.from_iterable(molecules))), c) + for M, c in FX] + result += P0.sum_of_terms(FG) + return result From 3763e592c4db96a874807716fa0d44266d0cfd7a Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Tue, 27 Aug 2024 14:39:17 +0530 Subject: [PATCH 164/537] Edited groebner_basis() lattice --- src/sage/matroids/chow_ring_ideal.py | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/src/sage/matroids/chow_ring_ideal.py b/src/sage/matroids/chow_ring_ideal.py index 92468e97492..15c31a8c268 100644 --- a/src/sage/matroids/chow_ring_ideal.py +++ b/src/sage/matroids/chow_ring_ideal.py @@ -230,8 +230,8 @@ def groebner_basis(self): flats = list(self._flats_generator) gb = list() R = self.ring() - if frozenset() in flats: - flats.remove(frozenset()) + if frozenset() not in flats: + flats.append(frozenset()) ranks = [self._matroid.rank(F) for F in flats] @@ -257,7 +257,7 @@ def m_n(i): else: for F in flats: - if F > P.join(list(subset)): #Getting missing argument error here + if F > P.join(list(subset)): term = R.one() for x in subset: term *= self._flats_generator[x] @@ -440,7 +440,7 @@ def groebner_basis(self): poly_ring = self.ring() for F in self._flats: for G in self._flats: - if not (F < G or G < F): + if not (F < G or G < F): #5.2 gb.append(self._flats_generator[F]*self._flats_generator[G]) for i in E: term = poly_ring.zero() @@ -448,19 +448,21 @@ def groebner_basis(self): for H in self._flats: if i in H: term += self._flats_generator[H] - if H > F: + if H > G: term1 += self._flats_generator[H] + if term != poly_ring.zero(): + gb.append(self._flats_generator[i] + term) #5.7 + if term1 != poly_ring.zero(): + gb.append(term1**(self._matroid.rank(G)) + 1) #5.6 - gb.append(self._flats_generator[i] + term) - gb.append(term1**(self._matroid.rank(F)) + 1) - - if i in F: - gb.append(self._flats_generator[i]*((term1)**self._matroid.rank(F))) + if i in G: #5.5 + if term1 != poly_ring.zero(): + gb.append(self._flats_generator[i]*((term1)**self._matroid.rank(G))) - elif not i in F: + elif not i in G: #5.3 gb.append(self._flats_generator[i]*self._flats_generator[F]) - elif G < F: + elif G < F: #5.4 gb.append(self._flats_generator[G]*term1**(self._matroid.rank(F)-self._matroid.rank(G))) g_basis = PolynomialSequence(poly_ring, [gb]) From 73acafea0f256d4d7bad5de57710f2e6e3a703d9 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Tue, 27 Aug 2024 14:39:38 +0530 Subject: [PATCH 165/537] Edited basis() method --- src/sage/matroids/chow_ring.py | 80 ++++++++++++++++++++++------------ 1 file changed, 51 insertions(+), 29 deletions(-) diff --git a/src/sage/matroids/chow_ring.py b/src/sage/matroids/chow_ring.py index 04b51341b51..1fc5e41b740 100644 --- a/src/sage/matroids/chow_ring.py +++ b/src/sage/matroids/chow_ring.py @@ -180,9 +180,9 @@ def basis(self): """ flats = [X for i in range(1, self._matroid.rank()) for X in self._matroid.flats(i)] - flats.append(frozenset()) maximum_rank = max(self._matroid.rank(F) for F in flats) flats_gen = self._ideal.flats_generator() + R = self._ideal.ring() flats = sorted(flats, key=lambda X: (len(X), sorted(X))) ranks = [self._matroid.rank(F) for F in flats] monomial_basis = [] @@ -203,15 +203,44 @@ def basis(self): elif self._presentation == 'atom-free': #all double equals need spacing first_rank = self._matroid.rank(flats[len(flats) - 1]) - print(first_rank) - for i in range(maximum_rank): - pow = [] - for j in range(1, len(flats) - 1): - if i < ranks[j] - ranks[j-1]: - pow.append((j , i)) - if sum(p[1] for p in pow) == first_rank + 1: - term = prod(flats_gen[flats[p[0]]] ** p[1] for p in pow) - monomial_basis.append(term) + reln = lambda p,q : p < q + P = Poset((flats, reln)) + chains = P.chains() + def generate_combinations(current_combination, index, max_powers, x_dict): + # Base case: If index equals the length of max_powers, print the current combination + if index == len(max_powers): + expression_terms = [x_dict[i+1] if current_combination[i] == 1 + else x_dict[i+1]**{current_combination[i]} + for i in range(len(current_combination)) if current_combination[i] != 0] + if expression_terms: + term = R.one() + for t in expression_terms: + term *= t + monomial_basis.append(term) + else: + monomial_basis.append(R.one()) + return + + # Recursive case: Iterate over the range for the current index + for power in range(max_powers[index]): + current_combination[index] = power + generate_combinations(current_combination, index + 1, max_powers, x_dict) + + for chain in chains: + x_dict = dict() + for i, F in enumerate(chain): + if F == frozenset(): + x_dict[i] = R.one() + else: + x_dict[i] = flats_gen[F] + ranks = [self._matroid.rank(F) for F in chain] + max_powers = [ranks[i-1] - ranks[i] for i in range(1, len(chain))] + k = len(chain) + current_combination = [0] * k + print(max_powers, k, x_dict, chain) + if sum(max_powers) == (first_rank + 1) and max_powers[len(chain) - 1] <= self._matroid.rank(chain[len(chain) - 1]): + generate_combinations(current_combination, 0, max_powers, x_dict) + else: def generate_combinations(current_combination, index, max_powers, x_dict): @@ -233,36 +262,29 @@ def generate_combinations(current_combination, index, max_powers, x_dict): for power in range(max_powers[index]): current_combination[index] = power generate_combinations(current_combination, index + 1, max_powers, x_dict) - - def m_n(i): - if flats[i] == frozenset(): - return 0 - else: - sum1 = 0 - for j in range(len(flats)): - if flats[j] < flats[i]: - sum1 += m_n(j) - - return ranks[i] - sum1 print(ranks) - flats = list(self._ideal.flats_generator()) R = self._ideal.ring() - if frozenset() in flats: - flats.remove(frozenset()) - reln = lambda p,q : p < q - P = Poset((flats, reln)) - chains = P.chains() + lattice_flats = self._matroid.lattice_of_flats() + chains = lattice_flats.chains() for chain in chains: + print(chain) + print(flats) max_powers = [] x_dict = dict() for F in chain: - max_powers.append(m_n(flats.index(F))) - x_dict[F] = flats_gen[F] + if F == frozenset(): + max_powers.append(0) + x_dict[F] = 1 + else: + max_powers.append(ranks[flats.index(F)] - ranks[flats.index(F) - 1]) + x_dict[F] = flats_gen[F] k = len(chain) print(max_powers, x_dict, k) current_combination = [0] * k generate_combinations(current_combination, 0, max_powers, x_dict) + + print(monomial_basis) from sage.sets.family import Family return Family([self.element_class(self, mon, reduce=False) for mon in monomial_basis]) From c71a4128421358e757bd5a954aa46ef20475de19 Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Tue, 27 Aug 2024 15:22:16 +0200 Subject: [PATCH 166/537] use Labelle's powersum species to compute compositions --- src/sage/rings/species.py | 166 ++++++++++++++++++++++++-------------- 1 file changed, 107 insertions(+), 59 deletions(-) diff --git a/src/sage/rings/species.py b/src/sage/rings/species.py index 01210e0f757..dcd7ac4460d 100644 --- a/src/sage/rings/species.py +++ b/src/sage/rings/species.py @@ -1103,7 +1103,7 @@ def domain(self): """ return FiniteEnumeratedSet(range(1, self._tc + 1)) - def compose_with_singletons(self, base_ring, names, args): + def _compose_with_singletons(self, base_ring, names, args): r""" Compute the inner sum of exercise 2.6.16 of BLL book. @@ -1123,7 +1123,7 @@ def compose_with_singletons(self, base_ring, names, args): sage: P = PolynomialSpecies(ZZ, "X") sage: M = P._indices sage: C4 = M(CyclicPermutationGroup(4)) - sage: C4.compose_with_singletons(ZZ, "X, Y", [[2, 2]]) # X^2Y^2 + C2(XY) + sage: C4._compose_with_singletons(ZZ, "X, Y", [[2, 2]]) # X^2Y^2 + C2(XY) E_2(XY) + X^2*Y^2 sage: P = PolynomialSpecies(ZZ, ["X", "Y"]) @@ -1131,9 +1131,15 @@ def compose_with_singletons(self, base_ring, names, args): sage: F = M(PermutationGroup([[(1,2,3), (4,5,6)]]), {1: [1,2,3], 2: [4,5,6]}) sage: F {((1,2,3)(4,5,6),): ({1, 2, 3}, {4, 5, 6})} - sage: F.compose_with_singletons(ZZ, "X1, X2, X3, Y1, Y2", [[1, 1, 1], [2, 1]]) + sage: F._compose_with_singletons(ZZ, "X1, X2, X3, Y1, Y2", [[1, 1, 1], [2, 1]]) 6*X1*X2*X3*Y1^2*Y2 + TESTS:: + + sage: P = PolynomialSpecies(ZZ, "X") + sage: M = P._indices + sage: M.one()._compose_with_singletons(ZZ, "X", [[1]]) + 1 """ # TODO: No checks are performed right now, must be added. # Checks: all args in Compositions, sums must match cardinalities. @@ -1386,8 +1392,15 @@ def product_on_basis(self, H, K): sage: matrix([[F * G for F in L1] for G in L2]) [ X^5 X^3*E_2 C_3*X^2 E_3*X^2] [X^3*E_2 X*E_2^2 C_3*E_2 E_3*E_2] + + TESTS:: + + sage: P = PolynomialSpecies(ZZ, "X") + sage: X = P(SymmetricGroup(1)) + sage: type(list(X^2)[0][1]) + """ - return self._from_dict({H * K: 1}) + return self._from_dict({H * K: ZZ(1)}) def _repr_(self): r""" @@ -1405,6 +1418,25 @@ def _repr_(self): return f"Polynomial species in {names[0]} over {self.base_ring()}" return f"Polynomial species in {', '.join(names)} over {self.base_ring()}" + @cached_method + def powersum(self, s, n): + r""" + Return `P_n(X_s)`. + + EXAMPLES:: + + sage: P = PolynomialSpecies(ZZ, "X") + sage: P.powersum(1, 4) + 4*E_4 - 4*X*E_3 + 4*X^2*E_2 - X^4 - 2*E_2^2 + """ + assert n in ZZ and n > 0 + if n == 1: + return self(SymmetricGroup(1), {s: [1]}) + return (ZZ(n) * self(SymmetricGroup(n), {s: range(1, n+1)}) + - sum(self(SymmetricGroup(i), {s: range(1, i+1)}) + * self.powersum(s, n-i) + for i in range(1, n))) + def exponential(self, multiplicities, degrees): r""" Return `E(\sum_i m_i X_i)` in the specified degrees. @@ -1412,47 +1444,59 @@ def exponential(self, multiplicities, degrees): EXAMPLES:: sage: P = PolynomialSpecies(QQ, ["X"]) - sage: P.exponential([3/2], [7]) - 3/4*X*E_6 + 3/4*E_2*E_5 + 3/4*E_3*E_4 + 3/2*E_7 - 3/16*X^2*E_5 - - 3/8*X*E_2*E_4 - 3/16*X*E_3^2 - 3/16*E_2^2*E_3 + 3/32*X^3*E_4 - + 9/32*X^2*E_2*E_3 + 3/32*X*E_2^3 - 15/256*X^4*E_3 - 15/128*X^3*E_2^2 - + 21/512*X^5*E_2 - 9/2048*X^7 + sage: P.exponential([3/2], [7]) # random + 3/2*E_7 + 3/4*X*E_6 - 3/16*X^2*E_5 + 3/32*X^3*E_4 - 15/256*E_3*X^4 + + 21/512*X^5*E_2 - 9/2048*X^7 - 15/128*X^3*E_2^2 - 3/8*E_2*E_4*X + + 3/32*X*E_2^3 - 3/16*X*E_3^2 + 3/4*E_2*E_5 - 3/16*E_3*E_2^2 + + 3/4*E_3*E_4 + 9/32*E_3*E_2*X^2 - TESTS:: + We support weights:: - sage: from sage.rings.lazy_species import LazySpecies - sage: L = LazySpecies(QQ, "X") - sage: E = L(lambda n: SymmetricGroup(n)) + sage: R. = QQ[] + sage: P = PolynomialSpecies(R, ["X"]) + sage: P.exponential([1], [2]) + E_2 - sage: c = 3/2; all((E^c)[i] == P.exponential([c], [i]) for i in range(6)) - True + sage: P.exponential([1+q], [3]) + (q^3+1)*E_3 + (q^2+q)*X*E_2 - sage: c = -5/3; all((E^c)[i] == P.exponential([c], [i]) for i in range(6)) - True + sage: P.exponential([1-q], [2]) + (-q^2+1)*E_2 + (q^2-q)*X^2 - sage: c = 0; all((E^c)[i] == P.exponential([c], [i]) for i in range(6)) - True + sage: P = PolynomialSpecies(R, ["X", "Y"]) + sage: P.exponential([1, q], [2, 2]) + q^2*E_2(X)*E_2(Y) - sage: c = 1; all((E^c)[i] == P.exponential([c], [i]) for i in range(6)) - True + TESTS:: - sage: c = -1; all((E^c)[i] == P.exponential([c], [i]) for i in range(6)) - True + sage: P = PolynomialSpecies(QQ, ["X"]) + sage: P.exponential([1], [0]).parent() + Polynomial species in X over Rational Field """ - def power(s, mu_exp): - return prod(self(SymmetricGroup(i), {s: range(1, i+1)}) ** m - for i, m in enumerate(mu_exp, 1)) + def stretch(c, k): + r""" + Return c + """ + if callable(c): + B = self.base_ring() + return c(*[g ** k for g in B.gens() if g != B.one()]) + return c def factor(s, c, d): - return sum(binomial(c, j) - * sum(multinomial(mu_exp := mu.to_exp()) - * power(s, mu_exp) - for mu in Partitions(d, length=j)) - for j in range(d+1)) + r""" + Return `E(c X_s)_d`. + + We use Proposition 2 in Labelle, New combinatorial + computational methods arising from pseudo-singletons. + """ + return self.sum(~ mu.centralizer_size() + * self.prod(stretch(c, k) + * self.powersum(s, k) for k in mu) + for mu in Partitions(d)) - return prod(factor(s+1, multiplicities[s], degrees[s]) - for s in range(self._k)) + return self.prod(factor(s+1, multiplicities[s], degrees[s]) + for s in range(self._k)) class Element(CombinatorialFreeModule.Element): def is_constant(self): @@ -1558,7 +1602,7 @@ def hadamard_product(self, other): """ P = self.parent() if P is not other.parent(): - raise ValueError("the factors of a Hadamard product must be the same") + raise ValueError("the factors of a Hadamard product must have the same parent") res = P.zero() # we should first collect matching multicardinalities. @@ -1583,7 +1627,7 @@ def hadamard_product(self, other): return res - def compose_with_weighted_singletons(self, base_ring, names, multiplicities, degrees): + def _compose_with_weighted_singletons(self, names, multiplicities, degrees): r""" Compute the composition with `(\sum_j m_{1,j} X_{1,j}, \sum_j m_{2,j} X_{2,j}, \dots)` @@ -1605,34 +1649,33 @@ def compose_with_weighted_singletons(self, base_ring, names, multiplicities, deg Equation (2.5.41):: - sage: P = PolynomialSpecies(ZZ, ["X"]) + sage: P = PolynomialSpecies(QQ, ["X"]) sage: E2 = P(SymmetricGroup(2)) - sage: E2.compose_with_weighted_singletons(ZZ, ["X"], [-1], [[2]]) + sage: E2._compose_with_weighted_singletons(["X"], [-1], [[2]]) -E_2 + X^2 sage: C4 = P(CyclicPermutationGroup(4)) - sage: C4.compose_with_weighted_singletons(ZZ, ["X"], [-1], [[4]]) - {((1,2)(3,4),): ({1, 2, 3, 4})} - C_4 + sage: C4._compose_with_weighted_singletons(["X"], [-1], [[4]]) + -C_4 + {((1,2)(3,4),): ({1, 2, 3, 4})} Exercise (2.5.17):: - sage: C4.compose_with_weighted_singletons(ZZ, ["X", "Y"], [1, 1], [[2, 2]]) + sage: C4._compose_with_weighted_singletons(["X", "Y"], [1, 1], [[2, 2]]) E_2(XY) + X^2*Y^2 - sage: C4.compose_with_weighted_singletons(ZZ, ["X", "Y"], [1, 1], [[3, 1]]) + sage: C4._compose_with_weighted_singletons(["X", "Y"], [1, 1], [[3, 1]]) X^3*Y - sage: C4.compose_with_weighted_singletons(ZZ, ["X", "Y"], [1, 1], [[4, 0]]) + sage: C4._compose_with_weighted_singletons(["X", "Y"], [1, 1], [[4, 0]]) C_4(X) Auger et al., Equation (4.60):: - sage: C4.compose_with_weighted_singletons(ZZ, ["X", "Y"], [1, -1], [[2, 2]]) + sage: C4._compose_with_weighted_singletons(["X", "Y"], [1, -1], [[2, 2]]) -E_2(XY) + 2*X^2*Y^2 TESTS:: - sage: (C4+E2^2).compose_with_weighted_singletons(ZZ, ["X"], [-1], [[4]]) - {((1,2)(3,4),): ({1, 2, 3, 4})} - C_4 - 2*X^2*E_2 + E_2^2 + X^4 - + sage: (C4+E2^2)._compose_with_weighted_singletons(["X"], [-1], [[4]]) + -C_4 + {((1,2)(3,4),): ({1, 2, 3, 4})} + E_2^2 - 2*X^2*E_2 + X^4 """ P = self.parent() if not self.support(): @@ -1640,9 +1683,9 @@ def compose_with_weighted_singletons(self, base_ring, names, multiplicities, deg if not self.is_homogeneous(): raise ValueError("element is not homogeneous") - left = sum(c * M.compose_with_singletons(P.base_ring(), - names, - degrees) + left = sum(c * M._compose_with_singletons(P.base_ring(), + names, + degrees) for M, c in self) P = left.parent() right = P.exponential(multiplicities, @@ -1654,7 +1697,7 @@ def __call__(self, *args): EXAMPLES:: - sage: P = PolynomialSpecies(ZZ, ["X"]) + sage: P = PolynomialSpecies(QQ, ["X"]) sage: X = P(SymmetricGroup(1)) sage: E2 = P(SymmetricGroup(2)) sage: E2(-X) @@ -1665,7 +1708,7 @@ def __call__(self, *args): sage: E2(X + X^2) E_2 + X^3 + {((1,2)(3,4),): ({1, 2, 3, 4})} - sage: P2 = PolynomialSpecies(ZZ, ["X", "Y"]) + sage: P2 = PolynomialSpecies(QQ, ["X", "Y"]) sage: X = P2(SymmetricGroup(1), {1:[1]}) sage: Y = P2(SymmetricGroup(1), {2:[1]}) sage: E2(X + Y) @@ -1674,17 +1717,23 @@ def __call__(self, *args): sage: E2(X*Y)(E2(X), E2(Y)) {((7,8), (5,6), (3,4), (1,2), (1,3)(2,4)(5,7)(6,8)): ({1, 2, 3, 4}, {5, 6, 7, 8})} + sage: R. = QQ[] + sage: P = PolynomialSpecies(R, ["X"]) + sage: X = P(SymmetricGroup(1)) + sage: E2 = P(SymmetricGroup(2)) + sage: E2(q*X) + q^2*E_2 + """ P = self.parent() if not self.support(): return P.zero() P0 = args[0].parent() assert all(P0 == arg.parent() for arg in args), "all parents must be the same" - R = P.base_ring() args = [sorted(g, key=lambda x: x[0]._mc) for g in args] - multiplicities = [[c for _, c in g] for g in args] - molecules = [[M for M, _ in g] for g in args] + multiplicities = list(chain.from_iterable([[c for _, c in g] for g in args])) + molecules = list(chain.from_iterable([[M for M, _ in g] for g in args])) F_degrees = sorted(set(M._mc for M, _ in self)) result = P0.zero() @@ -1694,10 +1743,9 @@ def __call__(self, *args): for n_i, arg in zip(n, args)]): # each degree is a weak composition of the degree of F in sort i names = ["X%s" % i for i in range(sum(len(arg) for arg in args))] - FX = F.compose_with_weighted_singletons(R, names, - list(chain.from_iterable(multiplicities)), - degrees) - FG = [(M(*list(chain.from_iterable(molecules))), c) - for M, c in FX] + FX = F._compose_with_weighted_singletons(names, + multiplicities, + degrees) + FG = [(M(*molecules), c) for M, c in FX] result += P0.sum_of_terms(FG) return result From 56beab2548542c6598402e417951b221434dfb08 Mon Sep 17 00:00:00 2001 From: Newtech66 Date: Fri, 30 Aug 2024 13:30:38 +0530 Subject: [PATCH 167/537] Only show dompart for arity >2 --- src/sage/rings/species.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/sage/rings/species.py b/src/sage/rings/species.py index dcd7ac4460d..babd75af1f7 100644 --- a/src/sage/rings/species.py +++ b/src/sage/rings/species.py @@ -471,6 +471,8 @@ def _repr_(self): sage: A = At(G, {2: [1,2,3,4,5,6,7,8,9,10]}); A {((1,2,3,4)(5,6)(7,8)(9,10),): ({}, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10})} """ + if self.parent()._k == 1: + return "{" + f"{self._dis}" + "}" dompart = ', '.join("{" + repr(sorted(b))[1:-1] + "}" for b in self._dompart) return "{" + f"{self._dis}: ({dompart})" + "}" From bf87e5020b303fd6178f01278f1127d7cd7a67d6 Mon Sep 17 00:00:00 2001 From: Newtech66 Date: Fri, 30 Aug 2024 13:34:58 +0530 Subject: [PATCH 168/537] Rename _k to _arity globally --- src/sage/rings/species.py | 75 ++++++++++++++++++++------------------- 1 file changed, 38 insertions(+), 37 deletions(-) diff --git a/src/sage/rings/species.py b/src/sage/rings/species.py index babd75af1f7..09a3a6d2f8a 100644 --- a/src/sage/rings/species.py +++ b/src/sage/rings/species.py @@ -446,7 +446,7 @@ def __eq__(self, other): return False # If they do, construct the mapping between the groups selflist, otherlist = [], [] - for i in range(self.parent()._k): + for i in range(self.parent()._arity): if len(self._dompart[i]) != len(other._dompart[i]): return False selflist.extend(sorted(list(self._dompart[i]))) @@ -471,7 +471,7 @@ def _repr_(self): sage: A = At(G, {2: [1,2,3,4,5,6,7,8,9,10]}); A {((1,2,3,4)(5,6)(7,8)(9,10),): ({}, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10})} """ - if self.parent()._k == 1: + if self.parent()._arity == 1: return "{" + f"{self._dis}" + "}" dompart = ', '.join("{" + repr(sorted(b))[1:-1] + "}" for b in self._dompart) @@ -517,8 +517,8 @@ def __init__(self, names): category = SetsWithGrading().Infinite() Parent.__init__(self, names=names, category=category) ElementCache.__init__(self) - self._k = len(names) - self._grading_set = IntegerVectors(length=self._k) + self._arity = len(names) + self._grading_set = IntegerVectors(length=self._arity) self._renamed = set() # the degrees that have been renamed already @cached_method @@ -535,8 +535,8 @@ def an_element(self): sage: At2.an_element() {((1,2)(3,4),): ({1, 2}, {3, 4})} """ - G = PermutationGroup([[(2 * i - 1, 2 * i) for i in range(1, self._k + 1)]]) - m = {i: [2 * i - 1, 2 * i] for i in range(1, self._k + 1)} + G = PermutationGroup([[(2 * i - 1, 2 * i) for i in range(1, self._arity + 1)]]) + m = {i: [2 * i - 1, 2 * i] for i in range(1, self._arity + 1)} return self._element_constructor_(G, m) def _element_constructor_(self, G, pi=None): @@ -557,12 +557,12 @@ def _element_constructor_(self, G, pi=None): if not isinstance(G, PermutationGroup_generic): raise ValueError(f"{G} must be a permutation group") if pi is None: - if self._k == 1: + if self._arity == 1: pi = {1: G.domain()} else: raise ValueError("the assignment of sorts to the domain elements must be provided") - if not set(pi.keys()).issubset(range(1, self._k + 1)): - raise ValueError(f"keys of pi (={pi.keys()}) must be in the range [1, {self._k}]") + if not set(pi.keys()).issubset(range(1, self._arity + 1)): + raise ValueError(f"keys of pi (={pi.keys()}) must be in the range [1, {self._arity}]") if sum(len(p) for p in pi.values()) != len(G.domain()) or set(chain.from_iterable(pi.values())) != set(G.domain()): raise ValueError(f"values of pi (={pi.values()}) must partition the domain of G (={G.domain()})") for orbit in G.orbits(): @@ -572,7 +572,7 @@ def _element_constructor_(self, G, pi=None): mapping = {v: i for i, v in enumerate(G.domain(), 1)} mapping2 = PermutationGroupElement([mapping[e] for o in sorted(G.orbits(), key=len, reverse=True) for e in o]).inverse() - dpart = [frozenset() for _ in range(self._k)] + dpart = [frozenset() for _ in range(self._arity)] for k, v in pi.items(): dpart[k - 1] = frozenset(mapping2(mapping[x]) for x in v) elm = self._cache_get(self.element_class(self, dis_elm, tuple(dpart))) @@ -612,11 +612,11 @@ def _rename(self, n): # prevent infinite recursion in self._element_constructor_ self._renamed.add(n) - for i in range(self._k): + for i in range(self._arity): if n == 1: self(SymmetricGroup(1), {i+1: [1]}).rename(self._names[i]) - if self._k == 1: + if self._arity == 1: sort = "" else: sort = f"({self._names[i]})" @@ -661,7 +661,7 @@ def __contains__(self, x): return True G, pi = None, None if isinstance(x, PermutationGroup_generic): - if self._k == 1: + if self._arity == 1: G = x pi = {1: G.domain()} else: @@ -670,8 +670,8 @@ def __contains__(self, x): G, pi = x if not isinstance(G, PermutationGroup_generic): raise ValueError(f"{G} must be a permutation group") - if not set(pi.keys()).issubset(range(1, self._k + 1)): - raise ValueError(f"keys of pi (={pi.keys()}) must be in the range [1, {self._k}]") + if not set(pi.keys()).issubset(range(1, self._arity + 1)): + raise ValueError(f"keys of pi (={pi.keys()}) must be in the range [1, {self._arity}]") if sum(len(p) for p in pi.values()) != len(G.domain()) or set(chain.from_iterable(pi.values())) != set(G.domain()): raise ValueError(f"values of pi (={pi.values()}) must partition the domain of G (={G.domain()})") for orbit in G.orbits(): @@ -720,7 +720,7 @@ def __init__(self, indices, prefix=None, **kwds): category = Monoids() & SetsWithGrading().Infinite() IndexedFreeAbelianMonoid.__init__(self, indices, prefix=prefix, category=category, **kwds) ElementCache.__init__(self) - self._k = indices._k + self._arity = indices._arity def _project(self, G, pi, part): r""" @@ -783,7 +783,7 @@ def _element_constructor_(self, G, pi=None): return G if isinstance(G, PermutationGroup_generic): if pi is None: - if self._k == 1: + if self._arity == 1: pi = {1: G.domain()} else: raise ValueError("the assignment of sorts to the domain elements must be provided") @@ -795,11 +795,11 @@ def _element_constructor_(self, G, pi=None): # Assume G is a tuple (X, a) X, a = G if pi is None: - if self._k == 1: + if self._arity == 1: pi = {1: X} else: raise ValueError("the assignment of sorts to the domain elements must be provided") - L = [None for _ in range(self._k)] + L = [None for _ in range(self._arity)] for k, v in pi.items(): L[k - 1] = list(v) # Create group @@ -826,7 +826,7 @@ def one(self): elm = super().one() elm._group = SymmetricGroup(0) elm._dompart = tuple() - elm._mc = tuple(0 for _ in range(self._k)) + elm._mc = tuple(0 for _ in range(self._arity)) elm._tc = 0 return elm @@ -929,7 +929,7 @@ def _elmmul(self, elm1, elm2): if elm2._tc == 0: self._assign_group_info(elm1) return - self._mc = tuple(elm1._mc[i] + elm2._mc[i] for i in range(self.parent()._k)) + self._mc = tuple(elm1._mc[i] + elm2._mc[i] for i in range(self.parent()._arity)) self._tc = elm1._tc + elm2._tc gens1 = elm1._group.gens() # Try to avoid gens_small unless necessary @@ -947,7 +947,7 @@ def _elmmul(self, elm1, elm2): gens.append([tuple(elm1._tc + k for k in cyc) for cyc in gen.cycle_tuples()]) self._group = PermutationGroup(gens, domain=range(1, elm1._tc + elm2._tc + 1)) self._dompart = list(elm1._dompart) - for i in range(elm2.parent()._k): + for i in range(elm2.parent()._arity): self._dompart[i] = frozenset(list(self._dompart[i]) + [elm1._tc + e for e in elm2._dompart[i]]) self._dompart = tuple(self._dompart) @@ -1201,11 +1201,11 @@ def __call__(self, *args): sage: C3(X*Y) {((1,2,3)(4,5,6),): ({1, 2, 3}, {4, 5, 6})} """ - if len(args) != self.parent()._k: + if len(args) != self.parent()._arity: raise ValueError("number of args must match arity of self") if not all(isinstance(arg, MolecularSpecies.Element) for arg in args): raise ValueError("all args must be molecular species") - if len(set(arg.parent()._k for arg in args)) > 1: + if len(set(arg.parent()._arity for arg in args)) > 1: raise ValueError("all args must have same arity") gens = [] @@ -1226,7 +1226,7 @@ def __call__(self, *args): gens.append(newgen) # gens from M_i and dompart - dpart = {i: [] for i in range(1, args[0].parent()._k + 1)} + dpart = {i: [] for i in range(1, args[0].parent()._arity + 1)} for start, M in zip(starts, Mlist): for i, v in enumerate(M._dompart, 1): dpart[i].extend([start + k for k in v]) @@ -1275,7 +1275,7 @@ def __init__(self, base_ring, names): category=category, element_class=self.Element, prefix='', bracket=False) - self._k = len(names) + self._arity = len(names) def degree_on_basis(self, m): r""" @@ -1326,19 +1326,19 @@ def _element_constructor_(self, G, pi=None): return G if isinstance(G, PermutationGroup_generic): if pi is None: - if self._k == 1: + if self._arity == 1: return self._from_dict({self._indices(G): ZZ.one()}) raise ValueError("the assignment of sorts to the domain elements must be provided") return self._from_dict({self._indices(G, pi): ZZ.one()}) # Assume G is a tuple (X, a) X, a = G if pi is None: - if self._k == 1: + if self._arity == 1: pi = {1: X} else: raise ValueError("the assignment of sorts to the domain elements must be provided") # Make iteration over values of pi deterministic - L = [None for _ in range(self._k)] + L = [None for _ in range(self._arity)] for k, v in pi.items(): L[k - 1] = list(v) # Create group @@ -1497,8 +1497,8 @@ def factor(s, c, d): * self.powersum(s, k) for k in mu) for mu in Partitions(d)) - return self.prod(factor(s+1, multiplicities[s], degrees[s]) - for s in range(self._k)) + return prod(factor(s+1, multiplicities[s], degrees[s]) + for s in range(self._arity)) class Element(CombinatorialFreeModule.Element): def is_constant(self): @@ -1657,8 +1657,8 @@ def _compose_with_weighted_singletons(self, names, multiplicities, degrees): -E_2 + X^2 sage: C4 = P(CyclicPermutationGroup(4)) - sage: C4._compose_with_weighted_singletons(["X"], [-1], [[4]]) - -C_4 + {((1,2)(3,4),): ({1, 2, 3, 4})} + sage: C4.compose_with_weighted_singletons(ZZ, ["X"], [-1], [[4]]) + {((1,2)(3,4),)} - C_4 Exercise (2.5.17):: @@ -1676,8 +1676,9 @@ def _compose_with_weighted_singletons(self, names, multiplicities, degrees): TESTS:: - sage: (C4+E2^2)._compose_with_weighted_singletons(["X"], [-1], [[4]]) - -C_4 + {((1,2)(3,4),): ({1, 2, 3, 4})} + E_2^2 - 2*X^2*E_2 + X^4 + sage: (C4+E2^2).compose_with_weighted_singletons(ZZ, ["X"], [-1], [[4]]) + {((1,2)(3,4),)} - C_4 - 2*X^2*E_2 + E_2^2 + X^4 + """ P = self.parent() if not self.support(): @@ -1705,10 +1706,10 @@ def __call__(self, *args): sage: E2(-X) -E_2 + X^2 sage: E2(X^2) - {((1,2)(3,4),): ({1, 2, 3, 4})} + {((1,2)(3,4),)} sage: E2(X + X^2) - E_2 + X^3 + {((1,2)(3,4),): ({1, 2, 3, 4})} + E_2 + X^3 + {((1,2)(3,4),)} sage: P2 = PolynomialSpecies(QQ, ["X", "Y"]) sage: X = P2(SymmetricGroup(1), {1:[1]}) From f9919ffb8106c8b07d54a6dbeb5f26a6df839c14 Mon Sep 17 00:00:00 2001 From: Newtech66 Date: Fri, 30 Aug 2024 14:38:58 +0530 Subject: [PATCH 169/537] fix doctests --- src/sage/rings/species.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/sage/rings/species.py b/src/sage/rings/species.py index 09a3a6d2f8a..f4d5bc047c1 100644 --- a/src/sage/rings/species.py +++ b/src/sage/rings/species.py @@ -1,6 +1,5 @@ from itertools import accumulate, chain -from sage.arith.misc import multinomial from sage.categories.graded_algebras_with_basis import GradedAlgebrasWithBasis from sage.categories.infinite_enumerated_sets import InfiniteEnumeratedSets from sage.categories.monoids import Monoids @@ -18,7 +17,6 @@ from sage.monoids.indexed_free_monoid import (IndexedFreeAbelianMonoid, IndexedFreeAbelianMonoidElement, IndexedMonoid) -from sage.functions.other import binomial from sage.rings.integer_ring import ZZ from sage.sets.finite_enumerated_set import FiniteEnumeratedSet from sage.structure.element import Element, parent @@ -1657,8 +1655,8 @@ def _compose_with_weighted_singletons(self, names, multiplicities, degrees): -E_2 + X^2 sage: C4 = P(CyclicPermutationGroup(4)) - sage: C4.compose_with_weighted_singletons(ZZ, ["X"], [-1], [[4]]) - {((1,2)(3,4),)} - C_4 + sage: C4._compose_with_weighted_singletons(["X"], [-1], [[4]]) + -C_4 + {((1,2)(3,4),)} Exercise (2.5.17):: @@ -1676,8 +1674,8 @@ def _compose_with_weighted_singletons(self, names, multiplicities, degrees): TESTS:: - sage: (C4+E2^2).compose_with_weighted_singletons(ZZ, ["X"], [-1], [[4]]) - {((1,2)(3,4),)} - C_4 - 2*X^2*E_2 + E_2^2 + X^4 + sage: (C4+E2^2)._compose_with_weighted_singletons(["X"], [-1], [[4]]) + -C_4 + {((1,2)(3,4),)} + E_2^2 - 2*X^2*E_2 + X^4 """ P = self.parent() From 792b8298667c72ff6a7e5d52374afd6c16ce7d3e Mon Sep 17 00:00:00 2001 From: Verrel Rievaldo Wijaya Date: Fri, 30 Aug 2024 17:08:52 +0700 Subject: [PATCH 170/537] Change output of dual subdivision from Graph to PolyhedralComplex --- .../rings/semirings/tropical_mpolynomial.py | 2 +- src/sage/rings/semirings/tropical_variety.py | 63 ++++++++----------- 2 files changed, 26 insertions(+), 39 deletions(-) diff --git a/src/sage/rings/semirings/tropical_mpolynomial.py b/src/sage/rings/semirings/tropical_mpolynomial.py index 50b15f45776..65354b18142 100644 --- a/src/sage/rings/semirings/tropical_mpolynomial.py +++ b/src/sage/rings/semirings/tropical_mpolynomial.py @@ -359,7 +359,7 @@ def tropical_variety(self): curve. For dimensions higher than two, it is referred to as a tropical hypersurface. - OUTPUT: a :class:`sage.rings.semirings.tropical_variety.TropicalVariety` + OUTPUT: :class:`sage.rings.semirings.tropical_variety.TropicalVariety` EXAMPLES: diff --git a/src/sage/rings/semirings/tropical_variety.py b/src/sage/rings/semirings/tropical_variety.py index d77cde29d47..4438a04588d 100644 --- a/src/sage/rings/semirings/tropical_variety.py +++ b/src/sage/rings/semirings/tropical_variety.py @@ -152,10 +152,10 @@ class TropicalVariety(UniqueRepresentation, SageObject): a tropical hypersurface embedded in a real space `\RR^n`:: sage: T = TropicalSemiring(QQ) - sage: R. = PolynomialRing(T) - sage: p1 = x*y + R(-1/2)*x*z + R(4)*z^2 + a*x + sage: R. = PolynomialRing(T) + sage: p1 = x*y + R(-1/2)*x*z + R(4)*z^2 + w*x sage: tv = p1.tropical_variety(); tv - Tropical hypersurface of 0*a*x + 0*x*y + (-1/2)*x*z + 4*z^2 + Tropical hypersurface of 0*w*x + 0*x*y + (-1/2)*x*z + 4*z^2 sage: tv.components() [[(t1, t2, t3 - 1/2, t3), [t2 - 9/2 <= t3, t3 <= t1 + 1/2, t2 - 5 <= t1], 1], [(t1, 2*t2 - t3 + 4, t3, t2), [t3 + 1/2 <= t2, t3 <= t1], 1], @@ -547,6 +547,8 @@ def dual_subdivision(self): the intersection of multiple components. Edges of the dual subdivision correspond to the individual components. + OUTPUT: :class:`sage.geometry.polyhedral_complex.PolyhedralComplex` + EXAMPLES: Dual subdivision of a tropical curve:: @@ -555,9 +557,9 @@ def dual_subdivision(self): sage: R. = PolynomialRing(T) sage: p1 = R(3) + R(2)*x + R(2)*y + R(3)*x*y + x^2 + y^2 sage: tv = p1.tropical_variety() - sage: G = tv.dual_subdivision() - sage: G.plot(vertex_labels=False) - Graphics object consisting of 10 graphics primitives + sage: pc = tv.dual_subdivision() + sage: pc.plot() + Graphics object consisting of 20 graphics primitives .. PLOT:: :width: 300 px @@ -567,8 +569,8 @@ def dual_subdivision(self): x, y = R.gen(), R.gen(1) p1 = R(3) + R(2)*x + R(2)*y + R(3)*x*y + x**2 + y**2 tv = p1.tropical_variety() - G = tv.dual_subdivision() - sphinx_plot(G.plot(vertex_labels=False)) + pc = tv.dual_subdivision() + sphinx_plot(pc.plot()) Dual subdivision of a tropical surface:: @@ -576,8 +578,8 @@ def dual_subdivision(self): sage: R. = PolynomialRing(T) sage: p1 = x + y + z + x^2 + R(1) sage: tv = p1.tropical_variety() - sage: G = tv.dual_subdivision() - sage: G.plot3d() + sage: pc = tv.dual_subdivision() + sage: pc.plot() Graphics3d Object .. PLOT:: @@ -588,8 +590,8 @@ def dual_subdivision(self): x, y, z = R.gen(), R.gen(1), R.gen(2) p1 = x + y + z + x**2 + R(1) tv = p1.tropical_variety() - G = tv.dual_subdivision() - sphinx_plot(G.plot3d()) + pc = tv.dual_subdivision() + sphinx_plot(pc.plot()) Dual subdivision of a tropical hypersurface:: @@ -597,38 +599,23 @@ def dual_subdivision(self): sage: R. = PolynomialRing(T) sage: p1 = a^2 + b^2 + c^2 + d^2 + a*b*c*d sage: tv = p1.tropical_variety() - sage: G = tv.dual_subdivision() - sage: G.plot(vertex_labels=False) - Graphics object consisting of 11 graphics primitives - - .. PLOT:: - :width: 300 px - - T = TropicalSemiring(QQ, use_min=False) - R = PolynomialRing(T, ('a,b,c,d')) - a, b, c, d = R.gen(), R.gen(1), R.gen(2), R.gen(3) - p1 = a**2 + b**2 + c**2 + d**2 + a*b*c*d - tv = p1.tropical_variety() - G = tv.dual_subdivision() - sphinx_plot(G.plot(vertex_labels=False)) + sage: pc = tv.dual_subdivision(); pc + Polyhedral complex with 6 maximal cells """ from sage.graphs.graph import Graph + from sage.geometry.polyhedron.constructor import Polyhedron + from sage.geometry.polyhedral_complex import PolyhedralComplex G = Graph() edges = [e for e in self._keys] G.add_edges(edges) - pos = {} - for vertex in G.vertices(): - pos[vertex] = list(vertex) - - if self._poly.parent().ngens() == 2: - G.layout(pos=pos, save_pos=True) - elif self._poly.parent().ngens() == 3: - G.layout(dim=3, save_pos=True) - G._pos3d = pos - else: - G.layout("spring", save_pos=True) - return G + + polyhedron_lst = [] + for cycle in G.cycle_basis(): + polyhedron = Polyhedron(vertices=cycle) + polyhedron_lst.append(polyhedron) + pc = PolyhedralComplex(polyhedron_lst) + return pc def weight_vectors(self): r""" From dd2d14d7184450be2a8e105593cae9893192a624 Mon Sep 17 00:00:00 2001 From: Verrel Rievaldo Wijaya Date: Fri, 30 Aug 2024 22:18:35 +0700 Subject: [PATCH 171/537] Refine docstring --- src/sage/rings/semirings/tropical_mpolynomial.py | 2 -- src/sage/rings/semirings/tropical_polynomial.py | 6 ++---- src/sage/rings/semirings/tropical_variety.py | 12 +++++++----- 3 files changed, 9 insertions(+), 11 deletions(-) diff --git a/src/sage/rings/semirings/tropical_mpolynomial.py b/src/sage/rings/semirings/tropical_mpolynomial.py index 65354b18142..e6744baf7ef 100644 --- a/src/sage/rings/semirings/tropical_mpolynomial.py +++ b/src/sage/rings/semirings/tropical_mpolynomial.py @@ -11,8 +11,6 @@ sage: R. = PolynomialRing(T) sage: z.parent() Multivariate Tropical Polynomial Semiring in x, y, z over Rational Field - sage: R(2)*x + R(-1)*x + R(5)*y + R(-3) - (-1)*x + 5*y + (-3) sage: (x+y+z)^2 0*x^2 + 0*x*y + 0*y^2 + 0*x*z + 0*y*z + 0*z^2 diff --git a/src/sage/rings/semirings/tropical_polynomial.py b/src/sage/rings/semirings/tropical_polynomial.py index f1d41c17ee0..cefe97c533a 100644 --- a/src/sage/rings/semirings/tropical_polynomial.py +++ b/src/sage/rings/semirings/tropical_polynomial.py @@ -11,10 +11,8 @@ sage: R. = PolynomialRing(T) sage: x.parent() Univariate Tropical Polynomial Semiring in x over Rational Field - sage: (x + R(3)*x) * (x^2 + x) - 3*x^3 + 3*x^2 - sage: (x^2 + R(1)*x + R(-1))^2 - 0*x^4 + 1*x^3 + 2*x^2 + 0*x + (-2) + sage: (x^2 + x + R(0))^2 + 0*x^4 + 0*x^3 + 0*x^2 + 0*x + 0 REFERENCES: diff --git a/src/sage/rings/semirings/tropical_variety.py b/src/sage/rings/semirings/tropical_variety.py index 4438a04588d..23149e970dd 100644 --- a/src/sage/rings/semirings/tropical_variety.py +++ b/src/sage/rings/semirings/tropical_variety.py @@ -1574,7 +1574,7 @@ def _parameter_intervals(self): intervals.append(interval) return intervals - def plot(self): + def plot(self, dominant_term=False): """ Return the plot of ``self``. @@ -1631,8 +1631,9 @@ def plot(self): Another tropical polynomial with numerous components, resulting in a more intricate structure:: - sage: p2 = (x^6 + R(4)*x^4*y^2 + R(2)*x^3*y^3 + R(3)*x^2*y^4 + x*y^5 - ....: + R(7)*x^2 + R(5)*x*y + R(3)*y^2 + R(2)*x + y + R(10)) + sage: p2 = (R(8) + R(4)*x + R(2)*y + R(1)*x^2 + x*y + R(1)*y^2 + ....: + R(2)*x^3 + x^2*y + x*y^2 + R(4)*y^3 + R(8)*x^4 + ....: + R(4)*x^3*y + x^2*y^2 + R(2)*x*y^3 + y^4) sage: p2.tropical_variety().plot() Graphics object consisting of 11 graphics primitives @@ -1642,8 +1643,9 @@ def plot(self): T = TropicalSemiring(QQ) R = PolynomialRing(T, ('x,y')) x, y = R.gen(), R.gen(1) - p2 = x**6 + R(4)*x**4*y**2 + R(2)*x**3*y**3 + R(3)*x**2*y**4 + \ - x*y**5 + R(7)*x**2 + R(5)*x*y + R(3)*y**2 + R(2)*x + y + R(10) + p2 = R(8) + R(4)*x + R(2)*y + R(1)*x**2 + x*y + R(1)*y**2 \ + + R(2)*x**3 + x**2*y + x*y**2 + R(4)*y**3 + R(8)*x**4 \ + + R(4)*x**3*y + x**2*y**2 + R(2)*x*y**3 + y**4 sphinx_plot(p2.tropical_variety().plot()) """ from sage.plot.plot import plot From f20838a8ae0d9375523f007a0f63c6fd74843b2c Mon Sep 17 00:00:00 2001 From: Verrel Rievaldo Wijaya Date: Fri, 30 Aug 2024 22:21:25 +0700 Subject: [PATCH 172/537] Small fix on example --- src/sage/rings/semirings/tropical_variety.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/rings/semirings/tropical_variety.py b/src/sage/rings/semirings/tropical_variety.py index 23149e970dd..c2f92405fd7 100644 --- a/src/sage/rings/semirings/tropical_variety.py +++ b/src/sage/rings/semirings/tropical_variety.py @@ -1635,7 +1635,7 @@ def plot(self, dominant_term=False): ....: + R(2)*x^3 + x^2*y + x*y^2 + R(4)*y^3 + R(8)*x^4 ....: + R(4)*x^3*y + x^2*y^2 + R(2)*x*y^3 + y^4) sage: p2.tropical_variety().plot() - Graphics object consisting of 11 graphics primitives + Graphics object consisting of 23 graphics primitives .. PLOT:: :width: 300 px From f425552d05b93842109734a2d8b86e5238755927 Mon Sep 17 00:00:00 2001 From: Verrel Rievaldo Wijaya Date: Fri, 30 Aug 2024 23:09:23 +0700 Subject: [PATCH 173/537] Refine the docstring more --- .../rings/semirings/tropical_mpolynomial.py | 2 +- .../rings/semirings/tropical_polynomial.py | 8 ++-- src/sage/rings/semirings/tropical_variety.py | 44 ++++++++++++------- 3 files changed, 32 insertions(+), 22 deletions(-) diff --git a/src/sage/rings/semirings/tropical_mpolynomial.py b/src/sage/rings/semirings/tropical_mpolynomial.py index e6744baf7ef..3d06fa1a7d8 100644 --- a/src/sage/rings/semirings/tropical_mpolynomial.py +++ b/src/sage/rings/semirings/tropical_mpolynomial.py @@ -593,7 +593,7 @@ def random_element(self, degree=2, terms=None, choose_degree=False, r""" Return a random multivariate tropical polynomial from ``self``. - OUTPUT: a :class:`TropicalMPolynomial` + OUTPUT: :class:`TropicalMPolynomial` .. SEEALSO:: diff --git a/src/sage/rings/semirings/tropical_polynomial.py b/src/sage/rings/semirings/tropical_polynomial.py index cefe97c533a..780a44c4758 100644 --- a/src/sage/rings/semirings/tropical_polynomial.py +++ b/src/sage/rings/semirings/tropical_polynomial.py @@ -165,7 +165,7 @@ def roots(self): Return the list of all tropical roots of ``self``, counted with multiplicity. - OUTPUT: a list of tropical numbers + OUTPUT: A list of tropical numbers ALGORITHM: @@ -291,7 +291,7 @@ def factor(self): `x + x_0` is `x_0` and not `-x_0`. However, not every tropical polynomial can be factored. - OUTPUT: a :class:'Factorization' + OUTPUT: :class:'Factorization' EXAMPLES:: @@ -798,7 +798,7 @@ def random_element(self, degree=(-1, 2), monic=False, *args, **kwds): r""" Return a random tropical polynomial of given degrees (bounds). - OUTPUT: a :class:`TropicalPolynomial` + OUTPUT: :class:`TropicalPolynomial` .. SEEALSO:: @@ -873,7 +873,7 @@ def interpolation(self, points): - ``points`` -- a list of tuples ``(x, y)`` - OUTPUT: a :class:`TropicalPolynomial` + OUTPUT: :class:`TropicalPolynomial` EXAMPLES:: diff --git a/src/sage/rings/semirings/tropical_variety.py b/src/sage/rings/semirings/tropical_variety.py index c2f92405fd7..6a9f4aa2314 100644 --- a/src/sage/rings/semirings/tropical_variety.py +++ b/src/sage/rings/semirings/tropical_variety.py @@ -539,13 +539,15 @@ def dual_subdivision(self): """ Return the dual subdivision of ``self``. - Dual subdivision refers to a specific decomposition of the Newton - polygon associated with a tropical polynomial. The term "dual" - is used in the sense that the combinatorial structure of the - tropical variety is reflected in the dual subdivision of the - Newton polygon. Vertices of the dual subdivision correspond to - the intersection of multiple components. Edges of the dual - subdivision correspond to the individual components. + Dual subdivision refers to a specific decomposition of the + Newton polygon of a tropical polynomial. This Newton polygon + is the convex hull of all the points corresponding to the + exponents of the terms of the tropical polynomial. The term + "dual" is used in the sense that the combinatorial structure + of the tropical variety is reflected in the dual subdivision. + Vertices of the dual subdivision correspond to the intersection + of multiple components. Edges of the dual subdivision correspond + to the individual components. OUTPUT: :class:`sage.geometry.polyhedral_complex.PolyhedralComplex` @@ -622,14 +624,19 @@ def weight_vectors(self): Return the weight vectors for each unique intesection of components of ``self``. + Weight vectors are a list of vectors associated with each + unique intersection of the components of tropical variety. + Each vector is a normal vector to a component with respect + to the unique intersection lying within that component. + Assume ``self`` is a `n`-dimensional tropical variety. - Suppose `L` is an intersection adjacent to the components + Suppose `L` is an intersection lying within the components `S_1, ldots, S_k` with respective weights `w_1, ldots, w_k`. This `L` is a linear structure in `\RR^{n-1}` and has `n-1` direction vectors `d_1,d_2,\dots, d_{n-1}`. Each component `S_1, ldots, S_k` has a normal vector `n_1, \ldots, n_k`. - Make sure that the normal vector is scale to an integer vector - such that the greatest common divisor of its elements is 1. + Then, we scale each normal vector to an integer vector such + that the greatest common divisor of its elements is 1. The weight vector of a component `S_i` with respect to `L` can be found by calculating the cross product between direction @@ -1331,14 +1338,17 @@ def weight_vectors(self): r""" Return the weight vectors for all vertices of ``self``. + Weight vectors are a list of vectors associated with each vertex + of the curve. Each vector corresponds to an edge emanating from + that vertex and points in the direction of the edge. + Suppose `v` is a vertex adjacent to the edges `e_1, ldots, e_k` with respective weights `w_1, ldots, w_k`. Every edge `e_i` is - contained in a line (component) defined by an equation with - integer coefficients. Because of this there exists a unique - integer vector `v_i=(\alpha, \beta)` in the direction of `e_i` - such that `\gcd(\alpha, \beta)=1`. Then each vertex `v` yield - the vectors `w_1v_1,ldots,w_kv_k`. These vectors will satisfy - the following balancing condition: + contained in a line (component) defined by an equation. Therefore, + there exists a unique integer vector `v_i=(\alpha, \beta)` in + the direction of `e_i` such that `\gcd(\alpha, \beta)=1`. Then, + each vertex `v` yield the vectors `w_1v_1,ldots,w_kv_k`. + These vectors will satisfy the following balancing condition: `\sum_{i=1}^k w_i v_i = 0`. OUTPUT: @@ -1574,7 +1584,7 @@ def _parameter_intervals(self): intervals.append(interval) return intervals - def plot(self, dominant_term=False): + def plot(self): """ Return the plot of ``self``. From 4306750c0b6ce223898c4a491e52cbaff83da61c Mon Sep 17 00:00:00 2001 From: Verrel Rievaldo Wijaya Date: Mon, 2 Sep 2024 21:34:29 +0700 Subject: [PATCH 174/537] Add more examples to ``TropicalCurve`` --- .../rings/semirings/tropical_polynomial.py | 2 +- src/sage/rings/semirings/tropical_variety.py | 60 ++++++++++++++++++- 2 files changed, 58 insertions(+), 4 deletions(-) diff --git a/src/sage/rings/semirings/tropical_polynomial.py b/src/sage/rings/semirings/tropical_polynomial.py index 780a44c4758..18c744ea8eb 100644 --- a/src/sage/rings/semirings/tropical_polynomial.py +++ b/src/sage/rings/semirings/tropical_polynomial.py @@ -53,7 +53,7 @@ class TropicalPolynomial(Polynomial_generic_sparse): EXAMPLES: - First, we construct a tropical polynomial semiring by defining a base + We construct a tropical polynomial semiring by defining a base tropical semiring and then inputting it to :class:`PolynomialRing`:: sage: T = TropicalSemiring(QQ, use_min=False) diff --git a/src/sage/rings/semirings/tropical_variety.py b/src/sage/rings/semirings/tropical_variety.py index 6a9f4aa2314..59b6279cd5a 100644 --- a/src/sage/rings/semirings/tropical_variety.py +++ b/src/sage/rings/semirings/tropical_variety.py @@ -1192,15 +1192,69 @@ class TropicalCurve(TropicalVariety): condition ensures that the sum of the outgoing slopes at each vertex is zero, reflecting the equilibrium. - EXAMPLES:: + EXAMPLES: + + We define some tropical curves:: sage: T = TropicalSemiring(QQ, use_min=False) sage: R. = PolynomialRing(T) sage: p1 = x + y + R(0) - sage: tv = p1.tropical_variety(); tv + sage: tv1 = p1.tropical_variety(); tv1 Tropical curve of 0*x + 0*y + 0 - sage: tv.components() + sage: tv1.components() [[(t1, t1), [t1 >= 0], 1], [(0, t1), [t1 <= 0], 1], [(t1, 0), [t1 <= 0], 1]] + sage: tv1.plot() + Graphics object consisting of 3 graphics primitives + + .. PLOT:: + :width: 300 px + + T = TropicalSemiring(QQ, use_min=False) + R = PolynomialRing(T, ('x,y')) + x, y = R.gen(), R.gen(1) + p1 = x + y + R(0) + sphinx_plot(p1.tropical_variety().plot()) + + :: + + sage: p2 = R(-2)*x^2 + R(-1)*x + R(1/2)*y + R(1/6) + sage: tv2 = p2.tropical_variety() + sage: tv2.components() + [[(1/2*t1 + 5/4, t1), [(-1/3) <= t1], 1], + [(13/12, t1), [t1 <= (-1/3)], 2], + [(t1, -1/3), [t1 <= (13/12)], 1]] + sage: tv2.plot() + Graphics object consisting of 4 graphics primitives + + .. PLOT:: + :width: 300 px + + T = TropicalSemiring(QQ, use_min=False) + R = PolynomialRing(T, ('x,y')) + x, y = R.gen(), R.gen(1) + p2 = R(-2)*x**2 + R(-1)*x + R(1/2)*y + R(1/6) + sphinx_plot(p2.tropical_variety().plot()) + + When two tropical polynomials are multiplied, the tropical curve of + the resulting polynomial is the union of the tropical curves of the + original polynomials:: + + sage: p3 = p1 * p2; p3 + (-2)*x^3 + (-2)*x^2*y + (-1)*x^2 + 1/2*x*y + 1/2*y^2 + 1/6*x + 1/2*y + 1/6 + sage: tv3 = p3.tropical_variety() + sage: tv3.plot() + Graphics object consisting of 11 graphics primitives + + .. PLOT:: + :width: 300 px + + T = TropicalSemiring(QQ, use_min=False) + R = PolynomialRing(T, ('x,y')) + x, y = R.gen(), R.gen(1) + p1 = x + y + R(0) + p2 = R(-2)*x**2 + R(-1)*x + R(1/2)*y + R(1/6) + p3 = p1 * p2 + sphinx_plot(p3.tropical_variety().plot()) """ def _axes(self): """ From b32359c1bebe28ca4c06156751ce4e9b25dcf26e Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Fri, 6 Sep 2024 12:35:48 +0530 Subject: [PATCH 175/537] Edited basis() method --- src/sage/matroids/chow_ring.py | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/src/sage/matroids/chow_ring.py b/src/sage/matroids/chow_ring.py index 1fc5e41b740..22b814dd6e4 100644 --- a/src/sage/matroids/chow_ring.py +++ b/src/sage/matroids/chow_ring.py @@ -10,8 +10,7 @@ from sage.rings.quotient_ring import QuotientRing_generic from sage.categories.graded_algebras_with_basis import GradedAlgebrasWithBasis from sage.categories.commutative_rings import CommutativeRings -from sage.misc.misc_c import prod -from itertools import product +from sage.sets.set import Set from sage.combinat.posets.posets import Poset from sage.combinat.subset import Subsets @@ -180,11 +179,12 @@ def basis(self): """ flats = [X for i in range(1, self._matroid.rank()) for X in self._matroid.flats(i)] + flats.append(frozenset()) maximum_rank = max(self._matroid.rank(F) for F in flats) flats_gen = self._ideal.flats_generator() R = self._ideal.ring() flats = sorted(flats, key=lambda X: (len(X), sorted(X))) - ranks = [self._matroid.rank(F) for F in flats] + ranks = {F:self._matroid.rank(F) for F in flats} monomial_basis = [] if self._augmented is True: if self._presentation == 'fy': @@ -263,24 +263,32 @@ def generate_combinations(current_combination, index, max_powers, x_dict): current_combination[index] = power generate_combinations(current_combination, index + 1, max_powers, x_dict) - print(ranks) R = self._ideal.ring() lattice_flats = self._matroid.lattice_of_flats() chains = lattice_flats.chains() for chain in chains: print(chain) - print(flats) + for chain in chains: + print(chain) + print(subset) + flag = False + for i in range(len(subset)): + if len(subset) != 1: + if (i != 0) & ((len(subset[i]) == len(subset[i-1]))): + flag = True + break + if flag is True: + break max_powers = [] x_dict = dict() - for F in chain: - if F == frozenset(): + for i in range(len(subset)): + if subset[i] == frozenset(): max_powers.append(0) - x_dict[F] = 1 + x_dict[subset[i]] = 1 else: - max_powers.append(ranks[flats.index(F)] - ranks[flats.index(F) - 1]) - x_dict[F] = flats_gen[F] - k = len(chain) - print(max_powers, x_dict, k) + max_powers.append(ranks[subset[i]] - ranks[subset[i-1]]) + x_dict[subset[i]] = flats_gen[subset[i]] + k = len(subset) current_combination = [0] * k generate_combinations(current_combination, 0, max_powers, x_dict) From 3d0525752e9b5b15a8832de80e98be2ffd9ece4c Mon Sep 17 00:00:00 2001 From: Verrel Rievaldo Wijaya Date: Sun, 8 Sep 2024 12:59:40 +0700 Subject: [PATCH 176/537] Move dual subdivision to ``TropicalMPolynomial`` --- .../rings/semirings/tropical_mpolynomial.py | 80 ++++++++++++++++++ src/sage/rings/semirings/tropical_variety.py | 84 ------------------- 2 files changed, 80 insertions(+), 84 deletions(-) diff --git a/src/sage/rings/semirings/tropical_mpolynomial.py b/src/sage/rings/semirings/tropical_mpolynomial.py index 3d06fa1a7d8..8b391911b6a 100644 --- a/src/sage/rings/semirings/tropical_mpolynomial.py +++ b/src/sage/rings/semirings/tropical_mpolynomial.py @@ -387,6 +387,86 @@ def tropical_variety(self): if self.parent().ngens() == 3: return TropicalSurface(self) return TropicalVariety(self) + + def dual_subdivision(self): + """ + Return the dual subdivision of ``self``. + + Dual subdivision refers to a specific decomposition of the + Newton polygon of a tropical polynomial. This Newton polygon + is the convex hull of all the points corresponding to the + exponents of the terms of the tropical polynomial. The term + "dual" is used in the sense that the combinatorial structure + of the tropical variety is reflected in the dual subdivision. + Vertices of the dual subdivision correspond to the intersection + of multiple components. Edges of the dual subdivision correspond + to the individual components. + + OUTPUT: :class:`sage.geometry.polyhedral_complex.PolyhedralComplex` + + EXAMPLES: + + Dual subdivision of a tropical curve:: + + sage: T = TropicalSemiring(QQ, use_min=False) + sage: R. = PolynomialRing(T) + sage: p1 = R(3) + R(2)*x + R(2)*y + R(3)*x*y + x^2 + y^2 + sage: p1.dual_subdivision() + Polyhedral complex with 4 maximal cells + + .. PLOT:: + :width: 300 px + + T = TropicalSemiring(QQ, use_min=False) + R = PolynomialRing(T, ('x,y')) + x, y = R.gen(), R.gen(1) + p1 = R(3) + R(2)*x + R(2)*y + R(3)*x*y + x**2 + y**2 + tv = p1.tropical_variety() + pc = tv.dual_subdivision() + sphinx_plot(pc.plot()) + + Dual subdivision of a tropical surface:: + + sage: T = TropicalSemiring(QQ) + sage: R. = PolynomialRing(T) + sage: p1 = x + y + z + x^2 + R(1) + sage: p1.dual_subdivision() + Polyhedral complex with 5 maximal cells + + .. PLOT:: + :width: 300 px + + T = TropicalSemiring(QQ, use_min=False) + R = PolynomialRing(T, ('x,y,z')) + x, y, z = R.gen(), R.gen(1), R.gen(2) + p1 = x + y + z + x**2 + R(1) + tv = p1.tropical_variety() + pc = tv.dual_subdivision() + sphinx_plot(pc.plot()) + + Dual subdivision of a tropical hypersurface:: + + sage: T = TropicalSemiring(QQ) + sage: R. = PolynomialRing(T) + sage: p1 = a^2 + b^2 + c^2 + d^2 + a*b*c*d + sage: p1.dual_subdivision() + Polyhedral complex with 6 maximal cells + """ + from sage.graphs.graph import Graph + from sage.geometry.polyhedron.constructor import Polyhedron + from sage.geometry.polyhedral_complex import PolyhedralComplex + + TV = self.tropical_variety() + G = Graph() + edges = [e for e in TV._keys] + G.add_edges(edges) + + polyhedron_lst = [] + for cycle in G.cycle_basis(): + polyhedron = Polyhedron(vertices=cycle) + polyhedron_lst.append(polyhedron) + pc = PolyhedralComplex(polyhedron_lst) + return pc def _repr_(self): r""" diff --git a/src/sage/rings/semirings/tropical_variety.py b/src/sage/rings/semirings/tropical_variety.py index 59b6279cd5a..7c3bf06dbf8 100644 --- a/src/sage/rings/semirings/tropical_variety.py +++ b/src/sage/rings/semirings/tropical_variety.py @@ -535,90 +535,6 @@ def update_result(result): update_result(result) return result - def dual_subdivision(self): - """ - Return the dual subdivision of ``self``. - - Dual subdivision refers to a specific decomposition of the - Newton polygon of a tropical polynomial. This Newton polygon - is the convex hull of all the points corresponding to the - exponents of the terms of the tropical polynomial. The term - "dual" is used in the sense that the combinatorial structure - of the tropical variety is reflected in the dual subdivision. - Vertices of the dual subdivision correspond to the intersection - of multiple components. Edges of the dual subdivision correspond - to the individual components. - - OUTPUT: :class:`sage.geometry.polyhedral_complex.PolyhedralComplex` - - EXAMPLES: - - Dual subdivision of a tropical curve:: - - sage: T = TropicalSemiring(QQ, use_min=False) - sage: R. = PolynomialRing(T) - sage: p1 = R(3) + R(2)*x + R(2)*y + R(3)*x*y + x^2 + y^2 - sage: tv = p1.tropical_variety() - sage: pc = tv.dual_subdivision() - sage: pc.plot() - Graphics object consisting of 20 graphics primitives - - .. PLOT:: - :width: 300 px - - T = TropicalSemiring(QQ, use_min=False) - R = PolynomialRing(T, ('x,y')) - x, y = R.gen(), R.gen(1) - p1 = R(3) + R(2)*x + R(2)*y + R(3)*x*y + x**2 + y**2 - tv = p1.tropical_variety() - pc = tv.dual_subdivision() - sphinx_plot(pc.plot()) - - Dual subdivision of a tropical surface:: - - sage: T = TropicalSemiring(QQ) - sage: R. = PolynomialRing(T) - sage: p1 = x + y + z + x^2 + R(1) - sage: tv = p1.tropical_variety() - sage: pc = tv.dual_subdivision() - sage: pc.plot() - Graphics3d Object - - .. PLOT:: - :width: 300 px - - T = TropicalSemiring(QQ, use_min=False) - R = PolynomialRing(T, ('x,y,z')) - x, y, z = R.gen(), R.gen(1), R.gen(2) - p1 = x + y + z + x**2 + R(1) - tv = p1.tropical_variety() - pc = tv.dual_subdivision() - sphinx_plot(pc.plot()) - - Dual subdivision of a tropical hypersurface:: - - sage: T = TropicalSemiring(QQ) - sage: R. = PolynomialRing(T) - sage: p1 = a^2 + b^2 + c^2 + d^2 + a*b*c*d - sage: tv = p1.tropical_variety() - sage: pc = tv.dual_subdivision(); pc - Polyhedral complex with 6 maximal cells - """ - from sage.graphs.graph import Graph - from sage.geometry.polyhedron.constructor import Polyhedron - from sage.geometry.polyhedral_complex import PolyhedralComplex - - G = Graph() - edges = [e for e in self._keys] - G.add_edges(edges) - - polyhedron_lst = [] - for cycle in G.cycle_basis(): - polyhedron = Polyhedron(vertices=cycle) - polyhedron_lst.append(polyhedron) - pc = PolyhedralComplex(polyhedron_lst) - return pc - def weight_vectors(self): r""" Return the weight vectors for each unique intesection of From d2d211b4169899bcb371d26504d647f2e343c115 Mon Sep 17 00:00:00 2001 From: Verrel Rievaldo Wijaya Date: Sun, 8 Sep 2024 13:20:07 +0700 Subject: [PATCH 177/537] Add ``polytope`` to ``TropicalMPolynomial`` --- .../rings/semirings/tropical_mpolynomial.py | 67 ++++++++++++++++--- 1 file changed, 58 insertions(+), 9 deletions(-) diff --git a/src/sage/rings/semirings/tropical_mpolynomial.py b/src/sage/rings/semirings/tropical_mpolynomial.py index 8b391911b6a..a506317ccc3 100644 --- a/src/sage/rings/semirings/tropical_mpolynomial.py +++ b/src/sage/rings/semirings/tropical_mpolynomial.py @@ -387,20 +387,69 @@ def tropical_variety(self): if self.parent().ngens() == 3: return TropicalSurface(self) return TropicalVariety(self) - + + def polytope(self): + """ + Return the Newton polytope of ``self``. + + The Newton polytope is the convex hull of all the points + corresponding to the exponents of the monomials of tropical + polynomial. + + OUTPUT: :class:`sage.geometry.polyhedron.constructor.Polyhedron` + + EXAMPLES: + + Newton polytope for two variable tropical polynomial:: + + sage: T = TropicalSemiring(QQ) + sage: R. = PolynomialRing(T) + sage: p1 = x + y + sage: p1.polytope() + A 1-dimensional polyhedron in ZZ^2 defined as the convex hull of 2 vertices + + .. PLOT:: + :width: 300 px + + T = TropicalSemiring(QQ) + R = PolynomialRing(T, ('x,y')) + x, y = R.gen(), R.gen(1) + p1 = x + y + sphinx_plot(p1.polytope().plot()) + + Newton polytope in three dimension:: + + sage: T = TropicalSemiring(QQ) + sage: R. = PolynomialRing(T) + sage: p1 = x^2 + x*y*z + x + y + z + R(0) + sage: p1.polytope() + A 3-dimensional polyhedron in ZZ^3 defined as the convex hull of 5 vertices + + .. PLOT:: + :width: 300 px + + T = TropicalSemiring(QQ) + R = PolynomialRing(T, ('x,y,z')) + x, y, z = R.gen(), R.gen(1), R.gen(2) + p1 = x**2 + x*y*z + x + y + z + R(0) + sphinx_plot(p1.polytope().plot()) + """ + from sage.geometry.polyhedron.constructor import Polyhedron + + exponents = self.exponents() + return Polyhedron(exponents) + def dual_subdivision(self): """ Return the dual subdivision of ``self``. Dual subdivision refers to a specific decomposition of the - Newton polygon of a tropical polynomial. This Newton polygon - is the convex hull of all the points corresponding to the - exponents of the terms of the tropical polynomial. The term - "dual" is used in the sense that the combinatorial structure - of the tropical variety is reflected in the dual subdivision. - Vertices of the dual subdivision correspond to the intersection - of multiple components. Edges of the dual subdivision correspond - to the individual components. + Newton polytope of a tropical polynomial. The term "dual" is + used in the sense that the combinatorial structure of the + tropical variety is reflected in the dual subdivision. + Specifically, vertices of the dual subdivision correspond to + the intersection of multiple components. Edges of the dual + subdivision correspond to the individual components. OUTPUT: :class:`sage.geometry.polyhedral_complex.PolyhedralComplex` From 53f495e6309267705d0cc37d610b7e9554476580 Mon Sep 17 00:00:00 2001 From: Verrel Rievaldo Wijaya Date: Sun, 8 Sep 2024 15:05:51 +0700 Subject: [PATCH 178/537] Fix ``PLOT`` section in dual subdivision --- src/sage/rings/semirings/tropical_mpolynomial.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/sage/rings/semirings/tropical_mpolynomial.py b/src/sage/rings/semirings/tropical_mpolynomial.py index a506317ccc3..887b21cddff 100644 --- a/src/sage/rings/semirings/tropical_mpolynomial.py +++ b/src/sage/rings/semirings/tropical_mpolynomial.py @@ -470,9 +470,7 @@ def dual_subdivision(self): R = PolynomialRing(T, ('x,y')) x, y = R.gen(), R.gen(1) p1 = R(3) + R(2)*x + R(2)*y + R(3)*x*y + x**2 + y**2 - tv = p1.tropical_variety() - pc = tv.dual_subdivision() - sphinx_plot(pc.plot()) + sphinx_plot(p1.dual_subdivision().plot()) Dual subdivision of a tropical surface:: @@ -489,9 +487,7 @@ def dual_subdivision(self): R = PolynomialRing(T, ('x,y,z')) x, y, z = R.gen(), R.gen(1), R.gen(2) p1 = x + y + z + x**2 + R(1) - tv = p1.tropical_variety() - pc = tv.dual_subdivision() - sphinx_plot(pc.plot()) + sphinx_plot(p1.dual_subdivision().plot()) Dual subdivision of a tropical hypersurface:: From 93b19bfdd0b7e2d864eb77f9273ddeaa182db814 Mon Sep 17 00:00:00 2001 From: Newtech66 Date: Mon, 9 Sep 2024 12:11:42 +0530 Subject: [PATCH 179/537] Fix in compose_with_singletons --- src/sage/rings/species.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/sage/rings/species.py b/src/sage/rings/species.py index f4d5bc047c1..084b605af1b 100644 --- a/src/sage/rings/species.py +++ b/src/sage/rings/species.py @@ -1140,6 +1140,14 @@ def _compose_with_singletons(self, base_ring, names, args): sage: M = P._indices sage: M.one()._compose_with_singletons(ZZ, "X", [[1]]) 1 + + sage: P = PolynomialSpecies(ZZ, "X") + sage: M = P._indices + sage: F = M(SymmetricGroup(1)) * M(SymmetricGroup(2)) + sage: F._compose_with_singletons(QQ,["T","S"],[[2,1]]) + E_2(T)*S + T^2*S + sage: F._compose_with_singletons(QQ,["T","S"],[[1,2]]) + T*S^2 + T*E_2(S) """ # TODO: No checks are performed right now, must be added. # Checks: all args in Compositions, sums must match cardinalities. @@ -1159,7 +1167,7 @@ def _compose_with_singletons(self, base_ring, names, args): taus = libgap.DoubleCosetRepsAndSizes(S_up, S_down, G) # Sum over double coset representatives. for tau, _ in taus: - H = libgap.Intersection(libgap.ConjugateGroup(G, tau), S_down) + H = libgap.Intersection(libgap.ConjugateGroup(G, tau ** -1), S_down) grp = PermutationGroup(gap_group=H, domain=self.domain()) res += Pn(grp, dpart) return res From 9f663272c0b440ff1de31ca08e6c4375dc7c32aa Mon Sep 17 00:00:00 2001 From: Verrel Rievaldo Wijaya Date: Tue, 10 Sep 2024 03:46:02 +0700 Subject: [PATCH 180/537] Fix dual subdivision --- .../rings/semirings/tropical_mpolynomial.py | 31 +++++++++++++++++-- src/sage/rings/semirings/tropical_variety.py | 20 ++++++------ 2 files changed, 38 insertions(+), 13 deletions(-) diff --git a/src/sage/rings/semirings/tropical_mpolynomial.py b/src/sage/rings/semirings/tropical_mpolynomial.py index 887b21cddff..4e103112bdc 100644 --- a/src/sage/rings/semirings/tropical_mpolynomial.py +++ b/src/sage/rings/semirings/tropical_mpolynomial.py @@ -478,7 +478,7 @@ def dual_subdivision(self): sage: R. = PolynomialRing(T) sage: p1 = x + y + z + x^2 + R(1) sage: p1.dual_subdivision() - Polyhedral complex with 5 maximal cells + Polyhedral complex with 7 maximal cells .. PLOT:: :width: 300 px @@ -495,7 +495,7 @@ def dual_subdivision(self): sage: R. = PolynomialRing(T) sage: p1 = a^2 + b^2 + c^2 + d^2 + a*b*c*d sage: p1.dual_subdivision() - Polyhedral complex with 6 maximal cells + Polyhedral complex with 10 maximal cells """ from sage.graphs.graph import Graph from sage.geometry.polyhedron.constructor import Polyhedron @@ -506,8 +506,33 @@ def dual_subdivision(self): edges = [e for e in TV._keys] G.add_edges(edges) + # Recursive function to find all cycles that partition the graph + # to its dual subdivision + def search(cycle, next, adj): + min_cycle = False + for n in next: + new_cycle = [i for i in cycle] + new_cycle.append(n) + if vertex in G.neighbors(n): + all_cycles.append(new_cycle) + min_cycle = True + if not min_cycle: + for n in next: + new_cycle = [i for i in cycle] + new_cycle.append(n) + new_next = [v for v in G.neighbors(n) if v != adj] + search(new_cycle, new_next, n) + + all_cycles = [] + for vertex in G.vertices(): + for adj in G.neighbors(vertex): + cycle = [vertex] + cycle.append(adj) + next = [v for v in G.neighbors(adj) if v != vertex] + search(cycle, next, adj) + polyhedron_lst = [] - for cycle in G.cycle_basis(): + for cycle in all_cycles: polyhedron = Polyhedron(vertices=cycle) polyhedron_lst.append(polyhedron) pc = PolyhedralComplex(polyhedron_lst) diff --git a/src/sage/rings/semirings/tropical_variety.py b/src/sage/rings/semirings/tropical_variety.py index 7c3bf06dbf8..5d8743f6b71 100644 --- a/src/sage/rings/semirings/tropical_variety.py +++ b/src/sage/rings/semirings/tropical_variety.py @@ -575,9 +575,9 @@ def weight_vectors(self): sage: tv = p.tropical_variety() sage: tv.weight_vectors() ({0: ((1/2*u2, u2 + 1, u2), {u2 <= 1}), - 1: ((1/2, 2, u2), {1 <= u2}), - 2: ((1/2, u2, 1), {2 <= u2}), - 3: ((u1, 2, 1), {(1/2) <= u1})}, + 1: ((1/2, 2, u2), {1 <= u2}), + 2: ((1/2, u2, 1), {2 <= u2}), + 3: ((u1, 2, 1), {(1/2) <= u1})}, {0: [(1, 2, -5/2), (1, -5/2, 2), (-2, 1/2, 1/2)], 1: [(-1, -2, 0), (0, 2, 0), (1, 0, 0)], 2: [(1, 0, 2), (0, 0, -2), (-1, 0, 0)], @@ -591,13 +591,13 @@ def weight_vectors(self): sage: tv = p1.tropical_variety() sage: tv.weight_vectors() ({0: ((u1, u3 - 7/3, u3 - 10/3, u3), {u1 <= u3 - 22/3}), - 1: ((u2 - 4, u2 + 1, u2, u3), {u2 <= u3 - 10/3}), - 2: ((2*u1 - u3 - 2/3, u3 - 7/3, u1, u3), {u3 - 10/3 <= u1}), - 3: ((u3 - 22/3, u2, u3 - 10/3, u3), {u3 - 7/3 <= u2})}, - {0: [(0, 1, 1, -2), (0, 1, -2, 1), (0, -2, 1, 1)], - 1: [(-2, 1, 1, 0), (3, -3, 0, 0), (-1, 2, -1, 0)], - 2: [(-1, 5, 2, -6), (2, 1, -4, 1), (-1, -6, 2, 5)], - 3: [(-1, 0, -1, 2), (-2, 0, 1, 1), (3, 0, 0, -3)]}) + 1: ((u2 - 4, u2 + 1, u2, u3), {u2 <= u3 - 10/3}), + 2: ((2*u1 - u3 - 2/3, u3 - 7/3, u1, u3), {u3 - 10/3 <= u1}), + 3: ((u3 - 22/3, u2, u3 - 10/3, u3), {u3 - 7/3 <= u2})}, + {0: [(0, -1, -1, 2), (0, -1, 2, -1), (0, 2, -1, -1)], + 1: [(2, -1, -1, 0), (-3, 3, 0, 0), (1, -2, 1, 0)], + 2: [(1, -5, -2, 6), (-2, -1, 4, -1), (1, 6, -2, -5)], + 3: [(1, 0, 1, -2), (2, 0, -1, -1), (-3, 0, 0, 3)]}) """ from sage.symbolic.ring import SR from sage.symbolic.relation import solve From 1cede4bc18b3e76a1750c0c462fe0918823f74c0 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Tue, 10 Sep 2024 09:55:51 +0530 Subject: [PATCH 181/537] Edited basis() method- added product func --- src/sage/matroids/chow_ring.py | 60 ++++++++++------------------------ 1 file changed, 17 insertions(+), 43 deletions(-) diff --git a/src/sage/matroids/chow_ring.py b/src/sage/matroids/chow_ring.py index 22b814dd6e4..cd12ec00912 100644 --- a/src/sage/matroids/chow_ring.py +++ b/src/sage/matroids/chow_ring.py @@ -13,6 +13,7 @@ from sage.sets.set import Set from sage.combinat.posets.posets import Poset from sage.combinat.subset import Subsets +from itertools import product class ChowRing(QuotientRing_generic): r""" @@ -177,7 +178,7 @@ def basis(self): sage: ch = matroids.Wheel(3).chow_ring(ZZ, False) [A0*A013, 1] """ - flats = [X for i in range(1, self._matroid.rank()) + flats = [X for i in range(1, self._matroid.rank() + 1) for X in self._matroid.flats(i)] flats.append(frozenset()) maximum_rank = max(self._matroid.rank(F) for F in flats) @@ -242,57 +243,30 @@ def generate_combinations(current_combination, index, max_powers, x_dict): generate_combinations(current_combination, 0, max_powers, x_dict) - else: - def generate_combinations(current_combination, index, max_powers, x_dict): - # Base case: If index equals the length of max_powers, print the current combination - if index == len(max_powers): - expression_terms = [x_dict[i+1] if current_combination[i] == 1 - else x_dict[i+1]**{current_combination[i]} - for i in range(len(current_combination)) if current_combination[i] != 0] - if expression_terms: - term = R.one() - for t in expression_terms: - term *= t - monomial_basis.append(term) - else: - monomial_basis.append(R.one()) - return - - # Recursive case: Iterate over the range for the current index - for power in range(max_powers[index]): - current_combination[index] = power - generate_combinations(current_combination, index + 1, max_powers, x_dict) - + else: R = self._ideal.ring() lattice_flats = self._matroid.lattice_of_flats() chains = lattice_flats.chains() for chain in chains: - print(chain) - for chain in chains: - print(chain) - print(subset) - flag = False - for i in range(len(subset)): - if len(subset) != 1: - if (i != 0) & ((len(subset[i]) == len(subset[i-1]))): - flag = True - break - if flag is True: - break max_powers = [] x_dict = dict() - for i in range(len(subset)): - if subset[i] == frozenset(): + for i in range(len(chain)): + if chain[i] == frozenset(): max_powers.append(0) - x_dict[subset[i]] = 1 + x_dict[chain[i]] = 1 + elif i == 0: + max_powers.append(ranks[chain[i]]) + x_dict[chain[i]] = flats_gen[chain[i]] else: - max_powers.append(ranks[subset[i]] - ranks[subset[i-1]]) - x_dict[subset[i]] = flats_gen[subset[i]] - k = len(subset) - current_combination = [0] * k - generate_combinations(current_combination, 0, max_powers, x_dict) + max_powers.append(ranks[chain[i]] - ranks[chain[i-1]]) + x_dict[chain[i]] = flats_gen[chain[i]] + k = len(chain) + for combination in product(*(range(p) for p in max_powers)): + expression = R.one() + for i in range(k): + expression *= x_dict[chain[i]]**combination[i] + monomial_basis.append(expression) - print(monomial_basis) from sage.sets.family import Family return Family([self.element_class(self, mon, reduce=False) for mon in monomial_basis]) From dc8e3809a6b3fbe86d73e6cd872af1a5ef1761ba Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Tue, 10 Sep 2024 09:56:11 +0530 Subject: [PATCH 182/537] Debugged groebner_basis() method --- src/sage/matroids/chow_ring_ideal.py | 25 +++++++------------------ 1 file changed, 7 insertions(+), 18 deletions(-) diff --git a/src/sage/matroids/chow_ring_ideal.py b/src/sage/matroids/chow_ring_ideal.py index 15c31a8c268..b73a9e63592 100644 --- a/src/sage/matroids/chow_ring_ideal.py +++ b/src/sage/matroids/chow_ring_ideal.py @@ -122,13 +122,13 @@ def __init__(self, M, R): sage: TestSuite(I).run(skip="_test_category") """ self._matroid = M - flats = [X for i in range(1, self._matroid.rank()) + flats = [X for i in range(1, self._matroid.rank() + 1) 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 except ValueError: # variables are not proper names - poly_ring = PolynomialRing(R, 'A', len(self.flats)) + poly_ring = PolynomialRing(R, 'A', len(flats)) gens = poly_ring.gens() self._flats_generator = dict(zip(flats, gens)) MPolynomialIdeal.__init__(self, poly_ring, self._gens_constructor(poly_ring)) @@ -233,18 +233,7 @@ def groebner_basis(self): if frozenset() not in flats: flats.append(frozenset()) - ranks = [self._matroid.rank(F) for F in flats] - - def m_n(i): - if flats[i] == frozenset(): - return 0 - else: - sum1 = 0 - for j in range(len(flats)): - if flats[j] < flats[i]: - sum1 += m_n(j) - - return ranks[i] - sum1 + ranks = {F:self._matroid.rank(F) for F in flats} P = LatticePoset(flats) subsets = Subsets(flats) @@ -266,7 +255,7 @@ def m_n(i): if G >= F: term1 += self._flats_generator[G] if term1 != R.zero(): - gb.append(term*(term1**m_n(flats.index(subset)))) + gb.append(term*(term1**())) g_basis = PolynomialSequence(R, [gb]) return g_basis @@ -338,7 +327,7 @@ def __init__(self, M, R): sage: TestSuite(I).run(skip="_test_category") """ self._matroid = M - self._flats = [X for i in range(1, self._matroid.rank()) + self._flats = [X for i in range(1, self._matroid.rank() + 1) for X in self._matroid.flats(i)] E = list(self._matroid.groundset()) self._flats_generator = dict() @@ -536,7 +525,7 @@ def __init__(self, M, R): sage: TestSuite(I).run(skip="_test_category") """ self._matroid = M - self._flats = [X for i in range(1, self._matroid.rank()) + self._flats = [X for i in range(1, self._matroid.rank() + 1) for X in self._matroid.flats(i)] E = list(self._matroid.groundset()) @@ -630,7 +619,7 @@ def groebner_basis(self): True """ gb = [] - flats = [X for i in range(1, self._matroid.rank()) + flats = [X for i in range(1, self._matroid.rank() + 1) for X in self._matroid.flats(i)] poly_ring = self.ring() if frozenset() in flats: From 2fe9f386d97605e268a713fc174915067468525f Mon Sep 17 00:00:00 2001 From: Verrel Rievaldo Wijaya Date: Tue, 10 Sep 2024 11:51:59 +0700 Subject: [PATCH 183/537] Modify dual subdivisio to utilize weight vectors --- .../rings/semirings/tropical_mpolynomial.py | 56 ++++++++----------- src/sage/rings/semirings/tropical_variety.py | 25 +++++---- 2 files changed, 37 insertions(+), 44 deletions(-) diff --git a/src/sage/rings/semirings/tropical_mpolynomial.py b/src/sage/rings/semirings/tropical_mpolynomial.py index 4e103112bdc..2e62f11b05a 100644 --- a/src/sage/rings/semirings/tropical_mpolynomial.py +++ b/src/sage/rings/semirings/tropical_mpolynomial.py @@ -493,46 +493,36 @@ def dual_subdivision(self): sage: T = TropicalSemiring(QQ) sage: R. = PolynomialRing(T) - sage: p1 = a^2 + b^2 + c^2 + d^2 + a*b*c*d + sage: p1 = R(2)*a*b + R(3)*a*c + R(-1)*c^2 + R(-1/3)*a*d sage: p1.dual_subdivision() - Polyhedral complex with 10 maximal cells + Polyhedral complex with 4 maximal cells """ - from sage.graphs.graph import Graph from sage.geometry.polyhedron.constructor import Polyhedron from sage.geometry.polyhedral_complex import PolyhedralComplex TV = self.tropical_variety() - G = Graph() - edges = [e for e in TV._keys] - G.add_edges(edges) - - # Recursive function to find all cycles that partition the graph - # to its dual subdivision - def search(cycle, next, adj): - min_cycle = False - for n in next: - new_cycle = [i for i in cycle] - new_cycle.append(n) - if vertex in G.neighbors(n): - all_cycles.append(new_cycle) - min_cycle = True - if not min_cycle: - for n in next: - new_cycle = [i for i in cycle] - new_cycle.append(n) - new_next = [v for v in G.neighbors(n) if v != adj] - search(new_cycle, new_next, n) - - all_cycles = [] - for vertex in G.vertices(): - for adj in G.neighbors(vertex): - cycle = [vertex] - cycle.append(adj) - next = [v for v in G.neighbors(adj) if v != vertex] - search(cycle, next, adj) - + cycles = [] + + if TV.dimension() == 2: + for indices in TV._vertices_components().values(): + cycle = [] + for index in indices: + vertices = TV._keys[index[0]] + for v in vertices: + cycle.append(v) + 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) + cycles.append(cycle) + polyhedron_lst = [] - for cycle in all_cycles: + for cycle in cycles: polyhedron = Polyhedron(vertices=cycle) polyhedron_lst.append(polyhedron) pc = PolyhedralComplex(polyhedron_lst) diff --git a/src/sage/rings/semirings/tropical_variety.py b/src/sage/rings/semirings/tropical_variety.py index 5d8743f6b71..96817231b95 100644 --- a/src/sage/rings/semirings/tropical_variety.py +++ b/src/sage/rings/semirings/tropical_variety.py @@ -561,9 +561,10 @@ def weight_vectors(self): OUTPUT: - A tuple of two dictionaries. The first dictionary contains + A tuple of three dictionaries. The first dictionary contains equations representing the intersections. The second dictionary - contains lists of vectors. + contains indices of components that contains the intersection. + The third dictionary contains lists of vectors. EXAMPLES: @@ -578,10 +579,11 @@ def weight_vectors(self): 1: ((1/2, 2, u2), {1 <= u2}), 2: ((1/2, u2, 1), {2 <= u2}), 3: ((u1, 2, 1), {(1/2) <= u1})}, - {0: [(1, 2, -5/2), (1, -5/2, 2), (-2, 1/2, 1/2)], - 1: [(-1, -2, 0), (0, 2, 0), (1, 0, 0)], - 2: [(1, 0, 2), (0, 0, -2), (-1, 0, 0)], - 3: [(0, 1, 1), (0, 0, -1), (0, -1, 0)]}) + {0: [0, 1, 3], 1: [0, 2, 4], 2: [1, 2, 5], 3: [3, 4, 5]}, + {0: [(1, 2, -5/2), (1, -5/2, 2), (-2, 1/2, 1/2)], + 1: [(-1, -2, 0), (0, 2, 0), (1, 0, 0)], + 2: [(1, 0, 2), (0, 0, -2), (-1, 0, 0)], + 3: [(0, 1, 1), (0, 0, -1), (0, -1, 0)]}) Weight vectors of tropical hypersurface:: @@ -594,10 +596,11 @@ def weight_vectors(self): 1: ((u2 - 4, u2 + 1, u2, u3), {u2 <= u3 - 10/3}), 2: ((2*u1 - u3 - 2/3, u3 - 7/3, u1, u3), {u3 - 10/3 <= u1}), 3: ((u3 - 22/3, u2, u3 - 10/3, u3), {u3 - 7/3 <= u2})}, - {0: [(0, -1, -1, 2), (0, -1, 2, -1), (0, 2, -1, -1)], - 1: [(2, -1, -1, 0), (-3, 3, 0, 0), (1, -2, 1, 0)], - 2: [(1, -5, -2, 6), (-2, -1, 4, -1), (1, 6, -2, -5)], - 3: [(1, 0, 1, -2), (2, 0, -1, -1), (-3, 0, 0, 3)]}) + {0: [0, 2, 4], 1: [0, 1, 3], 2: [1, 2, 5], 3: [3, 4, 5]}, + {0: [(0, -1, -1, 2), (0, -1, 2, -1), (0, 2, -1, -1)], + 1: [(2, -1, -1, 0), (-3, 3, 0, 0), (1, -2, 1, 0)], + 2: [(1, -5, -2, 6), (-2, -1, 4, -1), (1, 6, -2, -5)], + 3: [(1, 0, 1, -2), (2, 0, -1, -1), (-3, 0, 0, 3)]}) """ from sage.symbolic.ring import SR from sage.symbolic.relation import solve @@ -735,7 +738,7 @@ def weight_vectors(self): WV[k] = test_vectors break - return index_line, WV + return index_line, line_comps, WV class TropicalSurface(TropicalVariety): From 5e6bf99549167e1e81cba5da69aa64e5898ccb30 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Tue, 10 Sep 2024 11:18:25 +0530 Subject: [PATCH 184/537] Debugged groebner_basis() method for ChowRingIdeal_nonaug --- src/sage/matroids/chow_ring_ideal.py | 45 +++++++++++++++++++++------- 1 file changed, 34 insertions(+), 11 deletions(-) diff --git a/src/sage/matroids/chow_ring_ideal.py b/src/sage/matroids/chow_ring_ideal.py index b73a9e63592..6c21492e3ae 100644 --- a/src/sage/matroids/chow_ring_ideal.py +++ b/src/sage/matroids/chow_ring_ideal.py @@ -9,11 +9,10 @@ from sage.rings.polynomial.multi_polynomial_ideal import MPolynomialIdeal from sage.matroids.utilities import cmp_elements_key from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing -from sage.sets.set import Set from sage.rings.polynomial.multi_polynomial_sequence import PolynomialSequence from sage.misc.abstract_method import abstract_method -from sage.combinat.posets.lattices import LatticePoset from sage.combinat.subset import Subsets +from functools import reduce class ChowRingIdeal(MPolynomialIdeal): @abstract_method @@ -233,29 +232,53 @@ def groebner_basis(self): if frozenset() not in flats: flats.append(frozenset()) + def d(F, G): + lattice_flats = self._matroid.lattice_of_flats() + B = lattice_flats.bottom() + atoms = [x for x in B if B.is_cover(B, x)] + subsets = Subsets(atoms) + n = 0 + i = 0 + while (F != G): + if i == len(subsets): + break + l = [] + for j in list(subsets)[i]: + l.append(j) + l.append(F) + F = lattice_flats.join(l) + n += len(list(subsets)[i]) + i += 1 + return n + ranks = {F:self._matroid.rank(F) for F in flats} - - P = LatticePoset(flats) + flats_gen = self._flats_generator + flats_gen[frozenset()] = R.zero() subsets = Subsets(flats) for subset in subsets: - if not P.subposet(subset).is_chain(): + flag = True + for i in range (len(subset)): + if i != 0 & len(subset[i]) == len(subset[i-1]): + flag = False + + if not flag: term = R.one() for x in subset: - term *= self._flats_generator[x] + term *= flats_gen[x] gb.append(term) - else: + elif list(subset) != []: for F in flats: - if F > P.join(list(subset)): + if F > reduce(lambda a, b: a.union(b), list(subset)): term = R.one() for x in subset: - term *= self._flats_generator[x] + term *= flats_gen[x] term1 = R.zero() for G in flats: if G >= F: - term1 += self._flats_generator[G] + term1 += flats_gen[G] if term1 != R.zero(): - gb.append(term*(term1**())) + gb.append(term*(term1**(d(list(subset)[len(list(subset)) - 1], F)))) g_basis = PolynomialSequence(R, [gb]) return g_basis From 4ed084f1a3dd0b83fcba613bdaf8b642d5ff81fd Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Tue, 10 Sep 2024 12:45:37 +0530 Subject: [PATCH 185/537] Edited max_powers --- src/sage/matroids/chow_ring_ideal.py | 23 +++-------------------- 1 file changed, 3 insertions(+), 20 deletions(-) diff --git a/src/sage/matroids/chow_ring_ideal.py b/src/sage/matroids/chow_ring_ideal.py index 6c21492e3ae..1515736ef95 100644 --- a/src/sage/matroids/chow_ring_ideal.py +++ b/src/sage/matroids/chow_ring_ideal.py @@ -231,25 +231,6 @@ def groebner_basis(self): R = self.ring() if frozenset() not in flats: flats.append(frozenset()) - - def d(F, G): - lattice_flats = self._matroid.lattice_of_flats() - B = lattice_flats.bottom() - atoms = [x for x in B if B.is_cover(B, x)] - subsets = Subsets(atoms) - n = 0 - i = 0 - while (F != G): - if i == len(subsets): - break - l = [] - for j in list(subsets)[i]: - l.append(j) - l.append(F) - F = lattice_flats.join(l) - n += len(list(subsets)[i]) - i += 1 - return n ranks = {F:self._matroid.rank(F) for F in flats} flats_gen = self._flats_generator @@ -260,6 +241,8 @@ def d(F, G): for i in range (len(subset)): if i != 0 & len(subset[i]) == len(subset[i-1]): flag = False + break + if not flag: term = R.one() @@ -278,7 +261,7 @@ def d(F, G): if G >= F: term1 += flats_gen[G] if term1 != R.zero(): - gb.append(term*(term1**(d(list(subset)[len(list(subset)) - 1], F)))) + gb.append(term*(term1**(ranks[F] - ranks[list(subset)[len(subset) - 1]]))) g_basis = PolynomialSequence(R, [gb]) return g_basis From 5f89ce895d48369b5e5bd1b6f50aa1c467a320e4 Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Wed, 11 Sep 2024 11:42:49 +0200 Subject: [PATCH 186/537] move test for conjugacy to PermutationGroup_generic --- src/sage/groups/perm_gps/permgroup.py | 19 +++++++++++++++++++ src/sage/rings/species.py | 23 ++--------------------- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/src/sage/groups/perm_gps/permgroup.py b/src/sage/groups/perm_gps/permgroup.py index d97aad93b03..0d4d3a73b13 100644 --- a/src/sage/groups/perm_gps/permgroup.py +++ b/src/sage/groups/perm_gps/permgroup.py @@ -2734,6 +2734,25 @@ def conjugate(self, g): raise TypeError("{0} does not convert to a permutation group element".format(g)) return PermutationGroup(gap_group=libgap.ConjugateGroup(self, g)) + def are_conjugate(self, H1, H2): + r""" + Return whether ``H1`` and ``H2`` are conjugate subgroups in ``G``. + + EXAMPLES:: + + sage: G = SymmetricGroup(3) + sage: H1 = PermutationGroup([(1,2)]) + sage: H2 = PermutationGroup([(2,3)]) + sage: G.are_conjugate(H1, H2) + True + sage: G = SymmetricGroup(4) + sage: H1 = PermutationGroup([[(1,3),(2,4)], [(1,2),(3,4)]]) + sage: H2 = PermutationGroup([[(1,2)], [(1,2),(3,4)]]) + sage: G.are_conjugate(H1, H2) + False + """ + return libgap.IsConjugate(self, H1, H2).sage() + def direct_product(self, other, maps=True): """ Wraps GAP's ``DirectProduct``, ``Embedding``, and ``Projection``. diff --git a/src/sage/rings/species.py b/src/sage/rings/species.py index 084b605af1b..1c5ba7c887e 100644 --- a/src/sage/rings/species.py +++ b/src/sage/rings/species.py @@ -23,24 +23,6 @@ from sage.structure.parent import Parent from sage.structure.unique_representation import UniqueRepresentation -GAP_FAIL = libgap.eval('fail') - - -def _is_conjugate(G, H1, H2): - r""" - Test if ``H1`` and ``H2`` are conjugate subgroups in ``G``. - - EXAMPLES:: - - sage: G = SymmetricGroup(3) - sage: H1 = PermutationGroup([(1,2)]) - sage: H2 = PermutationGroup([(2,3)]) - sage: from sage.rings.species import _is_conjugate - sage: _is_conjugate(G, H1, H2) - True - """ - return GAP_FAIL != libgap.RepresentativeAction(G, H1, H2) - class ElementCache(): def __init__(self): @@ -195,10 +177,9 @@ def __eq__(self, other): True """ return (isinstance(other, ConjugacyClassOfDirectlyIndecomposableSubgroups) - and self._C.degree() == other._C.degree() + and (d := self._C.degree()) == other._C.degree() and (self._C == other._C - or _is_conjugate(SymmetricGroup(self._C.degree()), - self._C, other._C))) + or SymmetricGroup(d).are_conjugate(self._C, other._C))) class ConjugacyClassesOfDirectlyIndecomposableSubgroups(UniqueRepresentation, Parent, ElementCache): From a7058474691b218ffa76383865a9b6b721656166 Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Wed, 11 Sep 2024 12:05:52 +0200 Subject: [PATCH 187/537] more doctests, fixes for LazySpecies --- src/sage/rings/species.py | 79 +++++++++++++++++++++++++++++++-------- 1 file changed, 63 insertions(+), 16 deletions(-) diff --git a/src/sage/rings/species.py b/src/sage/rings/species.py index 1c5ba7c887e..9143e4432b3 100644 --- a/src/sage/rings/species.py +++ b/src/sage/rings/species.py @@ -1,5 +1,4 @@ from itertools import accumulate, chain - from sage.categories.graded_algebras_with_basis import GradedAlgebrasWithBasis from sage.categories.infinite_enumerated_sets import InfiniteEnumeratedSets from sage.categories.monoids import Monoids @@ -13,7 +12,6 @@ from sage.groups.perm_gps.permgroup_named import SymmetricGroup from sage.libs.gap.libgap import libgap from sage.misc.cachefunc import cached_method -from sage.misc.misc_c import prod from sage.monoids.indexed_free_monoid import (IndexedFreeAbelianMonoid, IndexedFreeAbelianMonoidElement, IndexedMonoid) @@ -828,6 +826,14 @@ def gen(self, x): sage: type(m) + sage: P = PolynomialSpecies(ZZ, ["X"]) + sage: M = P._indices + sage: A = AtomicSpecies("X") + sage: a = A(CyclicPermutationGroup(4)) + sage: M.gen(a) + C_4 + + sage: P = PolynomialSpecies(ZZ, ["X", "Y"]) sage: M = P._indices sage: m = M(SymmetricGroup(6).young_subgroup([2, 2, 2]), {1: [1,2], 2: [3,4,5,6]}) sage: list(m) @@ -1155,8 +1161,14 @@ def _compose_with_singletons(self, base_ring, names, args): def __call__(self, *args): r""" - Substitute M_1...M_k into self. - M_i must all have same arity and must be molecular. + Substitute `M_1,\dots, M_k` into ``self``. + + The arguments must all have the same parent and must all + be molecular. The number of arguments must be equal to + the arity of ``self``. + + The result is a molecular species, whose parent is the + same as those of the arguments. EXAMPLES:: @@ -1187,13 +1199,21 @@ def __call__(self, *args): sage: Y = M2(SymmetricGroup(1), {2: [1]}) sage: C3(X*Y) {((1,2,3)(4,5,6),): ({1, 2, 3}, {4, 5, 6})} + + TESTS:: + + sage: P = PolynomialSpecies(QQ, ["X"]) + sage: P.one()() + Traceback (most recent call last): + ... + ValueError: number of args must match arity of self """ if len(args) != self.parent()._arity: raise ValueError("number of args must match arity of self") + if len(set(arg.parent() for arg in args)) > 1: + raise ValueError("all args must have the same parent") if not all(isinstance(arg, MolecularSpecies.Element) for arg in args): raise ValueError("all args must be molecular species") - if len(set(arg.parent()._arity for arg in args)) > 1: - raise ValueError("all args must have same arity") gens = [] @@ -1461,7 +1481,6 @@ def exponential(self, multiplicities, degrees): sage: P = PolynomialSpecies(QQ, ["X"]) sage: P.exponential([1], [0]).parent() Polynomial species in X over Rational Field - """ def stretch(c, k): r""" @@ -1484,8 +1503,8 @@ def factor(s, c, d): * self.powersum(s, k) for k in mu) for mu in Partitions(d)) - return prod(factor(s+1, multiplicities[s], degrees[s]) - for s in range(self._arity)) + return self.prod(factor(s+1, multiplicities[s], degrees[s]) + for s in range(self._arity)) class Element(CombinatorialFreeModule.Element): def is_constant(self): @@ -1502,8 +1521,32 @@ def is_constant(self): True sage: P(0).is_constant() True + sage: (1 + X).is_constant() + False + """ + return self.is_zero() or not self.maximal_degree() + + def homogeneous_degree(self): + """ + + ..TODO:: + + This implementation should not be necessary. + + EXAMPLES:: + + sage: P = PolynomialSpecies(ZZ, ["X"]) + sage: C3 = P(CyclicPermutationGroup(3)) + sage: X = P(SymmetricGroup(1)) + sage: E2 = P(SymmetricGroup(2)) + sage: (E2*X + C3).homogeneous_degree() + 3 """ - return self.is_zero() or not self.degree() + if not self.support(): + raise ValueError("the zero element does not have a well-defined degree") + if not self.is_homogeneous(): + raise ValueError("element is not homogeneous") + return self.parent().degree_on_basis(self.support()[0]) def is_virtual(self): r""" @@ -1716,15 +1759,20 @@ def __call__(self, *args): """ P = self.parent() - if not self.support(): - return P.zero() + if len(args) != P._arity: + raise ValueError("number of args must match arity of self") + if len(set(arg.parent() for arg in args)) > 1: + raise ValueError("all args must have the same parent") + P0 = args[0].parent() - assert all(P0 == arg.parent() for arg in args), "all parents must be the same" - args = [sorted(g, key=lambda x: x[0]._mc) - for g in args] + if not self.support(): + return P0.zero() + + args = [sorted(g, key=lambda x: x[0]._mc) for g in args] multiplicities = list(chain.from_iterable([[c for _, c in g] for g in args])) molecules = list(chain.from_iterable([[M for M, _ in g] for g in args])) F_degrees = sorted(set(M._mc for M, _ in self)) + names = ["X%s" % i for i in range(sum(len(arg) for arg in args))] result = P0.zero() for n in F_degrees: @@ -1732,7 +1780,6 @@ def __call__(self, *args): for degrees in cartesian_product([IntegerVectors(n_i, length=len(arg)) for n_i, arg in zip(n, args)]): # each degree is a weak composition of the degree of F in sort i - names = ["X%s" % i for i in range(sum(len(arg) for arg in args))] FX = F._compose_with_weighted_singletons(names, multiplicities, degrees) From dada7503b15494c39fd629fa155c6a10d4bccb0a Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Wed, 11 Sep 2024 22:04:01 +0200 Subject: [PATCH 188/537] make MolecularSpecies accept names as argument, provide graded_components --- src/sage/rings/species.py | 127 +++++++++++++++++++++++++++++++------- 1 file changed, 106 insertions(+), 21 deletions(-) diff --git a/src/sage/rings/species.py b/src/sage/rings/species.py index 9143e4432b3..6b228fb084a 100644 --- a/src/sage/rings/species.py +++ b/src/sage/rings/species.py @@ -482,7 +482,7 @@ def __init__(self, names): INPUT: - - ``names`` -- an iterable of ``k`` strings + - ``names`` -- an iterable of ``k`` strings for the sorts of the species TESTS:: @@ -495,9 +495,20 @@ def __init__(self, names): Parent.__init__(self, names=names, category=category) ElementCache.__init__(self) self._arity = len(names) - self._grading_set = IntegerVectors(length=self._arity) self._renamed = set() # the degrees that have been renamed already + def grading_set(self): + r""" + Return the set of non-negative integer vectors, whose length is + the arity of ``self``. + + EXAMPLES:: + + sage: AtomicSpecies(["X"]).grading_set() + Integer vectors of length 1 + """ + return IntegerVectors(length=self._arity) + @cached_method def an_element(self): """ @@ -675,29 +686,89 @@ def _repr_(self): class MolecularSpecies(IndexedFreeAbelianMonoid, ElementCache): + """ + The set of (multivariate) molecular species. + """ @staticmethod - def __classcall__(cls, indices, prefix=None, **kwds): - return super(IndexedMonoid, cls).__classcall__(cls, indices, prefix, **kwds) - - def __init__(self, indices, prefix=None, **kwds): + def __classcall__(cls, *args, **kwds): + """ + Normalize the arguments. + """ + if isinstance(args[0], AtomicSpecies): + indices = args[0] + else: + assert "names" not in kwds or kwds["names"] is None + indices = AtomicSpecies(args[0]) + category = Monoids().Commutative() & SetsWithGrading().Infinite() + return super().__classcall__(cls, indices, + prefix='', bracket=False, + category=category) + + def __init__(self, *args, **kwds): r""" - Infinite set of multivariate molecular species. + Initialize the class of (multivariate) molecular species. INPUT: - - ``indices`` -- the underlying set of atomic species indexing the monoid + - ``names`` -- an iterable of ``k`` strings for the sorts of + the species + + EXAMPLES:: + + sage: from sage.rings.species import MolecularSpecies + sage: M = MolecularSpecies("X,Y") + sage: G = PermutationGroup([[(1,2),(3,4)], [(5,6)]]) + sage: M(G, {1: [5,6], 2: [1,2,3,4]}) + {((1,2)(3,4),): ({}, {1, 2, 3, 4})}*E_2(X) TESTS:: - sage: P1 = PolynomialSpecies(ZZ, "X") - sage: P2 = PolynomialSpecies(ZZ, ["X", "Y"]) - sage: TestSuite(P1._indices).run(skip="_test_graded_components") - sage: TestSuite(P2._indices).run(skip="_test_graded_components") + sage: M1 = MolecularSpecies("X") + sage: TestSuite(M1).run(skip="_test_graded_components") + sage: M2 = MolecularSpecies(["X", "Y"]) + sage: TestSuite(M2).run(skip="_test_graded_components") """ - category = Monoids() & SetsWithGrading().Infinite() - IndexedFreeAbelianMonoid.__init__(self, indices, prefix=prefix, category=category, **kwds) + IndexedFreeAbelianMonoid.__init__(self, *args, **kwds) ElementCache.__init__(self) - self._arity = indices._arity + self._arity = args[0]._arity + + def grading_set(self): + r""" + Return the set of non-negative integer vectors, whose length is + the arity of ``self``. + + EXAMPLES:: + + sage: from sage.rings.species import MolecularSpecies + sage: MolecularSpecies(["X", "Y"]).grading_set() + Integer vectors of length 2 + """ + return IntegerVectors(length=self._arity) + + def graded_component(self, grade): + """ + Return the set of molecular species with given multicardinality. + + The default implementation just calls the method :meth:`subset()` + with the first argument ``grade``. + + EXAMPLES:: + + sage: from sage.rings.species import MolecularSpecies + sage: M = MolecularSpecies(["X", "Y"]) + sage: M.graded_component([3,2]) # random + {E_3(X)*Y^2, X^3*Y^2, X*E_2(X)*E_2(Y), X^3*E_2(Y), + {((1,2,3), (1,3)(4,5)): ({1, 2, 3}, {4, 5})}, + X*{((1,2)(3,4),): ({1, 2}, {3, 4})}, X*E_2(X)*Y^2, E_3(X)*E_2(Y), + C_3(X)*Y^2, C_3(X)*E_2(Y)} + """ + from sage.sets.set import Set + assert len(grade) == self._arity + n = sum(grade) + S = SymmetricGroup(n).young_subgroup(grade) + dom = S.domain() + dom_part = {i+1: dom[sum(grade[:i]): sum(grade[:i+1])] for i in range(len(grade))} + return Set([self(G, dom_part) for G in S.conjugacy_classes_subgroups()]) def _project(self, G, pi, part): r""" @@ -786,7 +857,9 @@ def _element_constructor_(self, G, pi=None): if len(H.orbits()) > 1: # Then it is not transitive raise ValueError("Action is not transitive") - stabG = PermutationGroup([g for g in S.gens() if a(g, H.orbits()[0][0]) == H.orbits()[0][0]], domain=S.domain()) + stabG = PermutationGroup([g for g in S.gens() + if a(g, H.orbits()[0][0]) == H.orbits()[0][0]], + domain=S.domain()) return self(stabG, pi) @cached_method @@ -879,6 +952,20 @@ def __init__(self, F, x): self._mc = None self._tc = None + @cached_method + def group(self): + """ + Return the (transitive) permutation group corresponding to ``self``. + + EXAMPLES:: + + sage: from sage.rings.species import MolecularSpecies + sage: M = MolecularSpecies(AtomicSpecies("X,Y"), prefix='', bracket=False) + sage: G = PermutationGroup([[(1,2),(3,4)], [(5,6)]]) + sage: F = M(G, {1: [5,6], 2: [1,2,3,4]}) + """ + pass + def _assign_group_info(self, other): r""" Assign the group info of ``other`` to ``self``. @@ -1069,9 +1156,9 @@ def grade(self): sage: A = M(G, {1: [1,2,3,4], 2: [5,6,7,8,9,10]}); A {((1,2,3,4)(5,6)(7,8)(9,10),): ({5, 6, 7, 8}, {1, 2, 3, 4, 9, 10})} sage: A.grade() - (4, 6) + [4, 6] """ - return self._mc + return self.parent().grading_set()(self._mc) def domain(self): r""" @@ -1274,11 +1361,9 @@ def __init__(self, base_ring, names): sage: TestSuite(P2).run() """ # should we pass a category to basis_keys? - A = AtomicSpecies(names) - basis_keys = MolecularSpecies(A, prefix='', bracket=False) category = GradedAlgebrasWithBasis(base_ring).Commutative() CombinatorialFreeModule.__init__(self, base_ring, - basis_keys=basis_keys, + basis_keys=MolecularSpecies(names), category=category, element_class=self.Element, prefix='', bracket=False) From 772b79b15bacda45feebacb51e8d8c1156a28ad7 Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Thu, 12 Sep 2024 18:00:06 +0200 Subject: [PATCH 189/537] separate computation of group and domain partition of molecular species --- src/sage/rings/species.py | 600 +++++++++++++++++--------------------- 1 file changed, 272 insertions(+), 328 deletions(-) diff --git a/src/sage/rings/species.py b/src/sage/rings/species.py index 6b228fb084a..025816802e0 100644 --- a/src/sage/rings/species.py +++ b/src/sage/rings/species.py @@ -13,13 +13,12 @@ from sage.libs.gap.libgap import libgap from sage.misc.cachefunc import cached_method from sage.monoids.indexed_free_monoid import (IndexedFreeAbelianMonoid, - IndexedFreeAbelianMonoidElement, - IndexedMonoid) + IndexedFreeAbelianMonoidElement) from sage.rings.integer_ring import ZZ -from sage.sets.finite_enumerated_set import FiniteEnumeratedSet from sage.structure.element import Element, parent from sage.structure.parent import Parent from sage.structure.unique_representation import UniqueRepresentation +from sage.modules.free_module_element import vector class ElementCache(): @@ -41,19 +40,18 @@ def _cache_get(self, elm): TESTS:: - sage: P = PolynomialSpecies(ZZ, "X, Y") - sage: M = P._indices + sage: A = AtomicSpecies("X, Y") sage: G = PermutationGroup([[(1,2),(3,4),(5,6),(7,8,9,10)]]); G Permutation Group with generators [(1,2)(3,4)(5,6)(7,8,9,10)] - sage: A = M(G, {1: [1,2,3,4], 2: [5,6,7,8,9,10]}); A + sage: a = A(G, {1: [1,2,3,4], 2: [5,6,7,8,9,10]}); a {((1,2,3,4)(5,6)(7,8)(9,10),): ({5, 6, 7, 8}, {1, 2, 3, 4, 9, 10})} - sage: C = M(G, {1: [1,2,5,6], 2: [3,4,7,8,9,10]}); C + sage: b = A(G, {1: [1,2,5,6], 2: [3,4,7,8,9,10]}); b {((1,2,3,4)(5,6)(7,8)(9,10),): ({5, 6, 7, 8}, {1, 2, 3, 4, 9, 10})} + sage: a is b + True sage: from sage.rings.species import ElementCache sage: E = ElementCache() - sage: E._cache_get(A) - {((1,2,3,4)(5,6)(7,8)(9,10),): ({5, 6, 7, 8}, {1, 2, 3, 4, 9, 10})} - sage: E._cache_get(C) + sage: E._cache_get(a) {((1,2,3,4)(5,6)(7,8)(9,10),): ({5, 6, 7, 8}, {1, 2, 3, 4, 9, 10})} """ # TODO: Make _canonicalize optional. @@ -146,7 +144,7 @@ def _canonicalize(self): sage: from sage.rings.species import ConjugacyClassesOfDirectlyIndecomposableSubgroups sage: C = ConjugacyClassesOfDirectlyIndecomposableSubgroups() sage: G = PermutationGroup([[(1,3),(4,7)], [(2,5),(6,8)], [(1,4),(2,5),(3,7)]]) - sage: C(G) + sage: C(G) # indirect doctest ((5,6)(7,8), (1,2)(3,4), (1,3)(2,4)(5,6)) """ if self._C == SymmetricGroup(0): @@ -332,8 +330,17 @@ def __init__(self, parent, dis, domain_partition): def grade(self): r""" Return the grade of ``self``. + + EXAMPLES:: + + sage: A = AtomicSpecies("X, Y") + sage: G = PermutationGroup([[(1,2),(3,4),(5,6),(7,8,9,10)]]) + sage: a = A(G, {1: [1,2,3,4], 2: [5,6,7,8,9,10]}) + sage: a.grade() + [4, 6] """ - return self._mc + S = self.parent().grading_set() + return S(self._mc) def _element_key(self): r""" @@ -341,12 +348,12 @@ def _element_key(self): TESTS:: - sage: At = AtomicSpecies("X, Y") + sage: A = AtomicSpecies("X, Y") sage: G = PermutationGroup([[(1,2),(3,4),(5,6),(7,8,9,10)]]); G Permutation Group with generators [(1,2)(3,4)(5,6)(7,8,9,10)] - sage: A = At(G, {1: [1,2,3,4], 2: [5,6,7,8,9,10]}); A + sage: a = A(G, {1: [1,2,3,4], 2: [5,6,7,8,9,10]}); a {((1,2,3,4)(5,6)(7,8)(9,10),): ({5, 6, 7, 8}, {1, 2, 3, 4, 9, 10})} - sage: A._element_key() + sage: a._element_key() ((4, 6), ((1,2,3,4)(5,6)(7,8)(9,10),)) """ return self._mc, self._dis @@ -359,15 +366,13 @@ def _canonicalize(self): EXAMPLES:: - sage: At = AtomicSpecies("X, Y") + sage: A = AtomicSpecies("X, Y") sage: G = PermutationGroup([[(1,2),(3,4),(5,6),(7,8,9,10)]]); G Permutation Group with generators [(1,2)(3,4)(5,6)(7,8,9,10)] - sage: A = At(G, {1: [1,2,3,4], 2: [5,6,7,8,9,10]}) - sage: A._dompart - (frozenset({5, 6, 7, 8}), frozenset({1, 2, 3, 4, 9, 10})) - sage: C = At(G, {1: [1,2,5,6], 2: [3,4,7,8,9,10]}) - sage: C._dompart - (frozenset({5, 6, 7, 8}), frozenset({1, 2, 3, 4, 9, 10})) + sage: f = A(G, {1: [1,2,3,4], 2: [5,6,7,8,9,10]}); f + {((1,2,3,4)(5,6)(7,8)(9,10),): ({5, 6, 7, 8}, {1, 2, 3, 4, 9, 10})} + sage: A(G, {1: [1,2,5,6], 2: [3,4,7,8,9,10]}) is f # indirect doctest + True """ # The canonicalization is done in the element constructor. pass @@ -440,12 +445,12 @@ def _repr_(self): TESTS:: - sage: At = AtomicSpecies("X, Y") + sage: A = AtomicSpecies("X, Y") sage: G = PermutationGroup([[(1,2),(3,4),(5,6),(7,8,9,10)]]); G Permutation Group with generators [(1,2)(3,4)(5,6)(7,8,9,10)] - sage: A = At(G, {1: [1,2,3,4], 2: [5,6,7,8,9,10]}); A + sage: a = A(G, {1: [1,2,3,4], 2: [5,6,7,8,9,10]}); a {((1,2,3,4)(5,6)(7,8)(9,10),): ({5, 6, 7, 8}, {1, 2, 3, 4, 9, 10})} - sage: A = At(G, {2: [1,2,3,4,5,6,7,8,9,10]}); A + sage: a = A(G, {2: [1,2,3,4,5,6,7,8,9,10]}); a {((1,2,3,4)(5,6)(7,8)(9,10),): ({}, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10})} """ if self.parent()._arity == 1: @@ -537,6 +542,17 @@ def _element_constructor_(self, G, pi=None): or a permutation group. - ``pi`` - a dict mapping sorts to iterables whose union is the domain. If `k=1`, `pi` can be omitted. + + + EXAMPLES:: + + sage: A = AtomicSpecies("X, Y") + sage: A(DihedralGroup(5), {1: [1,2,3,4,5]}) + P_5(X) + + sage: G = PermutationGroup([[(1,2),(3,4,5,6)]]) + sage: a = A(G, {1: [1,2], 2: [3,4,5,6]}); a + {((1,2,3,4)(5,6),): ({5, 6}, {1, 2, 3, 4})} """ if parent(G) == self: if pi is not None: @@ -574,22 +590,22 @@ def _rename(self, n): EXAMPLES:: - sage: P = PolynomialSpecies(ZZ, ["X", "Y"]) - sage: P(SymmetricGroup(4), {1: range(1, 5)}) + sage: A = AtomicSpecies(["X", "Y"]) + sage: A(SymmetricGroup(4), {1: range(1, 5)}) # indirect doctest E_4(X) - sage: P(SymmetricGroup(4), {2: range(1, 5)}) + sage: A(SymmetricGroup(4), {2: range(1, 5)}) E_4(Y) - sage: P(CyclicPermutationGroup(4), {1: range(1, 5)}) + sage: A(CyclicPermutationGroup(4), {1: range(1, 5)}) C_4(X) - sage: P(CyclicPermutationGroup(4), {2: range(1, 5)}) + sage: A(CyclicPermutationGroup(4), {2: range(1, 5)}) C_4(Y) - sage: P(DihedralGroup(4), {1: range(1, 5)}) + sage: A(DihedralGroup(4), {1: range(1, 5)}) P_4(X) - sage: P(DihedralGroup(4), {2: range(1, 5)}) + sage: A(DihedralGroup(4), {2: range(1, 5)}) P_4(Y) - sage: P(AlternatingGroup(4), {1: range(1, 5)}) + sage: A(AlternatingGroup(4), {1: range(1, 5)}) Eo_4(X) - sage: P(AlternatingGroup(4), {2: range(1, 5)}) + sage: A(AlternatingGroup(4), {2: range(1, 5)}) Eo_4(Y) """ from sage.groups.perm_gps.permgroup import PermutationGroup @@ -685,7 +701,7 @@ def _repr_(self): Element = AtomicSpeciesElement -class MolecularSpecies(IndexedFreeAbelianMonoid, ElementCache): +class MolecularSpecies(IndexedFreeAbelianMonoid): """ The set of (multivariate) molecular species. """ @@ -693,6 +709,15 @@ class MolecularSpecies(IndexedFreeAbelianMonoid, ElementCache): def __classcall__(cls, *args, **kwds): """ Normalize the arguments. + + EXAMPLES:: + + sage: from sage.rings.species import MolecularSpecies + sage: MolecularSpecies("X,Y") is MolecularSpecies(["X", "Y"]) + True + + sage: MolecularSpecies("X,Y") == MolecularSpecies(["X", "Z"]) + False """ if isinstance(args[0], AtomicSpecies): indices = args[0] @@ -729,7 +754,6 @@ def __init__(self, *args, **kwds): sage: TestSuite(M2).run(skip="_test_graded_components") """ IndexedFreeAbelianMonoid.__init__(self, *args, **kwds) - ElementCache.__init__(self) self._arity = args[0]._arity def grading_set(self): @@ -816,30 +840,49 @@ def _element_constructor_(self, G, pi=None): If `G = (X, a)`, then `X` should be a finite set and `a` a transitive action of `G` on `X`. + EXAMPLES: + + Create a molecular species given a permutation group:: + + sage: from sage.rings.species import MolecularSpecies + sage: M = MolecularSpecies(["X", "Y"]) + sage: G = PermutationGroup([[(1,2)], [(3,4)]]) + sage: M(G, {1: [1,2], 2: [3,4]}) + E_2(X)*E_2(Y) + TESTS:: - sage: P = PolynomialSpecies(ZZ, ["X", "Y"]) - sage: M = P._indices sage: M(CyclicPermutationGroup(4), {1: [1,2], 2: [3,4]}) Traceback (most recent call last): ... ValueError: All elements of orbit (1, 2, 3, 4) must have the same sort + + sage: G = PermutationGroup([[(2,3),(4,5)]], domain=[2,3,4,5]) + sage: M(G, {1:[2, 3], 2:[4,5]}) + {((1,2)(3,4),): ({1, 2}, {3, 4})} """ if parent(G) == self: if pi is not None: raise ValueError("cannot reassign sorts to a molecular species") return G + if isinstance(G, PermutationGroup_generic): if pi is None: if self._arity == 1: pi = {1: G.domain()} else: raise ValueError("the assignment of sorts to the domain elements must be provided") + domain = [e for p in pi.values() for e in p] + if len(domain) != len(set(domain)): + raise ValueError("each domain element must have exactly one sort") + if set(G.domain()) != set(domain): + raise ValueError("each element of the domain of the group must have one sort") domain_partition = G.disjoint_direct_product_decomposition() elm = self.one() for part in domain_partition: elm *= self.gen(self._project(G, pi, part)) return elm + # Assume G is a tuple (X, a) X, a = G if pi is None: @@ -862,30 +905,15 @@ def _element_constructor_(self, G, pi=None): domain=S.domain()) return self(stabG, pi) - @cached_method - def one(self): - r""" - Return the one of this monoid. - - EXAMPLES:: - - sage: P = PolynomialSpecies(ZZ, "X, Y") - sage: P._indices.one() - 1 - """ - elm = super().one() - elm._group = SymmetricGroup(0) - elm._dompart = tuple() - elm._mc = tuple(0 for _ in range(self._arity)) - elm._tc = 0 - return elm - def gen(self, x): r""" - Create the molecular species from an atomic species. + The molecular species given by an atomic species. EXAMPLES:: + sage: from sage.rings.species import MolecularSpecies + sage: M = MolecularSpecies("X, Y") + sage: P = PolynomialSpecies(ZZ, "X, Y") sage: At = AtomicSpecies("X, Y") sage: G = PermutationGroup([[(1,2),(3,4)]]); G @@ -918,13 +946,7 @@ def gen(self, x): at = self._indices(x) else: at = self._indices(x[0], x[1]) - elm = self._cache_get(self.element_class(self, {at: ZZ.one()})) - if elm._group is None: - elm._group = at._dis._C - elm._dompart = at._dompart - elm._mc = at._mc - elm._tc = at._tc - return elm + return self.element_class(self, {at: ZZ.one()}) def _repr_(self): r""" @@ -932,254 +954,159 @@ def _repr_(self): TESTS:: - sage: PolynomialSpecies(ZZ, "X")._indices + sage: from sage.rings.species import MolecularSpecies + sage: MolecularSpecies("X") Molecular species in X - sage: PolynomialSpecies(ZZ, "X, Y")._indices - Molecular species in X, Y + sage: MolecularSpecies("A, B") + Molecular species in A, B """ if len(self._indices._names) == 1: return f"Molecular species in {self._indices._names[0]}" return f"Molecular species in {', '.join(self._indices._names)}" class Element(IndexedFreeAbelianMonoidElement): - def __init__(self, F, x): + def __init__(self, parent, x): r""" - Initialize a molecular species with no group information. + Initialize a molecular species. + + INPUT: + + - ``x``, a dictionary mapping atomic species to exponents + + EXAMPLES:: + + sage: from sage.rings.species import MolecularSpecies + sage: M = MolecularSpecies("X") + sage: M(CyclicPermutationGroup(3)) # indirect doctest + C_3 """ - super().__init__(F, x) - self._group = None - self._dompart = None - self._mc = None - self._tc = None + super().__init__(parent, x) @cached_method - def group(self): + def group_and_partition(self): """ Return the (transitive) permutation group corresponding to ``self``. EXAMPLES:: sage: from sage.rings.species import MolecularSpecies - sage: M = MolecularSpecies(AtomicSpecies("X,Y"), prefix='', bracket=False) + sage: M = MolecularSpecies("X,Y") sage: G = PermutationGroup([[(1,2),(3,4)], [(5,6)]]) - sage: F = M(G, {1: [5,6], 2: [1,2,3,4]}) - """ - pass - - def _assign_group_info(self, other): - r""" - Assign the group info of ``other`` to ``self``. - """ - self._group = other._group - self._dompart = other._dompart - self._mc = other._mc - self._tc = other._tc - - def _group_constructor(self): - r""" - Construct the group of ``self``. - """ - temp = self.parent().one() - for A, p in self._monomial.items(): - at = self.parent().gen(A) - at_p = at ** p - temp = temp * at_p - self._assign_group_info(temp) - - def _elmmul(self, elm1, elm2): - r""" - Populate the group info of ``self`` by multiplying - the groups of ``elm1`` and ``elm2``. - """ - if elm1._group is None: - elm1._group_constructor() - if elm2._group is None: - elm2._group_constructor() - if elm1._tc == 0: - self._assign_group_info(elm2) - return - if elm2._tc == 0: - self._assign_group_info(elm1) - return - self._mc = tuple(elm1._mc[i] + elm2._mc[i] for i in range(self.parent()._arity)) - self._tc = elm1._tc + elm2._tc - gens1 = elm1._group.gens() - # Try to avoid gens_small unless necessary - if len(gens1) > 50: - gens1 = elm1._group.gens_small() - gens2 = elm2._group.gens() - if len(gens2) > 50: - gens2 = elm2._group.gens_small() - # always loop over the smaller gens list - if len(gens1) < len(gens2): - gens1, gens2 = gens2, gens1 - elm1, elm2 = elm2, elm1 - gens = list(gens1) - for gen in gens2: - gens.append([tuple(elm1._tc + k for k in cyc) for cyc in gen.cycle_tuples()]) - self._group = PermutationGroup(gens, domain=range(1, elm1._tc + elm2._tc + 1)) - self._dompart = list(elm1._dompart) - for i in range(elm2.parent()._arity): - self._dompart[i] = frozenset(list(self._dompart[i]) + [elm1._tc + e for e in elm2._dompart[i]]) - self._dompart = tuple(self._dompart) - - def __floordiv__(self, elt): - raise NotImplementedError("Cannot cancel in this monoid") - - def _mul_(self, other): - r""" - Multiply ``self`` by ``other``. + sage: A = M(G, {1: [5,6], 2: [1,2,3,4]}) + sage: A.group_and_partition() + (Permutation Group with generators [(5,6), (1,2)(3,4)], + (frozenset({5, 6}), frozenset({1, 2, 3, 4}))) TESTS:: - sage: P = PolynomialSpecies(ZZ, "X, Y") - sage: M = P._indices - sage: E2X = M(SymmetricGroup(2), {1: [1,2]}); E2X - E_2(X) - sage: (E2X._group, E2X._dompart, E2X._mc, E2X._tc) - (Permutation Group with generators [(1,2)], - (frozenset({1, 2}), frozenset()), - (2, 0), - 2) - sage: E2Y = M(SymmetricGroup(2), {2: [1,2]}); E2Y - E_2(Y) - sage: (E2Y._group, E2Y._dompart, E2Y._mc, E2Y._tc) - (Permutation Group with generators [(1,2)], - (frozenset(), frozenset({1, 2})), - (0, 2), - 2) - sage: E2XE2Y = E2X * E2Y; E2XE2Y - E_2(X)*E_2(Y) - sage: (E2XE2Y._group, E2XE2Y._dompart, E2XE2Y._mc, E2XE2Y._tc) - (Permutation Group with generators [(3,4), (1,2)], - (frozenset({1, 2}), frozenset({3, 4})), - (2, 2), - 4) - """ - res = super()._mul_(other) - elm = self.parent()._cache_get(res) - if elm._group is None: - elm._elmmul(self, other) - elm._canonicalize() - return elm + sage: B = M(PermutationGroup([(1,2,3)]), {1: [1,2,3]}) + sage: B.group_and_partition() + (Permutation Group with generators [(1,2,3)], + (frozenset({1, 2, 3}), frozenset())) - def _elmexp(self, other, n): - r""" - Populate the group info of ``self`` by exponentiating - the group of ``other``. - """ - if other._group is None: - other._group_constructor() - temp = self.parent().one() - while n > 0: - if n % 2 == 1: - temp = temp * other - other = other * other - n //= 2 - self._assign_group_info(temp) + sage: (A*B).group_and_partition() + (Permutation Group with generators [(7,8,9), (5,6), (1,2)(3,4)], + (frozenset({5, 6, 7, 8, 9}), frozenset({1, 2, 3, 4}))) - def __pow__(self, n): - r""" - Raise ``self`` to the power of ``n``. + sage: C = M(PermutationGroup([(2,3)]), {1: [1], 2: [2,3]}) + sage: C.group_and_partition() + (Permutation Group with generators [(2,3)], + (frozenset({1}), frozenset({2, 3}))) - TESTS:: + sage: (C^3).group_and_partition() + (Permutation Group with generators [(8,9), (6,7), (4,5)], + (frozenset({1, 2, 3}), frozenset({4, 5, 6, 7, 8, 9}))) - sage: P = PolynomialSpecies(ZZ, "X") - sage: M = P._indices - sage: E2 = M(SymmetricGroup(2), {1: [1,2]}) - sage: (E2._group, E2._dompart, E2._mc, E2._tc) - (Permutation Group with generators [(1,2)], (frozenset({1, 2}),), (2,), 2) - sage: E2_3 = E2 ^ 3 - sage: (E2_3._group, E2_3._dompart, E2_3._mc, E2_3._tc) - (Permutation Group with generators [(5,6), (3,4), (1,2)], - (frozenset({1, 2, 3, 4, 5, 6}),), - (6,), - 6) + sage: M = MolecularSpecies("X") + sage: F = M(SymmetricGroup(1)) * M(SymmetricGroup(2)) + sage: F.group_and_partition() + (Permutation Group with generators [(2,3)], (frozenset({1, 2, 3}),)) """ - res = super().__pow__(n) - elm = self.parent()._cache_get(res) - if elm._group is None: - elm._elmexp(self, n) - elm._canonicalize() - return elm - - def _element_key(self): - r""" - Return the cache lookup key for ``self``. + def shift_gens(gens, n): + """ + Given a list of generators ``gens``, increase every element of the + domain by ``n``. + """ + return tuple([tuple([tuple([n + e for e in cyc]) + for cyc in gen.cycle_tuples()]) + for gen in gens]) + + factors = list(self) + if not factors: + k = self.parent()._arity + return SymmetricGroup(0), tuple([frozenset()]*k) + + if len(factors) == 1: + A, n = factors[0] + if n == 1: + a = list(A._monomial)[0] # as atomic species + return a._dis._C, a._dompart - TESTS:: - - sage: P = PolynomialSpecies(ZZ, "X") - sage: M = P._indices - sage: E2 = M(SymmetricGroup(2), {1: [1,2]}) - sage: E2._element_key() - E_2 - """ - return self + if n % 2 == 1: + a = list(A._monomial)[0] # as atomic species + b, b_dompart = (A ** (n-1)).group_and_partition() + gens = a._dis._C.gens() + shift_gens(b.gens(), a._tc) + new_dompart = tuple([frozenset(list(p_a) + [a._tc + e for e in p_b]) + for p_a, p_b in zip(a._dompart, b_dompart)]) + else: + f, f_dompart = (A ** (n // 2)).group_and_partition() + tc = sum(len(p) for p in f_dompart) + gens = f.gens() + shift_gens(f.gens(), tc) + new_dompart = tuple([frozenset(list(p) + [tc + e for e in p]) + for p in f_dompart]) + + G = PermutationGroup(gens) + return G, new_dompart + + f_dompart_list = [(A ** n).group_and_partition() for A, n in factors] + f_list = [f for f, _ in f_dompart_list] + dompart_list = [f_dompart for _, f_dompart in f_dompart_list] + tc_list = list(accumulate([sum(len(p) for p in f_dompart) + for f_dompart in dompart_list], + initial=0)) + gens = [gen + for f, tc in zip(f_list, tc_list) + for gen in shift_gens(f.gens(), tc) if gen] # gen is a tuple + G = PermutationGroup(gens) + new_dompart = tuple([frozenset(chain(*[[tc + e for e in p] + for p, tc in zip(f_dompart, tc_list)])) + for f_dompart in zip(*dompart_list)]) + + return G, new_dompart @cached_method - def _canonicalize(self): - r""" - Canonicalize this molecular species by sorting the orbits by - length and making them consecutive. - - EXAMPLES:: - - sage: P = PolynomialSpecies(ZZ, "X, Y") - sage: M = P._indices - sage: G = PermutationGroup([[(1,2),(3,4),(5,6),(7,8,9,10)]]); G - Permutation Group with generators [(1,2)(3,4)(5,6)(7,8,9,10)] - sage: A = M(G, {1: [1,2,3,4], 2: [5,6,7,8,9,10]}) - sage: A._dompart - (frozenset({5, 6, 7, 8}), frozenset({1, 2, 3, 4, 9, 10})) - sage: C = M(G, {1: [1,2,5,6], 2: [3,4,7,8,9,10]}) - sage: C._dompart - (frozenset({5, 6, 7, 8}), frozenset({1, 2, 3, 4, 9, 10})) - """ - if self._group is None or self._group == SymmetricGroup(0): - return - sorted_orbits = sorted([sorted(orbit) for orbit in self._group.orbits()], key=len, reverse=True) - pi = PermutationGroupElement(list(chain.from_iterable(sorted_orbits))).inverse() - self._group = self._group.conjugate(pi) - self._dompart = tuple(frozenset(pi(k) for k in v) for v in self._dompart) - def grade(self): r""" Return the grade of ``self``. EXAMPLES:: - sage: P = PolynomialSpecies(ZZ, "X, Y") - sage: M = P._indices + sage: from sage.rings.species import MolecularSpecies + sage: M = MolecularSpecies("X, Y") sage: G = PermutationGroup([[(1,2),(3,4),(5,6),(7,8,9,10)]]); G Permutation Group with generators [(1,2)(3,4)(5,6)(7,8,9,10)] - sage: A = M(G, {1: [1,2,3,4], 2: [5,6,7,8,9,10]}); A + sage: a = M(G, {1: [1,2,3,4], 2: [5,6,7,8,9,10]}); a {((1,2,3,4)(5,6)(7,8)(9,10),): ({5, 6, 7, 8}, {1, 2, 3, 4, 9, 10})} - sage: A.grade() + sage: a.grade() [4, 6] - """ - return self.parent().grading_set()(self._mc) - def domain(self): - r""" - Return the domain of ``self``. - - EXAMPLES:: + TESTS:: - sage: P = PolynomialSpecies(ZZ, "X, Y") - sage: M = P._indices - sage: G = PermutationGroup([[(1,2),(3,4),(5,6),(7,8,9,10)]]); G - Permutation Group with generators [(1,2)(3,4)(5,6)(7,8,9,10)] - sage: A = M(G, {1: [1,2,3,4], 2: [5,6,7,8,9,10]}); A - {((1,2,3,4)(5,6)(7,8)(9,10),): ({5, 6, 7, 8}, {1, 2, 3, 4, 9, 10})} - sage: A.domain() - {1, 2, 3, 4, 5, 6, 7, 8, 9, 10} + sage: M.one().grade() + [0, 0] """ - return FiniteEnumeratedSet(range(1, self._tc + 1)) + P = self.parent() + S = P.grading_set() + mons = self._monomial + if not mons: + return S([0] * P._arity) + mc = sum(n * vector(a._mc) for a, n in mons.items()) + return S(mc) def _compose_with_singletons(self, base_ring, names, args): r""" - Compute the inner sum of exercise 2.6.16 of BLL book. + Return the inner sum of Exercise 2.6.16 in [BLL1998]_, + generalized to the case of arbitrary arity. INPUT: @@ -1187,21 +1114,25 @@ def _compose_with_singletons(self, base_ring, names, args): - ``names``, the (flat) list of names of the result - - ``args``, the sequence of compositions, each of + - ``args``, the sequence of `k` compositions, each of which sums to the corresponding cardinality of - ``self``. The number of ``args`` is equal to the - arity of ``self``. + ``self``, where `k` is the arity of ``self``. + + OUTPUT: + + - the polynomial species + `self(X_1 + \dots + X_{m_1}, Y_1 + \dots + Y_{m_2}, \dots)`, + where `m_i` is the number of parts of the `i`-th composition. EXAMPLES:: - sage: P = PolynomialSpecies(ZZ, "X") - sage: M = P._indices + sage: from sage.rings.species import MolecularSpecies + sage: M = MolecularSpecies("X") sage: C4 = M(CyclicPermutationGroup(4)) sage: C4._compose_with_singletons(ZZ, "X, Y", [[2, 2]]) # X^2Y^2 + C2(XY) E_2(XY) + X^2*Y^2 - sage: P = PolynomialSpecies(ZZ, ["X", "Y"]) - sage: M = P._indices + sage: M = MolecularSpecies(["X", "Y"]) sage: F = M(PermutationGroup([[(1,2,3), (4,5,6)]]), {1: [1,2,3], 2: [4,5,6]}) sage: F {((1,2,3)(4,5,6),): ({1, 2, 3}, {4, 5, 6})} @@ -1210,39 +1141,40 @@ def _compose_with_singletons(self, base_ring, names, args): TESTS:: - sage: P = PolynomialSpecies(ZZ, "X") - sage: M = P._indices - sage: M.one()._compose_with_singletons(ZZ, "X", [[1]]) + sage: M = MolecularSpecies("X") + sage: O = M.one() + sage: O._compose_with_singletons(ZZ, "X", [[]]) 1 - sage: P = PolynomialSpecies(ZZ, "X") - sage: M = P._indices sage: F = M(SymmetricGroup(1)) * M(SymmetricGroup(2)) - sage: F._compose_with_singletons(QQ,["T","S"],[[2,1]]) - E_2(T)*S + T^2*S - sage: F._compose_with_singletons(QQ,["T","S"],[[1,2]]) - T*S^2 + T*E_2(S) + sage: F._compose_with_singletons(QQ, ["T", "S"], [[2, 1]]) + T^2*S + E_2(T)*S + sage: F._compose_with_singletons(QQ, ["T", "S"], [[1, 2]]) + T*E_2(S) + T*S^2 """ # TODO: No checks are performed right now, must be added. # Checks: all args in Compositions, sums must match cardinalities. # Create group of the composition - Pn = PolynomialSpecies(base_ring, names) - res = Pn.zero() - # conjugate self._group so that [1..k] is sort 1, [k+1,..] is sort 2, so on - conj = PermutationGroupElement(list(chain.from_iterable(self._dompart))).inverse() - G = libgap.ConjugateGroup(self._group, conj) + # conjugate self.group() so that [1..k] is sort 1, [k+1,..] is sort 2, so on + G, dompart = self.group_and_partition() + conj = PermutationGroupElement(list(chain.from_iterable(dompart))).inverse() + G = libgap.ConjugateGroup(G, conj) comp = list(chain.from_iterable(args)) dpart = {i + 1: range(x - comp[i] + 1, x + 1) for i, x in enumerate(accumulate(comp))} # Create the double coset representatives. S_down = SymmetricGroup(sum(comp)).young_subgroup(comp) - S_up = SymmetricGroup(self._tc).young_subgroup(self._mc) + mc = self.grade() + tc = sum(mc) + S_up = SymmetricGroup(tc).young_subgroup(mc) taus = libgap.DoubleCosetRepsAndSizes(S_up, S_down, G) - # Sum over double coset representatives. + # sum over double coset representatives. + Pn = PolynomialSpecies(base_ring, names) + res = Pn.zero() for tau, _ in taus: H = libgap.Intersection(libgap.ConjugateGroup(G, tau ** -1), S_down) - grp = PermutationGroup(gap_group=H, domain=self.domain()) + grp = PermutationGroup(gap_group=H, domain=range(1, tc + 1)) res += Pn(grp, dpart) return res @@ -1259,8 +1191,8 @@ def __call__(self, *args): EXAMPLES:: - sage: P = PolynomialSpecies(ZZ, ["X"]) - sage: M = P._indices + sage: from sage.rings.species import MolecularSpecies + sage: M = MolecularSpecies("X") sage: X = M(SymmetricGroup(1)) sage: E2 = M(SymmetricGroup(2)) sage: E2(X) @@ -1270,8 +1202,7 @@ def __call__(self, *args): sage: E2(E2) P_4 - sage: P = PolynomialSpecies(ZZ, ["X","Y"]) - sage: M = P._indices + sage: M = MolecularSpecies(["X","Y"]) sage: X = M(SymmetricGroup(1), {1:[1]}) sage: Y = M(SymmetricGroup(1), {2:[1]}) sage: (X*Y)(X, Y^2) @@ -1279,8 +1210,8 @@ def __call__(self, *args): A multivariate example:: - sage: M1 = PolynomialSpecies(QQ, "X")._indices - sage: M2 = PolynomialSpecies(QQ, "X, Y")._indices + sage: M1 = MolecularSpecies("X") + sage: M2 = MolecularSpecies("X, Y") sage: C3 = M1(CyclicPermutationGroup(3)) sage: X = M2(SymmetricGroup(1), {1: [1]}) sage: Y = M2(SymmetricGroup(1), {2: [1]}) @@ -1289,8 +1220,8 @@ def __call__(self, *args): TESTS:: - sage: P = PolynomialSpecies(QQ, ["X"]) - sage: P.one()() + sage: M = MolecularSpecies("X") + sage: M.one()() Traceback (most recent call last): ... ValueError: number of args must match arity of self @@ -1302,32 +1233,37 @@ def __call__(self, *args): if not all(isinstance(arg, MolecularSpecies.Element) for arg in args): raise ValueError("all args must be molecular species") - gens = [] - # TODO: What happens if in F(G), G has a constant part? E(1+X)? - Mlist = [None for _ in range(self._tc)] - for i, v in enumerate(self._dompart): + Mlist = [None for _ in range(sum(self.grade()))] + G, dompart = self.group_and_partition() + for i, v in enumerate(dompart): for k in v: Mlist[k - 1] = args[i] - starts = list(accumulate([M._tc for M in Mlist], initial=0)) + starts = list(accumulate([sum(M.grade()) for M in Mlist], + initial=0)) # gens from self - for gen in self._group.gens(): + gens = [] + for gen in G.gens(): newgen = [] for cyc in gen.cycle_tuples(): - for k in range(1, Mlist[cyc[0] - 1]._tc + 1): + for k in range(1, sum(Mlist[cyc[0] - 1].grade()) + 1): newgen.append(tuple(k + starts[i - 1] for i in cyc)) gens.append(newgen) # gens from M_i and dompart - dpart = {i: [] for i in range(1, args[0].parent()._arity + 1)} + P = args[0].parent() + dpart = {i: [] for i in range(1, P._arity + 1)} for start, M in zip(starts, Mlist): - for i, v in enumerate(M._dompart, 1): + K, dompart = M.group_and_partition() + for i, v in enumerate(dompart, 1): dpart[i].extend([start + k for k in v]) - for gen in M._group.gens(): - gens.append([tuple(start + k for k in cyc) for cyc in gen.cycle_tuples()]) + for gen in K.gens(): + gens.append([tuple(start + k for k in cyc) + for cyc in gen.cycle_tuples()]) - return args[0].parent()(PermutationGroup(gens, domain=range(1, starts[-1] + 1)), dpart) + return P(PermutationGroup(gens, + domain=range(1, starts[-1] + 1)), dpart) class PolynomialSpecies(CombinatorialFreeModule): @@ -1385,7 +1321,7 @@ def degree_on_basis(self, m): sage: P.degree_on_basis(E4Y.support()[0]) 4 """ - return m._tc + return sum(m.grade()) def _element_constructor_(self, G, pi=None): r""" @@ -1483,7 +1419,7 @@ def product_on_basis(self, H, K): sage: P = PolynomialSpecies(ZZ, "X") sage: L1 = [P(H) for H in SymmetricGroup(3).conjugacy_classes_subgroups()] sage: L2 = [P(H) for H in SymmetricGroup(2).conjugacy_classes_subgroups()] - sage: matrix([[F * G for F in L1] for G in L2]) + sage: matrix([[F * G for F in L1] for G in L2]) # indirect doctest [ X^5 X^3*E_2 C_3*X^2 E_3*X^2] [X^3*E_2 X*E_2^2 C_3*E_2 E_3*E_2] @@ -1699,7 +1635,7 @@ def hadamard_product(self, other): EXAMPLES: - Exercise 2.1.9 from the BLL book:: + Exercise 2.1.9 from [BLL1998]_:: sage: P = PolynomialSpecies(ZZ, ["X"]) sage: C3 = P(CyclicPermutationGroup(3)) @@ -1724,22 +1660,30 @@ def hadamard_product(self, other): res = P.zero() # we should first collect matching multicardinalities. for L, c in self: - S = SymmetricGroup(L._tc).young_subgroup(L._mc) + mc = L.grade() + tc = sum(mc) + S = SymmetricGroup(tc).young_subgroup(mc) # conjugate L and R to match S - conj_L = PermutationGroupElement(list(chain.from_iterable(L._dompart))).inverse() - G = libgap.ConjugateGroup(L._group, conj_L) - dpart = {i + 1: range(x - L._mc[i] + 1, x + 1) for i, x in enumerate(accumulate(L._mc))} + G, dompart = L.group_and_partition() + g = list(chain.from_iterable(dompart)) + conj_L = PermutationGroupElement(g).inverse() + G = libgap.ConjugateGroup(G, conj_L) + dpart = {i + 1: range(x - mc[i] + 1, x + 1) + for i, x in enumerate(accumulate(mc))} for R, d in other: - if L._mc != R._mc: + if mc != R.grade(): continue - conj_R = PermutationGroupElement(list(chain.from_iterable(R._dompart))).inverse() - H = libgap.ConjugateGroup(R._group, conj_R) + G_R, dompart_R = R.group_and_partition() + g = list(chain.from_iterable(dompart_R)) + conj_R = PermutationGroupElement(g).inverse() + H = libgap.ConjugateGroup(G_R, conj_R) taus = libgap.DoubleCosetRepsAndSizes(S, G, H) # loop over representatives new = P.zero() for tau, _ in taus: F = libgap.Intersection(libgap.ConjugateGroup(H, tau), G) - new += P(PermutationGroup(gap_group=F, domain=L.domain()), dpart) + new += P(PermutationGroup(gap_group=F, domain=range(1, tc + 1)), + dpart) res += c * d * new return res @@ -1764,7 +1708,7 @@ def _compose_with_weighted_singletons(self, names, multiplicities, degrees): EXAMPLES: - Equation (2.5.41):: + Equation (2.5.41) in [BLL1998]_:: sage: P = PolynomialSpecies(QQ, ["X"]) sage: E2 = P(SymmetricGroup(2)) @@ -1775,7 +1719,7 @@ def _compose_with_weighted_singletons(self, names, multiplicities, degrees): sage: C4._compose_with_weighted_singletons(["X"], [-1], [[4]]) -C_4 + {((1,2)(3,4),)} - Exercise (2.5.17):: + Exercise (2.5.17) in [BLL1998]_:: sage: C4._compose_with_weighted_singletons(["X", "Y"], [1, 1], [[2, 2]]) E_2(XY) + X^2*Y^2 @@ -1830,7 +1774,7 @@ def __call__(self, *args): sage: X = P2(SymmetricGroup(1), {1:[1]}) sage: Y = P2(SymmetricGroup(1), {2:[1]}) sage: E2(X + Y) - E_2(Y) + X*Y + E_2(X) + E_2(Y) + Y*X + E_2(X) sage: E2(X*Y)(E2(X), E2(Y)) {((7,8), (5,6), (3,4), (1,2), (1,3)(2,4)(5,7)(6,8)): ({1, 2, 3, 4}, {5, 6, 7, 8})} @@ -1853,15 +1797,15 @@ def __call__(self, *args): if not self.support(): return P0.zero() - args = [sorted(g, key=lambda x: x[0]._mc) for g in args] + args = [sorted(g, key=lambda x: x[0].grade()) for g in args] multiplicities = list(chain.from_iterable([[c for _, c in g] for g in args])) molecules = list(chain.from_iterable([[M for M, _ in g] for g in args])) - F_degrees = sorted(set(M._mc for M, _ in self)) + F_degrees = sorted(set(M.grade() for M, _ in self)) names = ["X%s" % i for i in range(sum(len(arg) for arg in args))] result = P0.zero() for n in F_degrees: - F = P.sum_of_terms((M, c) for M, c in self if M._mc == n) + F = P.sum_of_terms((M, c) for M, c in self if M.grade() == n) for degrees in cartesian_product([IntegerVectors(n_i, length=len(arg)) for n_i, arg in zip(n, args)]): # each degree is a weak composition of the degree of F in sort i From 7c1f219b7ec4d2a32cfbf466a6b5f1d20b405b93 Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Fri, 13 Sep 2024 09:04:06 +0200 Subject: [PATCH 190/537] remove _project and gen --- src/sage/rings/species.py | 137 ++++++++++++++------------------------ 1 file changed, 49 insertions(+), 88 deletions(-) diff --git a/src/sage/rings/species.py b/src/sage/rings/species.py index 025816802e0..eadf97bec05 100644 --- a/src/sage/rings/species.py +++ b/src/sage/rings/species.py @@ -521,12 +521,17 @@ def an_element(self): TESTS:: - sage: At1 = AtomicSpecies("X") - sage: At2 = AtomicSpecies("X, Y") - sage: At1.an_element() + sage: A = AtomicSpecies("X") + sage: A.an_element() E_2 - sage: At2.an_element() + + sage: A = AtomicSpecies("X, Y") + sage: a = A.an_element(); a {((1,2)(3,4),): ({1, 2}, {3, 4})} + + sage: a.rename("E_2(XY)") + sage: a + E_2(XY) """ G = PermutationGroup([[(2 * i - 1, 2 * i) for i in range(1, self._arity + 1)]]) m = {i: [2 * i - 1, 2 * i] for i in range(1, self._arity + 1)} @@ -791,38 +796,8 @@ def graded_component(self, grade): n = sum(grade) S = SymmetricGroup(n).young_subgroup(grade) dom = S.domain() - dom_part = {i+1: dom[sum(grade[:i]): sum(grade[:i+1])] for i in range(len(grade))} - return Set([self(G, dom_part) for G in S.conjugacy_classes_subgroups()]) - - def _project(self, G, pi, part): - r""" - Project `G` onto a subset ``part`` of its domain. - - ``part`` must be a union of cycles, but this is not checked. - - TESTS:: - - sage: P = PolynomialSpecies(ZZ, ["X", "Y"]) - sage: M = P._indices - sage: G = PermutationGroup([[(1,2),(3,4)], [(5,6)]]); G - Permutation Group with generators [(5,6), (1,2)(3,4)] - sage: parts = G.disjoint_direct_product_decomposition(); parts - {{1, 2, 3, 4}, {5, 6}} - sage: pi = {1: [1,2,3,4], 2: [5,6]} - sage: M._project(G, pi, parts[0]) - (Permutation Group with generators [(1,2)(3,4)], {1: [1, 2, 3, 4]}) - sage: M._project(G, pi, parts[1]) - (Permutation Group with generators [(5,6)], {2: [5, 6]}) - """ - restricted_gens = [[cyc for cyc in gen.cycle_tuples() if cyc[0] in part] - for gen in G.gens()] - restricted_gens = [gen for gen in restricted_gens if gen] - mapping = dict() - for k, v in pi.items(): - es = [e for e in v if e in part] - if es: - mapping[k] = es - return PermutationGroup(gens=restricted_gens, domain=part), mapping + dompart = {i+1: dom[sum(grade[:i]): sum(grade[:i+1])] for i in range(len(grade))} + return Set([self(G, dompart) for G in S.conjugacy_classes_subgroups()]) def _element_constructor_(self, G, pi=None): r""" @@ -832,14 +807,11 @@ def _element_constructor_(self, G, pi=None): - ``G`` - an element of ``self`` (in this case pi must be ``None``) or a permutation group, or a pair ``(X, a)`` consisting of a - finite set and an action. + finite set and a transitive action. - ``pi`` - a dict mapping sorts to iterables whose union is the domain of ``G`` (if ``G`` is a permutation group) or `X` (if ``G``) is a pair ``(X, a)``. If `k=1`, `pi` can be omitted. - If `G = (X, a)`, then `X` should be a finite set and `a` a transitive - action of `G` on `X`. - EXAMPLES: Create a molecular species given a permutation group:: @@ -850,16 +822,36 @@ def _element_constructor_(self, G, pi=None): sage: M(G, {1: [1,2], 2: [3,4]}) E_2(X)*E_2(Y) + Create a molecular species given an action:: + + sage: M = MolecularSpecies("X") + sage: a = lambda g, x: SetPartition([[g(e) for e in b] for b in x]) + sage: X = SetPartitions(4, [2, 2]) + sage: M((X, a), {1: X.base_set()}) + P_4 + + sage: X = SetPartitions(8, [4, 2, 2]) + sage: M((X, a), {1: X.base_set()}) + + TESTS:: + sage: M = MolecularSpecies(["X", "Y"]) sage: M(CyclicPermutationGroup(4), {1: [1,2], 2: [3,4]}) Traceback (most recent call last): ... ValueError: All elements of orbit (1, 2, 3, 4) must have the same sort sage: G = PermutationGroup([[(2,3),(4,5)]], domain=[2,3,4,5]) - sage: M(G, {1:[2, 3], 2:[4,5]}) - {((1,2)(3,4),): ({1, 2}, {3, 4})} + sage: M(G, {1:[2, 3], 2:[4, 5]}) + E_2(XY) + + sage: X = SetPartitions(4, 2) + sage: a = lambda g, x: SetPartition([[g(e) for e in b] for b in x]) + sage: M((X, a), {1: [1,2], 2: [3,4]}) + Traceback (most recent call last): + ... + ValueError: Action is not transitive """ if parent(G) == self: if pi is not None: @@ -877,10 +869,16 @@ def _element_constructor_(self, G, pi=None): raise ValueError("each domain element must have exactly one sort") if set(G.domain()) != set(domain): raise ValueError("each element of the domain of the group must have one sort") - domain_partition = G.disjoint_direct_product_decomposition() + components = G.disjoint_direct_product_decomposition() elm = self.one() - for part in domain_partition: - elm *= self.gen(self._project(G, pi, part)) + for component in components: + gens = [[cyc for cyc in gen.cycle_tuples() if cyc[0] in component] + for gen in G.gens()] + H = PermutationGroup([gen for gen in gens if gen], + domain=component) + dompart = {k: [e for e in v if e in component] + for k, v in pi.items()} + elm *= self.gen(self._indices(H, dompart)) return elm # Assume G is a tuple (X, a) @@ -905,49 +903,6 @@ def _element_constructor_(self, G, pi=None): domain=S.domain()) return self(stabG, pi) - def gen(self, x): - r""" - The molecular species given by an atomic species. - - EXAMPLES:: - - sage: from sage.rings.species import MolecularSpecies - sage: M = MolecularSpecies("X, Y") - - sage: P = PolynomialSpecies(ZZ, "X, Y") - sage: At = AtomicSpecies("X, Y") - sage: G = PermutationGroup([[(1,2),(3,4)]]); G - Permutation Group with generators [(1,2)(3,4)] - sage: pi = {1: [1,2], 2: [3,4]} - sage: E2XY = At(G, pi) - sage: At(G, pi).rename("E_2(XY)"); E2XY - E_2(XY) - sage: m = P._indices.gen((G, pi)); m - E_2(XY) - sage: type(m) - - - sage: P = PolynomialSpecies(ZZ, ["X"]) - sage: M = P._indices - sage: A = AtomicSpecies("X") - sage: a = A(CyclicPermutationGroup(4)) - sage: M.gen(a) - C_4 - - sage: P = PolynomialSpecies(ZZ, ["X", "Y"]) - sage: M = P._indices - sage: m = M(SymmetricGroup(6).young_subgroup([2, 2, 2]), {1: [1,2], 2: [3,4,5,6]}) - sage: list(m) - [(E_2(X), 1), (E_2(Y), 2)] - """ - if x not in self._indices: - raise IndexError(f"{x} is not in the index set") - if isinstance(x, (PermutationGroup_generic, AtomicSpecies.Element)): - at = self._indices(x) - else: - at = self._indices(x[0], x[1]) - return self.element_class(self, {at: ZZ.one()}) - def _repr_(self): r""" Return a string representation of ``self``. @@ -1347,6 +1302,12 @@ def _element_constructor_(self, G, pi=None): sage: a = lambda g, x: SetPartition([[g(e) for e in b] for b in x]) sage: P((X, a), {1: [1,2], 2: [3,4]}) X^2*E_2(Y) + X^2*Y^2 + E_2(X)*Y^2 + E_2(X)*E_2(Y) + + sage: P = PolynomialSpecies(ZZ, ["X"]) + sage: X = SetPartitions(4, 2) + sage: a = lambda g, x: SetPartition([[g(e) for e in b] for b in x]) + sage: P((X, a)) + """ if parent(G) == self: if pi is not None: From 9e11b4117ff55217daf654558cc219db48f0ed66 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Fri, 13 Sep 2024 12:54:24 +0530 Subject: [PATCH 191/537] Debugged groebner_basis() method as per hand calculation --- src/sage/matroids/chow_ring_ideal.py | 54 +++++++++++++++++----------- 1 file changed, 33 insertions(+), 21 deletions(-) diff --git a/src/sage/matroids/chow_ring_ideal.py b/src/sage/matroids/chow_ring_ideal.py index 1515736ef95..2d849082f97 100644 --- a/src/sage/matroids/chow_ring_ideal.py +++ b/src/sage/matroids/chow_ring_ideal.py @@ -10,8 +10,9 @@ from sage.matroids.utilities import cmp_elements_key from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing from sage.rings.polynomial.multi_polynomial_sequence import PolynomialSequence +from sage.sets.set import Set from sage.misc.abstract_method import abstract_method -from sage.combinat.subset import Subsets +from itertools import combinations from functools import reduce class ChowRingIdeal(MPolynomialIdeal): @@ -229,39 +230,50 @@ def groebner_basis(self): flats = list(self._flats_generator) gb = list() R = self.ring() - if frozenset() not in flats: - flats.append(frozenset()) + if frozenset() in flats: + flats.remove(frozenset()) ranks = {F:self._matroid.rank(F) for F in flats} + flats_gen = self._flats_generator - flats_gen[frozenset()] = R.zero() - subsets = Subsets(flats) + subsets = [] + # Generate all subsets of the frozenset using combinations + for r in range(len(flats) + 1): # r is the size of the subset + subsets.extend(list(subset) for subset in combinations(flats, r)) + for subset in subsets: flag = True - for i in range (len(subset)): - if i != 0 & len(subset[i]) == len(subset[i-1]): + sorted_list = sorted(subset, key=len) + for i in range (len(sorted_list)): + if (i != 0) & (len(sorted_list[i]) == len(sorted_list[i-1])): flag = False break - - if not flag: + if flag is False: term = R.one() for x in subset: term *= flats_gen[x] gb.append(term) - elif list(subset) != []: - for F in flats: - if F > reduce(lambda a, b: a.union(b), list(subset)): - term = R.one() - for x in subset: - term *= flats_gen[x] - term1 = R.zero() - for G in flats: - if G >= F: - term1 += flats_gen[G] - if term1 != R.zero(): - gb.append(term*(term1**(ranks[F] - ranks[list(subset)[len(subset) - 1]]))) + elif sorted_list != []: + for j in range(len(subset)): + for k in range(j+1, len(subset)): + if (sorted_list[j] != sorted_list[k]) & (sorted_list[j].issubset(sorted_list[k])): + flag = False + break + + if flag is True: + for F in flats: + if F > reduce(lambda a, b: a.union(b), sorted_list): + term = R.one() + for x in subset: + term *= flats_gen[x] + term1 = R.zero() + for G in flats: + if G >= F: + term1 += flats_gen[G] + if term1 != R.zero(): + gb.append(term*(term1**(ranks[F] - ranks[sorted_list[len(subset) - 1]]))) g_basis = PolynomialSequence(R, [gb]) return g_basis From ec079dc3b20b5e84dd779ac3d6185e52a2301ecd Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Fri, 13 Sep 2024 15:44:54 +0530 Subject: [PATCH 192/537] Added test case for empty subset --- src/sage/matroids/chow_ring_ideal.py | 45 +++++++++++++++++----------- 1 file changed, 27 insertions(+), 18 deletions(-) diff --git a/src/sage/matroids/chow_ring_ideal.py b/src/sage/matroids/chow_ring_ideal.py index 2d849082f97..ac5c5c7e513 100644 --- a/src/sage/matroids/chow_ring_ideal.py +++ b/src/sage/matroids/chow_ring_ideal.py @@ -255,25 +255,34 @@ def groebner_basis(self): term *= flats_gen[x] gb.append(term) - elif sorted_list != []: - for j in range(len(subset)): - for k in range(j+1, len(subset)): - if (sorted_list[j] != sorted_list[k]) & (sorted_list[j].issubset(sorted_list[k])): - flag = False - break - - if flag is True: + else: + if subset == []: for F in flats: - if F > reduce(lambda a, b: a.union(b), sorted_list): - term = R.one() - for x in subset: - term *= flats_gen[x] - term1 = R.zero() - for G in flats: - if G >= F: - term1 += flats_gen[G] - if term1 != R.zero(): - gb.append(term*(term1**(ranks[F] - ranks[sorted_list[len(subset) - 1]]))) + term = R.zero() + for G in flats: + if G >= F: + term += flats_gen[G] + gb.append((term)**(ranks[F])) + + else: + for j in range(len(subset)): + for k in range(j+1, len(subset)): + if (sorted_list[j] != sorted_list[k]) & (sorted_list[j].issubset(sorted_list[k])): + flag = False + break + + if flag is True: + for F in flats: + if F > reduce(lambda a, b: a.union(b), sorted_list): + term = R.one() + for x in subset: + term *= flats_gen[x] + term1 = R.zero() + for G in flats: + if G >= F: + term1 += flats_gen[G] + if term1 != R.zero(): + gb.append(term*(term1**(ranks[F] - ranks[sorted_list[len(subset) - 1]]))) g_basis = PolynomialSequence(R, [gb]) return g_basis From 1cf68947df2e54af1883123494b892a44b8bb9a4 Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Fri, 13 Sep 2024 16:46:05 +0200 Subject: [PATCH 193/537] fix bugs in _element_constructor_ when creating species from a group action --- src/sage/rings/species.py | 152 ++++++++++++++++++++++++-------------- 1 file changed, 95 insertions(+), 57 deletions(-) diff --git a/src/sage/rings/species.py b/src/sage/rings/species.py index eadf97bec05..5ff9ab5eae4 100644 --- a/src/sage/rings/species.py +++ b/src/sage/rings/species.py @@ -1,4 +1,5 @@ from itertools import accumulate, chain + from sage.categories.graded_algebras_with_basis import GradedAlgebrasWithBasis from sage.categories.infinite_enumerated_sets import InfiniteEnumeratedSets from sage.categories.monoids import Monoids @@ -12,30 +13,34 @@ from sage.groups.perm_gps.permgroup_named import SymmetricGroup from sage.libs.gap.libgap import libgap from sage.misc.cachefunc import cached_method +from sage.modules.free_module_element import vector from sage.monoids.indexed_free_monoid import (IndexedFreeAbelianMonoid, IndexedFreeAbelianMonoidElement) from sage.rings.integer_ring import ZZ +from sage.structure.category_object import normalize_names from sage.structure.element import Element, parent from sage.structure.parent import Parent from sage.structure.unique_representation import UniqueRepresentation -from sage.modules.free_module_element import vector class ElementCache(): def __init__(self): r""" - Class for caching elements. + A class for caching elements. """ self._cache = dict() def _cache_get(self, elm): r""" - Return the cached element, or add it - if it doesn't exist. + Return the cached element, or add it if it doesn't exist. + + INPUT: - ``elm`` must implement the following methods: - - ``_element_key`` - hashable type for dict lookup. - - ``__eq__`` - to compare two elements. + - ``elm``, an element of a class which implements the + following methods:: + + - ``_element_key`` - hashable type for dict lookup, + - ``__eq__`` - to compare two elements, - ``_canonicalize`` - to preprocess the element. TESTS:: @@ -53,6 +58,7 @@ def _cache_get(self, elm): sage: E = ElementCache() sage: E._cache_get(a) {((1,2,3,4)(5,6)(7,8)(9,10),): ({5, 6, 7, 8}, {1, 2, 3, 4, 9, 10})} + """ # TODO: Make _canonicalize optional. # Possibly the following works: @@ -230,7 +236,7 @@ def _element_constructor_(self, x): mapping = {v: i for i, v in enumerate(x.domain(), 1)} normalized_gens = [[tuple(mapping[x] for x in cyc) for cyc in gen.cycle_tuples()] - for gen in x.gens()] + for gen in x.gens()] P = PermutationGroup(gens=normalized_gens) # Fix for SymmetricGroup(0) if x.degree() == 0: @@ -456,7 +462,7 @@ def _repr_(self): if self.parent()._arity == 1: return "{" + f"{self._dis}" + "}" dompart = ', '.join("{" + repr(sorted(b))[1:-1] + "}" - for b in self._dompart) + for b in self._dompart) return "{" + f"{self._dis}: ({dompart})" + "}" @@ -477,7 +483,6 @@ def __classcall__(cls, names): sage: A3 is A4 True """ - from sage.structure.category_object import normalize_names names = normalize_names(-1, names) return super().__classcall__(cls, names) @@ -632,25 +637,25 @@ def _rename(self, n): if n >= 2: self(SymmetricGroup(n), - {i+1: range(1, n+1)}).rename(f"E_{n}" + sort) + {i+1: range(1, n+1)}).rename(f"E_{n}" + sort) if n >= 3: self(CyclicPermutationGroup(n), - {i+1: range(1, n+1)}).rename(f"C_{n}" + sort) + {i+1: range(1, n+1)}).rename(f"C_{n}" + sort) if n >= 4: self(DihedralGroup(n), - {i+1: range(1, n+1)}).rename(f"P_{n}" + sort) + {i+1: range(1, n+1)}).rename(f"P_{n}" + sort) if n >= 4: self(AlternatingGroup(n), - {i+1: range(1, n+1)}).rename(f"Eo_{n}" + sort) + {i+1: range(1, n+1)}).rename(f"Eo_{n}" + sort) if n >= 4 and not n % 2: gens = [[(i, n-i+1) for i in range(1, n//2 + 1)], [(i, i+1) for i in range(1, n, 2)]] self(PermutationGroup(gens), - {i+1: range(1, n+1)}).rename(f"Pb_{n}" + sort) + {i+1: range(1, n+1)}).rename(f"Pb_{n}" + sort) def __contains__(self, x): r""" @@ -706,6 +711,65 @@ def _repr_(self): Element = AtomicSpeciesElement +def _stabilizer_subgroups(G, X, a): + r""" + Return subgroups conjugate to the stabilizer subgroups of the + given (left) group action. + + INPUT: + + - ``G``, the acting group + - ``X``, the set ``G`` is acting on + - ``a``, the (left) action + + EXAMPLES:: + + sage: from sage.rings.species import _stabilizer_subgroups + sage: S = SymmetricGroup(4) + sage: X = SetPartitions(S.degree(), [2,2]) + sage: a = lambda g, x: SetPartition([[g(e) for e in b] for b in x]) + sage: _stabilizer_subgroups(S, X, a) + [Permutation Group with generators [(1,2), (1,3)(2,4)]] + + sage: S = SymmetricGroup(8) + sage: X = SetPartitions(S.degree(), [3,3,2]) + sage: _stabilizer_subgroups(S, X, a) + [Permutation Group with generators [(7,8), (6,7), (4,5), (1,3)(2,6)(4,7)(5,8), (1,3)]] + + sage: S = SymmetricGroup(4) + sage: X = SetPartitions(S.degree(), 2) + sage: _stabilizer_subgroups(S, X, a) + [Permutation Group with generators [(1,4), (1,3,4)], + Permutation Group with generators [(1,3)(2,4), (1,4)]] + + Let us keep 3 and 6 in separate blocks, and check that the + returned subgroups have the proper domains:: + + sage: S = SymmetricGroup([1,2,4,5,3,6]).young_subgroup([4, 2]) + sage: X = [pi for pi in SetPartitions(6, [3,3]) if all(sum(1 for e in b if e % 3) == 2 for b in pi)] + sage: _stabilizer_subgroups(S, X, a) + [Permutation Group with generators [(1,2), (4,5), (1,4)(2,5)(3,6)]] + + """ + from sage.combinat.cyclic_sieving_phenomenon import orbit_decomposition + to_gap = {x: i for i, x in enumerate(X, 1)} + + g_orbits = [orbit_decomposition(list(to_gap), lambda x: a(g, x)) + for g in G.gens()] + + gens = [PermutationGroupElement(gen) for g_orbit in g_orbits + if (gen := [tuple([to_gap[x] for x in o]) + for o in g_orbit if len(o) > 1])] + result = [] + M = set(range(1, len(to_gap) + 1)) + while M: + p = M.pop() + OS = libgap.OrbitStabilizer(G, p, G.gens(), gens) + result.append(PermutationGroup(gap_group=OS["stabilizer"], domain=G.domain())) + M.difference_update(OS["orbit"].sage()) + return result + + class MolecularSpecies(IndexedFreeAbelianMonoid): """ The set of (multivariate) molecular species. @@ -832,7 +896,7 @@ def _element_constructor_(self, G, pi=None): sage: X = SetPartitions(8, [4, 2, 2]) sage: M((X, a), {1: X.base_set()}) - + P_4*E_4 TESTS:: @@ -881,27 +945,13 @@ def _element_constructor_(self, G, pi=None): elm *= self.gen(self._indices(H, dompart)) return elm - # Assume G is a tuple (X, a) X, a = G - if pi is None: - if self._arity == 1: - pi = {1: X} - else: - raise ValueError("the assignment of sorts to the domain elements must be provided") - L = [None for _ in range(self._arity)] - for k, v in pi.items(): - L[k - 1] = list(v) - # Create group - # TODO: Is this correct? - S = SymmetricGroup(list(chain.from_iterable(L))).young_subgroup([len(v) for v in L]) - H = PermutationGroup(S.gens(), action=a, domain=X) - if len(H.orbits()) > 1: - # Then it is not transitive + L = [len(pi[i]) for i in range(1, self._arity + 1)] + S = SymmetricGroup(sum(L)).young_subgroup(L) + H = _stabilizer_subgroups(S, X, a) + if len(H) > 1: raise ValueError("Action is not transitive") - stabG = PermutationGroup([g for g in S.gens() - if a(g, H.orbits()[0][0]) == H.orbits()[0][0]], - domain=S.domain()) - return self(stabG, pi) + return self(H[0], pi) def _repr_(self): r""" @@ -998,7 +1048,7 @@ def shift_gens(gens, n): return a._dis._C, a._dompart if n % 2 == 1: - a = list(A._monomial)[0] # as atomic species + a = list(A._monomial)[0] # as atomic species b, b_dompart = (A ** (n-1)).group_and_partition() gens = a._dis._C.gens() + shift_gens(b.gens(), a._tc) new_dompart = tuple([frozenset(list(p_a) + [a._tc + e for e in p_b]) @@ -1301,13 +1351,13 @@ def _element_constructor_(self, G, pi=None): sage: X = SetPartitions(4, 2) sage: a = lambda g, x: SetPartition([[g(e) for e in b] for b in x]) sage: P((X, a), {1: [1,2], 2: [3,4]}) - X^2*E_2(Y) + X^2*Y^2 + E_2(X)*Y^2 + E_2(X)*E_2(Y) + X^2*E_2(Y) + E_2(XY) + E_2(X)*Y^2 + E_2(X)*E_2(Y) sage: P = PolynomialSpecies(ZZ, ["X"]) sage: X = SetPartitions(4, 2) sage: a = lambda g, x: SetPartition([[g(e) for e in b] for b in x]) - sage: P((X, a)) - + sage: P((X, a), {1: [1,2,3,4]}) + E_3*X + P_4 """ if parent(G) == self: if pi is not None: @@ -1319,25 +1369,13 @@ def _element_constructor_(self, G, pi=None): return self._from_dict({self._indices(G): ZZ.one()}) raise ValueError("the assignment of sorts to the domain elements must be provided") return self._from_dict({self._indices(G, pi): ZZ.one()}) - # Assume G is a tuple (X, a) + X, a = G - if pi is None: - if self._arity == 1: - pi = {1: X} - else: - raise ValueError("the assignment of sorts to the domain elements must be provided") - # Make iteration over values of pi deterministic - L = [None for _ in range(self._arity)] - for k, v in pi.items(): - L[k - 1] = list(v) - # Create group - # TODO: Is this correct? - S = SymmetricGroup(list(chain.from_iterable(L))).young_subgroup([len(v) for v in L]) - H = PermutationGroup(S.gens(), action=a, domain=X) - res = self.zero() - for orbit in H.orbits(): - stabG = PermutationGroup([g for g in S.gens() if a(g, orbit[0]) == orbit[0]], domain=S.domain()) - res += self._from_dict({self._indices(stabG, pi): ZZ.one()}) + X, a = G + L = [len(pi[i]) for i in range(1, self._arity + 1)] + S = SymmetricGroup(sum(L)).young_subgroup(L) + Hs = _stabilizer_subgroups(S, X, a) + res = self._from_dict({self._indices(H, pi): ZZ.one() for H in Hs}) return res @cached_method From 0c72461156cda3cb9df6a77ed7264a56f11a9c47 Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Fri, 13 Sep 2024 17:48:26 +0200 Subject: [PATCH 194/537] make indexing of sorts 0-based, be more permissive with input of domain partition --- src/sage/rings/species.py | 205 +++++++++++++++++++++----------------- 1 file changed, 112 insertions(+), 93 deletions(-) diff --git a/src/sage/rings/species.py b/src/sage/rings/species.py index 5ff9ab5eae4..cac26cdd404 100644 --- a/src/sage/rings/species.py +++ b/src/sage/rings/species.py @@ -48,9 +48,9 @@ def _cache_get(self, elm): sage: A = AtomicSpecies("X, Y") sage: G = PermutationGroup([[(1,2),(3,4),(5,6),(7,8,9,10)]]); G Permutation Group with generators [(1,2)(3,4)(5,6)(7,8,9,10)] - sage: a = A(G, {1: [1,2,3,4], 2: [5,6,7,8,9,10]}); a + sage: a = A(G, {0: [1,2,3,4], 1: [5,6,7,8,9,10]}); a {((1,2,3,4)(5,6)(7,8)(9,10),): ({5, 6, 7, 8}, {1, 2, 3, 4, 9, 10})} - sage: b = A(G, {1: [1,2,5,6], 2: [3,4,7,8,9,10]}); b + sage: b = A(G, {0: [1,2,5,6], 1: [3,4,7,8,9,10]}); b {((1,2,3,4)(5,6)(7,8)(9,10),): ({5, 6, 7, 8}, {1, 2, 3, 4, 9, 10})} sage: a is b True @@ -341,7 +341,7 @@ def grade(self): sage: A = AtomicSpecies("X, Y") sage: G = PermutationGroup([[(1,2),(3,4),(5,6),(7,8,9,10)]]) - sage: a = A(G, {1: [1,2,3,4], 2: [5,6,7,8,9,10]}) + sage: a = A(G, {0: [1,2,3,4], 1: [5,6,7,8,9,10]}) sage: a.grade() [4, 6] """ @@ -357,7 +357,7 @@ def _element_key(self): sage: A = AtomicSpecies("X, Y") sage: G = PermutationGroup([[(1,2),(3,4),(5,6),(7,8,9,10)]]); G Permutation Group with generators [(1,2)(3,4)(5,6)(7,8,9,10)] - sage: a = A(G, {1: [1,2,3,4], 2: [5,6,7,8,9,10]}); a + sage: a = A(G, {0: [1,2,3,4], 1: [5,6,7,8,9,10]}); a {((1,2,3,4)(5,6)(7,8)(9,10),): ({5, 6, 7, 8}, {1, 2, 3, 4, 9, 10})} sage: a._element_key() ((4, 6), ((1,2,3,4)(5,6)(7,8)(9,10),)) @@ -375,9 +375,9 @@ def _canonicalize(self): sage: A = AtomicSpecies("X, Y") sage: G = PermutationGroup([[(1,2),(3,4),(5,6),(7,8,9,10)]]); G Permutation Group with generators [(1,2)(3,4)(5,6)(7,8,9,10)] - sage: f = A(G, {1: [1,2,3,4], 2: [5,6,7,8,9,10]}); f + sage: f = A(G, {0: [1,2,3,4], 1: [5,6,7,8,9,10]}); f {((1,2,3,4)(5,6)(7,8)(9,10),): ({5, 6, 7, 8}, {1, 2, 3, 4, 9, 10})} - sage: A(G, {1: [1,2,5,6], 2: [3,4,7,8,9,10]}) is f # indirect doctest + sage: A(G, {0: [1,2,5,6], 1: [3,4,7,8,9,10]}) is f # indirect doctest True """ # The canonicalization is done in the element constructor. @@ -394,11 +394,11 @@ def __hash__(self): Permutation Group with generators [(1,2)(3,4)(5,6)(7,8,9,10)] sage: H = PermutationGroup([[(1,2,3,4),(5,6),(7,8),(9,10)]]); H Permutation Group with generators [(1,2,3,4)(5,6)(7,8)(9,10)] - sage: A = At(G, {1: [1,2,3,4], 2: [5,6,7,8,9,10]}); A + sage: A = At(G, {0: [1,2,3,4], 1: [5,6,7,8,9,10]}); A {((1,2,3,4)(5,6)(7,8)(9,10),): ({5, 6, 7, 8}, {1, 2, 3, 4, 9, 10})} - sage: B = At(H, {1: [1,2,3,4], 2: [5,6,7,8,9,10]}); B + sage: B = At(H, {0: [1,2,3,4], 1: [5,6,7,8,9,10]}); B {((1,2,3,4)(5,6)(7,8)(9,10),): ({1, 2, 3, 4}, {5, 6, 7, 8, 9, 10})} - sage: C = At(G, {1: [1,2,5,6], 2: [3,4,7,8,9,10]}); C + sage: C = At(G, {0: [1,2,5,6], 1: [3,4,7,8,9,10]}); C {((1,2,3,4)(5,6)(7,8)(9,10),): ({5, 6, 7, 8}, {1, 2, 3, 4, 9, 10})} sage: hash(A) == hash(B) True @@ -419,9 +419,9 @@ def __eq__(self, other): Permutation Group with generators [(1,2)(3,4)(5,6)(7,8,9,10)] sage: H = PermutationGroup([[(1,2,3,4),(5,6),(7,8),(9,10)]]); H Permutation Group with generators [(1,2,3,4)(5,6)(7,8)(9,10)] - sage: A = At(G, {1: [1,2,3,4], 2: [5,6,7,8,9,10]}) - sage: B = At(H, {1: [1,2,3,4], 2: [5,6,7,8,9,10]}) - sage: C = At(G, {1: [1,2,5,6], 2: [3,4,7,8,9,10]}) + sage: A = At(G, {0: [1,2,3,4], 1: [5,6,7,8,9,10]}) + sage: B = At(H, {0: [1,2,3,4], 1: [5,6,7,8,9,10]}) + sage: C = At(G, {0: [1,2,5,6], 1: [3,4,7,8,9,10]}) sage: A != B True sage: A == C @@ -454,9 +454,9 @@ def _repr_(self): sage: A = AtomicSpecies("X, Y") sage: G = PermutationGroup([[(1,2),(3,4),(5,6),(7,8,9,10)]]); G Permutation Group with generators [(1,2)(3,4)(5,6)(7,8,9,10)] - sage: a = A(G, {1: [1,2,3,4], 2: [5,6,7,8,9,10]}); a + sage: a = A(G, {0: [1,2,3,4], 1: [5,6,7,8,9,10]}); a {((1,2,3,4)(5,6)(7,8)(9,10),): ({5, 6, 7, 8}, {1, 2, 3, 4, 9, 10})} - sage: a = A(G, {2: [1,2,3,4,5,6,7,8,9,10]}); a + sage: a = A(G, {1: [1,2,3,4,5,6,7,8,9,10]}); a {((1,2,3,4)(5,6)(7,8)(9,10),): ({}, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10})} """ if self.parent()._arity == 1: @@ -538,8 +538,8 @@ def an_element(self): sage: a E_2(XY) """ - G = PermutationGroup([[(2 * i - 1, 2 * i) for i in range(1, self._arity + 1)]]) - m = {i: [2 * i - 1, 2 * i] for i in range(1, self._arity + 1)} + G = PermutationGroup([[(2 * i + 1, 2 * i + 2) for i in range(self._arity)]]) + m = {i: [2 * i + 1, 2 * i + 2] for i in range(self._arity)} return self._element_constructor_(G, m) def _element_constructor_(self, G, pi=None): @@ -550,19 +550,29 @@ def _element_constructor_(self, G, pi=None): - ``G`` - an element of ``self`` (in this case pi must be ``None``) or a permutation group. - - ``pi`` - a dict mapping sorts to iterables whose union is the domain. - If `k=1`, `pi` can be omitted. + - ``pi`` - a `k`-tuple or list of iterables or a dict mapping + sorts to iterables whose union is the domain. If `k=1`, + `pi` can be omitted. EXAMPLES:: sage: A = AtomicSpecies("X, Y") - sage: A(DihedralGroup(5), {1: [1,2,3,4,5]}) + sage: A(DihedralGroup(5), {0: [1,2,3,4,5]}) P_5(X) sage: G = PermutationGroup([[(1,2),(3,4,5,6)]]) - sage: a = A(G, {1: [1,2], 2: [3,4,5,6]}); a + sage: A(G, {0: [1,2], 1: [3,4,5,6]}) + {((1,2,3,4)(5,6),): ({5, 6}, {1, 2, 3, 4})} + + sage: A(G, ([1,2], [3,4,5,6])) {((1,2,3,4)(5,6),): ({5, 6}, {1, 2, 3, 4})} + + TESTS:: + + sage: G = PermutationGroup([[(1,3),(5,7)]], domain=[1,3,5,7]) + sage: A(G, ([1,3], [5,7])) + E_2(XY) """ if parent(G) == self: if pi is not None: @@ -572,11 +582,13 @@ def _element_constructor_(self, G, pi=None): raise ValueError(f"{G} must be a permutation group") if pi is None: if self._arity == 1: - pi = {1: G.domain()} + pi = {0: G.domain()} else: raise ValueError("the assignment of sorts to the domain elements must be provided") - if not set(pi.keys()).issubset(range(1, self._arity + 1)): - raise ValueError(f"keys of pi (={pi.keys()}) must be in the range [1, {self._arity}]") + elif not isinstance(pi, dict): + pi = {i: v for i, v in enumerate(pi)} + if not set(pi.keys()).issubset(range(self._arity)): + raise ValueError(f"keys of pi (={pi.keys()}) must be in range({self._arity})") if sum(len(p) for p in pi.values()) != len(G.domain()) or set(chain.from_iterable(pi.values())) != set(G.domain()): raise ValueError(f"values of pi (={pi.values()}) must partition the domain of G (={G.domain()})") for orbit in G.orbits(): @@ -584,12 +596,11 @@ def _element_constructor_(self, G, pi=None): raise ValueError(f"All elements of orbit {orbit} must have the same sort") dis_elm = ConjugacyClassesOfDirectlyIndecomposableSubgroups()(G) mapping = {v: i for i, v in enumerate(G.domain(), 1)} - mapping2 = PermutationGroupElement([mapping[e] for o in sorted(G.orbits(), key=len, reverse=True) - for e in o]).inverse() - dpart = [frozenset() for _ in range(self._arity)] - for k, v in pi.items(): - dpart[k - 1] = frozenset(mapping2(mapping[x]) for x in v) - elm = self._cache_get(self.element_class(self, dis_elm, tuple(dpart))) + O = sorted(G.orbits(), key=len, reverse=True) + mapping2 = PermutationGroupElement([mapping[e] for o in O for e in o]).inverse() + dompart = [frozenset(mapping2(mapping[x]) for x in pi.get(k, [])) + for k in range(self._arity)] + elm = self._cache_get(self.element_class(self, dis_elm, tuple(dompart))) if elm._tc not in self._renamed: self._rename(elm._tc) return elm @@ -601,21 +612,21 @@ def _rename(self, n): EXAMPLES:: sage: A = AtomicSpecies(["X", "Y"]) - sage: A(SymmetricGroup(4), {1: range(1, 5)}) # indirect doctest + sage: A(SymmetricGroup(4), {0: range(1, 5)}) # indirect doctest E_4(X) - sage: A(SymmetricGroup(4), {2: range(1, 5)}) + sage: A(SymmetricGroup(4), {1: range(1, 5)}) E_4(Y) - sage: A(CyclicPermutationGroup(4), {1: range(1, 5)}) + sage: A(CyclicPermutationGroup(4), {0: range(1, 5)}) C_4(X) - sage: A(CyclicPermutationGroup(4), {2: range(1, 5)}) + sage: A(CyclicPermutationGroup(4), {1: range(1, 5)}) C_4(Y) - sage: A(DihedralGroup(4), {1: range(1, 5)}) + sage: A(DihedralGroup(4), {0: range(1, 5)}) P_4(X) - sage: A(DihedralGroup(4), {2: range(1, 5)}) + sage: A(DihedralGroup(4), {1: range(1, 5)}) P_4(Y) - sage: A(AlternatingGroup(4), {1: range(1, 5)}) + sage: A(AlternatingGroup(4), {0: range(1, 5)}) Eo_4(X) - sage: A(AlternatingGroup(4), {2: range(1, 5)}) + sage: A(AlternatingGroup(4), {1: range(1, 5)}) Eo_4(Y) """ from sage.groups.perm_gps.permgroup import PermutationGroup @@ -628,7 +639,7 @@ def _rename(self, n): self._renamed.add(n) for i in range(self._arity): if n == 1: - self(SymmetricGroup(1), {i+1: [1]}).rename(self._names[i]) + self(SymmetricGroup(1), {i: [1]}).rename(self._names[i]) if self._arity == 1: sort = "" @@ -637,25 +648,25 @@ def _rename(self, n): if n >= 2: self(SymmetricGroup(n), - {i+1: range(1, n+1)}).rename(f"E_{n}" + sort) + {i: range(1, n+1)}).rename(f"E_{n}" + sort) if n >= 3: self(CyclicPermutationGroup(n), - {i+1: range(1, n+1)}).rename(f"C_{n}" + sort) + {i: range(1, n+1)}).rename(f"C_{n}" + sort) if n >= 4: self(DihedralGroup(n), - {i+1: range(1, n+1)}).rename(f"P_{n}" + sort) + {i: range(1, n+1)}).rename(f"P_{n}" + sort) if n >= 4: self(AlternatingGroup(n), - {i+1: range(1, n+1)}).rename(f"Eo_{n}" + sort) + {i: range(1, n+1)}).rename(f"Eo_{n}" + sort) if n >= 4 and not n % 2: gens = [[(i, n-i+1) for i in range(1, n//2 + 1)], [(i, i+1) for i in range(1, n, 2)]] self(PermutationGroup(gens), - {i+1: range(1, n+1)}).rename(f"Pb_{n}" + sort) + {i: range(1, n+1)}).rename(f"Pb_{n}" + sort) def __contains__(self, x): r""" @@ -677,15 +688,15 @@ def __contains__(self, x): if isinstance(x, PermutationGroup_generic): if self._arity == 1: G = x - pi = {1: G.domain()} + pi = {0: G.domain()} else: raise ValueError("the assignment of sorts to the domain elements must be provided") else: G, pi = x if not isinstance(G, PermutationGroup_generic): raise ValueError(f"{G} must be a permutation group") - if not set(pi.keys()).issubset(range(1, self._arity + 1)): - raise ValueError(f"keys of pi (={pi.keys()}) must be in the range [1, {self._arity}]") + if not set(pi.keys()).issubset(range(self._arity)): + raise ValueError(f"keys of pi (={pi.keys()}) must be in range({self._arity})") if sum(len(p) for p in pi.values()) != len(G.domain()) or set(chain.from_iterable(pi.values())) != set(G.domain()): raise ValueError(f"values of pi (={pi.values()}) must partition the domain of G (={G.domain()})") for orbit in G.orbits(): @@ -812,7 +823,7 @@ def __init__(self, *args, **kwds): sage: from sage.rings.species import MolecularSpecies sage: M = MolecularSpecies("X,Y") sage: G = PermutationGroup([[(1,2),(3,4)], [(5,6)]]) - sage: M(G, {1: [5,6], 2: [1,2,3,4]}) + sage: M(G, {0: [5,6], 1: [1,2,3,4]}) {((1,2)(3,4),): ({}, {1, 2, 3, 4})}*E_2(X) TESTS:: @@ -860,7 +871,7 @@ def graded_component(self, grade): n = sum(grade) S = SymmetricGroup(n).young_subgroup(grade) dom = S.domain() - dompart = {i+1: dom[sum(grade[:i]): sum(grade[:i+1])] for i in range(len(grade))} + dompart = {i: dom[sum(grade[:i]): sum(grade[:i+1])] for i in range(len(grade))} return Set([self(G, dompart) for G in S.conjugacy_classes_subgroups()]) def _element_constructor_(self, G, pi=None): @@ -883,7 +894,7 @@ def _element_constructor_(self, G, pi=None): sage: from sage.rings.species import MolecularSpecies sage: M = MolecularSpecies(["X", "Y"]) sage: G = PermutationGroup([[(1,2)], [(3,4)]]) - sage: M(G, {1: [1,2], 2: [3,4]}) + sage: M(G, {0: [1,2], 1: [3,4]}) E_2(X)*E_2(Y) Create a molecular species given an action:: @@ -891,31 +902,35 @@ def _element_constructor_(self, G, pi=None): sage: M = MolecularSpecies("X") sage: a = lambda g, x: SetPartition([[g(e) for e in b] for b in x]) sage: X = SetPartitions(4, [2, 2]) - sage: M((X, a), {1: X.base_set()}) + sage: M((X, a), {0: X.base_set()}) P_4 sage: X = SetPartitions(8, [4, 2, 2]) - sage: M((X, a), {1: X.base_set()}) + sage: M((X, a), {0: X.base_set()}) P_4*E_4 TESTS:: sage: M = MolecularSpecies(["X", "Y"]) - sage: M(CyclicPermutationGroup(4), {1: [1,2], 2: [3,4]}) + sage: M(CyclicPermutationGroup(4), {0: [1,2], 1: [3,4]}) Traceback (most recent call last): ... ValueError: All elements of orbit (1, 2, 3, 4) must have the same sort sage: G = PermutationGroup([[(2,3),(4,5)]], domain=[2,3,4,5]) - sage: M(G, {1:[2, 3], 2:[4, 5]}) + sage: M(G, {0: [2, 3], 1: [4, 5]}) E_2(XY) sage: X = SetPartitions(4, 2) sage: a = lambda g, x: SetPartition([[g(e) for e in b] for b in x]) - sage: M((X, a), {1: [1,2], 2: [3,4]}) + sage: M((X, a), {0: [1,2], 1: [3,4]}) Traceback (most recent call last): ... ValueError: Action is not transitive + + sage: G = PermutationGroup([[(1,3),(5,7)]], domain=[1,3,5,7]) + sage: M(G, ([1,3], [5,7])) + E_2(XY) """ if parent(G) == self: if pi is not None: @@ -925,9 +940,11 @@ def _element_constructor_(self, G, pi=None): if isinstance(G, PermutationGroup_generic): if pi is None: if self._arity == 1: - pi = {1: G.domain()} + pi = {0: G.domain()} else: raise ValueError("the assignment of sorts to the domain elements must be provided") + elif not isinstance(pi, dict): + pi = {i: v for i, v in enumerate(pi)} domain = [e for p in pi.values() for e in p] if len(domain) != len(set(domain)): raise ValueError("each domain element must have exactly one sort") @@ -946,7 +963,7 @@ def _element_constructor_(self, G, pi=None): return elm X, a = G - L = [len(pi[i]) for i in range(1, self._arity + 1)] + L = [len(pi.get(i, [])) for i in range(self._arity)] S = SymmetricGroup(sum(L)).young_subgroup(L) H = _stabilizer_subgroups(S, X, a) if len(H) > 1: @@ -997,14 +1014,14 @@ def group_and_partition(self): sage: from sage.rings.species import MolecularSpecies sage: M = MolecularSpecies("X,Y") sage: G = PermutationGroup([[(1,2),(3,4)], [(5,6)]]) - sage: A = M(G, {1: [5,6], 2: [1,2,3,4]}) + sage: A = M(G, {0: [5,6], 1: [1,2,3,4]}) sage: A.group_and_partition() (Permutation Group with generators [(5,6), (1,2)(3,4)], (frozenset({5, 6}), frozenset({1, 2, 3, 4}))) TESTS:: - sage: B = M(PermutationGroup([(1,2,3)]), {1: [1,2,3]}) + sage: B = M(PermutationGroup([(1,2,3)]), {0: [1,2,3]}) sage: B.group_and_partition() (Permutation Group with generators [(1,2,3)], (frozenset({1, 2, 3}), frozenset())) @@ -1013,7 +1030,7 @@ def group_and_partition(self): (Permutation Group with generators [(7,8,9), (5,6), (1,2)(3,4)], (frozenset({5, 6, 7, 8, 9}), frozenset({1, 2, 3, 4}))) - sage: C = M(PermutationGroup([(2,3)]), {1: [1], 2: [2,3]}) + sage: C = M(PermutationGroup([(2,3)]), {0: [1], 1: [2,3]}) sage: C.group_and_partition() (Permutation Group with generators [(2,3)], (frozenset({1}), frozenset({2, 3}))) @@ -1090,7 +1107,7 @@ def grade(self): sage: M = MolecularSpecies("X, Y") sage: G = PermutationGroup([[(1,2),(3,4),(5,6),(7,8,9,10)]]); G Permutation Group with generators [(1,2)(3,4)(5,6)(7,8,9,10)] - sage: a = M(G, {1: [1,2,3,4], 2: [5,6,7,8,9,10]}); a + sage: a = M(G, {0: [1,2,3,4], 1: [5,6,7,8,9,10]}); a {((1,2,3,4)(5,6)(7,8)(9,10),): ({5, 6, 7, 8}, {1, 2, 3, 4, 9, 10})} sage: a.grade() [4, 6] @@ -1138,7 +1155,7 @@ def _compose_with_singletons(self, base_ring, names, args): E_2(XY) + X^2*Y^2 sage: M = MolecularSpecies(["X", "Y"]) - sage: F = M(PermutationGroup([[(1,2,3), (4,5,6)]]), {1: [1,2,3], 2: [4,5,6]}) + sage: F = M(PermutationGroup([[(1,2,3), (4,5,6)]]), {0: [1,2,3], 1: [4,5,6]}) sage: F {((1,2,3)(4,5,6),): ({1, 2, 3}, {4, 5, 6})} sage: F._compose_with_singletons(ZZ, "X1, X2, X3, Y1, Y2", [[1, 1, 1], [2, 1]]) @@ -1167,7 +1184,7 @@ def _compose_with_singletons(self, base_ring, names, args): G = libgap.ConjugateGroup(G, conj) comp = list(chain.from_iterable(args)) - dpart = {i + 1: range(x - comp[i] + 1, x + 1) for i, x in enumerate(accumulate(comp))} + dompart = {i: range(x - comp[i] + 1, x + 1) for i, x in enumerate(accumulate(comp))} # Create the double coset representatives. S_down = SymmetricGroup(sum(comp)).young_subgroup(comp) mc = self.grade() @@ -1179,8 +1196,8 @@ def _compose_with_singletons(self, base_ring, names, args): res = Pn.zero() for tau, _ in taus: H = libgap.Intersection(libgap.ConjugateGroup(G, tau ** -1), S_down) - grp = PermutationGroup(gap_group=H, domain=range(1, tc + 1)) - res += Pn(grp, dpart) + K = PermutationGroup(gap_group=H, domain=range(1, tc + 1)) + res += Pn(K, dompart) return res def __call__(self, *args): @@ -1208,8 +1225,8 @@ def __call__(self, *args): P_4 sage: M = MolecularSpecies(["X","Y"]) - sage: X = M(SymmetricGroup(1), {1:[1]}) - sage: Y = M(SymmetricGroup(1), {2:[1]}) + sage: X = M(SymmetricGroup(1), {0: [1]}) + sage: Y = M(SymmetricGroup(1), {1: [1]}) sage: (X*Y)(X, Y^2) X*Y^2 @@ -1218,8 +1235,8 @@ def __call__(self, *args): sage: M1 = MolecularSpecies("X") sage: M2 = MolecularSpecies("X, Y") sage: C3 = M1(CyclicPermutationGroup(3)) - sage: X = M2(SymmetricGroup(1), {1: [1]}) - sage: Y = M2(SymmetricGroup(1), {2: [1]}) + sage: X = M2(SymmetricGroup(1), {0: [1]}) + sage: Y = M2(SymmetricGroup(1), {1: [1]}) sage: C3(X*Y) {((1,2,3)(4,5,6),): ({1, 2, 3}, {4, 5, 6})} @@ -1258,17 +1275,17 @@ def __call__(self, *args): # gens from M_i and dompart P = args[0].parent() - dpart = {i: [] for i in range(1, P._arity + 1)} + dompart = {i: [] for i in range(P._arity)} for start, M in zip(starts, Mlist): - K, dompart = M.group_and_partition() - for i, v in enumerate(dompart, 1): - dpart[i].extend([start + k for k in v]) + K, K_dompart = M.group_and_partition() + for i, v in enumerate(K_dompart): + dompart[i].extend([start + k for k in v]) for gen in K.gens(): gens.append([tuple(start + k for k in cyc) for cyc in gen.cycle_tuples()]) return P(PermutationGroup(gens, - domain=range(1, starts[-1] + 1)), dpart) + domain=range(1, starts[-1] + 1)), dompart) class PolynomialSpecies(CombinatorialFreeModule): @@ -1317,9 +1334,9 @@ def degree_on_basis(self, m): EXAMPLES:: sage: P = PolynomialSpecies(ZZ, ["X", "Y"]) - sage: E4X = P(SymmetricGroup(4), {1: range(1, 5)}); E4X + sage: E4X = P(SymmetricGroup(4), {0: range(1, 5)}); E4X E_4(X) - sage: E4Y = P(SymmetricGroup(4), {2: range(1, 5)}); E4Y + sage: E4Y = P(SymmetricGroup(4), {1: range(1, 5)}); E4Y E_4(Y) sage: P.degree_on_basis(E4X.support()[0]) 4 @@ -1345,18 +1362,18 @@ def _element_constructor_(self, G, pi=None): EXAMPLES:: sage: P = PolynomialSpecies(ZZ, ["X", "Y"]) - sage: P(SymmetricGroup(4).young_subgroup([2, 2]), {1: [1,2], 2: [3,4]}) + sage: P(SymmetricGroup(4).young_subgroup([2, 2]), ([1,2], [3,4])) E_2(X)*E_2(Y) sage: X = SetPartitions(4, 2) sage: a = lambda g, x: SetPartition([[g(e) for e in b] for b in x]) - sage: P((X, a), {1: [1,2], 2: [3,4]}) + sage: P((X, a), {0: [1,2], 1: [3,4]}) X^2*E_2(Y) + E_2(XY) + E_2(X)*Y^2 + E_2(X)*E_2(Y) sage: P = PolynomialSpecies(ZZ, ["X"]) sage: X = SetPartitions(4, 2) sage: a = lambda g, x: SetPartition([[g(e) for e in b] for b in x]) - sage: P((X, a), {1: [1,2,3,4]}) + sage: P((X, a), {0: [1,2,3,4]}) E_3*X + P_4 """ if parent(G) == self: @@ -1368,11 +1385,13 @@ def _element_constructor_(self, G, pi=None): if self._arity == 1: return self._from_dict({self._indices(G): ZZ.one()}) raise ValueError("the assignment of sorts to the domain elements must be provided") + elif not isinstance(pi, dict): + pi = {i: v for i, v in enumerate(pi)} return self._from_dict({self._indices(G, pi): ZZ.one()}) X, a = G X, a = G - L = [len(pi[i]) for i in range(1, self._arity + 1)] + L = [len(pi.get(i, [])) for i in range(self._arity)] S = SymmetricGroup(sum(L)).young_subgroup(L) Hs = _stabilizer_subgroups(S, X, a) res = self._from_dict({self._indices(H, pi): ZZ.one() for H in Hs}) @@ -1455,7 +1474,7 @@ def powersum(self, s, n): EXAMPLES:: sage: P = PolynomialSpecies(ZZ, "X") - sage: P.powersum(1, 4) + sage: P.powersum(0, 4) 4*E_4 - 4*X*E_3 + 4*X^2*E_2 - X^4 - 2*E_2^2 """ assert n in ZZ and n > 0 @@ -1523,7 +1542,7 @@ def factor(s, c, d): * self.powersum(s, k) for k in mu) for mu in Partitions(d)) - return self.prod(factor(s+1, multiplicities[s], degrees[s]) + return self.prod(factor(s, multiplicities[s], degrees[s]) for s in range(self._arity)) class Element(CombinatorialFreeModule.Element): @@ -1534,7 +1553,7 @@ def is_constant(self): EXAMPLES:: sage: P = PolynomialSpecies(ZZ, ["X", "Y"]) - sage: X = P(SymmetricGroup(1), {1: [1]}) + sage: X = P(SymmetricGroup(1), {0: [1]}) sage: X.is_constant() False sage: (3*P.one()).is_constant() @@ -1575,8 +1594,8 @@ def is_virtual(self): TESTS:: sage: P = PolynomialSpecies(ZZ, ["X", "Y"]) - sage: X = P(SymmetricGroup(1), {1: [1]}) - sage: Y = P(SymmetricGroup(1), {2: [1]}) + sage: X = P(SymmetricGroup(1), {0: [1]}) + sage: Y = P(SymmetricGroup(1), {1: [1]}) sage: V = 2 * X - 3 * Y; V 2*X - 3*Y sage: V.is_virtual() @@ -1593,8 +1612,8 @@ def is_molecular(self): TESTS:: sage: P = PolynomialSpecies(ZZ, ["X", "Y"]) - sage: X = P(SymmetricGroup(1), {1: [1]}) - sage: Y = P(SymmetricGroup(1), {2: [1]}) + sage: X = P(SymmetricGroup(1), {0: [1]}) + sage: Y = P(SymmetricGroup(1), {1: [1]}) sage: V = 2 * X - 3 * Y; V 2*X - 3*Y sage: V.is_molecular() @@ -1613,8 +1632,8 @@ def is_atomic(self): TESTS:: sage: P = PolynomialSpecies(ZZ, ["X", "Y"]) - sage: X = P(SymmetricGroup(1), {1: [1]}) - sage: Y = P(SymmetricGroup(1), {2: [1]}) + sage: X = P(SymmetricGroup(1), {0: [1]}) + sage: Y = P(SymmetricGroup(1), {1: [1]}) sage: V = 2 * X - 3 * Y; V 2*X - 3*Y sage: V.is_atomic() @@ -1667,8 +1686,8 @@ def hadamard_product(self, other): g = list(chain.from_iterable(dompart)) conj_L = PermutationGroupElement(g).inverse() G = libgap.ConjugateGroup(G, conj_L) - dpart = {i + 1: range(x - mc[i] + 1, x + 1) - for i, x in enumerate(accumulate(mc))} + dompart = {i: range(x - mc[i] + 1, x + 1) + for i, x in enumerate(accumulate(mc))} for R, d in other: if mc != R.grade(): continue @@ -1682,7 +1701,7 @@ def hadamard_product(self, other): for tau, _ in taus: F = libgap.Intersection(libgap.ConjugateGroup(H, tau), G) new += P(PermutationGroup(gap_group=F, domain=range(1, tc + 1)), - dpart) + dompart) res += c * d * new return res @@ -1770,8 +1789,8 @@ def __call__(self, *args): E_2 + X^3 + {((1,2)(3,4),)} sage: P2 = PolynomialSpecies(QQ, ["X", "Y"]) - sage: X = P2(SymmetricGroup(1), {1:[1]}) - sage: Y = P2(SymmetricGroup(1), {2:[1]}) + sage: X = P2(SymmetricGroup(1), {0: [1]}) + sage: Y = P2(SymmetricGroup(1), {1: [1]}) sage: E2(X + Y) E_2(Y) + Y*X + E_2(X) From 9ad914589a0a070902efc79d585ec12d5916b58e Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Tue, 17 Sep 2024 12:30:31 +0530 Subject: [PATCH 195/537] Added comments and edited doctests --- src/sage/matroids/chow_ring_ideal.py | 90 +++++++++++++++------------- 1 file changed, 48 insertions(+), 42 deletions(-) diff --git a/src/sage/matroids/chow_ring_ideal.py b/src/sage/matroids/chow_ring_ideal.py index ac5c5c7e513..026383c3982 100644 --- a/src/sage/matroids/chow_ring_ideal.py +++ b/src/sage/matroids/chow_ring_ideal.py @@ -10,7 +10,6 @@ from sage.matroids.utilities import cmp_elements_key from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing from sage.rings.polynomial.multi_polynomial_sequence import PolynomialSequence -from sage.sets.set import Set from sage.misc.abstract_method import abstract_method from itertools import combinations from functools import reduce @@ -106,11 +105,12 @@ class ChowRingIdeal_nonaug(ChowRingIdeal): sage: ch = matroids.Uniform(3,6).chow_ring(QQ, False) sage: ch - Chow ring ideal of U(3, 6): Matroid of rank 3 on 6 elements with circuit-closures - {3: {{0, 1, 2, 3, 4, 5}}} + Chow ring ideal of U(3, 6): Matroid of rank 3 on 6 elements with + circuit-closures {3: {{0, 1, 2, 3, 4, 5}}} sage: ch = matroids.catalog.Fano().chow_ring(QQ, False) sage: ch - Chow ring ideal of Fano: Binary matroid of rank 3 on 7 elements, type (3, 0) + Chow ring ideal of Fano: Binary matroid of rank 3 on 7 elements, + type (3, 0) """ def __init__(self, M, R): r""" @@ -122,7 +122,7 @@ def __init__(self, M, R): sage: TestSuite(I).run(skip="_test_category") """ self._matroid = M - flats = [X for i in range(1, self._matroid.rank() + 1) + flats = [X for i in range(1, self._matroid.rank()) 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: @@ -141,7 +141,7 @@ def _gens_constructor(self, poly_ring): EXAMPLES:: sage: ch = matroids.catalog.NonFano().chow_ring(QQ, False) - sage: ch._gens_constructor(ch.ring()) + sage: ch.defining_ideal()._gens_constructor(ch.defining_ideal.ring()) [Aa*Ab, Aa*Ac, Aa*Ad, Aa*Ae, Aa*Af, Aa*Ag, Aa*Abcd, Aa*Abeg, Aa*Acfg, Aa*Ade, Aa*Adf, Aa*Aef, Ab*Ac, Ab*Ad, Ab*Ae, Ab*Af, Ab*Ag, Ab*Aace, Ab*Aadg, Ab*Acfg, Ab*Ade, Ab*Adf, Ab*Aef, Ac*Ad, Ac*Ae, @@ -186,10 +186,10 @@ def _gens_constructor(self, poly_ring): flats_containing[x].append(i) gens = poly_ring.gens() Q = [gens[i] * gens[i+j+1] for i,F in enumerate(flats) - for j,G in enumerate(flats[i+1:]) if not (F < G or G < F)] + for j,G in enumerate(flats[i+1:]) if not (F < G or G < F)] #Quadratic Generators L = [sum(gens[i] for i in flats_containing[x]) - sum(gens[i] for i in flats_containing[y]) - for j,x in enumerate(E) for y in E[j+1:]] + for j,x in enumerate(E) for y in E[j+1:]] #Linear Generators return Q + L def _repr_(self): @@ -211,18 +211,20 @@ def groebner_basis(self): sage: from sage.matroids.basis_matroid import BasisMatroid - sage: ch = M=BasisMatroid(groundset='abc', bases=['ab', 'ac'])).chow_ring(QQ, False) + sage: ch = BasisMatroid(groundset='abc', bases=['ab', 'ac'])).chow_ring(QQ, False) sage: ch.groebner_basis() - [Aa^2, Aa*Abc, Aa*Abc, Abc^2] + [Aa, Abc] sage: ch.groebner_basis().is_groebner() True Another example would be the Groebner basis of the Chow ring ideal of - the Non-Fano matroid:: + the Graphic matroid of CycleGraph(3):: - sage: ch = matroids.catalog.NonFano().chow_ring(QQ, False) + sage: from sage.matroids.graphic_matroid import GraphicMatroid + + sage: ch = GraphicMatroid(graphs.CycleGraph(3)).chow_ring(QQ, False) sage: ch.groebner_basis() - Polynomial Sequence with 232 Polynomials in 16 Variables + [A0, A1, A2, A0*A1, A0*A2, A1*A2, A0*A1*A2] sage: ch.groebner_basis().is_groebner() True """ @@ -231,25 +233,25 @@ def groebner_basis(self): gb = list() R = self.ring() if frozenset() in flats: - flats.remove(frozenset()) + flats.remove(frozenset()) #Non-empty proper flats needed ranks = {F:self._matroid.rank(F) for F in flats} flats_gen = self._flats_generator subsets = [] - # Generate all subsets of the frozenset using combinations + # Generate all subsets of flats using combinations for r in range(len(flats) + 1): # r is the size of the subset subsets.extend(list(subset) for subset in combinations(flats, r)) for subset in subsets: flag = True sorted_list = sorted(subset, key=len) - for i in range (len(sorted_list)): + for i in range (len(sorted_list)): #Checking whether the subset is a chain if (i != 0) & (len(sorted_list[i]) == len(sorted_list[i-1])): flag = False break - if flag is False: + if flag is False: term = R.one() for x in subset: term *= flats_gen[x] @@ -266,7 +268,7 @@ def groebner_basis(self): else: for j in range(len(subset)): - for k in range(j+1, len(subset)): + for k in range(j+1, len(subset)): #Checking if every element in the chain is maximal if (sorted_list[j] != sorted_list[k]) & (sorted_list[j].issubset(sorted_list[k])): flag = False break @@ -354,15 +356,15 @@ def __init__(self, M, R): sage: TestSuite(I).run(skip="_test_category") """ self._matroid = M - self._flats = [X for i in range(1, self._matroid.rank() + 1) + self._flats = [X for i in range(1, self._matroid.rank()) for X in self._matroid.flats(i)] E = list(self._matroid.groundset()) self._flats_generator = dict() try: names_groundset = ['A{}'.format(''.join(str(x))) for x in E] names_flats = ['B{}'.format(''.join(str(x) for x in sorted(F, key=cmp_elements_key))) for F in self._flats] - poly_ring = PolynomialRing(R, names_groundset + names_flats) - except ValueError: + poly_ring = PolynomialRing(R, names_groundset + names_flats) #self.ring() + except ValueError: #variables are not proper names poly_ring = PolynomialRing(R, 'A', len(E) + len(self._flats)) for i,x in enumerate(E): self._flats_generator[x] = poly_ring.gens()[i] @@ -417,14 +419,14 @@ def _gens_constructor(self, poly_ring): for F in self._flats: for G in self._flats: if not (F < G or G < F): - Q.append(self._flats_generator[F] * self._flats_generator[G]) + Q.append(self._flats_generator[F] * self._flats_generator[G]) #Quadratic Generators L = list() for x in E: term = poly_ring.zero() for F in self._flats: if F not in flats_containing[x]: term += self._flats_generator[F] - L.append(self._flats_generator[x] - term) + L.append(self._flats_generator[x] - term) #Linear Generators return Q + L def _repr_(self): @@ -445,10 +447,12 @@ def groebner_basis(self): EXAMPLES:: - sage: ch = matroids.catalog.Fano().chow_ring(QQ, True, 'fy') - sage: ch.groebner_basis() - Polynomial Sequence with 1400 Polynomials in 10 Variables - sage: ch.groebner_basis().is_groebner() + sage: ch = matroids.Uniform(2,5).chow_ring(QQ, True, 'fy') + sage: ch.defining_ideal().groebner_basis() + Polynomial Sequence with 250 Polynomials in 10 Variables + sage: ch.defining_ideal().groebner_basis().is_groebner() + True + sage: ch.defining_ideal().basis_is_groebner() True """ gb = [] @@ -456,7 +460,7 @@ def groebner_basis(self): poly_ring = self.ring() for F in self._flats: for G in self._flats: - if not (F < G or G < F): #5.2 + if not (F < G or G < F): #Non-nested flats gb.append(self._flats_generator[F]*self._flats_generator[G]) for i in E: term = poly_ring.zero() @@ -471,14 +475,14 @@ def groebner_basis(self): if term1 != poly_ring.zero(): gb.append(term1**(self._matroid.rank(G)) + 1) #5.6 - if i in G: #5.5 + if i in G: #if element in flat if term1 != poly_ring.zero(): gb.append(self._flats_generator[i]*((term1)**self._matroid.rank(G))) - elif not i in G: #5.3 + elif not i in G: #if element not in flat gb.append(self._flats_generator[i]*self._flats_generator[F]) - elif G < F: #5.4 + elif G < F: #nested flats gb.append(self._flats_generator[G]*term1**(self._matroid.rank(F)-self._matroid.rank(G))) g_basis = PolynomialSequence(poly_ring, [gb]) @@ -552,7 +556,7 @@ def __init__(self, M, R): sage: TestSuite(I).run(skip="_test_category") """ self._matroid = M - self._flats = [X for i in range(1, self._matroid.rank() + 1) + self._flats = [X for i in range(1, self._matroid.rank()) for X in self._matroid.flats(i)] E = list(self._matroid.groundset()) @@ -595,22 +599,22 @@ def _gens_constructor(self, poly_ring): """ E = list(self._matroid.groundset()) - Q = [] + Q = [] #Quadratic Generators flats_containing = {x: [] for x in E} for F in self._flats: for x in F: flats_containing[x].append(F) for F in self._flats: for G in self._flats: - if not (G > F or F > G): + if not (G > F or F > G): #generators for every pair of non-nested flats Q.append(self._flats_generator[F]*self._flats_generator[G]) - for x in E: + for x in E: #generators for every set of flats containing element term = poly_ring.zero() for H in flats_containing[x]: term += self._flats_generator[H] Q.append(term**2) - if F not in flats_containing[x]: + if F not in flats_containing[x]: #generators for every set of flats not containing element term = poly_ring.zero() for H in flats_containing[x]: term += self._flats_generator[H] @@ -640,22 +644,24 @@ def groebner_basis(self): sage: M1 = GraphicMatroid(graphs.CycleGraph(3)) sage: ch = M1.chow_ring(QQ, True, 'atom-free') - sage: ch.groebner_basis() + sage: ch.defining_ideal().groebner_basis() [A0^2, A0*A1, A0*A2, A0*A1, A1^2, A1*A2, A0*A2, A1*A2, A2^2] - sage: ch.groebner_basis().is_groebner() + sage: ch.defining_ideal().groebner_basis().is_groebner() + True + sage: ch.defining_ideal().basis_is_groebner() True """ gb = [] - flats = [X for i in range(1, self._matroid.rank() + 1) + flats = [X for i in range(1, self._matroid.rank()) for X in self._matroid.flats(i)] poly_ring = self.ring() - if frozenset() in flats: + if frozenset() in flats: #Non empty proper flats flats.remove(frozenset()) for F in flats: for G in flats: - if not (F > G or G > F): + if not (F > G or G > F): #Non nested flats gb.append(self._flats_generator[F]*self._flats_generator[G]) - elif F < G: + elif F < G: #Nested flats term = poly_ring.zero() for H in flats: if H < F: From 8b8ab5d496c90914ff7f7de24fc9920a1ee1c8b5 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Wed, 18 Sep 2024 09:50:27 +0530 Subject: [PATCH 196/537] Edited basis() method for augmented ChowRing (fy presentation) --- src/sage/matroids/chow_ring.py | 89 +++++++++++++++++++--------------- 1 file changed, 50 insertions(+), 39 deletions(-) diff --git a/src/sage/matroids/chow_ring.py b/src/sage/matroids/chow_ring.py index cd12ec00912..23272de19c2 100644 --- a/src/sage/matroids/chow_ring.py +++ b/src/sage/matroids/chow_ring.py @@ -10,10 +10,8 @@ from sage.rings.quotient_ring import QuotientRing_generic from sage.categories.graded_algebras_with_basis import GradedAlgebrasWithBasis from sage.categories.commutative_rings import CommutativeRings -from sage.sets.set import Set from sage.combinat.posets.posets import Poset -from sage.combinat.subset import Subsets -from itertools import product +from itertools import product, combinations class ChowRing(QuotientRing_generic): r""" @@ -111,7 +109,7 @@ def __init__(self, R, M, augmented, presentation=None): elif presentation == 'atom-free': self._ideal = AugmentedChowRingIdeal_atom_free(M, R) else: - self._ideal = ChowRingIdeal_nonaug(M, R) #check method to get ring + self._ideal = ChowRingIdeal_nonaug(M, R) C = CommutativeRings().Quotients() & GradedAlgebrasWithBasis(R).FiniteDimensional() QuotientRing_generic.__init__(self, R=self._ideal.ring(), I=self._ideal, names=self._ideal.ring().variable_names(), category=C) @@ -178,10 +176,9 @@ def basis(self): sage: ch = matroids.Wheel(3).chow_ring(ZZ, False) [A0*A013, 1] """ - flats = [X for i in range(1, self._matroid.rank() + 1) + flats = [X for i in range(1, self._matroid.rank()) for X in self._matroid.flats(i)] flats.append(frozenset()) - maximum_rank = max(self._matroid.rank(F) for F in flats) flats_gen = self._ideal.flats_generator() R = self._ideal.ring() flats = sorted(flats, key=lambda X: (len(X), sorted(X))) @@ -189,18 +186,22 @@ def basis(self): monomial_basis = [] if self._augmented is True: if self._presentation == 'fy': - for i in range(maximum_rank): - term = self._ideal.ring().one() - for j in range(len(flats)): - if j == 0: - if i <= ranks[0]: - if flats[j] in flats_gen: - term *= flats_gen[flats[j]]**(i + 1) - else: - if i < ranks[j] - ranks[j-1]: - if flats[j] in flats_gen: - term *= flats_gen[flats[j]]**(i + 1) - monomial_basis.append(term) + flats.remove(frozenset()) + max_powers = [] + max_powers[0] = ranks[flats[0]] + for i in range(1, len(flats)): + max_powers = ranks[flats[i]] - ranks[flats[i-1]] + for combination in product(*(range(p) for p in max_powers)): + expression = R.one() + for i in range(k): + expression *= flats_gen[subset[i]]**combination[i] + monomial_basis.append(expression) + max_powers.remove(ranks[flats[0]]) + for combination in product(*(range(p) for p in max_powers)): + expression = flats_gen[flats[0]]**ranks[flats[0]] + for i in range(k): + expression *= flats_gen[subset[i]]**combination[i] + monomial_basis.append(expression) elif self._presentation == 'atom-free': #all double equals need spacing first_rank = self._matroid.rank(flats[len(flats) - 1]) @@ -245,27 +246,37 @@ def generate_combinations(current_combination, index, max_powers, x_dict): else: R = self._ideal.ring() - lattice_flats = self._matroid.lattice_of_flats() - chains = lattice_flats.chains() - for chain in chains: - max_powers = [] - x_dict = dict() - for i in range(len(chain)): - if chain[i] == frozenset(): - max_powers.append(0) - x_dict[chain[i]] = 1 - elif i == 0: - max_powers.append(ranks[chain[i]]) - x_dict[chain[i]] = flats_gen[chain[i]] - else: - max_powers.append(ranks[chain[i]] - ranks[chain[i-1]]) - x_dict[chain[i]] = flats_gen[chain[i]] - k = len(chain) - for combination in product(*(range(p) for p in max_powers)): - expression = R.one() - for i in range(k): - expression *= x_dict[chain[i]]**combination[i] - monomial_basis.append(expression) + subsets = [] + # Generate all subsets of the frozenset using combinations + for r in range(len(flats) + 1): # r is the size of the subset + subsets.extend(list(subset) for subset in combinations(flats, r)) + for subset in subsets: + flag = True + sorted_list = sorted(subset, key=len) + for i in range (len(sorted_list)): + if (i != 0) & (len(sorted_list[i]) == len(sorted_list[i-1])): + flag = False + break + + if flag is True: + max_powers = [] + x_dict = dict() + for i in range(len(subset)): + if subset[i] == frozenset(): + max_powers.append(0) + x_dict[subset[i]] = 1 + elif i == 0: + max_powers.append(ranks[subset[i]]) + x_dict[subset[i]] = flats_gen[subset[i]] + else: + max_powers.append(ranks[subset[i]] - ranks[subset[i-1]]) + x_dict[subset[i]] = flats_gen[subset[i]] + k = len(subset) + for combination in product(*(range(p) for p in max_powers)): + expression = R.one() + for i in range(k): + expression *= x_dict[subset[i]]**combination[i] + monomial_basis.append(expression) from sage.sets.family import Family return Family([self.element_class(self, mon, reduce=False) for mon in monomial_basis]) From 91a757a29e89e3dcce325c789a704c4808665f30 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Wed, 18 Sep 2024 10:40:58 +0530 Subject: [PATCH 197/537] Edited basis() method for augmented Chow Ring (atom-free presentation) --- src/sage/matroids/chow_ring.py | 107 ++++++++++++++++----------------- 1 file changed, 53 insertions(+), 54 deletions(-) diff --git a/src/sage/matroids/chow_ring.py b/src/sage/matroids/chow_ring.py index 23272de19c2..1fbc10580cf 100644 --- a/src/sage/matroids/chow_ring.py +++ b/src/sage/matroids/chow_ring.py @@ -178,7 +178,6 @@ def basis(self): """ flats = [X for i in range(1, self._matroid.rank()) for X in self._matroid.flats(i)] - flats.append(frozenset()) flats_gen = self._ideal.flats_generator() R = self._ideal.ring() flats = sorted(flats, key=lambda X: (len(X), sorted(X))) @@ -186,66 +185,69 @@ def basis(self): monomial_basis = [] if self._augmented is True: if self._presentation == 'fy': - flats.remove(frozenset()) + flats.remove(frozenset()) #Non empty proper flats max_powers = [] max_powers[0] = ranks[flats[0]] for i in range(1, len(flats)): max_powers = ranks[flats[i]] - ranks[flats[i-1]] - for combination in product(*(range(p) for p in max_powers)): + for combination in product(*(range(p) for p in max_powers)): #Generating combinations for all powers up to max_powers expression = R.one() - for i in range(k): - expression *= flats_gen[subset[i]]**combination[i] - monomial_basis.append(expression) - max_powers.remove(ranks[flats[0]]) - for combination in product(*(range(p) for p in max_powers)): - expression = flats_gen[flats[0]]**ranks[flats[0]] - for i in range(k): + for i in range(len(flats)): expression *= flats_gen[subset[i]]**combination[i] monomial_basis.append(expression) + if combination[0] == 0: #Generating combinations for all powers including first max_powers + expression *= flats_gen[subset[0]]**max_powers[0] + monomial_basis.append(expression) - elif self._presentation == 'atom-free': #all double equals need spacing - first_rank = self._matroid.rank(flats[len(flats) - 1]) - reln = lambda p,q : p < q - P = Poset((flats, reln)) - chains = P.chains() - def generate_combinations(current_combination, index, max_powers, x_dict): - # Base case: If index equals the length of max_powers, print the current combination - if index == len(max_powers): - expression_terms = [x_dict[i+1] if current_combination[i] == 1 - else x_dict[i+1]**{current_combination[i]} - for i in range(len(current_combination)) if current_combination[i] != 0] - if expression_terms: - term = R.one() - for t in expression_terms: - term *= t - monomial_basis.append(term) - else: - monomial_basis.append(R.one()) - return - - # Recursive case: Iterate over the range for the current index - for power in range(max_powers[index]): - current_combination[index] = power - generate_combinations(current_combination, index + 1, max_powers, x_dict) - - for chain in chains: + elif self._presentation == 'atom-free': + subsets = [] + # Generate all subsets of the frozenset using combinations + for r in range(len(flats) + 1): # r is the size of the subset + subsets.extend(list(subset) for subset in combinations(flats, r)) + for subset in subsets: + flag = True + sorted_list = sorted(subset, key=len) + for i in range (len(sorted_list)): #Taking only chains + if (i != 0) & (len(sorted_list[i]) == len(sorted_list[i-1])): + flag = False + break + if flag is True: #For every chain + max_powers = [] x_dict = dict() - for i, F in enumerate(chain): - if F == frozenset(): - x_dict[i] = R.one() + k = len(subset) + for i in range(k-1): + if i == 0: + max_powers.append(ranks[subset[i]]) + x_dict[subset[i]] = flats_gen[subset[i]] else: - x_dict[i] = flats_gen[F] - ranks = [self._matroid.rank(F) for F in chain] - max_powers = [ranks[i-1] - ranks[i] for i in range(1, len(chain))] - k = len(chain) - current_combination = [0] * k - print(max_powers, k, x_dict, chain) - if sum(max_powers) == (first_rank + 1) and max_powers[len(chain) - 1] <= self._matroid.rank(chain[len(chain) - 1]): - generate_combinations(current_combination, 0, max_powers, x_dict) - + max_powers.append(ranks[subset[i]] - ranks[subset[i-1]]) + x_dict[subset[i]] = flats_gen[subset[i]] + x_dict[subset[k-1]] = flats_gen[subset[k-1]] + max_powers[k-1] = ranks[subset[k-1]] + first_rank = ranks[subset[0]] + 1 + last_rank = ranks[subset[k-1]] + for combination in product(*(range(1, p) for p in max_powers)): #Generating combinations for all powers from 1 to max_powers + expression = R.one() + if sum(combination) == first_rank: + for i in range(k): + expression *= x_dict[subset[i]]**combination[i] + monomial_basis.append(expression) + max_powers.remove(last_rank) + for combination in product(*(range(1, p) for p in max_powers)): #Generating all combinations including 0 power and max_power for first flat + expression = R.one() + if sum(combination) == first_rank: + for i in range(len(combination)): + expression *= x_dict[subset[i]]**combination[i] + monomial_basis.append(expression) + else: + expression *= x_dict[subset[k-1]]**last_rank + if sum(combination) + last_rank == first_rank: + for i in range(k): + expression *= x_dict[subset[i]]**combination[i] + monomial_basis.append(expression) - else: - R = self._ideal.ring() + else: + flats.remove(frozenset()) #Non empty proper flats subsets = [] # Generate all subsets of the frozenset using combinations for r in range(len(flats) + 1): # r is the size of the subset @@ -262,10 +264,7 @@ def generate_combinations(current_combination, index, max_powers, x_dict): max_powers = [] x_dict = dict() for i in range(len(subset)): - if subset[i] == frozenset(): - max_powers.append(0) - x_dict[subset[i]] = 1 - elif i == 0: + if i == 0: max_powers.append(ranks[subset[i]]) x_dict[subset[i]] = flats_gen[subset[i]] else: From 12c0d5f65bc75a812601eca48886687b862e8f08 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Wed, 18 Sep 2024 10:53:49 +0530 Subject: [PATCH 198/537] Added 'algorithm' parameter to all groebner_basis() methods --- src/sage/matroids/chow_ring_ideal.py | 236 ++++++++++++++------------- 1 file changed, 123 insertions(+), 113 deletions(-) diff --git a/src/sage/matroids/chow_ring_ideal.py b/src/sage/matroids/chow_ring_ideal.py index 026383c3982..c80ba21f5c2 100644 --- a/src/sage/matroids/chow_ring_ideal.py +++ b/src/sage/matroids/chow_ring_ideal.py @@ -202,7 +202,7 @@ def _repr_(self): """ return "Chow ring ideal of {}".format(self._matroid) - def groebner_basis(self): + def groebner_basis(self, algorithm='constructed'): r""" Returns the Groebner basis of the Chow ring ideal. Return type - ``PolynomialSequence``. @@ -228,66 +228,69 @@ def groebner_basis(self): sage: ch.groebner_basis().is_groebner() True """ - - flats = list(self._flats_generator) - gb = list() - R = self.ring() - if frozenset() in flats: - flats.remove(frozenset()) #Non-empty proper flats needed - - ranks = {F:self._matroid.rank(F) for F in flats} - - flats_gen = self._flats_generator - subsets = [] - # Generate all subsets of flats using combinations - for r in range(len(flats) + 1): # r is the size of the subset - subsets.extend(list(subset) for subset in combinations(flats, r)) - - for subset in subsets: - flag = True - sorted_list = sorted(subset, key=len) - for i in range (len(sorted_list)): #Checking whether the subset is a chain - if (i != 0) & (len(sorted_list[i]) == len(sorted_list[i-1])): - flag = False - break - - if flag is False: - term = R.one() - for x in subset: - term *= flats_gen[x] - gb.append(term) - - else: - if subset == []: - for F in flats: - term = R.zero() - for G in flats: - if G >= F: - term += flats_gen[G] - gb.append((term)**(ranks[F])) - + if algorithm == 'constructed': + flats = list(self._flats_generator) + gb = list() + R = self.ring() + if frozenset() in flats: + flats.remove(frozenset()) #Non-empty proper flats needed + + ranks = {F:self._matroid.rank(F) for F in flats} + + flats_gen = self._flats_generator + subsets = [] + # Generate all subsets of flats using combinations + for r in range(len(flats) + 1): # r is the size of the subset + subsets.extend(list(subset) for subset in combinations(flats, r)) + + for subset in subsets: + flag = True + sorted_list = sorted(subset, key=len) + for i in range (len(sorted_list)): #Checking whether the subset is a chain + if (i != 0) & (len(sorted_list[i]) == len(sorted_list[i-1])): + flag = False + break + + if flag is False: + term = R.one() + for x in subset: + term *= flats_gen[x] + gb.append(term) + else: - for j in range(len(subset)): - for k in range(j+1, len(subset)): #Checking if every element in the chain is maximal - if (sorted_list[j] != sorted_list[k]) & (sorted_list[j].issubset(sorted_list[k])): - flag = False - break - - if flag is True: + if subset == []: for F in flats: - if F > reduce(lambda a, b: a.union(b), sorted_list): - term = R.one() - for x in subset: - term *= flats_gen[x] - term1 = R.zero() - for G in flats: - if G >= F: - term1 += flats_gen[G] - if term1 != R.zero(): - gb.append(term*(term1**(ranks[F] - ranks[sorted_list[len(subset) - 1]]))) - - g_basis = PolynomialSequence(R, [gb]) - return g_basis + term = R.zero() + for G in flats: + if G >= F: + term += flats_gen[G] + gb.append((term)**(ranks[F])) + + else: + for j in range(len(subset)): + for k in range(j+1, len(subset)): #Checking if every element in the chain is maximal + if (sorted_list[j] != sorted_list[k]) & (sorted_list[j].issubset(sorted_list[k])): + flag = False + break + + if flag is True: + for F in flats: + if F > reduce(lambda a, b: a.union(b), sorted_list): + term = R.one() + for x in subset: + term *= flats_gen[x] + term1 = R.zero() + for G in flats: + if G >= F: + term1 += flats_gen[G] + if term1 != R.zero(): + gb.append(term*(term1**(ranks[F] - ranks[sorted_list[len(subset) - 1]]))) + + g_basis = PolynomialSequence(R, [gb]) + return g_basis + + elif algorithm == 'generic': + super().groebner_basis() class AugmentedChowRingIdeal_fy(ChowRingIdeal): @@ -440,7 +443,7 @@ def _repr_(self): """ return "Augmented Chow ring ideal of {} of Feitchner-Yuzvinsky presentation".format(self._matroid) - def groebner_basis(self): + def groebner_basis(self, algorithm='constructed'): r""" Returns the Groebner basis of the augmented Chow ring ideal. Return type - ``PolynomialSequence``. @@ -455,38 +458,41 @@ def groebner_basis(self): sage: ch.defining_ideal().basis_is_groebner() True """ - gb = [] - E = list(self._matroid.groundset()) - poly_ring = self.ring() - for F in self._flats: - for G in self._flats: - if not (F < G or G < F): #Non-nested flats - gb.append(self._flats_generator[F]*self._flats_generator[G]) - for i in E: - term = poly_ring.zero() - term1 = poly_ring.zero() - for H in self._flats: - if i in H: - term += self._flats_generator[H] - if H > G: - term1 += self._flats_generator[H] - if term != poly_ring.zero(): - gb.append(self._flats_generator[i] + term) #5.7 - if term1 != poly_ring.zero(): - gb.append(term1**(self._matroid.rank(G)) + 1) #5.6 - - if i in G: #if element in flat + if algorithm == 'constructed': + gb = [] + E = list(self._matroid.groundset()) + poly_ring = self.ring() + for F in self._flats: + for G in self._flats: + if not (F < G or G < F): #Non-nested flats + gb.append(self._flats_generator[F]*self._flats_generator[G]) + for i in E: + term = poly_ring.zero() + term1 = poly_ring.zero() + for H in self._flats: + if i in H: + term += self._flats_generator[H] + if H > G: + term1 += self._flats_generator[H] + if term != poly_ring.zero(): + gb.append(self._flats_generator[i] + term) #5.7 if term1 != poly_ring.zero(): - gb.append(self._flats_generator[i]*((term1)**self._matroid.rank(G))) - - elif not i in G: #if element not in flat - gb.append(self._flats_generator[i]*self._flats_generator[F]) - - elif G < F: #nested flats - gb.append(self._flats_generator[G]*term1**(self._matroid.rank(F)-self._matroid.rank(G))) - - g_basis = PolynomialSequence(poly_ring, [gb]) - return g_basis + gb.append(term1**(self._matroid.rank(G)) + 1) #5.6 + + if i in G: #if element in flat + if term1 != poly_ring.zero(): + gb.append(self._flats_generator[i]*((term1)**self._matroid.rank(G))) + + elif not i in G: #if element not in flat + gb.append(self._flats_generator[i]*self._flats_generator[F]) + + elif G < F: #nested flats + gb.append(self._flats_generator[G]*term1**(self._matroid.rank(F)-self._matroid.rank(G))) + + g_basis = PolynomialSequence(poly_ring, [gb]) + return g_basis + elif algorithm == 'generic': + super().groebner_basis() class AugmentedChowRingIdeal_atom_free(ChowRingIdeal): r""" @@ -633,7 +639,7 @@ def _repr_(self): """ return "Augmented Chow ring ideal of {} of atom-free presentation".format(self._matroid) - def groebner_basis(self): + def groebner_basis(self, algorithm='constructed'): """ Returns the Groebner basis of the augmented Chow ring ideal. Return type - ``PolynomialSequence``. @@ -651,27 +657,31 @@ def groebner_basis(self): sage: ch.defining_ideal().basis_is_groebner() True """ - gb = [] - flats = [X for i in range(1, self._matroid.rank()) - for X in self._matroid.flats(i)] - poly_ring = self.ring() - if frozenset() in flats: #Non empty proper flats - flats.remove(frozenset()) - for F in flats: - for G in flats: - if not (F > G or G > F): #Non nested flats - gb.append(self._flats_generator[F]*self._flats_generator[G]) - elif F < G: #Nested flats - term = poly_ring.zero() - for H in flats: - if H < F: - term += self._flats_generator[H] - if term != poly_ring.zero(): - gb.append(self._flats_generator[F]*(term**self._matroid.rank(G))* - (term**(self._matroid.rank(G)-self._matroid.rank(F)))) - - g_basis = PolynomialSequence(poly_ring, [gb]) - return g_basis + if algorithm == 'constructed': + gb = [] + flats = [X for i in range(1, self._matroid.rank()) + for X in self._matroid.flats(i)] + poly_ring = self.ring() + if frozenset() in flats: #Non empty proper flats + flats.remove(frozenset()) + for F in flats: + for G in flats: + if not (F > G or G > F): #Non nested flats + gb.append(self._flats_generator[F]*self._flats_generator[G]) + elif F < G: #Nested flats + term = poly_ring.zero() + for H in flats: + if H < F: + term += self._flats_generator[H] + if term != poly_ring.zero(): + gb.append(self._flats_generator[F]*(term**self._matroid.rank(G))* + (term**(self._matroid.rank(G)-self._matroid.rank(F)))) + + g_basis = PolynomialSequence(poly_ring, [gb]) + return g_basis + + elif algorithm == 'generic': + super().groebner_basis() From 87cd7bc63efbb8fbf2be584f0d07830c49800115 Mon Sep 17 00:00:00 2001 From: Verrel Rievaldo Wijaya Date: Wed, 18 Sep 2024 22:03:46 +0700 Subject: [PATCH 199/537] Add more examples for dual subdivision --- .../rings/semirings/tropical_mpolynomial.py | 63 +++++++++++++++++-- src/sage/rings/semirings/tropical_variety.py | 4 +- 2 files changed, 59 insertions(+), 8 deletions(-) diff --git a/src/sage/rings/semirings/tropical_mpolynomial.py b/src/sage/rings/semirings/tropical_mpolynomial.py index 2e62f11b05a..0935508339d 100644 --- a/src/sage/rings/semirings/tropical_mpolynomial.py +++ b/src/sage/rings/semirings/tropical_mpolynomial.py @@ -148,6 +148,23 @@ class TropicalMPolynomial(MPolynomial_polydict): p1 = R(3)*a*b + a + R(-1)*b sphinx_plot(p1.plot3d()) + Another way to represent tropical curve is through dual subdivision, + which is a subdivision of Newton polytope of tropical polynomial:: + + sage: p1.Newton_polytope() + A 2-dimensional polyhedron in ZZ^2 defined as the convex hull of 3 vertices + sage: p1.dual_subdivision() + Polyhedral complex with 1 maximal cell + + .. PLOT:: + :width: 300 px + + T = TropicalSemiring(QQ, use_min=False) + R = PolynomialRing(T, ('a,b')) + a, b = R.gen(), R.gen(1) + p1 = R(3)*a*b + a + R(-1)*b + sphinx_plot(p1.dual_subdivision().plot()) + TESTS: There is no subtraction defined for tropical polynomials:: @@ -388,7 +405,7 @@ def tropical_variety(self): return TropicalSurface(self) return TropicalVariety(self) - def polytope(self): + def Newton_polytope(self): """ Return the Newton polytope of ``self``. @@ -400,12 +417,12 @@ def polytope(self): EXAMPLES: - Newton polytope for two variable tropical polynomial:: + Newton polytope for a two-variable tropical polynomial:: sage: T = TropicalSemiring(QQ) sage: R. = PolynomialRing(T) sage: p1 = x + y - sage: p1.polytope() + sage: p1.Newton_polytope() A 1-dimensional polyhedron in ZZ^2 defined as the convex hull of 2 vertices .. PLOT:: @@ -415,14 +432,14 @@ def polytope(self): R = PolynomialRing(T, ('x,y')) x, y = R.gen(), R.gen(1) p1 = x + y - sphinx_plot(p1.polytope().plot()) + sphinx_plot(p1.Newton_polytope().plot()) Newton polytope in three dimension:: sage: T = TropicalSemiring(QQ) sage: R. = PolynomialRing(T) sage: p1 = x^2 + x*y*z + x + y + z + R(0) - sage: p1.polytope() + sage: p1.Newton_polytope() A 3-dimensional polyhedron in ZZ^3 defined as the convex hull of 5 vertices .. PLOT:: @@ -432,7 +449,7 @@ def polytope(self): R = PolynomialRing(T, ('x,y,z')) x, y, z = R.gen(), R.gen(1), R.gen(2) p1 = x**2 + x*y*z + x + y + z + R(0) - sphinx_plot(p1.polytope().plot()) + sphinx_plot(p1.Newton_polytope().plot()) """ from sage.geometry.polyhedron.constructor import Polyhedron @@ -472,6 +489,40 @@ def dual_subdivision(self): p1 = R(3) + R(2)*x + R(2)*y + R(3)*x*y + x**2 + y**2 sphinx_plot(p1.dual_subdivision().plot()) + A subdivision of a pentagonal Newton polytope:: + + sage: p2 = R(3) + x^2 + R(-2)*y + R(1/2)*x^2*y + R(2)*x*y^3 + R(-1)*x^3*y^4 + sage: p2.dual_subdivision() + Polyhedral complex with 5 maximal cells + + .. PLOT:: + :width: 300 px + + T = TropicalSemiring(QQ, use_min=False) + R = PolynomialRing(T, ('x,y')) + x, y = R.gen(), R.gen(1) + p2 = R(3) + x**2 + R(-2)*y + R(1/2)*x**2*y + R(2)*x*y**3 + R(-1)*x**3*y**4 + sphinx_plot(p2.dual_subdivision().plot()) + + A subdivision with many faces, not all of which are triangles:: + + sage: p3 = R(8) + R(4)*x + R(2)*y + R(1)*x^2 + x*y + R(1)*y^2 \ + ....: + R(2)*x^3 + x^2*y + x*y^2 + R(4)*y^3 + R(8)*x^4 \ + ....: + R(4)*x^3*y + x^2*y^2 + R(2)*x*y^3 + y^4 + sage: p3.dual_subdivision().plot() + Graphics object consisting of 10 graphics primitives + + .. PLOT:: + :width: 300 px + + T = TropicalSemiring(QQ, use_min=False) + R = PolynomialRing(T, ('x,y')) + x, y = R.gen(), R.gen(1) + p3 = R(8) + R(4)*x + R(2)*y + R(1)*x**2 + x*y + R(1)*y**2 \ + + R(2)*x**3 + x**2*y + x*y**2 + R(4)*y**3 + R(8)*x**4 \ + + R(4)*x**3*y + x**2*y**2 + R(2)*x*y**3 + y**4 + sphinx_plot(p3.dual_subdivision().plot()) + Dual subdivision of a tropical surface:: sage: T = TropicalSemiring(QQ) diff --git a/src/sage/rings/semirings/tropical_variety.py b/src/sage/rings/semirings/tropical_variety.py index 96817231b95..a3ed0676b47 100644 --- a/src/sage/rings/semirings/tropical_variety.py +++ b/src/sage/rings/semirings/tropical_variety.py @@ -598,9 +598,9 @@ def weight_vectors(self): 3: ((u3 - 22/3, u2, u3 - 10/3, u3), {u3 - 7/3 <= u2})}, {0: [0, 2, 4], 1: [0, 1, 3], 2: [1, 2, 5], 3: [3, 4, 5]}, {0: [(0, -1, -1, 2), (0, -1, 2, -1), (0, 2, -1, -1)], - 1: [(2, -1, -1, 0), (-3, 3, 0, 0), (1, -2, 1, 0)], + 1: [(-2, 1, 1, 0), (3, -3, 0, 0), (-1, 2, -1, 0)], 2: [(1, -5, -2, 6), (-2, -1, 4, -1), (1, 6, -2, -5)], - 3: [(1, 0, 1, -2), (2, 0, -1, -1), (-3, 0, 0, 3)]}) + 3: [(-1, 0, -1, 2), (-2, 0, 1, 1), (3, 0, 0, -3)]}) """ from sage.symbolic.ring import SR from sage.symbolic.relation import solve From 204a525ee1b4c01130ce15cf47c7bc72d02b84b7 Mon Sep 17 00:00:00 2001 From: Verrel Rievaldo Wijaya Date: Sun, 22 Sep 2024 11:11:57 +0700 Subject: [PATCH 200/537] Fix lint error --- src/sage/rings/semirings/tropical_mpolynomial.py | 6 +++--- src/sage/rings/semirings/tropical_variety.py | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/sage/rings/semirings/tropical_mpolynomial.py b/src/sage/rings/semirings/tropical_mpolynomial.py index 812fc1bc516..48323fadaf2 100644 --- a/src/sage/rings/semirings/tropical_mpolynomial.py +++ b/src/sage/rings/semirings/tropical_mpolynomial.py @@ -164,7 +164,7 @@ class TropicalMPolynomial(MPolynomial_polydict): R = PolynomialRing(T, ('a,b')) a, b = R.gen(), R.gen(1) p1 = R(3)*a*b + a + R(-1)*b - sphinx_plot(p1.dual_subdivision().plot()) + sphinx_plot(p1.dual_subdivision().plot()) TESTS: @@ -494,7 +494,7 @@ def dual_subdivision(self): sage: p2 = R(3) + x^2 + R(-2)*y + R(1/2)*x^2*y + R(2)*x*y^3 + R(-1)*x^3*y^4 sage: p2.dual_subdivision() Polyhedral complex with 5 maximal cells - + .. PLOT:: :width: 300 px @@ -503,7 +503,7 @@ def dual_subdivision(self): x, y = R.gen(), R.gen(1) p2 = R(3) + x**2 + R(-2)*y + R(1/2)*x**2*y + R(2)*x*y**3 + R(-1)*x**3*y**4 sphinx_plot(p2.dual_subdivision().plot()) - + A subdivision with many faces, not all of which are triangles:: sage: p3 = R(8) + R(4)*x + R(2)*y + R(1)*x^2 + x*y + R(1)*y^2 \ diff --git a/src/sage/rings/semirings/tropical_variety.py b/src/sage/rings/semirings/tropical_variety.py index 4c4dacbe1d9..6d0342a3d74 100644 --- a/src/sage/rings/semirings/tropical_variety.py +++ b/src/sage/rings/semirings/tropical_variety.py @@ -593,9 +593,9 @@ def weight_vectors(self): 3: ((u3 - 22/3, u2, u3 - 10/3, u3), {u3 - 7/3 <= u2})}, {0: [0, 2, 4], 1: [0, 1, 3], 2: [1, 2, 5], 3: [3, 4, 5]}, {0: [(0, -1, -1, 2), (0, -1, 2, -1), (0, 2, -1, -1)], - 1: [(-2, 1, 1, 0), (3, -3, 0, 0), (-1, 2, -1, 0)], + 1: [(2, -1, -1, 0), (-3, 3, 0, 0), (1, -2, 1, 0)], 2: [(1, -5, -2, 6), (-2, -1, 4, -1), (1, 6, -2, -5)], - 3: [(-1, 0, -1, 2), (-2, 0, 1, 1), (3, 0, 0, -3)]}) + 3: [(1, 0, 1, -2), (2, 0, -1, -1), (-3, 0, 0, 3)]}) """ from sage.symbolic.ring import SR from sage.symbolic.relation import solve From 369db7f88d215062a4f072aab97298eb274a0305 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Mon, 23 Sep 2024 12:01:31 +0530 Subject: [PATCH 201/537] Edited and formatted doctests --- src/sage/matroids/chow_ring_ideal.py | 180 +++++++++++---------------- 1 file changed, 73 insertions(+), 107 deletions(-) diff --git a/src/sage/matroids/chow_ring_ideal.py b/src/sage/matroids/chow_ring_ideal.py index c80ba21f5c2..66107410070 100644 --- a/src/sage/matroids/chow_ring_ideal.py +++ b/src/sage/matroids/chow_ring_ideal.py @@ -51,22 +51,7 @@ def flats_generator(self): class ChowRingIdeal_nonaug(ChowRingIdeal): r""" - The Chow ring ideal. - Returns the Chow ring ideal over ring `R` of matroid `M`. - - INPUT: - - - `M` -- a matroid - - `R` -- a commutative ring - - OUTPUT: Chow ring ideal of matroid `M` - - These are the classes of Chow ring ideals for matroids. There are three classes - created - Chow ring ideal and augmented Chow ring ideal. The augmented - Chow ring ideal has two different presentations implemented - the Feitchner- - Yuzvinsky presentation and atom-free presentation. Both classes have - ``grobner_basis()`` methods as well, as an explicit Groebner basis is known - in each case. + The Chow ring ideal of a matroid `M`. The Chow ring ideal is defined over a polynomial ring for a matroid `M`: @@ -74,30 +59,32 @@ class ChowRingIdeal_nonaug(ChowRingIdeal): R[x_{F_1}, \ldots, x_{F_k}] - as - - ..MATH:: - - (Q_M + L_M) + as `(Q_M + L_M)` - where + where - - `F_1, \ldots, F_k` are the non-empty proper flats of `M`, - - `Q_M` is the ideal generated by all `x_{F_i} x_{F_j}` where - `F_i` and `F_j` are incomparable elements in the lattice of - flats, and - - `L_M` is the ideal generated by all linear forms + - `F_1, \ldots, F_k` are the non-empty proper flats of `M`, + - `Q_M` is the ideal generated by all `x_{F_i} x_{F_j}` where + `F_i` and `F_j` are incomparable elements in the lattice of + flats, and + - `L_M` is the ideal generated by all linear forms .. MATH:: \sum_{i_1 \in F} x_F - \sum_{i_2 \in F} x_F - for all `i_1 \neq i_2 \in E`. + for all `i_1 \neq i_2 \in E`. + + INPUT: + + - `M` -- a matroid + - `R` -- a commutative ring + + OUTPUT: Chow ring ideal of matroid `M` - REFERENCES + REFERENCES: - [ANR2023]_ - - [MM2022]_ EXAMPLES: @@ -202,19 +189,18 @@ def _repr_(self): """ return "Chow ring ideal of {}".format(self._matroid) - def groebner_basis(self, algorithm='constructed'): + def groebner_basis(self, algorithm='constructed'): #can you reduce it? - consider every antichain of size 2, and chains? r""" Returns the Groebner basis of the Chow ring ideal. - Return type - ``PolynomialSequence``. EXAMPLES:: sage: from sage.matroids.basis_matroid import BasisMatroid sage: ch = BasisMatroid(groundset='abc', bases=['ab', 'ac'])).chow_ring(QQ, False) - sage: ch.groebner_basis() + sage: ch.defining_ideal().groebner_basis(algorithm='') [Aa, Abc] - sage: ch.groebner_basis().is_groebner() + sage: ch.defining_ideal().groebner_basis(algorithm='').is_groebner() True Another example would be the Groebner basis of the Chow ring ideal of @@ -223,12 +209,12 @@ def groebner_basis(self, algorithm='constructed'): sage: from sage.matroids.graphic_matroid import GraphicMatroid sage: ch = GraphicMatroid(graphs.CycleGraph(3)).chow_ring(QQ, False) - sage: ch.groebner_basis() + sage: ch.defining_ideal().groebner_basis(algorithm='') [A0, A1, A2, A0*A1, A0*A2, A1*A2, A0*A1*A2] - sage: ch.groebner_basis().is_groebner() + sage: ch.defining_ideal().groebner_basis(algorithm='').is_groebner() True """ - if algorithm == 'constructed': + if algorithm == '': flats = list(self._flats_generator) gb = list() R = self.ring() @@ -251,7 +237,7 @@ def groebner_basis(self, algorithm='constructed'): flag = False break - if flag is False: + if not flag: term = R.one() for x in subset: term *= flats_gen[x] @@ -273,7 +259,7 @@ def groebner_basis(self, algorithm='constructed'): flag = False break - if flag is True: + if flag: for F in flats: if F > reduce(lambda a, b: a.union(b), sorted_list): term = R.one() @@ -289,52 +275,49 @@ def groebner_basis(self, algorithm='constructed'): g_basis = PolynomialSequence(R, [gb]) return g_basis - elif algorithm == 'generic': + elif algorithm == 'constructed': #*args **kwds super().groebner_basis() class AugmentedChowRingIdeal_fy(ChowRingIdeal): r""" - The class of augmented Chow ring ideal of Feitchner-Yuzvinsky - presentation, a multi-polynomial ideal. - Base class - ``MPolynomialIdeal``. - - INPUT: - - - - `M` -- a matroid - - `R` -- a commutative ring + The augmented Chow ring ideal of matroid `M` over ring `R` in + Feitchner-Yuzvinsky presentation. - OUTPUT: augmented Chow ring ideal of matroid `M` of Feitchner-Yuzvinsky - presentation. - - The augmented Chow ring ideal of Feitchner-Yuzvinsky presentation is defined - over the following polynomial ring: + The augmented Chow ring ideal of Feitchner-Yuzvinsky presentation + is defined over the following polynomial ring: ..MATH:: R[y_{e_1}, \ldots, y_{e_n}, x_{F_1}, \ldots, x_{F_k}] - as + as `(I_M + J_M)` where + + - `F_1, \ldots, F_k` are the non-empty proper flats of `M`, + - `e_1 \ldots, e_n` are `n` elements of groundset of `M`, + - `J_M` is the ideal generated by all quadratic forms `x_{F_i} x_{F_j}` + where `F_i` and `F_j` are incomparable elements in the lattice of + flats, and `y_{i} x_F` for every `i \in E` and `i \notin F`, and + - `I_M` is the ideal generated by all linear forms ..MATH:: - (I_M + J_M) + y_i - \sum_{i \notin F} x_F - where + for all `i \in E`. + + REFERENCES: - - `F_1, \ldots, F_k` are the non-empty proper flats of `M`, - - `e_1 \ldots, e_n` are `n` elements of groundset of `M`, - - `J_M` is the ideal generated by all quadratic forms `x_{F_i} x_{F_j}` - where `F_i` and `F_j` are incomparable elements in the lattice of - flats, and `y_{i} x_F` for every `i \in E` and `i \notin F`, and - - `I_M` is the ideal generated by all linear forms + - [MM2022]_ + + INPUT: - ..MATH:: - y_i - \sum_{i \notin F} x_F + - `M` -- a matroid + - `R` -- a commutative ring - for all `i \in E`. + OUTPUT: augmented Chow ring ideal of matroid `M` of Feitchner-Yuzvinsky + presentation EXAMPLES:: @@ -344,10 +327,6 @@ class AugmentedChowRingIdeal_fy(ChowRingIdeal): sage: ch Augmented Chow ring ideal of Wheel(3): Regular matroid of rank 3 on 6 elements with 16 bases of Feitchner-Yuzvinsky presentation - - REFERENCES - - - [MM2022]_ """ def __init__(self, M, R): r""" @@ -446,19 +425,16 @@ def _repr_(self): def groebner_basis(self, algorithm='constructed'): r""" Returns the Groebner basis of the augmented Chow ring ideal. - Return type - ``PolynomialSequence``. EXAMPLES:: sage: ch = matroids.Uniform(2,5).chow_ring(QQ, True, 'fy') - sage: ch.defining_ideal().groebner_basis() + sage: ch.defining_ideal().groebner_basis(algorithm='') Polynomial Sequence with 250 Polynomials in 10 Variables - sage: ch.defining_ideal().groebner_basis().is_groebner() - True - sage: ch.defining_ideal().basis_is_groebner() + sage: ch.defining_ideal().groebner_basis(algorithm='').is_groebner() True """ - if algorithm == 'constructed': + if algorithm == '': gb = [] E = list(self._matroid.groundset()) poly_ring = self.ring() @@ -491,20 +467,12 @@ def groebner_basis(self, algorithm='constructed'): g_basis = PolynomialSequence(poly_ring, [gb]) return g_basis - elif algorithm == 'generic': + elif algorithm == 'constructed': super().groebner_basis() class AugmentedChowRingIdeal_atom_free(ChowRingIdeal): r""" - The augmented Chow ring ideal in the atom-free - presentation. - - INPUT: - - - ``M`` -- a matroid - - ``R`` -- a commutative ring - - OUTPUT: augmented Chow ring ideal of matroid `M` of atom-free + The augmented Chow ring ideal of matroid `M` over ring `R` in the atom-free presentation. The augmented Chow ring ideal for the atom-free presentation is defined @@ -514,13 +482,7 @@ class AugmentedChowRingIdeal_atom_free(ChowRingIdeal): R[x_{F_1}, \ldots, x_{F_k}] - as - - ..MATH:: - - I_{af}(M) - - where + as `I_{af}(M)` where - `F_1, \ldots, F_k` are the non-empty proper flats of `M`, - `I_{af }M` is the ideal generated by all quadratic forms `x_{F_i} x_{F_j}` @@ -531,13 +493,24 @@ class AugmentedChowRingIdeal_atom_free(ChowRingIdeal): x_F \sum_{i \in F'} x_{F'} - for all `i \in E` and `i \notin F`, and + for all `i \in E` and `i \notin F`, and ..MATH:: \sum_{i \in F'} (x_{F'})^2 - for all `i \in E`. + for all `i \in E`. + + REFERENCES: + + - [MM2022]_ + + INPUT: + + - ``M`` -- a matroid + - ``R`` -- a commutative ring + + OUTPUT: augmented Chow ring ideal of matroid `M` of atom-free presentation EXAMPLES: @@ -547,10 +520,6 @@ class AugmentedChowRingIdeal_atom_free(ChowRingIdeal): sage: ch Augmented Chow ring ideal of Wheel(3): Regular matroid of rank 3 on 6 elements with 16 bases of atom-free presentation - - REFERENCES - - - [MM2022]_ """ def __init__(self, M, R): r""" @@ -586,7 +555,7 @@ def __init__(self, M, R): def _gens_constructor(self, poly_ring): r""" Return the generators of augmented Chow ring ideal of - atom-free presentation. Takes in the ring of that augmented + atom-free presentation. Takes in the ring of the augmented Chow ring ideal as input. EXAMPLES:: @@ -642,7 +611,6 @@ def _repr_(self): def groebner_basis(self, algorithm='constructed'): """ Returns the Groebner basis of the augmented Chow ring ideal. - Return type - ``PolynomialSequence``. EXAMPLES:: @@ -650,14 +618,12 @@ def groebner_basis(self, algorithm='constructed'): sage: M1 = GraphicMatroid(graphs.CycleGraph(3)) sage: ch = M1.chow_ring(QQ, True, 'atom-free') - sage: ch.defining_ideal().groebner_basis() + sage: ch.defining_ideal().groebner_basis(algorithm='') [A0^2, A0*A1, A0*A2, A0*A1, A1^2, A1*A2, A0*A2, A1*A2, A2^2] - sage: ch.defining_ideal().groebner_basis().is_groebner() - True - sage: ch.defining_ideal().basis_is_groebner() + sage: ch.defining_ideal().groebner_basis(algorithm='').is_groebner() True """ - if algorithm == 'constructed': + if algorithm == '': gb = [] flats = [X for i in range(1, self._matroid.rank()) for X in self._matroid.flats(i)] @@ -680,7 +646,7 @@ def groebner_basis(self, algorithm='constructed'): g_basis = PolynomialSequence(poly_ring, [gb]) return g_basis - elif algorithm == 'generic': + elif algorithm == 'constructed': super().groebner_basis() From 54276307c329fd3c1ef213c02c99fe3e1b63b4ce Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Mon, 23 Sep 2024 12:01:57 +0530 Subject: [PATCH 202/537] Edited and formatted doctests for the Chow ring class --- src/sage/matroids/chow_ring.py | 84 +++++++++++++--------------------- 1 file changed, 32 insertions(+), 52 deletions(-) diff --git a/src/sage/matroids/chow_ring.py b/src/sage/matroids/chow_ring.py index 1fbc10580cf..32816a36890 100644 --- a/src/sage/matroids/chow_ring.py +++ b/src/sage/matroids/chow_ring.py @@ -15,78 +15,58 @@ class ChowRing(QuotientRing_generic): r""" - The class of Chow ring, a multi-polynomial quotient ring. + The Chow ring of a matroid. - INPUT: - - - - `M` -- a matroid - - `R` -- a commutative ring - - ``augmented`` -- a Boolean value. When ``True``, it returns the augmented - Chow ring. If ``False``, it returns the Chow ring - - ``presentation`` -- a string literal. Takes in the presentation of - augmented Chow ring (`fy` or `atom-free`). Default value `None` - - OUTPUT: Chow ring of matroid `M` - - These are the classes of Chow rings for matroids. It also takes in - a parameter boolean ``augmented`` which creates the augmented Chow - ring if given ``True``. - - The Chow ring of a matroid is defined as the quotient ring: + The *Chow ring of a matroid* `M` is defined as the quotient ring: .. MATH:: A^*(M)_R := R[x_{F_1}, \ldots, x_{F_k}] / (Q_M + L_M) - where - - ..MATH:: - - (Q_M + L_M) - - is the Chow ring ideal of matroid `M`. + where `(Q_M + L_M)` is the Chow ring ideal of matroid `M`. - The augmented Chow ring of matroid `M` of Feitchner-Yuzvinsky presentation + The *augmented Chow ring of matroid* `M` in the Feitchner-Yuzvinsky presentation is the quotient ring: ..MATH:: A(M)_R := R[y_{e_1}, \ldots, y_{e_n}, x_{F_1}, \ldots, x_{F_k}] / (I_M + J_M) - where - - ..MATH:: - - (I_M + J_M) + where `(I_M + J_M)` is the augmented Chow ring ideal of matroid `M` + of Feitchner-Yuzvinsky presentation. - is the augmented Chow ring ideal of matroid `M` of Feitchner-Yuzvinsky - presentation. - - The augmented Chow ring of atom-free presentation is the quotient ring: + The *augmented Chow ring of atom-free presentation* is the quotient ring: ..MATH:: A(M)_R := R[x_{F_1}, \ldots, x_{F_k}] / I_{af}M - where - - I_{af}M - - is the augmented Chow ring ideal of matroid `M` of atom-free presentation. + where `I_{af}M` is the augmented Chow ring ideal of matroid `M` of atom-free presentation. .. SEEALSO:: - :mod: sage.matroids.chow_ring_ideal + :mod:`sage.matroids.chow_ring_ideal` + + INPUT: + + - `M` -- a matroid + - `R` -- a commutative ring + - ``augmented`` -- boolean; when ``True``, this is the augmented + Chow ring and if ``False``, this is the non-augmented Chow ring + - ``presentation`` -- string (default: ``None``); one of the following: + + * ``"fy"`` - Feitchner-Yuzvinsky presentation* + * ``"atom-free" - Atom-free presentation* + REFERENCES: - - [FY2004]_ - - [AHK2015]_ + - [FY2004]_ + - [AHK2015]_ EXAMPLES:: - sage: M1 = matroids.catalog.P8pp() + sage: M1 = matroids.catalog.P8pp() #more examples sage: ch = M1.chow_ring(QQ, False) sage: ch Chow ring of P8'': Matroid of rank 4 on 8 elements with 8 nonspanning circuits @@ -97,8 +77,8 @@ def __init__(self, R, M, augmented, presentation=None): EXAMPLES:: - sage: I = matroids.Wheel(3).chow_ring(QQ, False) - sage: TestSuite(I).run() + sage: ch = matroids.Wheel(3).chow_ring(QQ, False) + sage: TestSuite(ch).run() """ self._matroid = M self._augmented = augmented @@ -117,10 +97,10 @@ def _repr_(self): r""" EXAMPLES:: - sage: M1 = matroids.catalog.Fano() - sage: ch = M1.chow_ring(QQ, False) - sage: ch - Chow ring of Fano: Binary matroid of rank 3 on 7 elements, type (3, 0) + sage: M1 = matroids.catalog.Fano() + sage: ch = M1.chow_ring(QQ, False) + sage: ch + Chow ring of Fano: Binary matroid of rank 3 on 7 elements, type (3, 0) """ if self._augmented is True: if self._presentation == 'fy': @@ -290,7 +270,7 @@ def to_vector(self, order=None): sage: ch = matroids.Uniform(3, 6).chow_ring(QQ, False) sage: v = ch.an_element(); v A0 - sage: v.to_vector() #Error in output! + sage: v.to_vector() """ P = self.parent() @@ -310,7 +290,7 @@ def monomial_coefficients(self, copy=None): sage: ch = matroids.catalog.NonFano().chow_ring(QQ, True, 'fy') sage: v = ch.an_element(); v 0 - sage: v.monomial_coefficients() #error in output! + sage: v.monomial_coefficients() """ B = self.parent().basis() From 4e6419a93694f5ce6692625afade8854877b3234 Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Mon, 23 Sep 2024 12:12:52 +0200 Subject: [PATCH 203/537] fix domain bug in group_and_partition, add cycle_index --- src/sage/rings/species.py | 52 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 50 insertions(+), 2 deletions(-) diff --git a/src/sage/rings/species.py b/src/sage/rings/species.py index cac26cdd404..4cb80118ae1 100644 --- a/src/sage/rings/species.py +++ b/src/sage/rings/species.py @@ -2,12 +2,16 @@ from sage.categories.graded_algebras_with_basis import GradedAlgebrasWithBasis from sage.categories.infinite_enumerated_sets import InfiniteEnumeratedSets +from sage.categories.modules import Modules from sage.categories.monoids import Monoids from sage.categories.sets_cat import cartesian_product from sage.categories.sets_with_grading import SetsWithGrading +from sage.categories.tensor import tensor from sage.combinat.free_module import CombinatorialFreeModule from sage.combinat.integer_vector import IntegerVectors -from sage.combinat.partition import Partitions +from sage.combinat.partition import Partitions, _Partitions +from sage.combinat.sf.sf import SymmetricFunctions +from sage.rings.integer_ring import ZZ from sage.groups.perm_gps.constructor import PermutationGroupElement from sage.groups.perm_gps.permgroup import PermutationGroup, PermutationGroup_generic from sage.groups.perm_gps.permgroup_named import SymmetricGroup @@ -16,6 +20,7 @@ from sage.modules.free_module_element import vector from sage.monoids.indexed_free_monoid import (IndexedFreeAbelianMonoid, IndexedFreeAbelianMonoidElement) +from sage.rings.rational_field import QQ from sage.rings.integer_ring import ZZ from sage.structure.category_object import normalize_names from sage.structure.element import Element, parent @@ -1021,6 +1026,7 @@ def group_and_partition(self): TESTS:: + sage: M = MolecularSpecies("X,Y") sage: B = M(PermutationGroup([(1,2,3)]), {0: [1,2,3]}) sage: B.group_and_partition() (Permutation Group with generators [(1,2,3)], @@ -1043,6 +1049,10 @@ def group_and_partition(self): sage: F = M(SymmetricGroup(1)) * M(SymmetricGroup(2)) sage: F.group_and_partition() (Permutation Group with generators [(2,3)], (frozenset({1, 2, 3}),)) + + sage: F = M(PermutationGroup([(1,2),(3,)])) + sage: F.group_and_partition()[0].domain() + {1, 2, 3} """ def shift_gens(gens, n): """ @@ -1089,13 +1099,51 @@ def shift_gens(gens, n): gens = [gen for f, tc in zip(f_list, tc_list) for gen in shift_gens(f.gens(), tc) if gen] # gen is a tuple - G = PermutationGroup(gens) + G = PermutationGroup(gens, domain=range(1, tc_list[-1]+1)) new_dompart = tuple([frozenset(chain(*[[tc + e for e in p] for p, tc in zip(f_dompart, tc_list)])) for f_dompart in zip(*dompart_list)]) return G, new_dompart + def cycle_index(self, parent=None): + r""" + Return the cycle index of ``self``. + + EXAMPLES:: + + sage: from sage.rings.species import MolecularSpecies + sage: M = MolecularSpecies("X,Y") + sage: G = PermutationGroup([[(1,2),(3,4)], [(5,6)]]) + sage: A = M(G, {0: [5,6], 1: [1,2,3,4]}) + sage: A.cycle_index() + 1/4*p[1, 1] # p[1, 1, 1, 1] + 1/4*p[1, 1] # p[2, 2] + 1/4*p[2] # p[1, 1, 1, 1] + 1/4*p[2] # p[2, 2] + """ + k = self.parent()._arity + if parent is None: + p = SymmetricFunctions(QQ).powersum() + parent = tensor([p]*k) + elif parent not in Modules.WithBasis: + raise ValueError("`parent` should be a module with basis indexed by partitions") + base_ring = parent.base_ring() + G, dompart = self.group_and_partition() + dompart_dict = {} + for i, s in enumerate(dompart): + dompart_dict.update({e: i for e in s}) + + def cycle_type(pi): + tuples = pi.cycle_tuples(singletons=True) + cycle_type = [[] for _ in range(k)] + for c in tuples: + cycle_type[dompart_dict[c[0]]].append(len(c)) + return tuple(_Partitions(sorted(c, reverse=True)) + for c in cycle_type) + + return (parent.sum_of_terms([cycle_type(C.an_element()), + base_ring(C.cardinality())] + for C in G.conjugacy_classes()) + / G.cardinality()) + @cached_method def grade(self): r""" From 53ea5fcd5fc2e1d68115c133fb21b4b014c88d3b Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Mon, 23 Sep 2024 16:12:00 +0530 Subject: [PATCH 204/537] Edited suggested changes to chow_ring.py --- src/sage/matroids/chow_ring.py | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/src/sage/matroids/chow_ring.py b/src/sage/matroids/chow_ring.py index 32816a36890..2f66aab6d89 100644 --- a/src/sage/matroids/chow_ring.py +++ b/src/sage/matroids/chow_ring.py @@ -30,7 +30,7 @@ class ChowRing(QuotientRing_generic): ..MATH:: - A(M)_R := R[y_{e_1}, \ldots, y_{e_n}, x_{F_1}, \ldots, x_{F_k}] / (I_M + J_M) + A(M)_R := R[y_{e_1}, \ldots, y_{e_n}, x_{F_1}, \ldots, x_{F_k}] / (I_M + J_M), where `(I_M + J_M)` is the augmented Chow ring ideal of matroid `M` of Feitchner-Yuzvinsky presentation. @@ -39,9 +39,10 @@ class ChowRing(QuotientRing_generic): ..MATH:: - A(M)_R := R[x_{F_1}, \ldots, x_{F_k}] / I_{af}M + A(M)_R := R[x_{F_1}, \ldots, x_{F_k}] / I_M^{af} - where `I_{af}M` is the augmented Chow ring ideal of matroid `M` of atom-free presentation. + where `I_M^{af}` is the augmented Chow ring ideal of matroid `M` in the + atom-free presentation. .. SEEALSO:: @@ -91,7 +92,10 @@ def __init__(self, R, M, augmented, presentation=None): else: self._ideal = ChowRingIdeal_nonaug(M, R) C = CommutativeRings().Quotients() & GradedAlgebrasWithBasis(R).FiniteDimensional() - QuotientRing_generic.__init__(self, R=self._ideal.ring(), I=self._ideal, names=self._ideal.ring().variable_names(), category=C) + QuotientRing_generic.__init__(self, R=self._ideal.ring(), + I=self._ideal, + names=self._ideal.ring().variable_names(), + category=C) def _repr_(self): r""" @@ -127,8 +131,8 @@ def _latex_(self): \Bold{Q}[A_{0}, A_{1}, A_{2}, B_{0}, B_{1}, B_{2}] """ - import sage.misc.latex as latex - return "%s/%s" % (latex.latex(self._ideal.ring()), latex.latex(self._ideal)) + from sage.misc.latex import latex + return "{} / {}".format(latex(self._ideal.ring()), latex(self._ideal)) def _coerce_map_from_base_ring(self): r""" @@ -136,7 +140,6 @@ def _coerce_map_from_base_ring(self): TESTS:: - sage: ch = matroids.Wheel(3).chow_ring(QQ, False) sage: ch._coerce_map_from_base_ring() is None True @@ -149,7 +152,6 @@ def basis(self): EXAMPLES:: - sage: ch = matroids.Uniform(3, 6).chow_ring(QQ, True, 'fy') sage: ch.basis() [B0*B01, 1] @@ -161,9 +163,9 @@ def basis(self): flats_gen = self._ideal.flats_generator() R = self._ideal.ring() flats = sorted(flats, key=lambda X: (len(X), sorted(X))) - ranks = {F:self._matroid.rank(F) for F in flats} + ranks = {F: self._matroid.rank(F) for F in flats} monomial_basis = [] - if self._augmented is True: + if self._augmented: if self._presentation == 'fy': flats.remove(frozenset()) #Non empty proper flats max_powers = [] From d631779709fe8e2c95b624626f9cefc628d634c7 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Mon, 23 Sep 2024 16:12:41 +0530 Subject: [PATCH 205/537] Edited suggested changes to chow_ring_ideal.py --- src/sage/matroids/chow_ring_ideal.py | 140 +++++++++++++-------------- 1 file changed, 66 insertions(+), 74 deletions(-) diff --git a/src/sage/matroids/chow_ring_ideal.py b/src/sage/matroids/chow_ring_ideal.py index 66107410070..baeddd71156 100644 --- a/src/sage/matroids/chow_ring_ideal.py +++ b/src/sage/matroids/chow_ring_ideal.py @@ -53,35 +53,32 @@ class ChowRingIdeal_nonaug(ChowRingIdeal): r""" The Chow ring ideal of a matroid `M`. - The Chow ring ideal is defined over a polynomial ring for a matroid `M`: - + The *Chow ring ideal* for a matroid `M` is defined as the ideal + `(Q_M + L_M)` of the polynomial ring: + ..MATH:: R[x_{F_1}, \ldots, x_{F_k}] - as `(Q_M + L_M)` - where - - `F_1, \ldots, F_k` are the non-empty proper flats of `M`, + - `F_1, \ldots, F_k` are the non-empty flats of `M`, - `Q_M` is the ideal generated by all `x_{F_i} x_{F_j}` where - `F_i` and `F_j` are incomparable elements in the lattice of - flats, and + `F_i` and `F_j` are incomparable elements in the lattice of + flats, and - `L_M` is the ideal generated by all linear forms - .. MATH:: + .. MATH:: - \sum_{i_1 \in F} x_F - \sum_{i_2 \in F} x_F + \sum_{i_1 \in F} x_F - \sum_{i_2 \in F} x_F - for all `i_1 \neq i_2 \in E`. + for all `i_1 \neq i_2 \in E`. INPUT: - `M` -- a matroid - `R` -- a commutative ring - OUTPUT: Chow ring ideal of matroid `M` - REFERENCES: - [ANR2023]_ @@ -91,11 +88,11 @@ 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 + 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}}} sage: ch = matroids.catalog.Fano().chow_ring(QQ, False) - sage: ch + sage: ch.defining_ideal() Chow ring ideal of Fano: Binary matroid of rank 3 on 7 elements, type (3, 0) """ @@ -105,7 +102,7 @@ def __init__(self, M, R): EXAMPLES:: - sage: I = matroids.catalog.Fano().chow_ring(QQ, False) + sage: I = matroids.catalog.Fano().chow_ring(QQ, False).defining_ideal() sage: TestSuite(I).run(skip="_test_category") """ self._matroid = M @@ -122,7 +119,7 @@ def __init__(self, M, R): def _gens_constructor(self, poly_ring): r""" - Returns the generators of the Chow ring ideal. Takes in the + Returns the generators of `self`. Takes in the ring of Chow ring ideal as input. EXAMPLES:: @@ -184,14 +181,14 @@ def _repr_(self): EXAMPLES:: sage: ch = matroids.catalog.Fano().chow_ring(QQ, False) - sage: ch + sage: ch.defining_ideal() Chow ring ideal of Fano: Binary matroid of rank 3 on 7 elements, type (3, 0) """ - return "Chow ring ideal of {}".format(self._matroid) + return "Chow ring ideal of {}- non augmented".format(self._matroid) def groebner_basis(self, algorithm='constructed'): #can you reduce it? - consider every antichain of size 2, and chains? r""" - Returns the Groebner basis of the Chow ring ideal. + Returns the Groebner basis of `self`. EXAMPLES:: @@ -281,60 +278,58 @@ def groebner_basis(self, algorithm='constructed'): #can you reduce it? - conside class AugmentedChowRingIdeal_fy(ChowRingIdeal): r""" - The augmented Chow ring ideal of matroid `M` over ring `R` in - Feitchner-Yuzvinsky presentation. - - The augmented Chow ring ideal of Feitchner-Yuzvinsky presentation - is defined over the following polynomial ring: + The augmented Chow ring ideal of matroid `M` over ring `R` in + Feitchner-Yuzvinsky presentation. - ..MATH:: + The augmented Chow ring ideal in the Feitchner-Yuzvinsky presentation + for a matroid `M` is defined as the ideal + `(I_M + J_M)` of the following polynomial ring: - R[y_{e_1}, \ldots, y_{e_n}, x_{F_1}, \ldots, x_{F_k}] + ..MATH:: - as `(I_M + J_M)` where + R[y_{e_1}, \ldots, y_{e_n}, x_{F_1}, \ldots, x_{F_k}] - - `F_1, \ldots, F_k` are the non-empty proper flats of `M`, - - `e_1 \ldots, e_n` are `n` elements of groundset of `M`, - - `J_M` is the ideal generated by all quadratic forms `x_{F_i} x_{F_j}` - where `F_i` and `F_j` are incomparable elements in the lattice of - flats, and `y_{i} x_F` for every `i \in E` and `i \notin F`, and - - `I_M` is the ideal generated by all linear forms + as - ..MATH:: + - `F_1, \ldots, F_k` are the non-empty proper flats of `M`, + - `e_1 \ldots, e_n` are `n` elements of groundset of `M`, + - `J_M` is the ideal generated by all quadratic forms `x_{F_i} x_{F_j}` + where `F_i` and `F_j` are incomparable elements in the lattice of + flats, and `y_{i} x_F` for every `i \in E` and `i \notin F`, and + - `I_M` is the ideal generated by all linear forms - y_i - \sum_{i \notin F} x_F + ..MATH:: - for all `i \in E`. - - REFERENCES: + y_i - \sum_{i \notin F} x_F - - [MM2022]_ + for all `i \in E`. - INPUT: + REFERENCES: + - [MM2022]_ - - `M` -- a matroid - - `R` -- a commutative ring + INPUT: - OUTPUT: augmented Chow ring ideal of matroid `M` of Feitchner-Yuzvinsky - presentation - EXAMPLES:: + - `M` -- a matroid + - `R` -- a commutative ring - Augmented Chow ring ideal of Wheel matroid of rank 3:: + EXAMPLES:: - sage: ch = matroids.Wheel(3).chow_ring(QQ, True, 'fy') - sage: ch - Augmented Chow ring ideal of Wheel(3): Regular matroid of rank 3 on - 6 elements with 16 bases of Feitchner-Yuzvinsky presentation - """ + Augmented Chow ring ideal of Wheel matroid of rank 3:: + + sage: ch = matroids.Wheel(3).chow_ring(QQ, True, 'fy') + sage: ch.defining_ideal() + Augmented Chow ring ideal of Wheel(3): Regular matroid of rank 3 on + 6 elements with 16 bases of Feitchner-Yuzvinsky presentation + """ def __init__(self, M, R): r""" Initialize ``self``. EXAMPLES:: - sage: I = matroids.Wheel(3).chow_ring(QQ, True, 'fy') + sage: I = matroids.Wheel(3).chow_ring(QQ, True, 'fy').defining_ideal() sage: TestSuite(I).run(skip="_test_category") """ self._matroid = M @@ -357,14 +352,13 @@ def __init__(self, M, R): def _gens_constructor(self, poly_ring): r""" - Return the generators of augmented Chow ring ideal of - Feitchner-Yuzvinsky presentation. Takes in the ring of + Return the generators of `self`. Takes in the ring of that augmented Chow ring ideal as input. EXAMPLES:: sage: ch = matroids.Wheel(3).chow_ring(QQ, True, 'fy') - sage: ch._gens_constructor(ch.ring()) + sage: ch.defining_ideal()._gens_constructor(ch.ring()) [B0^2, B0*B1, B0*B2, B0*B3, B0*B4, B0*B5, B0*B124, B0*B15, B0*B23, B0*B345, B0*B1, B1^2, B1*B2, B1*B3, B1*B4, B1*B5, B1*B025, B1*B04, B1*B23, B1*B345, B0*B2, B1*B2, B2^2, B2*B3, B2*B4, B2*B5, B2*B013, @@ -416,7 +410,7 @@ def _repr_(self): EXAMPLES:: sage: ch = matroids.Wheel(3).chow_ring(QQ, True, 'fy') - sage: ch + sage: ch.defining_ideal() Augmented Chow ring ideal of Wheel(3): Regular matroid of rank 3 on 6 elements with 16 bases of Feitchner-Yuzvinsky presentation """ @@ -424,7 +418,7 @@ def _repr_(self): def groebner_basis(self, algorithm='constructed'): r""" - Returns the Groebner basis of the augmented Chow ring ideal. + Returns the Groebner basis of `self`. EXAMPLES:: @@ -472,22 +466,23 @@ def groebner_basis(self, algorithm='constructed'): class AugmentedChowRingIdeal_atom_free(ChowRingIdeal): r""" - The augmented Chow ring ideal of matroid `M` over ring `R` in the atom-free - presentation. + The augmented Chow ring ideal for a matroid `M` over ring `R` in the + atom-free presentation. - The augmented Chow ring ideal for the atom-free presentation is defined - over the polynomial ring: + The augmented Chow ring ideal in the atom-free presentation for a matroid + `M` is defined as the ideal + `I_{af}(M)` of the polynomial ring: ..MATH:: R[x_{F_1}, \ldots, x_{F_k}] - as `I_{af}(M)` where + as - `F_1, \ldots, F_k` are the non-empty proper flats of `M`, - `I_{af }M` is the ideal generated by all quadratic forms `x_{F_i} x_{F_j}` - where `F_i` and `F_j` are incomparable elements in the lattice of - flats, + where `F_i` and `F_j` are incomparable elements in the lattice of + flats, ..MATH:: @@ -510,14 +505,12 @@ class AugmentedChowRingIdeal_atom_free(ChowRingIdeal): - ``M`` -- a matroid - ``R`` -- a commutative ring - OUTPUT: augmented Chow ring ideal of matroid `M` of atom-free presentation - EXAMPLES: Augmented Chow ring ideal of Wheel matroid of rank 3:: sage: ch = matroids.Wheel(3).chow_ring(QQ, True, 'atom-free') - sage: ch + sage: ch.defining_ideal() Augmented Chow ring ideal of Wheel(3): Regular matroid of rank 3 on 6 elements with 16 bases of atom-free presentation """ @@ -527,7 +520,7 @@ def __init__(self, M, R): EXAMPLES:: - sage: I = matroids.Wheel(3).chow_ring(QQ, True, 'atom-free') + sage: I = matroids.Wheel(3).chow_ring(QQ, True, 'atom-free').defining_ideal() sage: TestSuite(I).run(skip="_test_category") """ self._matroid = M @@ -554,8 +547,7 @@ def __init__(self, M, R): def _gens_constructor(self, poly_ring): r""" - Return the generators of augmented Chow ring ideal of - atom-free presentation. Takes in the ring of the augmented + Return the generators of `self`. Takes in the ring of the augmented Chow ring ideal as input. EXAMPLES:: @@ -564,7 +556,7 @@ def _gens_constructor(self, poly_ring): sage: M1 = GraphicMatroid(graphs.CycleGraph(3)) sage: ch = M1.chow_ring(QQ, True, 'atom-free') - sage: ch._gens_constructor(ch.ring()) + sage: ch.defining_ideal()._gens_constructor(ch.ring()) [A0^2, A0^2, A1^2, A0*A1, A2^2, A0*A2, A0*A1, A0^2, A1^2, A0*A1, A2^2, A0*A2, A0*A2, A0^2, A1^2, A0*A1, A2^2, A0*A2, A0*A1, A0^2, A0*A1, A1^2, A2^2, A1*A2, A1^2, A0^2, A0*A1, A1^2, A2^2, A1*A2, @@ -602,15 +594,15 @@ def _repr_(self): EXAMPLE:: sage: ch = matroids.Wheel(3).chow_ring(QQ, True, 'atom-free') - sage: ch + sage: ch.defining_ideal() Augmented Chow ring ideal of Wheel(3): Regular matroid of rank 3 on 6 elements with 16 bases of atom-free presentation """ - return "Augmented Chow ring ideal of {} of atom-free presentation".format(self._matroid) + return "Augmented Chow ring ideal of {} in the atom-free presentation".format(self._matroid) def groebner_basis(self, algorithm='constructed'): """ - Returns the Groebner basis of the augmented Chow ring ideal. + Returns the Groebner basis of `self`. EXAMPLES:: From 6ddca26dcdc777ee277a339619e99af4846eeb2d Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Mon, 23 Sep 2024 16:13:50 +0530 Subject: [PATCH 206/537] Fixed doctest typos in 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 baeddd71156..1e4e4eb5117 100644 --- a/src/sage/matroids/chow_ring_ideal.py +++ b/src/sage/matroids/chow_ring_ideal.py @@ -23,7 +23,7 @@ def matroid(self): EXAMPLES:: sage: ch = matroids.Uniform(3,6).chow_ring(QQ, False) - sage: ch.matroid() + 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}}} """ @@ -38,7 +38,7 @@ def flats_generator(self): EXAMPLES:: sage: ch = matroids.catalog.Fano().chow_ring(QQ, False) - sage: ch.flats_generator() + sage: ch.defining_ideal().flats_generator() {frozenset({'a'}): Aa, frozenset({'b'}): Ab, frozenset({'c'}): Ac, frozenset({'d'}): Ad, frozenset({'e'}): Ae, frozenset({'f'}): Af, frozenset({'g'}): Ag, frozenset({'b', 'a', 'f'}): Aabf, From 80a889232bbb9920ff50de1ff5fcb26310ac6a18 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Mon, 23 Sep 2024 16:16:28 +0530 Subject: [PATCH 207/537] Fixed doctest typos in chow_ring_ideal.py --- src/sage/matroids/chow_ring_ideal.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sage/matroids/chow_ring_ideal.py b/src/sage/matroids/chow_ring_ideal.py index 1e4e4eb5117..e1f763b2ebc 100644 --- a/src/sage/matroids/chow_ring_ideal.py +++ b/src/sage/matroids/chow_ring_ideal.py @@ -125,7 +125,7 @@ def _gens_constructor(self, poly_ring): EXAMPLES:: sage: ch = matroids.catalog.NonFano().chow_ring(QQ, False) - sage: ch.defining_ideal()._gens_constructor(ch.defining_ideal.ring()) + sage: ch.defining_ideal()._gens_constructor(ch.defining_ideal().ring()) [Aa*Ab, Aa*Ac, Aa*Ad, Aa*Ae, Aa*Af, Aa*Ag, Aa*Abcd, Aa*Abeg, Aa*Acfg, Aa*Ade, Aa*Adf, Aa*Aef, Ab*Ac, Ab*Ad, Ab*Ae, Ab*Af, Ab*Ag, Ab*Aace, Ab*Aadg, Ab*Acfg, Ab*Ade, Ab*Adf, Ab*Aef, Ac*Ad, Ac*Ae, @@ -358,7 +358,7 @@ def _gens_constructor(self, poly_ring): EXAMPLES:: sage: ch = matroids.Wheel(3).chow_ring(QQ, True, 'fy') - sage: ch.defining_ideal()._gens_constructor(ch.ring()) + sage: ch.defining_ideal()._gens_constructor(ch.defining_ideal().ring()) [B0^2, B0*B1, B0*B2, B0*B3, B0*B4, B0*B5, B0*B124, B0*B15, B0*B23, B0*B345, B0*B1, B1^2, B1*B2, B1*B3, B1*B4, B1*B5, B1*B025, B1*B04, B1*B23, B1*B345, B0*B2, B1*B2, B2^2, B2*B3, B2*B4, B2*B5, B2*B013, @@ -556,7 +556,7 @@ def _gens_constructor(self, poly_ring): sage: M1 = GraphicMatroid(graphs.CycleGraph(3)) sage: ch = M1.chow_ring(QQ, True, 'atom-free') - sage: ch.defining_ideal()._gens_constructor(ch.ring()) + sage: ch.defining_ideal()._gens_constructor(ch.defining_ideal().ring()) [A0^2, A0^2, A1^2, A0*A1, A2^2, A0*A2, A0*A1, A0^2, A1^2, A0*A1, A2^2, A0*A2, A0*A2, A0^2, A1^2, A0*A1, A2^2, A0*A2, A0*A1, A0^2, A0*A1, A1^2, A2^2, A1*A2, A1^2, A0^2, A0*A1, A1^2, A2^2, A1*A2, From 17b628724d9de40710ac1bcf685262d8a510e020 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Mon, 23 Sep 2024 19:16:53 +0530 Subject: [PATCH 208/537] Fixed doctest typos in chow_ring.py --- src/sage/matroids/chow_ring.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/sage/matroids/chow_ring.py b/src/sage/matroids/chow_ring.py index 2f66aab6d89..f1cb86d02d2 100644 --- a/src/sage/matroids/chow_ring.py +++ b/src/sage/matroids/chow_ring.py @@ -10,7 +10,6 @@ from sage.rings.quotient_ring import QuotientRing_generic from sage.categories.graded_algebras_with_basis import GradedAlgebrasWithBasis from sage.categories.commutative_rings import CommutativeRings -from sage.combinat.posets.posets import Poset from itertools import product, combinations class ChowRing(QuotientRing_generic): From 7439ab9181132d090d6adff1cc3116346c98122f Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Tue, 24 Sep 2024 09:13:18 +0530 Subject: [PATCH 209/537] Debugged all 3 basis() method cases --- src/sage/matroids/chow_ring.py | 161 +++++++++++++++++++-------------- 1 file changed, 92 insertions(+), 69 deletions(-) diff --git a/src/sage/matroids/chow_ring.py b/src/sage/matroids/chow_ring.py index f1cb86d02d2..3fe030fdd06 100644 --- a/src/sage/matroids/chow_ring.py +++ b/src/sage/matroids/chow_ring.py @@ -166,69 +166,89 @@ def basis(self): monomial_basis = [] if self._augmented: if self._presentation == 'fy': - flats.remove(frozenset()) #Non empty proper flats - max_powers = [] - max_powers[0] = ranks[flats[0]] - for i in range(1, len(flats)): - max_powers = ranks[flats[i]] - ranks[flats[i-1]] - for combination in product(*(range(p) for p in max_powers)): #Generating combinations for all powers up to max_powers - expression = R.one() - for i in range(len(flats)): - expression *= flats_gen[subset[i]]**combination[i] - monomial_basis.append(expression) - if combination[0] == 0: #Generating combinations for all powers including first max_powers - expression *= flats_gen[subset[0]]**max_powers[0] - monomial_basis.append(expression) + if frozenset() in flats: + flats.remove(frozenset()) #Non empty proper flats + subsets = [] + # Generate all subsets of the frozenset using combinations + for r in range(len(flats) + 1): # r is the size of the subset + subsets.extend(list(subset) for subset in combinations(flats, r)) + for subset in subsets: + flag = True + sorted_list = sorted(subset, key=len) + for i in range (len(sorted_list)): #Taking only chains + if (i != 0) & (len(sorted_list[i]) == len(sorted_list[i-1])): + flag = False + break + if flag: + k = len(subset) + if k == 0: + monomial_basis.append(R.one()) + elif k == 1 & ranks[subset[0]] == 1: + monomial_basis.append(flats_gen[subset[0]]) + else: + max_powers = [] + max_powers.append(ranks[subset[0]]) + for i in range(1, k): + max_powers.append(ranks[subset[i]] - ranks[subset[i-1]]) + for p in max_powers: + for combination in product(*(range(1, p))): #Generating combinations for all powers up to max_powers + expression = R.one() + for i in range(k): + expression *= flats_gen[subset[i]]**combination[i] + monomial_basis.append(expression) + if max_powers.index(p) == 0: #Generating combinations for all powers including first max_powers + expression *= flats_gen[subset[0]]**max_powers[0] + monomial_basis.append(expression) elif self._presentation == 'atom-free': subsets = [] # Generate all subsets of the frozenset using combinations - for r in range(len(flats) + 1): # r is the size of the subset - subsets.extend(list(subset) for subset in combinations(flats, r)) - for subset in subsets: - flag = True - sorted_list = sorted(subset, key=len) - for i in range (len(sorted_list)): #Taking only chains - if (i != 0) & (len(sorted_list[i]) == len(sorted_list[i-1])): - flag = False - break - if flag is True: #For every chain - max_powers = [] - x_dict = dict() - k = len(subset) - for i in range(k-1): - if i == 0: - max_powers.append(ranks[subset[i]]) - x_dict[subset[i]] = flats_gen[subset[i]] - else: - max_powers.append(ranks[subset[i]] - ranks[subset[i-1]]) - x_dict[subset[i]] = flats_gen[subset[i]] - x_dict[subset[k-1]] = flats_gen[subset[k-1]] - max_powers[k-1] = ranks[subset[k-1]] - first_rank = ranks[subset[0]] + 1 - last_rank = ranks[subset[k-1]] - for combination in product(*(range(1, p) for p in max_powers)): #Generating combinations for all powers from 1 to max_powers - expression = R.one() - if sum(combination) == first_rank: - for i in range(k): - expression *= x_dict[subset[i]]**combination[i] - monomial_basis.append(expression) - max_powers.remove(last_rank) - for combination in product(*(range(1, p) for p in max_powers)): #Generating all combinations including 0 power and max_power for first flat - expression = R.one() - if sum(combination) == first_rank: - for i in range(len(combination)): - expression *= x_dict[subset[i]]**combination[i] - monomial_basis.append(expression) + for r in range(len(flats) + 1): # r is the size of the subset + subsets.extend(list(subset) for subset in combinations(flats, r)) + for subset in subsets: + flag = True + sorted_list = sorted(subset, key=len) + for i in range (len(sorted_list)): #Taking only chains + if (i != 0) & (len(sorted_list[i]) == len(sorted_list[i-1])): + flag = False + break + if flag: #For every chain + max_powers = [] + k = len(subset) + if subset == []: + monomial_basis.append(R.one()) else: - expression *= x_dict[subset[k-1]]**last_rank - if sum(combination) + last_rank == first_rank: - for i in range(k): - expression *= x_dict[subset[i]]**combination[i] - monomial_basis.append(expression) + for i in range(k-1): + if i == 0: + max_powers.append(ranks[subset[i]]) + else: + max_powers.append(ranks[subset[i]] - ranks[subset[i-1]]) + max_powers.append(ranks[subset[k-1]]) + first_rank = ranks[subset[0]] + 1 + last_rank = ranks[subset[k-1]] + for combination in product(*(range(1, p) for p in max_powers)): #Generating combinations for all powers from 1 to max_powers + expression = R.one() + if sum(combination) == first_rank: + for i in range(k): + expression *= flats_gen[subset[i]]**combination[i] + monomial_basis.append(expression) + max_powers.remove(last_rank) + for combination in product(*(range(1, p) for p in max_powers)): #Generating all combinations including 0 power and max_power for first flat + expression = R.one() + if sum(combination) == first_rank: + for i in range(len(combination)): + expression *= flats_gen[subset[i]]**combination[i] + monomial_basis.append(expression) + else: + expression *= flats_gen[subset[k-1]]**last_rank + if sum(combination) + last_rank == first_rank: + for i in range(k): + expression *= flats_gen[subset[i]]**combination[i] + monomial_basis.append(expression) else: - flats.remove(frozenset()) #Non empty proper flats + if frozenset() in flats: + flats.remove(frozenset()) #Non empty proper flats subsets = [] # Generate all subsets of the frozenset using combinations for r in range(len(flats) + 1): # r is the size of the subset @@ -241,22 +261,25 @@ def basis(self): flag = False break - if flag is True: + if flag: max_powers = [] - x_dict = dict() - for i in range(len(subset)): - if i == 0: - max_powers.append(ranks[subset[i]]) - x_dict[subset[i]] = flats_gen[subset[i]] - else: - max_powers.append(ranks[subset[i]] - ranks[subset[i-1]]) - x_dict[subset[i]] = flats_gen[subset[i]] k = len(subset) - for combination in product(*(range(p) for p in max_powers)): - expression = R.one() + if k == 0: + monomial_basis.append(R.one()) + elif k == 1 & ranks[subset[0]] == 1: + monomial_basis.append(flats_gen[subset[0]]) + else: for i in range(k): - expression *= x_dict[subset[i]]**combination[i] - monomial_basis.append(expression) + if i == 0: + max_powers.append(ranks[subset[i]]) + else: + max_powers.append(ranks[subset[i]] - ranks[subset[i-1]]) + for combination in product(*(range(1, p) for p in max_powers)): + expression = R.one() + for i in range(k): + expression *= flats_gen[subset[i]]**combination[i] + monomial_basis.append(expression) + from sage.sets.family import Family return Family([self.element_class(self, mon, reduce=False) for mon in monomial_basis]) From 96a7dc81060005af5fe84a19bed1839d125d2e47 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Tue, 24 Sep 2024 09:15:45 +0530 Subject: [PATCH 210/537] Optimized groebner_basis() method --- src/sage/matroids/chow_ring_ideal.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/sage/matroids/chow_ring_ideal.py b/src/sage/matroids/chow_ring_ideal.py index e1f763b2ebc..84dbe458760 100644 --- a/src/sage/matroids/chow_ring_ideal.py +++ b/src/sage/matroids/chow_ring_ideal.py @@ -227,6 +227,7 @@ def groebner_basis(self, algorithm='constructed'): #can you reduce it? - conside subsets.extend(list(subset) for subset in combinations(flats, r)) for subset in subsets: + k = len(subset) flag = True sorted_list = sorted(subset, key=len) for i in range (len(sorted_list)): #Checking whether the subset is a chain @@ -235,13 +236,14 @@ def groebner_basis(self, algorithm='constructed'): #can you reduce it? - conside break if not flag: - term = R.one() - for x in subset: - term *= flats_gen[x] - gb.append(term) + if k == 2: #Taking only antichains of length 2 + term = R.one() + for x in subset: + term *= flats_gen[x] + gb.append(term) else: - if subset == []: + if k == 0: for F in flats: term = R.zero() for G in flats: @@ -250,7 +252,7 @@ def groebner_basis(self, algorithm='constructed'): #can you reduce it? - conside gb.append((term)**(ranks[F])) else: - for j in range(len(subset)): + for i in range(len(subset)): for k in range(j+1, len(subset)): #Checking if every element in the chain is maximal if (sorted_list[j] != sorted_list[k]) & (sorted_list[j].issubset(sorted_list[k])): flag = False From f01279ad6f1fdf9ed62596af9bf3d663b764ed13 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Tue, 24 Sep 2024 09:53:49 +0530 Subject: [PATCH 211/537] Fixed typos in groebner_basis() method --- 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 84dbe458760..b5a30986e54 100644 --- a/src/sage/matroids/chow_ring_ideal.py +++ b/src/sage/matroids/chow_ring_ideal.py @@ -253,8 +253,8 @@ def groebner_basis(self, algorithm='constructed'): #can you reduce it? - conside else: for i in range(len(subset)): - for k in range(j+1, len(subset)): #Checking if every element in the chain is maximal - if (sorted_list[j] != sorted_list[k]) & (sorted_list[j].issubset(sorted_list[k])): + for j in range(i+1, len(subset)): #Checking if every element in the chain is maximal + if (sorted_list[i] != sorted_list[j]) & (sorted_list[i].issubset(sorted_list[j])): flag = False break From d0fb2baaa094fdc8e05d200b9045af229cf9ab14 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Tue, 24 Sep 2024 10:14:30 +0530 Subject: [PATCH 212/537] Added LaTeX method for the ideals --- src/sage/matroids/chow_ring_ideal.py | 73 ++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) diff --git a/src/sage/matroids/chow_ring_ideal.py b/src/sage/matroids/chow_ring_ideal.py index b5a30986e54..3c99fa85683 100644 --- a/src/sage/matroids/chow_ring_ideal.py +++ b/src/sage/matroids/chow_ring_ideal.py @@ -185,6 +185,27 @@ def _repr_(self): Chow ring ideal of Fano: Binary matroid of rank 3 on 7 elements, type (3, 0) """ return "Chow ring ideal of {}- non augmented".format(self._matroid) + + def _latex_(self): + r""" + Return the LaTeX output of the ring and generators of `self`. + + EXAMPLES:: + + sage: from sage.matroids.basis_matroid import BasisMatroid + + sage: M1 = BasisMatroid(groundset='abcd', bases=['ab','ad', 'bc']) + sage: ch = M1.chow_ring(QQ, False) + sage: ch.defining_ideal()._latex_() + '\\left(\\mathit{Aac} \\mathit{Abd}, 0, + \\mathit{Aac} - \\mathit{Abd}, \\mathit{Aac} - \\mathit{Abd}, + \\mathit{Aac} - \\mathit{Abd}, \\mathit{Aac} - \\mathit{Abd}, + 0\\right)\\Bold{Q}[\\mathit{Aac}, \\mathit{Abd}]' + """ + from sage.misc.latex import latex + return '\\left(%s\\right)%s' % (", ".join(latex(g) + for g in self.gens()), + latex(self.ring())) def groebner_basis(self, algorithm='constructed'): #can you reduce it? - consider every antichain of size 2, and chains? r""" @@ -418,6 +439,29 @@ def _repr_(self): """ return "Augmented Chow ring ideal of {} of Feitchner-Yuzvinsky presentation".format(self._matroid) + def _latex_(self): + r""" + Return the LaTeX output of the ring and generators of `self`. + + EXAMPLES:: + + sage: from sage.matroids.basis_matroid import BasisMatroid + + sage: M1 = BasisMatroid(groundset='abcd', bases=['ab','ad', 'bc']) + sage: ch = M1.chow_ring(QQ, True, 'fy') + sage: ch.defining_ideal()._latex_() + '\\left(\\mathit{Bac}^{2}, \\mathit{Bac} \\mathit{Bbd}, + \\mathit{Bac} \\mathit{Bbd}, \\mathit{Bbd}^{2}, + \\mathit{Ad} - \\mathit{Bac}, \\mathit{Ab} - \\mathit{Bac}, + \\mathit{Aa} - \\mathit{Bbd}, \\mathit{Ac} - \\mathit{Bbd}\\right) + \\Bold{Q}[\\mathit{Ad}, \\mathit{Ab}, \\mathit{Aa}, \\mathit{Ac}, + \\mathit{Bac}, \\mathit{Bbd}]' + """ + from sage.misc.latex import latex + return '\\left(%s\\right)%s' % (", ".join(latex(g) + for g in self.gens()), + latex(self.ring())) + def groebner_basis(self, algorithm='constructed'): r""" Returns the Groebner basis of `self`. @@ -602,6 +646,35 @@ def _repr_(self): """ return "Augmented Chow ring ideal of {} in the atom-free presentation".format(self._matroid) + def _latex_(self): + r""" + Return the LaTeX output of the ring and generators of `self`. + + EXAMPLES:: + + sage: from sage.matroids.basis_matroid import BasisMatroid + + sage: M1 = BasisMatroid(groundset='abcd', bases=['ab','ad', 'bc']) + sage: ch = M1.chow_ring(QQ, True, 'atom-free') + sage: ch.defining_ideal()._latex_() + '\\left(\\mathit{Aac}^{2}, \\mathit{Abd}^{2}, + \\mathit{Aac} \\mathit{Abd}, \\mathit{Abd}^{2}, + \\mathit{Aac} \\mathit{Abd}, \\mathit{Aac}^{2}, \\mathit{Aac}^{2}, + \\mathit{Aac} \\mathit{Abd}, \\mathit{Abd}^{2}, + \\mathit{Aac} \\mathit{Abd}, \\mathit{Abd}^{2}, + \\mathit{Aac} \\mathit{Abd}, \\mathit{Aac}^{2}, \\mathit{Aac}^{2}, + \\mathit{Aac} \\mathit{Abd}, \\mathit{Abd}^{2}, \\mathit{Abd}^{2}, + \\mathit{Aac}^{2}, \\mathit{Aac} \\mathit{Abd}, \\mathit{Aac}^{2}, + \\mathit{Aac} \\mathit{Abd}, \\mathit{Abd}^{2}, \\mathit{Abd}^{2}, + \\mathit{Abd}^{2}, \\mathit{Aac}^{2}, \\mathit{Aac} \\mathit{Abd}, + \\mathit{Aac}^{2}, \\mathit{Aac} \\mathit{Abd}\\right) + \\Bold{Q}[\\mathit{Aac}, \\mathit{Abd}]' + """ + from sage.misc.latex import latex + return '\\left(%s\\right)%s' % (", ".join(latex(g) + for g in self.gens()), + latex(self.ring())) + def groebner_basis(self, algorithm='constructed'): """ Returns the Groebner basis of `self`. From 3ed13fa30b42fc097f50985a086e4b79e6585d92 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Tue, 24 Sep 2024 10:46:04 +0530 Subject: [PATCH 213/537] Edited definintions for augmented Chow ring ideal --- 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 3c99fa85683..393c0ee1629 100644 --- a/src/sage/matroids/chow_ring_ideal.py +++ b/src/sage/matroids/chow_ring_ideal.py @@ -314,7 +314,7 @@ class AugmentedChowRingIdeal_fy(ChowRingIdeal): as - - `F_1, \ldots, F_k` are the non-empty proper flats of `M`, + - `F_1, \ldots, F_k` are the proper flats of `M`, - `e_1 \ldots, e_n` are `n` elements of groundset of `M`, - `J_M` is the ideal generated by all quadratic forms `x_{F_i} x_{F_j}` where `F_i` and `F_j` are incomparable elements in the lattice of @@ -525,7 +525,7 @@ class AugmentedChowRingIdeal_atom_free(ChowRingIdeal): as - - `F_1, \ldots, F_k` are the non-empty proper flats of `M`, + - `F_1, \ldots, F_k` are the non-empty flats of `M`, - `I_{af }M` is the ideal generated by all quadratic forms `x_{F_i} x_{F_j}` where `F_i` and `F_j` are incomparable elements in the lattice of flats, From db165d7202e2065b858ec51ab4c48a6fe3abcce6 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Tue, 24 Sep 2024 10:52:16 +0530 Subject: [PATCH 214/537] Fixed definitions of augmented Chow ring ideals --- 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 393c0ee1629..aba6db99ccd 100644 --- a/src/sage/matroids/chow_ring_ideal.py +++ b/src/sage/matroids/chow_ring_ideal.py @@ -314,7 +314,7 @@ class AugmentedChowRingIdeal_fy(ChowRingIdeal): as - - `F_1, \ldots, F_k` are the proper flats of `M`, + - `F_1, \ldots, F_k` are the flats of `M`, - `e_1 \ldots, e_n` are `n` elements of groundset of `M`, - `J_M` is the ideal generated by all quadratic forms `x_{F_i} x_{F_j}` where `F_i` and `F_j` are incomparable elements in the lattice of @@ -526,7 +526,7 @@ class AugmentedChowRingIdeal_atom_free(ChowRingIdeal): as - `F_1, \ldots, F_k` are the non-empty flats of `M`, - - `I_{af }M` is the ideal generated by all quadratic forms `x_{F_i} x_{F_j}` + - `I_{af}M` is the ideal generated by all quadratic forms `x_{F_i} x_{F_j}` where `F_i` and `F_j` are incomparable elements in the lattice of flats, From 88b20fb09714184381e5536db98358b7e9269fbb Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Tue, 24 Sep 2024 11:08:31 +0530 Subject: [PATCH 215/537] Edited groebner_basis() method for all 3 ideals --- src/sage/matroids/chow_ring_ideal.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/sage/matroids/chow_ring_ideal.py b/src/sage/matroids/chow_ring_ideal.py index aba6db99ccd..3efcdbc4e54 100644 --- a/src/sage/matroids/chow_ring_ideal.py +++ b/src/sage/matroids/chow_ring_ideal.py @@ -207,7 +207,7 @@ def _latex_(self): for g in self.gens()), latex(self.ring())) - def groebner_basis(self, algorithm='constructed'): #can you reduce it? - consider every antichain of size 2, and chains? + def groebner_basis(self, algorithm='constructed', *args, **kwargs): #can you reduce it? - consider every antichain of size 2, and chains? r""" Returns the Groebner basis of `self`. @@ -295,8 +295,8 @@ def groebner_basis(self, algorithm='constructed'): #can you reduce it? - conside g_basis = PolynomialSequence(R, [gb]) return g_basis - elif algorithm == 'constructed': #*args **kwds - super().groebner_basis() + elif algorithm == 'constructed': + super().groebner_basis(*args, **kwargs) class AugmentedChowRingIdeal_fy(ChowRingIdeal): @@ -462,7 +462,7 @@ def _latex_(self): for g in self.gens()), latex(self.ring())) - def groebner_basis(self, algorithm='constructed'): + def groebner_basis(self, algorithm='constructed', *args, **kwargs): r""" Returns the Groebner basis of `self`. @@ -508,7 +508,7 @@ def groebner_basis(self, algorithm='constructed'): g_basis = PolynomialSequence(poly_ring, [gb]) return g_basis elif algorithm == 'constructed': - super().groebner_basis() + super().groebner_basis(*args, **kwargs) class AugmentedChowRingIdeal_atom_free(ChowRingIdeal): r""" @@ -675,7 +675,7 @@ def _latex_(self): for g in self.gens()), latex(self.ring())) - def groebner_basis(self, algorithm='constructed'): + def groebner_basis(self, algorithm='constructed', *args, **kwargs): """ Returns the Groebner basis of `self`. @@ -714,7 +714,7 @@ def groebner_basis(self, algorithm='constructed'): return g_basis elif algorithm == 'constructed': - super().groebner_basis() + super().groebner_basis(*args, **kwargs) From 4669fd61c77458b679e007216382dec62f5f2445 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Wed, 25 Sep 2024 17:02:32 +0530 Subject: [PATCH 216/537] Edited chow_ring() function examples --- src/sage/matroids/matroid.pyx | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/sage/matroids/matroid.pyx b/src/sage/matroids/matroid.pyx index 428d565b2b8..6999c30252a 100644 --- a/src/sage/matroids/matroid.pyx +++ b/src/sage/matroids/matroid.pyx @@ -8030,14 +8030,12 @@ cdef class Matroid(SageObject): def chow_ring(self, R, augmented=False, presentation=None): r""" - Return the Chow ring of ``self`` over ``R``. - Return the augmented Chow ring of `self` over `R`of `presentation` - if `augmented` is `True`. + Return the (augmented) Chow ring of ``self`` over ``R``. .. SEEALSO:: - :mod: sage.matroids.chow_ring_ideal - :mod: sage.matroids.chow_ring + - :mod:`sage.matroids.chow_ring_ideal` + - :mod:`sage.matroids.chow_ring` EXAMPLES:: @@ -8058,7 +8056,7 @@ cdef class Matroid(SageObject): Chow ring of Fano: Binary matroid of rank 3 on 7 elements, type (3, 0) over Rational Field. - The augmented Chow ring can also be instantiated with the + The augmented Chow ring can also be constructed with the Feitchner-Yuzvinsky and atom-free presentation:: sage: M = matroids.Wheel(3) @@ -8069,7 +8067,6 @@ cdef class Matroid(SageObject): sage: ch = M.chow_ring(QQ, augmented=True, presentation='atom-free') Augmented Chow ring of U(3, 6): Matroid of rank 3 on 6 elements with circuit-closures {3: {{0, 1, 2, 3, 4, 5}}} of atom-free presentation - """ from sage.matroids.chow_ring import ChowRing return ChowRing(M=self, R=R, augmented=augmented, presentation=presentation) From a84a41d371dfa177d15ad68e0339efca2780d403 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Wed, 25 Sep 2024 17:03:12 +0530 Subject: [PATCH 217/537] Edited Doctests --- src/sage/matroids/chow_ring.py | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/src/sage/matroids/chow_ring.py b/src/sage/matroids/chow_ring.py index 3fe030fdd06..46edaacdf95 100644 --- a/src/sage/matroids/chow_ring.py +++ b/src/sage/matroids/chow_ring.py @@ -16,29 +16,29 @@ class ChowRing(QuotientRing_generic): r""" The Chow ring of a matroid. - The *Chow ring of a matroid* `M` is defined as the quotient ring: + The *Chow ring of a matroid* `M` is defined as the quotient ring .. MATH:: - A^*(M)_R := R[x_{F_1}, \ldots, x_{F_k}] / (Q_M + L_M) + A^*(M)_R := R[x_{F_1}, \ldots, x_{F_k}] / (Q_M + L_M), where `(Q_M + L_M)` is the Chow ring ideal of matroid `M`. The *augmented Chow ring of matroid* `M` in the Feitchner-Yuzvinsky presentation - is the quotient ring: + is the quotient ring - ..MATH:: + .. MATH:: A(M)_R := R[y_{e_1}, \ldots, y_{e_n}, x_{F_1}, \ldots, x_{F_k}] / (I_M + J_M), where `(I_M + J_M)` is the augmented Chow ring ideal of matroid `M` of Feitchner-Yuzvinsky presentation. - The *augmented Chow ring of atom-free presentation* is the quotient ring: + The *augmented Chow ring of atom-free presentation* is the quotient ring - ..MATH:: + .. MATH:: - A(M)_R := R[x_{F_1}, \ldots, x_{F_k}] / I_M^{af} + A(M)_R := R[x_{F_1}, \ldots, x_{F_k}] / I_M^{af}, where `I_M^{af}` is the augmented Chow ring ideal of matroid `M` in the atom-free presentation. @@ -49,15 +49,14 @@ class ChowRing(QuotientRing_generic): INPUT: - - `M` -- a matroid - - `R` -- a commutative ring + - ``M`` -- matroid + - ``R`` -- commutative ring - ``augmented`` -- boolean; when ``True``, this is the augmented - Chow ring and if ``False``, this is the non-augmented Chow ring + Chow ring and if ``False``, this is the non-augmented Chow ring - ``presentation`` -- string (default: ``None``); one of the following: - * ``"fy"`` - Feitchner-Yuzvinsky presentation* - * ``"atom-free" - Atom-free presentation* - + * ``"fy"`` - the Feitchner-Yuzvinsky presentation + * ``"atom-free" - the atom-free presentation REFERENCES: @@ -295,7 +294,6 @@ def to_vector(self, order=None): sage: v = ch.an_element(); v A0 sage: v.to_vector() - """ P = self.parent() B = P.basis() @@ -315,7 +313,6 @@ def monomial_coefficients(self, copy=None): sage: v = ch.an_element(); v 0 sage: v.monomial_coefficients() - """ B = self.parent().basis() f = self.lift() From e45f4b991ac14a2da4038970126dd06d68f817ce Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Wed, 25 Sep 2024 17:03:40 +0530 Subject: [PATCH 218/537] Edited doctests for ideals --- src/sage/matroids/chow_ring_ideal.py | 197 +++++++++++++-------------- 1 file changed, 96 insertions(+), 101 deletions(-) diff --git a/src/sage/matroids/chow_ring_ideal.py b/src/sage/matroids/chow_ring_ideal.py index 3efcdbc4e54..8785360f3b0 100644 --- a/src/sage/matroids/chow_ring_ideal.py +++ b/src/sage/matroids/chow_ring_ideal.py @@ -54,16 +54,16 @@ class ChowRingIdeal_nonaug(ChowRingIdeal): The Chow ring ideal of a matroid `M`. The *Chow ring ideal* for a matroid `M` is defined as the ideal - `(Q_M + L_M)` of the polynomial ring: + `(Q_M + L_M)` of the polynomial ring - ..MATH:: + .. MATH:: - R[x_{F_1}, \ldots, x_{F_k}] + R[x_{F_1}, \ldots, x_{F_k}], where - `F_1, \ldots, F_k` are the non-empty flats of `M`, - - `Q_M` is the ideal generated by all `x_{F_i} x_{F_j}` where + - `Q_M` is the ideal generated by all `x_{F_i} x_{F_j}`, where `F_i` and `F_j` are incomparable elements in the lattice of flats, and - `L_M` is the ideal generated by all linear forms @@ -76,8 +76,8 @@ class ChowRingIdeal_nonaug(ChowRingIdeal): INPUT: - - `M` -- a matroid - - `R` -- a commutative ring + - `M` -- matroid + - `R` -- commutative ring REFERENCES: @@ -119,8 +119,7 @@ def __init__(self, M, R): def _gens_constructor(self, poly_ring): r""" - Returns the generators of `self`. Takes in the - ring of Chow ring ideal as input. + Return the generators of ``self``. EXAMPLES:: @@ -178,6 +177,8 @@ def _gens_constructor(self, poly_ring): def _repr_(self): r""" + Return a string representation of ``self``. + EXAMPLES:: sage: ch = matroids.catalog.Fano().chow_ring(QQ, False) @@ -188,7 +189,7 @@ def _repr_(self): def _latex_(self): r""" - Return the LaTeX output of the ring and generators of `self`. + Return a LaTeX representation of ``self``. EXAMPLES:: @@ -207,96 +208,92 @@ def _latex_(self): for g in self.gens()), latex(self.ring())) - def groebner_basis(self, algorithm='constructed', *args, **kwargs): #can you reduce it? - consider every antichain of size 2, and chains? + def groebner_basis(self, algorithm='', *args, **kwargs): #can you reduce it? - consider every antichain of size 2, and chains? r""" - Returns the Groebner basis of `self`. + Return a Groebner basis of ``self``. EXAMPLES:: - sage: from sage.matroids.basis_matroid import BasisMatroid - - sage: ch = BasisMatroid(groundset='abc', bases=['ab', 'ac'])).chow_ring(QQ, False) - sage: ch.defining_ideal().groebner_basis(algorithm='') + sage: ch = Matroid(groundset='abc', bases=['ab', 'ac']).chow_ring(QQ, False) + sage: ch.defining_ideal().groebner_basis() [Aa, Abc] - sage: ch.defining_ideal().groebner_basis(algorithm='').is_groebner() + sage: ch.defining_ideal().groebner_basis().is_groebner() True Another example would be the Groebner basis of the Chow ring ideal of - the Graphic matroid of CycleGraph(3):: + the matroid of the length 3 cycle graph:: - sage: from sage.matroids.graphic_matroid import GraphicMatroid - - sage: ch = GraphicMatroid(graphs.CycleGraph(3)).chow_ring(QQ, False) - sage: ch.defining_ideal().groebner_basis(algorithm='') + sage: ch = Matroid(graphs.CycleGraph(3)).chow_ring(QQ, False) + sage: ch.defining_ideal().groebner_basis() [A0, A1, A2, A0*A1, A0*A2, A1*A2, A0*A1*A2] - sage: ch.defining_ideal().groebner_basis(algorithm='').is_groebner() + sage: ch.defining_ideal().groebner_basis().is_groebner() True """ if algorithm == '': - flats = list(self._flats_generator) - gb = list() - R = self.ring() - if frozenset() in flats: - flats.remove(frozenset()) #Non-empty proper flats needed - - ranks = {F:self._matroid.rank(F) for F in flats} - - flats_gen = self._flats_generator - subsets = [] - # Generate all subsets of flats using combinations - for r in range(len(flats) + 1): # r is the size of the subset - subsets.extend(list(subset) for subset in combinations(flats, r)) - - for subset in subsets: - k = len(subset) - flag = True - sorted_list = sorted(subset, key=len) - for i in range (len(sorted_list)): #Checking whether the subset is a chain - if (i != 0) & (len(sorted_list[i]) == len(sorted_list[i-1])): - flag = False - break - - if not flag: - if k == 2: #Taking only antichains of length 2 - term = R.one() - for x in subset: - term *= flats_gen[x] - gb.append(term) - + algorithm = 'constructed' + if algorithm != 'constructed': + return super().groebner_basis(algorithm=algorithm, *args, **kwargs) + flats = list(self._flats_generator) + gb = list() + R = self.ring() + if frozenset() in flats: + flats.remove(frozenset()) #Non-empty proper flats needed + + ranks = {F:self._matroid.rank(F) for F in flats} + + flats_gen = self._flats_generator + subsets = [] + # Generate all subsets of flats using combinations + for r in range(len(flats) + 1): # r is the size of the subset + subsets.extend(list(subset) for subset in combinations(flats, r)) + + for subset in subsets: + k = len(subset) + flag = True + sorted_list = sorted(subset, key=len) + for i in range (len(sorted_list)): #Checking whether the subset is a chain + if (i != 0) & (len(sorted_list[i]) == len(sorted_list[i-1])): + flag = False + break + + if not flag: + if k == 2: #Taking only antichains of length 2 + term = R.one() + for x in subset: + term *= flats_gen[x] + gb.append(term) + + else: + if k == 0: + for F in flats: + term = R.zero() + for G in flats: + if G >= F: + term += flats_gen[G] + gb.append((term)**(ranks[F])) + else: - if k == 0: + for i in range(len(subset)): + for j in range(i+1, len(subset)): #Checking if every element in the chain is maximal + if (sorted_list[i] != sorted_list[j]) & (sorted_list[i].issubset(sorted_list[j])): + flag = False + break + + if flag: for F in flats: - term = R.zero() - for G in flats: - if G >= F: - term += flats_gen[G] - gb.append((term)**(ranks[F])) - - else: - for i in range(len(subset)): - for j in range(i+1, len(subset)): #Checking if every element in the chain is maximal - if (sorted_list[i] != sorted_list[j]) & (sorted_list[i].issubset(sorted_list[j])): - flag = False - break - - if flag: - for F in flats: - if F > reduce(lambda a, b: a.union(b), sorted_list): - term = R.one() - for x in subset: - term *= flats_gen[x] - term1 = R.zero() - for G in flats: - if G >= F: - term1 += flats_gen[G] - if term1 != R.zero(): - gb.append(term*(term1**(ranks[F] - ranks[sorted_list[len(subset) - 1]]))) - - g_basis = PolynomialSequence(R, [gb]) - return g_basis - - elif algorithm == 'constructed': - super().groebner_basis(*args, **kwargs) + if F > reduce(lambda a, b: a.union(b), sorted_list): + term = R.one() + for x in subset: + term *= flats_gen[x] + term1 = R.zero() + for G in flats: + if G >= F: + term1 += flats_gen[G] + if term1 != R.zero(): + gb.append(term*(term1**(ranks[F] - ranks[sorted_list[len(subset) - 1]]))) + + g_basis = PolynomialSequence(R, [gb]) + return g_basis class AugmentedChowRingIdeal_fy(ChowRingIdeal): @@ -306,26 +303,26 @@ class AugmentedChowRingIdeal_fy(ChowRingIdeal): The augmented Chow ring ideal in the Feitchner-Yuzvinsky presentation for a matroid `M` is defined as the ideal - `(I_M + J_M)` of the following polynomial ring: + `(I_M + J_M)` of the following polynomial ring - ..MATH:: + .. MATH:: - R[y_{e_1}, \ldots, y_{e_n}, x_{F_1}, \ldots, x_{F_k}] + R[y_{e_1}, \ldots, y_{e_n}, x_{F_1}, \ldots, x_{F_k}], - as + where - `F_1, \ldots, F_k` are the flats of `M`, - `e_1 \ldots, e_n` are `n` elements of groundset of `M`, - - `J_M` is the ideal generated by all quadratic forms `x_{F_i} x_{F_j}` - where `F_i` and `F_j` are incomparable elements in the lattice of - flats, and `y_{i} x_F` for every `i \in E` and `i \notin F`, and - - `I_M` is the ideal generated by all linear forms + - `J_M` is the ideal generated by all quadratic forms `x_{F_i} x_{F_j}`, + where `F_i` and `F_j` are incomparable elements in the lattice of + flats and `y_{i} x_F` for every `i \in E` and `i \notin F`, and + - `I_M` is the ideal generated by all linear forms - ..MATH:: + .. MATH:: - y_i - \sum_{i \notin F} x_F + y_i - \sum_{i \notin F} x_F - for all `i \in E`. + for all `i \in E`. REFERENCES: @@ -333,9 +330,8 @@ class AugmentedChowRingIdeal_fy(ChowRingIdeal): INPUT: - - - `M` -- a matroid - - `R` -- a commutative ring + - ``M`` -- matroid + - ``R`` -- commutative ring EXAMPLES:: @@ -375,8 +371,7 @@ def __init__(self, M, R): def _gens_constructor(self, poly_ring): r""" - Return the generators of `self`. Takes in the ring of - that augmented Chow ring ideal as input. + Return the generators of ``self``. EXAMPLES:: @@ -441,7 +436,7 @@ def _repr_(self): def _latex_(self): r""" - Return the LaTeX output of the ring and generators of `self`. + Return a LaTeX representation`self`. EXAMPLES:: From d62beaea5ca20aa87b6b1aacc8efb7dd9c964d45 Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Wed, 25 Sep 2024 17:25:03 +0200 Subject: [PATCH 219/537] rename and simplify ElementCache by using hash --- src/sage/rings/species.py | 247 ++++++++++++++++++-------------------- 1 file changed, 116 insertions(+), 131 deletions(-) diff --git a/src/sage/rings/species.py b/src/sage/rings/species.py index 4cb80118ae1..dd07d353a1c 100644 --- a/src/sage/rings/species.py +++ b/src/sage/rings/species.py @@ -11,7 +11,6 @@ from sage.combinat.integer_vector import IntegerVectors from sage.combinat.partition import Partitions, _Partitions from sage.combinat.sf.sf import SymmetricFunctions -from sage.rings.integer_ring import ZZ from sage.groups.perm_gps.constructor import PermutationGroupElement from sage.groups.perm_gps.permgroup import PermutationGroup, PermutationGroup_generic from sage.groups.perm_gps.permgroup_named import SymmetricGroup @@ -28,27 +27,42 @@ from sage.structure.unique_representation import UniqueRepresentation -class ElementCache(): +class UniqueElements(): + r""" + A class for ensuring that equal elements are identical. + + This class creates a cache, which is a dictionary mapping + invariants to lists of distinct elements. + """ def __init__(self): r""" - A class for caching elements. + Initialize the cache. """ self._cache = dict() def _cache_get(self, elm): r""" - Return the cached element, or add it if it doesn't exist. + Return the cached element, adding it to the cache if it has not + been encountered yet. INPUT: - - ``elm``, an element of a class which implements the - following methods:: + - ``elm``, a hashable element. - - ``_element_key`` - hashable type for dict lookup, - - ``__eq__`` - to compare two elements, - - ``_canonicalize`` - to preprocess the element. + The parent of ``elm`` may additionally implement a method + ``_standardize`` that preprocesses the element before it is + put in the cache. - TESTS:: + TESTS: + + Two different groups with the same hash:: + + sage: from sage.rings.species import ConjugacyClassesOfDirectlyIndecomposableSubgroups + sage: C = ConjugacyClassesOfDirectlyIndecomposableSubgroups() + sage: G = C(PermutationGroup([[(1,3),(2,4)], [(1,4),(2,3)]])) + sage: H = C(PermutationGroup([[(1,3,2,4)]])) + sage: C._cache[hash(G)] + [((1,3)(2,4), (1,4)(2,3)), ((1,3,2,4),)] sage: A = AtomicSpecies("X, Y") sage: G = PermutationGroup([[(1,2),(3,4),(5,6),(7,8,9,10)]]); G @@ -59,30 +73,33 @@ def _cache_get(self, elm): {((1,2,3,4)(5,6)(7,8)(9,10),): ({5, 6, 7, 8}, {1, 2, 3, 4, 9, 10})} sage: a is b True - sage: from sage.rings.species import ElementCache - sage: E = ElementCache() + sage: from sage.rings.species import UniqueElements + sage: E = UniqueElements() sage: E._cache_get(a) {((1,2,3,4)(5,6)(7,8)(9,10),): ({5, 6, 7, 8}, {1, 2, 3, 4, 9, 10})} - """ - # TODO: Make _canonicalize optional. - # Possibly the following works: - # use getattr to check if name exists - # use callable to check if it is a function - # if both true, call _canonicalize - key = elm._element_key() + key = hash(elm) if key in self._cache: lookup = self._cache[key] for other_elm in lookup: if elm == other_elm: return other_elm - elm._canonicalize() + elm = self._standardize(elm) lookup.append(elm) else: - elm._canonicalize() + elm = self._standardize(elm) self._cache[key] = [elm] return elm + def _standardize(self, elm): + r""" + Return a standardized representation of ``elm``. + + This method can be implemented to transform elements in a way + that is more expensive than comparing them. + """ + return elm + class ConjugacyClassOfDirectlyIndecomposableSubgroups(Element): def __init__(self, parent, C): @@ -99,23 +116,6 @@ def __init__(self, parent, C): Element.__init__(self, parent) self._C = C - def __hash__(self): - r""" - Return the hash for the conjugacy class. - - TESTS:: - - sage: from sage.rings.species import ConjugacyClassesOfDirectlyIndecomposableSubgroups - sage: C = ConjugacyClassesOfDirectlyIndecomposableSubgroups() - sage: G = PermutationGroup([[(1,2),(3,4),(5,6),(7,8,9,10)]]); G - Permutation Group with generators [(1,2)(3,4)(5,6)(7,8,9,10)] - sage: H = PermutationGroup([[(1,2,3,4),(5,6),(7,8),(9,10)]]); H - Permutation Group with generators [(1,2,3,4)(5,6)(7,8)(9,10)] - sage: hash(C(G)) == hash(C(H)) - True - """ - return hash(self._C) - def _repr_(self): r""" Return a string representation of ``self``. @@ -130,40 +130,31 @@ def _repr_(self): """ return f"{self._C.gens()}" - def _element_key(self): + def __hash__(self): r""" - Return the cache lookup key for ``self``. + Return the hash of ``self``. + + Note that this serves also as lookup key in the cache. TESTS:: sage: from sage.rings.species import ConjugacyClassesOfDirectlyIndecomposableSubgroups sage: C = ConjugacyClassesOfDirectlyIndecomposableSubgroups() - sage: G = PermutationGroup([[(1,3),(4,7)], [(2,5),(6,8)], [(1,4),(2,5),(3,7)]]) - sage: C(G)._element_key() - (8, 8, (2, 2, 4)) - """ - return self._C.degree(), self._C.order(), tuple(len(orbit) for orbit in sorted(self._C.orbits(), key=len)) - - @cached_method - def _canonicalize(self): - r""" - Canonicalize this conjugacy class by sorting the orbits by - length and making them consecutive. - - EXAMPLES:: + sage: G = PermutationGroup([[(1,2),(3,4),(5,6),(7,8,9,10)]]); G + Permutation Group with generators [(1,2)(3,4)(5,6)(7,8,9,10)] + sage: H = PermutationGroup([[(1,2,3,4),(5,6),(7,8),(9,10)]]); H + Permutation Group with generators [(1,2,3,4)(5,6)(7,8)(9,10)] + sage: hash(C(G)) == hash(C(H)) + True - sage: from sage.rings.species import ConjugacyClassesOfDirectlyIndecomposableSubgroups - sage: C = ConjugacyClassesOfDirectlyIndecomposableSubgroups() sage: G = PermutationGroup([[(1,3),(4,7)], [(2,5),(6,8)], [(1,4),(2,5),(3,7)]]) - sage: C(G) # indirect doctest - ((5,6)(7,8), (1,2)(3,4), (1,3)(2,4)(5,6)) + sage: hash(C(G)) == hash((8, 8, (2, 2, 4))) + True """ - if self._C == SymmetricGroup(0): - return - sorted_orbits = sorted((sorted(orbit) for orbit in self._C.orbits()), - key=len, reverse=True) - pi = PermutationGroupElement(list(chain.from_iterable(sorted_orbits))).inverse() - self._C = PermutationGroup(self._C.gens_small(), domain=self._C.domain()).conjugate(pi) + assert self._C.degree() == sum(tuple(sorted(len(orbit) for orbit in self._C.orbits()))) + return hash((self._C.degree(), + self._C.cardinality(), + tuple(sorted(len(orbit) for orbit in self._C.orbits())))) def __eq__(self, other): r""" @@ -183,13 +174,14 @@ def __eq__(self, other): sage: C(G) == C(H) True """ - return (isinstance(other, ConjugacyClassOfDirectlyIndecomposableSubgroups) - and (d := self._C.degree()) == other._C.degree() - and (self._C == other._C - or SymmetricGroup(d).are_conjugate(self._C, other._C))) + return (self is other + or (isinstance(other, ConjugacyClassOfDirectlyIndecomposableSubgroups) + and (d := self._C.degree()) == other._C.degree() + and (self._C == other._C + or SymmetricGroup(d).are_conjugate(self._C, other._C)))) -class ConjugacyClassesOfDirectlyIndecomposableSubgroups(UniqueRepresentation, Parent, ElementCache): +class ConjugacyClassesOfDirectlyIndecomposableSubgroups(UniqueRepresentation, Parent, UniqueElements): def __init__(self): r""" Conjugacy classes of directly indecomposable subgroups. @@ -201,7 +193,7 @@ def __init__(self): sage: TestSuite(C).run(max_runs=5) # It takes far too long otherwise """ Parent.__init__(self, category=InfiniteEnumeratedSets()) - ElementCache.__init__(self) + UniqueElements.__init__(self) @cached_method def an_element(self): @@ -217,6 +209,27 @@ def an_element(self): """ return self._element_constructor_(SymmetricGroup(1)) + def _standardize(self, elm): + r""" + Return a representative of the same conjugacy class by sorting the orbits by + length and making them consecutive. + + EXAMPLES:: + + sage: from sage.rings.species import ConjugacyClassesOfDirectlyIndecomposableSubgroups + sage: C = ConjugacyClassesOfDirectlyIndecomposableSubgroups() + sage: G = PermutationGroup([[(1,3),(4,7)], [(2,5),(6,8)], [(1,4),(2,5),(3,7)]]) + sage: C(G) # indirect doctest + ((5,6)(7,8), (1,2)(3,4), (1,3)(2,4)(5,6)) + """ + if elm._C == SymmetricGroup(0): + return elm + sorted_orbits = sorted((sorted(orbit) for orbit in elm._C.orbits()), + key=len, reverse=True) + pi = PermutationGroupElement(list(chain.from_iterable(sorted_orbits))).inverse() + G = PermutationGroup(elm._C.gens_small(), domain=elm._C.domain()).conjugate(pi) + return self.element_class(self, G) + def _element_constructor_(self, x): r""" ``x`` is an element of ``self`` or a group `H` such that @@ -242,12 +255,11 @@ def _element_constructor_(self, x): normalized_gens = [[tuple(mapping[x] for x in cyc) for cyc in gen.cycle_tuples()] for gen in x.gens()] - P = PermutationGroup(gens=normalized_gens) + G = PermutationGroup(gens=normalized_gens) # Fix for SymmetricGroup(0) if x.degree() == 0: - P = SymmetricGroup(0) - elm = self.element_class(self, P) - return self._cache_get(elm) + G = SymmetricGroup(0) + return self._cache_get(self.element_class(self, G)) raise ValueError(f"unable to convert {x} to {self}") def __iter__(self): @@ -259,9 +271,9 @@ def __iter__(self): sage: from sage.rings.species import ConjugacyClassesOfDirectlyIndecomposableSubgroups sage: C = ConjugacyClassesOfDirectlyIndecomposableSubgroups() - sage: iterC = iter(C) + sage: it = iter(C) sage: for i in range(5): - ....: print(next(iterC)) + ....: print(next(it)) () ((),) ((1,2),) @@ -328,10 +340,6 @@ def __init__(self, parent, dis, domain_partition): sage: G = PermutationGroup([[(1,3),(4,7)], [(2,5),(6,8)], [(1,4),(2,5),(3,7)]]) sage: TestSuite(A(G)).run() """ - # Notice that a molecular species (and therefore an atomic species) - # must be centered on a multicardinality, otherwise it wouldn't be - # molecular. So it is kind of redundant to say "atomic species - # centered on a given multicardinality." Element.__init__(self, parent) self._dis = dis self._dompart = domain_partition @@ -353,29 +361,29 @@ def grade(self): S = self.parent().grading_set() return S(self._mc) - def _element_key(self): + def __hash__(self): r""" - Return the cache lookup key for ``self``. + Return the hash of the atomic species. + + Note that this serves also as lookup key in the cache. TESTS:: sage: A = AtomicSpecies("X, Y") sage: G = PermutationGroup([[(1,2),(3,4),(5,6),(7,8,9,10)]]); G Permutation Group with generators [(1,2)(3,4)(5,6)(7,8,9,10)] + sage: H = PermutationGroup([[(1,2,3,4),(5,6),(7,8),(9,10)]]); H + Permutation Group with generators [(1,2,3,4)(5,6)(7,8)(9,10)] sage: a = A(G, {0: [1,2,3,4], 1: [5,6,7,8,9,10]}); a {((1,2,3,4)(5,6)(7,8)(9,10),): ({5, 6, 7, 8}, {1, 2, 3, 4, 9, 10})} - sage: a._element_key() - ((4, 6), ((1,2,3,4)(5,6)(7,8)(9,10),)) - """ - return self._mc, self._dis - - @cached_method - def _canonicalize(self): - r""" - Canonicalize this atomic species by sorting the orbits by - length and making them consecutive. - - EXAMPLES:: + sage: b = A(H, {0: [1,2,3,4], 1: [5,6,7,8,9,10]}); b + {((1,2,3,4)(5,6)(7,8)(9,10),): ({1, 2, 3, 4}, {5, 6, 7, 8, 9, 10})} + sage: c = A(G, {0: [1,2,5,6], 1: [3,4,7,8,9,10]}); c + {((1,2,3,4)(5,6)(7,8)(9,10),): ({5, 6, 7, 8}, {1, 2, 3, 4, 9, 10})} + sage: hash(a) == hash(b) + True + sage: hash(a) == hash(c) + True sage: A = AtomicSpecies("X, Y") sage: G = PermutationGroup([[(1,2),(3,4),(5,6),(7,8,9,10)]]); G @@ -385,32 +393,7 @@ def _canonicalize(self): sage: A(G, {0: [1,2,5,6], 1: [3,4,7,8,9,10]}) is f # indirect doctest True """ - # The canonicalization is done in the element constructor. - pass - - def __hash__(self): - r""" - Return the hash of the atomic species. - - TESTS:: - - sage: At = AtomicSpecies("X, Y") - sage: G = PermutationGroup([[(1,2),(3,4),(5,6),(7,8,9,10)]]); G - Permutation Group with generators [(1,2)(3,4)(5,6)(7,8,9,10)] - sage: H = PermutationGroup([[(1,2,3,4),(5,6),(7,8),(9,10)]]); H - Permutation Group with generators [(1,2,3,4)(5,6)(7,8)(9,10)] - sage: A = At(G, {0: [1,2,3,4], 1: [5,6,7,8,9,10]}); A - {((1,2,3,4)(5,6)(7,8)(9,10),): ({5, 6, 7, 8}, {1, 2, 3, 4, 9, 10})} - sage: B = At(H, {0: [1,2,3,4], 1: [5,6,7,8,9,10]}); B - {((1,2,3,4)(5,6)(7,8)(9,10),): ({1, 2, 3, 4}, {5, 6, 7, 8, 9, 10})} - sage: C = At(G, {0: [1,2,5,6], 1: [3,4,7,8,9,10]}); C - {((1,2,3,4)(5,6)(7,8)(9,10),): ({5, 6, 7, 8}, {1, 2, 3, 4, 9, 10})} - sage: hash(A) == hash(B) - True - sage: hash(A) == hash(C) - True - """ - return hash(self._element_key()) + return hash((self._mc, self._dis)) def __eq__(self, other): r""" @@ -419,19 +402,21 @@ def __eq__(self, other): TESTS:: - sage: At = AtomicSpecies("X, Y") + sage: A = AtomicSpecies("X, Y") sage: G = PermutationGroup([[(1,2),(3,4),(5,6),(7,8,9,10)]]); G Permutation Group with generators [(1,2)(3,4)(5,6)(7,8,9,10)] sage: H = PermutationGroup([[(1,2,3,4),(5,6),(7,8),(9,10)]]); H Permutation Group with generators [(1,2,3,4)(5,6)(7,8)(9,10)] - sage: A = At(G, {0: [1,2,3,4], 1: [5,6,7,8,9,10]}) - sage: B = At(H, {0: [1,2,3,4], 1: [5,6,7,8,9,10]}) - sage: C = At(G, {0: [1,2,5,6], 1: [3,4,7,8,9,10]}) - sage: A != B + sage: a = A(G, {0: [1,2,3,4], 1: [5,6,7,8,9,10]}) + sage: b = A(H, {0: [1,2,3,4], 1: [5,6,7,8,9,10]}) + sage: c = A(G, {0: [1,2,5,6], 1: [3,4,7,8,9,10]}) + sage: a != b True - sage: A == C + sage: a == c True """ + if self is other: + return True if parent(self) != parent(other): return False # Check if multicardinalities match @@ -471,7 +456,7 @@ def _repr_(self): return "{" + f"{self._dis}: ({dompart})" + "}" -class AtomicSpecies(UniqueRepresentation, Parent, ElementCache): +class AtomicSpecies(UniqueRepresentation, Parent, UniqueElements): @staticmethod def __classcall__(cls, names): """ @@ -501,14 +486,14 @@ def __init__(self, names): TESTS:: - sage: At1 = AtomicSpecies(["X"]) - sage: At2 = AtomicSpecies(["X", "Y"]) - sage: TestSuite(At1).run(skip="_test_graded_components") - sage: TestSuite(At2).run(skip="_test_graded_components") + sage: A1 = AtomicSpecies(["X"]) + sage: A2 = AtomicSpecies(["X", "Y"]) + sage: TestSuite(A1).run(skip="_test_graded_components") + sage: TestSuite(A2).run(skip="_test_graded_components") """ category = SetsWithGrading().Infinite() Parent.__init__(self, names=names, category=category) - ElementCache.__init__(self) + UniqueElements.__init__(self) self._arity = len(names) self._renamed = set() # the degrees that have been renamed already From 51326d2452c5606f431206441ddf2f6a079754c8 Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Wed, 25 Sep 2024 19:10:43 +0200 Subject: [PATCH 220/537] remove debugging statement --- src/sage/rings/species.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/sage/rings/species.py b/src/sage/rings/species.py index dd07d353a1c..13ae1ac92fd 100644 --- a/src/sage/rings/species.py +++ b/src/sage/rings/species.py @@ -151,7 +151,6 @@ def __hash__(self): sage: hash(C(G)) == hash((8, 8, (2, 2, 4))) True """ - assert self._C.degree() == sum(tuple(sorted(len(orbit) for orbit in self._C.orbits()))) return hash((self._C.degree(), self._C.cardinality(), tuple(sorted(len(orbit) for orbit in self._C.orbits())))) From 0e0ae47a9307ca6194901b110c4232014c473da3 Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Wed, 25 Sep 2024 22:55:42 +0200 Subject: [PATCH 221/537] simpler and less buggy by using UniqueRepresentation --- src/sage/rings/species.py | 370 +++++++++++++++----------------------- 1 file changed, 145 insertions(+), 225 deletions(-) diff --git a/src/sage/rings/species.py b/src/sage/rings/species.py index 13ae1ac92fd..f58f49146b7 100644 --- a/src/sage/rings/species.py +++ b/src/sage/rings/species.py @@ -16,6 +16,7 @@ from sage.groups.perm_gps.permgroup_named import SymmetricGroup from sage.libs.gap.libgap import libgap from sage.misc.cachefunc import cached_method +from sage.misc.inherit_comparison import InheritComparisonClasscallMetaclass from sage.modules.free_module_element import vector from sage.monoids.indexed_free_monoid import (IndexedFreeAbelianMonoid, IndexedFreeAbelianMonoidElement) @@ -27,84 +28,76 @@ from sage.structure.unique_representation import UniqueRepresentation -class UniqueElements(): +class ConjugacyClassOfDirectlyIndecomposableSubgroups(UniqueRepresentation, Element, + metaclass=InheritComparisonClasscallMetaclass): r""" - A class for ensuring that equal elements are identical. + A directly indecomposable conjugacy class of subgroups of a + symmetric group. - This class creates a cache, which is a dictionary mapping - invariants to lists of distinct elements. + Two conjugacy classes of subgroups are equal if they have the + same degree (say `n`) and are conjugate within `S_n`. """ - def __init__(self): - r""" - Initialize the cache. + @staticmethod + def __classcall__(cls, parent, C): """ - self._cache = dict() - - def _cache_get(self, elm): - r""" - Return the cached element, adding it to the cache if it has not - been encountered yet. - - INPUT: - - - ``elm``, a hashable element. - - The parent of ``elm`` may additionally implement a method - ``_standardize`` that preprocesses the element before it is - put in the cache. + Normalize the input for unique representation. - TESTS: - - Two different groups with the same hash:: + TESTS:: sage: from sage.rings.species import ConjugacyClassesOfDirectlyIndecomposableSubgroups sage: C = ConjugacyClassesOfDirectlyIndecomposableSubgroups() - sage: G = C(PermutationGroup([[(1,3),(2,4)], [(1,4),(2,3)]])) - sage: H = C(PermutationGroup([[(1,3,2,4)]])) - sage: C._cache[hash(G)] - [((1,3)(2,4), (1,4)(2,3)), ((1,3,2,4),)] - sage: A = AtomicSpecies("X, Y") + Check that the domain is standardized:: + + sage: G = PermutationGroup([("a", "b", "c"), ("d", "a"), ("d", "b"), ("d", "c")]) + sage: C(G) + ((2,4,3), (1,2)) + sage: G = PermutationGroup([[(1,2),(3,4),(5,6),(7,8,9,10)]]); G Permutation Group with generators [(1,2)(3,4)(5,6)(7,8,9,10)] - sage: a = A(G, {0: [1,2,3,4], 1: [5,6,7,8,9,10]}); a - {((1,2,3,4)(5,6)(7,8)(9,10),): ({5, 6, 7, 8}, {1, 2, 3, 4, 9, 10})} - sage: b = A(G, {0: [1,2,5,6], 1: [3,4,7,8,9,10]}); b - {((1,2,3,4)(5,6)(7,8)(9,10),): ({5, 6, 7, 8}, {1, 2, 3, 4, 9, 10})} - sage: a is b + sage: H = PermutationGroup([[(1,2,3,4),(5,6),(7,8),(9,10)]]); H + Permutation Group with generators [(1,2,3,4)(5,6)(7,8)(9,10)] + sage: C(G) is C(H) True - sage: from sage.rings.species import UniqueElements - sage: E = UniqueElements() - sage: E._cache_get(a) - {((1,2,3,4)(5,6)(7,8)(9,10),): ({5, 6, 7, 8}, {1, 2, 3, 4, 9, 10})} - """ - key = hash(elm) - if key in self._cache: - lookup = self._cache[key] - for other_elm in lookup: - if elm == other_elm: - return other_elm - elm = self._standardize(elm) - lookup.append(elm) - else: - elm = self._standardize(elm) - self._cache[key] = [elm] - return elm - def _standardize(self, elm): - r""" - Return a standardized representation of ``elm``. + Two different transitive groups with the same cardinality:: - This method can be implemented to transform elements in a way - that is more expensive than comparing them. + sage: a = C(PermutationGroup([[(1,3),(2,4)], [(1,4),(2,3)]])) + sage: b = C(PermutationGroup([[(1,3,2,4)]])) + sage: a == b + False """ - return elm + def is_equal(elm): + return SymmetricGroup(elm._C.degree()).are_conjugate(elm._C, C) + + def standardize(C): + if not C.degree(): + return SymmetricGroup(0) + # an directly indecomposable group is transitive, so we + # can use the gap group without worrying about the domain + G = C.gap() + sorted_orbits = sorted(G.Orbits().sage(), key=len, reverse=True) + pi = PermutationGroupElement([e for o in sorted_orbits for e in o]) + G = PermutationGroup(G.SmallGeneratingSet().sage()) + return G.conjugate(pi.inverse()) + + key = C.cardinality(), tuple(sorted(len(o) for o in C.orbits())) + if key in parent._cache: + lookup = parent._cache[key] + for elm in lookup: + if is_equal(elm): + return elm + else: + lookup = parent._cache[key] = [] + elm = super().__classcall__(cls, parent, standardize(C)) + lookup.append(elm) + return elm -class ConjugacyClassOfDirectlyIndecomposableSubgroups(Element): def __init__(self, parent, C): r""" - A conjugacy class of directly indecomposable subgroups. + Initialize a conjugacy class of directly indecomposable subgroups + of a symmetric group. TESTS:: @@ -112,6 +105,7 @@ def __init__(self, parent, C): sage: C = ConjugacyClassesOfDirectlyIndecomposableSubgroups() sage: G = C(PermutationGroup([[(1,2),(3,4)],[(1,2),(5,6)]])) sage: TestSuite(G).run() + """ Element.__init__(self, parent) self._C = C @@ -130,60 +124,11 @@ def _repr_(self): """ return f"{self._C.gens()}" - def __hash__(self): - r""" - Return the hash of ``self``. - - Note that this serves also as lookup key in the cache. - - TESTS:: - sage: from sage.rings.species import ConjugacyClassesOfDirectlyIndecomposableSubgroups - sage: C = ConjugacyClassesOfDirectlyIndecomposableSubgroups() - sage: G = PermutationGroup([[(1,2),(3,4),(5,6),(7,8,9,10)]]); G - Permutation Group with generators [(1,2)(3,4)(5,6)(7,8,9,10)] - sage: H = PermutationGroup([[(1,2,3,4),(5,6),(7,8),(9,10)]]); H - Permutation Group with generators [(1,2,3,4)(5,6)(7,8)(9,10)] - sage: hash(C(G)) == hash(C(H)) - True - - sage: G = PermutationGroup([[(1,3),(4,7)], [(2,5),(6,8)], [(1,4),(2,5),(3,7)]]) - sage: hash(C(G)) == hash((8, 8, (2, 2, 4))) - True - """ - return hash((self._C.degree(), - self._C.cardinality(), - tuple(sorted(len(orbit) for orbit in self._C.orbits())))) - - def __eq__(self, other): - r""" - Return whether ``self`` is equal to ``other``. - - ``self`` is equal to ``other`` if they have the same degree (say `n`) - and are conjugate within `S_n`. - - TESTS:: - - sage: from sage.rings.species import ConjugacyClassesOfDirectlyIndecomposableSubgroups - sage: C = ConjugacyClassesOfDirectlyIndecomposableSubgroups() - sage: G = PermutationGroup([[(1,2),(3,4),(5,6),(7,8,9,10)]]); G - Permutation Group with generators [(1,2)(3,4)(5,6)(7,8,9,10)] - sage: H = PermutationGroup([[(1,2,3,4),(5,6),(7,8),(9,10)]]); H - Permutation Group with generators [(1,2,3,4)(5,6)(7,8)(9,10)] - sage: C(G) == C(H) - True - """ - return (self is other - or (isinstance(other, ConjugacyClassOfDirectlyIndecomposableSubgroups) - and (d := self._C.degree()) == other._C.degree() - and (self._C == other._C - or SymmetricGroup(d).are_conjugate(self._C, other._C)))) - - -class ConjugacyClassesOfDirectlyIndecomposableSubgroups(UniqueRepresentation, Parent, UniqueElements): +class ConjugacyClassesOfDirectlyIndecomposableSubgroups(UniqueRepresentation, Parent): def __init__(self): r""" - Conjugacy classes of directly indecomposable subgroups. + Conjugacy classes of directly indecomposable subgroups of a symmetric group. TESTS:: @@ -192,7 +137,7 @@ def __init__(self): sage: TestSuite(C).run(max_runs=5) # It takes far too long otherwise """ Parent.__init__(self, category=InfiniteEnumeratedSets()) - UniqueElements.__init__(self) + self._cache = dict() @cached_method def an_element(self): @@ -208,31 +153,14 @@ def an_element(self): """ return self._element_constructor_(SymmetricGroup(1)) - def _standardize(self, elm): + def _element_constructor_(self, x): r""" - Return a representative of the same conjugacy class by sorting the orbits by - length and making them consecutive. - - EXAMPLES:: + Construct a conjugacy class from ``x``. - sage: from sage.rings.species import ConjugacyClassesOfDirectlyIndecomposableSubgroups - sage: C = ConjugacyClassesOfDirectlyIndecomposableSubgroups() - sage: G = PermutationGroup([[(1,3),(4,7)], [(2,5),(6,8)], [(1,4),(2,5),(3,7)]]) - sage: C(G) # indirect doctest - ((5,6)(7,8), (1,2)(3,4), (1,3)(2,4)(5,6)) - """ - if elm._C == SymmetricGroup(0): - return elm - sorted_orbits = sorted((sorted(orbit) for orbit in elm._C.orbits()), - key=len, reverse=True) - pi = PermutationGroupElement(list(chain.from_iterable(sorted_orbits))).inverse() - G = PermutationGroup(elm._C.gens_small(), domain=elm._C.domain()).conjugate(pi) - return self.element_class(self, G) + INPUT: - def _element_constructor_(self, x): - r""" - ``x`` is an element of ``self`` or a group `H` such that - `H` is directly indecomposable. + - ``x``, an element of ``self`` or a directly indecomposable + permutation group. EXAMPLES:: @@ -250,15 +178,7 @@ def _element_constructor_(self, x): if isinstance(x, PermutationGroup_generic): if len(x.disjoint_direct_product_decomposition()) > 1: raise ValueError(f"{x} is not directly indecomposable") - mapping = {v: i for i, v in enumerate(x.domain(), 1)} - normalized_gens = [[tuple(mapping[x] for x in cyc) - for cyc in gen.cycle_tuples()] - for gen in x.gens()] - G = PermutationGroup(gens=normalized_gens) - # Fix for SymmetricGroup(0) - if x.degree() == 0: - G = SymmetricGroup(0) - return self._cache_get(self.element_class(self, G)) + return self.element_class(self, x) raise ValueError(f"unable to convert {x} to {self}") def __iter__(self): @@ -320,7 +240,74 @@ def _repr_(self): Element = ConjugacyClassOfDirectlyIndecomposableSubgroups -class AtomicSpeciesElement(Element): +class AtomicSpeciesElement(UniqueRepresentation, Element, + metaclass=InheritComparisonClasscallMetaclass): + r""" + An atomic species. + + Two atomic species are equal if the underlying groups are + conjugate, and their domain partitions are equal under the + conjugating element. + """ + @staticmethod + def __classcall__(cls, parent, dis, domain_partition): + r""" + Normalize the input for unique representation. + + TESTS:: + + sage: A = AtomicSpecies("X, Y") + + Check that the domain is irrelevant:: + + sage: G = PermutationGroup([[("a", "b", "c", "d"), ("e", "f")]]) + sage: A(G, {0: "abcd", 1: "ef"}) + {((1,2,3,4)(5,6),): ({1, 2, 3, 4}, {5, 6})} + + sage: G = PermutationGroup([[(1,2),(3,4),(5,6),(7,8,9,10)]]); G + Permutation Group with generators [(1,2)(3,4)(5,6)(7,8,9,10)] + sage: H = PermutationGroup([[(1,2,3,4),(5,6),(7,8),(9,10)]]); H + Permutation Group with generators [(1,2,3,4)(5,6)(7,8)(9,10)] + sage: a = A(G, {0: [1,2,3,4], 1: [5,6,7,8,9,10]}); a + {((1,2,3,4)(5,6)(7,8)(9,10),): ({5, 6, 7, 8}, {1, 2, 3, 4, 9, 10})} + sage: b = A(H, {0: [1,2,3,4], 1: [5,6,7,8,9,10]}); b + {((1,2,3,4)(5,6)(7,8)(9,10),): ({1, 2, 3, 4}, {5, 6, 7, 8, 9, 10})} + sage: c = A(G, {0: [1,2,5,6], 1: [3,4,7,8,9,10]}); c + {((1,2,3,4)(5,6)(7,8)(9,10),): ({5, 6, 7, 8}, {1, 2, 3, 4, 9, 10})} + sage: a == b + False + sage: a is c + True + """ + mc = tuple(len(v) for v in domain_partition) + domain = list(chain(*map(sorted, domain_partition))) + + def is_equal(elm): + # check if multicardinalities match + if elm._mc != mc: + return False + # If they do, construct the mapping between the groups + elm_domain = list(chain(*map(sorted, elm._dompart))) + mapping = libgap.MappingPermListList(elm_domain, domain) + G = PermutationGroup(gap_group=libgap.ConjugateGroup(elm._dis._C, + mapping), + domain=elm._dis._C.domain()) + # The conjugated group must be exactly equal to the other group + return G == dis._C + + key = mc, dis + if key in parent._cache: + lookup = parent._cache[key] + for elm in lookup: + if is_equal(elm): + return elm + else: + lookup = parent._cache[key] = [] + + elm = super().__classcall__(cls, parent, dis, domain_partition) + lookup.append(elm) + return elm + def __init__(self, parent, dis, domain_partition): r""" Initialize an atomic species. @@ -338,6 +325,9 @@ def __init__(self, parent, dis, domain_partition): sage: A = AtomicSpecies("X") sage: G = PermutationGroup([[(1,3),(4,7)], [(2,5),(6,8)], [(1,4),(2,5),(3,7)]]) sage: TestSuite(A(G)).run() + + sage: loads(dumps(A(G))) is A(G) + True """ Element.__init__(self, parent) self._dis = dis @@ -360,80 +350,6 @@ def grade(self): S = self.parent().grading_set() return S(self._mc) - def __hash__(self): - r""" - Return the hash of the atomic species. - - Note that this serves also as lookup key in the cache. - - TESTS:: - - sage: A = AtomicSpecies("X, Y") - sage: G = PermutationGroup([[(1,2),(3,4),(5,6),(7,8,9,10)]]); G - Permutation Group with generators [(1,2)(3,4)(5,6)(7,8,9,10)] - sage: H = PermutationGroup([[(1,2,3,4),(5,6),(7,8),(9,10)]]); H - Permutation Group with generators [(1,2,3,4)(5,6)(7,8)(9,10)] - sage: a = A(G, {0: [1,2,3,4], 1: [5,6,7,8,9,10]}); a - {((1,2,3,4)(5,6)(7,8)(9,10),): ({5, 6, 7, 8}, {1, 2, 3, 4, 9, 10})} - sage: b = A(H, {0: [1,2,3,4], 1: [5,6,7,8,9,10]}); b - {((1,2,3,4)(5,6)(7,8)(9,10),): ({1, 2, 3, 4}, {5, 6, 7, 8, 9, 10})} - sage: c = A(G, {0: [1,2,5,6], 1: [3,4,7,8,9,10]}); c - {((1,2,3,4)(5,6)(7,8)(9,10),): ({5, 6, 7, 8}, {1, 2, 3, 4, 9, 10})} - sage: hash(a) == hash(b) - True - sage: hash(a) == hash(c) - True - - sage: A = AtomicSpecies("X, Y") - sage: G = PermutationGroup([[(1,2),(3,4),(5,6),(7,8,9,10)]]); G - Permutation Group with generators [(1,2)(3,4)(5,6)(7,8,9,10)] - sage: f = A(G, {0: [1,2,3,4], 1: [5,6,7,8,9,10]}); f - {((1,2,3,4)(5,6)(7,8)(9,10),): ({5, 6, 7, 8}, {1, 2, 3, 4, 9, 10})} - sage: A(G, {0: [1,2,5,6], 1: [3,4,7,8,9,10]}) is f # indirect doctest - True - """ - return hash((self._mc, self._dis)) - - def __eq__(self, other): - r""" - Two atomic species are equal if the underlying groups are conjugate, - and their domain partitions are equal under the conjugating element. - - TESTS:: - - sage: A = AtomicSpecies("X, Y") - sage: G = PermutationGroup([[(1,2),(3,4),(5,6),(7,8,9,10)]]); G - Permutation Group with generators [(1,2)(3,4)(5,6)(7,8,9,10)] - sage: H = PermutationGroup([[(1,2,3,4),(5,6),(7,8),(9,10)]]); H - Permutation Group with generators [(1,2,3,4)(5,6)(7,8)(9,10)] - sage: a = A(G, {0: [1,2,3,4], 1: [5,6,7,8,9,10]}) - sage: b = A(H, {0: [1,2,3,4], 1: [5,6,7,8,9,10]}) - sage: c = A(G, {0: [1,2,5,6], 1: [3,4,7,8,9,10]}) - sage: a != b - True - sage: a == c - True - """ - if self is other: - return True - if parent(self) != parent(other): - return False - # Check if multicardinalities match - if self._mc != other._mc: - return False - # If they do, construct the mapping between the groups - selflist, otherlist = [], [] - for i in range(self.parent()._arity): - if len(self._dompart[i]) != len(other._dompart[i]): - return False - selflist.extend(sorted(list(self._dompart[i]))) - otherlist.extend(sorted(list(other._dompart[i]))) - mapping = libgap.MappingPermListList(selflist, otherlist) - G = PermutationGroup(gap_group=libgap.ConjugateGroup(self._dis._C, mapping), - domain=self._dis._C.domain()) - # The conjugated group must be exactly equal to the other group - return G == other._dis._C - def _repr_(self): r""" Return a string representation of ``self``. @@ -455,7 +371,10 @@ def _repr_(self): return "{" + f"{self._dis}: ({dompart})" + "}" -class AtomicSpecies(UniqueRepresentation, Parent, UniqueElements): +class AtomicSpecies(UniqueRepresentation, Parent): + """ + The class of atomic species. + """ @staticmethod def __classcall__(cls, names): """ @@ -492,8 +411,8 @@ def __init__(self, names): """ category = SetsWithGrading().Infinite() Parent.__init__(self, names=names, category=category) - UniqueElements.__init__(self) self._arity = len(names) + self._cache = dict() self._renamed = set() # the degrees that have been renamed already def grading_set(self): @@ -583,13 +502,14 @@ def _element_constructor_(self, G, pi=None): for orbit in G.orbits(): if not any(set(orbit).issubset(p) for p in pi.values()): raise ValueError(f"All elements of orbit {orbit} must have the same sort") + # TODO: perhaps move to AtomicSpeciesElement.__classcall__ dis_elm = ConjugacyClassesOfDirectlyIndecomposableSubgroups()(G) mapping = {v: i for i, v in enumerate(G.domain(), 1)} - O = sorted(G.orbits(), key=len, reverse=True) - mapping2 = PermutationGroupElement([mapping[e] for o in O for e in o]).inverse() + sorted_orbits = sorted(G.orbits(), key=len, reverse=True) + mapping2 = PermutationGroupElement([mapping[e] for o in sorted_orbits for e in o]).inverse() dompart = [frozenset(mapping2(mapping[x]) for x in pi.get(k, [])) for k in range(self._arity)] - elm = self._cache_get(self.element_class(self, dis_elm, tuple(dompart))) + elm = self.element_class(self, dis_elm, tuple(dompart)) if elm._tc not in self._renamed: self._rename(elm._tc) return elm @@ -1184,7 +1104,7 @@ def _compose_with_singletons(self, base_ring, names, args): sage: M = MolecularSpecies("X") sage: C4 = M(CyclicPermutationGroup(4)) sage: C4._compose_with_singletons(ZZ, "X, Y", [[2, 2]]) # X^2Y^2 + C2(XY) - E_2(XY) + X^2*Y^2 + X^2*Y^2 + E_2(XY) sage: M = MolecularSpecies(["X", "Y"]) sage: F = M(PermutationGroup([[(1,2,3), (4,5,6)]]), {0: [1,2,3], 1: [4,5,6]}) @@ -1772,7 +1692,7 @@ def _compose_with_weighted_singletons(self, names, multiplicities, degrees): Exercise (2.5.17) in [BLL1998]_:: sage: C4._compose_with_weighted_singletons(["X", "Y"], [1, 1], [[2, 2]]) - E_2(XY) + X^2*Y^2 + X^2*Y^2 + E_2(XY) sage: C4._compose_with_weighted_singletons(["X", "Y"], [1, 1], [[3, 1]]) X^3*Y sage: C4._compose_with_weighted_singletons(["X", "Y"], [1, 1], [[4, 0]]) @@ -1781,7 +1701,7 @@ def _compose_with_weighted_singletons(self, names, multiplicities, degrees): Auger et al., Equation (4.60):: sage: C4._compose_with_weighted_singletons(["X", "Y"], [1, -1], [[2, 2]]) - -E_2(XY) + 2*X^2*Y^2 + 2*X^2*Y^2 - E_2(XY) TESTS:: From cc40a27218fbb93577d3aa1fa21ef90858aeadad Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Thu, 26 Sep 2024 09:19:03 +0200 Subject: [PATCH 222/537] make homogeneous_degree work if the monomials are not comparable --- .../categories/filtered_modules_with_basis.py | 2 +- src/sage/rings/species.py | 35 +++++++------------ 2 files changed, 14 insertions(+), 23 deletions(-) diff --git a/src/sage/categories/filtered_modules_with_basis.py b/src/sage/categories/filtered_modules_with_basis.py index cb1df2f0bba..bdb170223c8 100644 --- a/src/sage/categories/filtered_modules_with_basis.py +++ b/src/sage/categories/filtered_modules_with_basis.py @@ -854,7 +854,7 @@ def homogeneous_degree(self): raise ValueError("the zero element does not have a well-defined degree") if not self.is_homogeneous(): raise ValueError("element is not homogeneous") - return self.parent().degree_on_basis(self.leading_support()) + return self.parent().degree_on_basis(next(iter(self.support()))) # default choice for degree; will be overridden as necessary degree = homogeneous_degree diff --git a/src/sage/rings/species.py b/src/sage/rings/species.py index f58f49146b7..08a6670c2d9 100644 --- a/src/sage/rings/species.py +++ b/src/sage/rings/species.py @@ -1498,6 +1498,19 @@ def factor(s, c, d): for s in range(self._arity)) class Element(CombinatorialFreeModule.Element): + r""" + Multivariate polynomial (virtual) species. + + TESTS:: + + sage: P = PolynomialSpecies(ZZ, ["X"]) + sage: C3 = P(CyclicPermutationGroup(3)) + sage: X = P(SymmetricGroup(1)) + sage: E2 = P(SymmetricGroup(2)) + sage: (E2*X + C3).homogeneous_degree() + 3 + """ + def is_constant(self): """ Return ``True`` if this is a constant polynomial species. @@ -1517,28 +1530,6 @@ def is_constant(self): """ return self.is_zero() or not self.maximal_degree() - def homogeneous_degree(self): - """ - - ..TODO:: - - This implementation should not be necessary. - - EXAMPLES:: - - sage: P = PolynomialSpecies(ZZ, ["X"]) - sage: C3 = P(CyclicPermutationGroup(3)) - sage: X = P(SymmetricGroup(1)) - sage: E2 = P(SymmetricGroup(2)) - sage: (E2*X + C3).homogeneous_degree() - 3 - """ - if not self.support(): - raise ValueError("the zero element does not have a well-defined degree") - if not self.is_homogeneous(): - raise ValueError("element is not homogeneous") - return self.parent().degree_on_basis(self.support()[0]) - def is_virtual(self): r""" Return if ``self`` is a virtual species. From 8b7a09635f780baf82459a5dec511868e2c2c9a4 Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Thu, 26 Sep 2024 10:37:14 +0200 Subject: [PATCH 223/537] beautify --- src/sage/rings/species.py | 1094 +++++++++++++++++++------------------ 1 file changed, 549 insertions(+), 545 deletions(-) diff --git a/src/sage/rings/species.py b/src/sage/rings/species.py index 08a6670c2d9..3c916b9eff9 100644 --- a/src/sage/rings/species.py +++ b/src/sage/rings/species.py @@ -139,20 +139,6 @@ def __init__(self): Parent.__init__(self, category=InfiniteEnumeratedSets()) self._cache = dict() - @cached_method - def an_element(self): - r""" - Return an element of ``self``. - - EXAMPLES:: - - sage: from sage.rings.species import ConjugacyClassesOfDirectlyIndecomposableSubgroups - sage: C = ConjugacyClassesOfDirectlyIndecomposableSubgroups() - sage: C.an_element() - ((),) - """ - return self._element_constructor_(SymmetricGroup(1)) - def _element_constructor_(self, x): r""" Construct a conjugacy class from ``x``. @@ -181,6 +167,18 @@ def _element_constructor_(self, x): return self.element_class(self, x) raise ValueError(f"unable to convert {x} to {self}") + def _repr_(self): + r""" + Return the string representation for ``self``. + + TESTS:: + + sage: from sage.rings.species import ConjugacyClassesOfDirectlyIndecomposableSubgroups + sage: C = ConjugacyClassesOfDirectlyIndecomposableSubgroups(); C + Infinite set of conjugacy classes of directly indecomposable subgroups + """ + return "Infinite set of conjugacy classes of directly indecomposable subgroups" + def __iter__(self): r""" An iterator over all conjugacy classes of directly indecomposable @@ -225,17 +223,19 @@ def __contains__(self, G): return True return len(G.disjoint_direct_product_decomposition()) <= 1 - def _repr_(self): + @cached_method + def an_element(self): r""" - Return the string representation for ``self``. + Return an element of ``self``. - TESTS:: + EXAMPLES:: sage: from sage.rings.species import ConjugacyClassesOfDirectlyIndecomposableSubgroups - sage: C = ConjugacyClassesOfDirectlyIndecomposableSubgroups(); C - Infinite set of conjugacy classes of directly indecomposable subgroups + sage: C = ConjugacyClassesOfDirectlyIndecomposableSubgroups() + sage: C.an_element() + ((),) """ - return "Infinite set of conjugacy classes of directly indecomposable subgroups" + return self._element_constructor_(SymmetricGroup(1)) Element = ConjugacyClassOfDirectlyIndecomposableSubgroups @@ -335,21 +335,6 @@ def __init__(self, parent, dis, domain_partition): self._mc = tuple(len(v) for v in self._dompart) self._tc = sum(self._mc) - def grade(self): - r""" - Return the grade of ``self``. - - EXAMPLES:: - - sage: A = AtomicSpecies("X, Y") - sage: G = PermutationGroup([[(1,2),(3,4),(5,6),(7,8,9,10)]]) - sage: a = A(G, {0: [1,2,3,4], 1: [5,6,7,8,9,10]}) - sage: a.grade() - [4, 6] - """ - S = self.parent().grading_set() - return S(self._mc) - def _repr_(self): r""" Return a string representation of ``self``. @@ -370,6 +355,21 @@ def _repr_(self): for b in self._dompart) return "{" + f"{self._dis}: ({dompart})" + "}" + def grade(self): + r""" + Return the grade of ``self``. + + EXAMPLES:: + + sage: A = AtomicSpecies("X, Y") + sage: G = PermutationGroup([[(1,2),(3,4),(5,6),(7,8,9,10)]]) + sage: a = A(G, {0: [1,2,3,4], 1: [5,6,7,8,9,10]}) + sage: a.grade() + [4, 6] + """ + S = self.parent().grading_set() + return S(self._mc) + class AtomicSpecies(UniqueRepresentation, Parent): """ @@ -415,40 +415,20 @@ def __init__(self, names): self._cache = dict() self._renamed = set() # the degrees that have been renamed already - def grading_set(self): + def _repr_(self): r""" - Return the set of non-negative integer vectors, whose length is - the arity of ``self``. - - EXAMPLES:: - - sage: AtomicSpecies(["X"]).grading_set() - Integer vectors of length 1 - """ - return IntegerVectors(length=self._arity) - - @cached_method - def an_element(self): - """ - Return an element of ``self``. + Return a string representation of ``self``. TESTS:: - sage: A = AtomicSpecies("X") - sage: A.an_element() - E_2 - - sage: A = AtomicSpecies("X, Y") - sage: a = A.an_element(); a - {((1,2)(3,4),): ({1, 2}, {3, 4})} - - sage: a.rename("E_2(XY)") - sage: a - E_2(XY) + sage: AtomicSpecies("X") + Atomic species in X + sage: AtomicSpecies("X, Y") + Atomic species in X, Y """ - G = PermutationGroup([[(2 * i + 1, 2 * i + 2) for i in range(self._arity)]]) - m = {i: [2 * i + 1, 2 * i + 2] for i in range(self._arity)} - return self._element_constructor_(G, m) + if len(self._names) == 1: + return f"Atomic species in {self._names[0]}" + return f"Atomic species in {', '.join(self._names)}" def _element_constructor_(self, G, pi=None): r""" @@ -480,7 +460,7 @@ def _element_constructor_(self, G, pi=None): sage: G = PermutationGroup([[(1,3),(5,7)]], domain=[1,3,5,7]) sage: A(G, ([1,3], [5,7])) - E_2(XY) + {((1,2)(3,4),): ({1, 2}, {3, 4})} """ if parent(G) == self: if pi is not None: @@ -613,20 +593,40 @@ def __contains__(self, x): raise ValueError(f"All elements of orbit {orbit} must have the same sort") return len(G.disjoint_direct_product_decomposition()) <= 1 - def _repr_(self): + def grading_set(self): r""" - Return a string representation of ``self``. + Return the set of non-negative integer vectors, whose length is + the arity of ``self``. + + EXAMPLES:: + + sage: AtomicSpecies(["X"]).grading_set() + Integer vectors of length 1 + """ + return IntegerVectors(length=self._arity) + + @cached_method + def an_element(self): + """ + Return an element of ``self``. TESTS:: - sage: AtomicSpecies("X") - Atomic species in X - sage: AtomicSpecies("X, Y") - Atomic species in X, Y + sage: A = AtomicSpecies("X") + sage: A.an_element() + E_2 + + sage: A = AtomicSpecies("X, Y") + sage: a = A.an_element(); a + {((1,2)(3,4),): ({1, 2}, {3, 4})} + + sage: a.rename("E_2(XY)") + sage: a + E_2(XY) """ - if len(self._names) == 1: - return f"Atomic species in {self._names[0]}" - return f"Atomic species in {', '.join(self._names)}" + G = PermutationGroup([[(2 * i + 1, 2 * i + 2) for i in range(self._arity)]]) + m = {i: [2 * i + 1, 2 * i + 2] for i in range(self._arity)} + return self._element_constructor_(G, m) Element = AtomicSpeciesElement @@ -745,43 +745,21 @@ def __init__(self, *args, **kwds): IndexedFreeAbelianMonoid.__init__(self, *args, **kwds) self._arity = args[0]._arity - def grading_set(self): + def _repr_(self): r""" - Return the set of non-negative integer vectors, whose length is - the arity of ``self``. - - EXAMPLES:: - - sage: from sage.rings.species import MolecularSpecies - sage: MolecularSpecies(["X", "Y"]).grading_set() - Integer vectors of length 2 - """ - return IntegerVectors(length=self._arity) - - def graded_component(self, grade): - """ - Return the set of molecular species with given multicardinality. - - The default implementation just calls the method :meth:`subset()` - with the first argument ``grade``. + Return a string representation of ``self``. - EXAMPLES:: + TESTS:: sage: from sage.rings.species import MolecularSpecies - sage: M = MolecularSpecies(["X", "Y"]) - sage: M.graded_component([3,2]) # random - {E_3(X)*Y^2, X^3*Y^2, X*E_2(X)*E_2(Y), X^3*E_2(Y), - {((1,2,3), (1,3)(4,5)): ({1, 2, 3}, {4, 5})}, - X*{((1,2)(3,4),): ({1, 2}, {3, 4})}, X*E_2(X)*Y^2, E_3(X)*E_2(Y), - C_3(X)*Y^2, C_3(X)*E_2(Y)} + sage: MolecularSpecies("X") + Molecular species in X + sage: MolecularSpecies("A, B") + Molecular species in A, B """ - from sage.sets.set import Set - assert len(grade) == self._arity - n = sum(grade) - S = SymmetricGroup(n).young_subgroup(grade) - dom = S.domain() - dompart = {i: dom[sum(grade[:i]): sum(grade[:i+1])] for i in range(len(grade))} - return Set([self(G, dompart) for G in S.conjugacy_classes_subgroups()]) + if len(self._indices._names) == 1: + return f"Molecular species in {self._indices._names[0]}" + return f"Molecular species in {', '.join(self._indices._names)}" def _element_constructor_(self, G, pi=None): r""" @@ -879,21 +857,43 @@ def _element_constructor_(self, G, pi=None): raise ValueError("Action is not transitive") return self(H[0], pi) - def _repr_(self): + def grading_set(self): r""" - Return a string representation of ``self``. + Return the set of non-negative integer vectors, whose length is + the arity of ``self``. - TESTS:: + EXAMPLES:: sage: from sage.rings.species import MolecularSpecies - sage: MolecularSpecies("X") - Molecular species in X - sage: MolecularSpecies("A, B") - Molecular species in A, B + sage: MolecularSpecies(["X", "Y"]).grading_set() + Integer vectors of length 2 """ - if len(self._indices._names) == 1: - return f"Molecular species in {self._indices._names[0]}" - return f"Molecular species in {', '.join(self._indices._names)}" + return IntegerVectors(length=self._arity) + + def graded_component(self, grade): + """ + Return the set of molecular species with given multicardinality. + + The default implementation just calls the method :meth:`subset()` + with the first argument ``grade``. + + EXAMPLES:: + + sage: from sage.rings.species import MolecularSpecies + sage: M = MolecularSpecies(["X", "Y"]) + sage: M.graded_component([3,2]) # random + {E_3(X)*Y^2, X^3*Y^2, X*E_2(X)*E_2(Y), X^3*E_2(Y), + {((1,2,3), (1,3)(4,5)): ({1, 2, 3}, {4, 5})}, + X*{((1,2)(3,4),): ({1, 2}, {3, 4})}, X*E_2(X)*Y^2, E_3(X)*E_2(Y), + C_3(X)*Y^2, C_3(X)*E_2(Y)} + """ + from sage.sets.set import Set + assert len(grade) == self._arity + n = sum(grade) + S = SymmetricGroup(n).young_subgroup(grade) + dom = S.domain() + dompart = {i: dom[sum(grade[:i]): sum(grade[:i+1])] for i in range(len(grade))} + return Set([self(G, dompart) for G in S.conjugacy_classes_subgroups()]) class Element(IndexedFreeAbelianMonoidElement): def __init__(self, parent, x): @@ -914,27 +914,56 @@ def __init__(self, parent, x): super().__init__(parent, x) @cached_method - def group_and_partition(self): - """ - Return the (transitive) permutation group corresponding to ``self``. + def grade(self): + r""" + Return the grade of ``self``. EXAMPLES:: sage: from sage.rings.species import MolecularSpecies - sage: M = MolecularSpecies("X,Y") - sage: G = PermutationGroup([[(1,2),(3,4)], [(5,6)]]) - sage: A = M(G, {0: [5,6], 1: [1,2,3,4]}) - sage: A.group_and_partition() - (Permutation Group with generators [(5,6), (1,2)(3,4)], - (frozenset({5, 6}), frozenset({1, 2, 3, 4}))) + sage: M = MolecularSpecies("X, Y") + sage: G = PermutationGroup([[(1,2),(3,4),(5,6),(7,8,9,10)]]); G + Permutation Group with generators [(1,2)(3,4)(5,6)(7,8,9,10)] + sage: a = M(G, {0: [1,2,3,4], 1: [5,6,7,8,9,10]}); a + {((1,2,3,4)(5,6)(7,8)(9,10),): ({5, 6, 7, 8}, {1, 2, 3, 4, 9, 10})} + sage: a.grade() + [4, 6] TESTS:: - sage: M = MolecularSpecies("X,Y") - sage: B = M(PermutationGroup([(1,2,3)]), {0: [1,2,3]}) - sage: B.group_and_partition() - (Permutation Group with generators [(1,2,3)], - (frozenset({1, 2, 3}), frozenset())) + sage: M.one().grade() + [0, 0] + """ + P = self.parent() + S = P.grading_set() + mons = self._monomial + if not mons: + return S([0] * P._arity) + mc = sum(n * vector(a._mc) for a, n in mons.items()) + return S(mc) + + @cached_method + def group_and_partition(self): + """ + Return the (transitive) permutation group corresponding to ``self``. + + EXAMPLES:: + + sage: from sage.rings.species import MolecularSpecies + sage: M = MolecularSpecies("X,Y") + sage: G = PermutationGroup([[(1,2),(3,4)], [(5,6)]]) + sage: A = M(G, {0: [5,6], 1: [1,2,3,4]}) + sage: A.group_and_partition() + (Permutation Group with generators [(5,6), (1,2)(3,4)], + (frozenset({5, 6}), frozenset({1, 2, 3, 4}))) + + TESTS:: + + sage: M = MolecularSpecies("X,Y") + sage: B = M(PermutationGroup([(1,2,3)]), {0: [1,2,3]}) + sage: B.group_and_partition() + (Permutation Group with generators [(1,2,3)], + (frozenset({1, 2, 3}), frozenset())) sage: (A*B).group_and_partition() (Permutation Group with generators [(7,8,9), (5,6), (1,2)(3,4)], @@ -1048,110 +1077,6 @@ def cycle_type(pi): for C in G.conjugacy_classes()) / G.cardinality()) - @cached_method - def grade(self): - r""" - Return the grade of ``self``. - - EXAMPLES:: - - sage: from sage.rings.species import MolecularSpecies - sage: M = MolecularSpecies("X, Y") - sage: G = PermutationGroup([[(1,2),(3,4),(5,6),(7,8,9,10)]]); G - Permutation Group with generators [(1,2)(3,4)(5,6)(7,8,9,10)] - sage: a = M(G, {0: [1,2,3,4], 1: [5,6,7,8,9,10]}); a - {((1,2,3,4)(5,6)(7,8)(9,10),): ({5, 6, 7, 8}, {1, 2, 3, 4, 9, 10})} - sage: a.grade() - [4, 6] - - TESTS:: - - sage: M.one().grade() - [0, 0] - """ - P = self.parent() - S = P.grading_set() - mons = self._monomial - if not mons: - return S([0] * P._arity) - mc = sum(n * vector(a._mc) for a, n in mons.items()) - return S(mc) - - def _compose_with_singletons(self, base_ring, names, args): - r""" - Return the inner sum of Exercise 2.6.16 in [BLL1998]_, - generalized to the case of arbitrary arity. - - INPUT: - - - ``base_ring``, the base ring of the result - - - ``names``, the (flat) list of names of the result - - - ``args``, the sequence of `k` compositions, each of - which sums to the corresponding cardinality of - ``self``, where `k` is the arity of ``self``. - - OUTPUT: - - - the polynomial species - `self(X_1 + \dots + X_{m_1}, Y_1 + \dots + Y_{m_2}, \dots)`, - where `m_i` is the number of parts of the `i`-th composition. - - EXAMPLES:: - - sage: from sage.rings.species import MolecularSpecies - sage: M = MolecularSpecies("X") - sage: C4 = M(CyclicPermutationGroup(4)) - sage: C4._compose_with_singletons(ZZ, "X, Y", [[2, 2]]) # X^2Y^2 + C2(XY) - X^2*Y^2 + E_2(XY) - - sage: M = MolecularSpecies(["X", "Y"]) - sage: F = M(PermutationGroup([[(1,2,3), (4,5,6)]]), {0: [1,2,3], 1: [4,5,6]}) - sage: F - {((1,2,3)(4,5,6),): ({1, 2, 3}, {4, 5, 6})} - sage: F._compose_with_singletons(ZZ, "X1, X2, X3, Y1, Y2", [[1, 1, 1], [2, 1]]) - 6*X1*X2*X3*Y1^2*Y2 - - TESTS:: - - sage: M = MolecularSpecies("X") - sage: O = M.one() - sage: O._compose_with_singletons(ZZ, "X", [[]]) - 1 - - sage: F = M(SymmetricGroup(1)) * M(SymmetricGroup(2)) - sage: F._compose_with_singletons(QQ, ["T", "S"], [[2, 1]]) - T^2*S + E_2(T)*S - sage: F._compose_with_singletons(QQ, ["T", "S"], [[1, 2]]) - T*E_2(S) + T*S^2 - """ - # TODO: No checks are performed right now, must be added. - # Checks: all args in Compositions, sums must match cardinalities. - - # Create group of the composition - # conjugate self.group() so that [1..k] is sort 1, [k+1,..] is sort 2, so on - G, dompart = self.group_and_partition() - conj = PermutationGroupElement(list(chain.from_iterable(dompart))).inverse() - G = libgap.ConjugateGroup(G, conj) - - comp = list(chain.from_iterable(args)) - dompart = {i: range(x - comp[i] + 1, x + 1) for i, x in enumerate(accumulate(comp))} - # Create the double coset representatives. - S_down = SymmetricGroup(sum(comp)).young_subgroup(comp) - mc = self.grade() - tc = sum(mc) - S_up = SymmetricGroup(tc).young_subgroup(mc) - taus = libgap.DoubleCosetRepsAndSizes(S_up, S_down, G) - # sum over double coset representatives. - Pn = PolynomialSpecies(base_ring, names) - res = Pn.zero() - for tau, _ in taus: - H = libgap.Intersection(libgap.ConjugateGroup(G, tau ** -1), S_down) - K = PermutationGroup(gap_group=H, domain=range(1, tc + 1)) - res += Pn(K, dompart) - return res - def __call__(self, *args): r""" Substitute `M_1,\dots, M_k` into ``self``. @@ -1236,8 +1161,366 @@ def __call__(self, *args): gens.append([tuple(start + k for k in cyc) for cyc in gen.cycle_tuples()]) - return P(PermutationGroup(gens, - domain=range(1, starts[-1] + 1)), dompart) + return P(PermutationGroup(gens, domain=range(1, starts[-1] + 1)), + dompart) + + +class PolynomialSpeciesElement(CombinatorialFreeModule.Element): + r""" + Multivariate polynomial (virtual) species. + + TESTS:: + + sage: P = PolynomialSpecies(ZZ, ["X"]) + sage: C3 = P(CyclicPermutationGroup(3)) + sage: X = P(SymmetricGroup(1)) + sage: E2 = P(SymmetricGroup(2)) + sage: (E2*X + C3).homogeneous_degree() + 3 + """ + def is_constant(self): + """ + Return ``True`` if this is a constant polynomial species. + + EXAMPLES:: + + sage: P = PolynomialSpecies(ZZ, ["X", "Y"]) + sage: X = P(SymmetricGroup(1), {0: [1]}) + sage: X.is_constant() + False + sage: (3*P.one()).is_constant() + True + sage: P(0).is_constant() + True + sage: (1 + X).is_constant() + False + """ + return self.is_zero() or not self.maximal_degree() + + def is_virtual(self): + r""" + Return if ``self`` is a virtual species. + + TESTS:: + + sage: P = PolynomialSpecies(ZZ, ["X", "Y"]) + sage: X = P(SymmetricGroup(1), {0: [1]}) + sage: Y = P(SymmetricGroup(1), {1: [1]}) + sage: V = 2 * X - 3 * Y; V + 2*X - 3*Y + sage: V.is_virtual() + True + sage: (X * Y).is_virtual() + False + """ + return any(x < 0 for x in self.coefficients(sort=False)) + + def is_molecular(self): + r""" + Return if ``self`` is a molecular species. + + TESTS:: + + sage: P = PolynomialSpecies(ZZ, ["X", "Y"]) + sage: X = P(SymmetricGroup(1), {0: [1]}) + sage: Y = P(SymmetricGroup(1), {1: [1]}) + sage: V = 2 * X - 3 * Y; V + 2*X - 3*Y + sage: V.is_molecular() + False + sage: (2 * X).is_molecular() + False + sage: (X * Y).is_molecular() + True + """ + return len(self.coefficients(sort=False)) == 1 and self.coefficients(sort=False)[0] == 1 + + def is_atomic(self): + r""" + Return if ``self`` is an atomic species. + + TESTS:: + + sage: P = PolynomialSpecies(ZZ, ["X", "Y"]) + sage: X = P(SymmetricGroup(1), {0: [1]}) + sage: Y = P(SymmetricGroup(1), {1: [1]}) + sage: V = 2 * X - 3 * Y; V + 2*X - 3*Y + sage: V.is_atomic() + False + sage: (2 * X).is_atomic() + False + sage: (X * Y).is_atomic() + False + sage: Y.is_atomic() + True + """ + return self.is_molecular() and len(self.support()[0]) == 1 + + def hadamard_product(self, other): + r""" + Compute the hadamard product of ``self`` and ``other``. + + EXAMPLES: + + Exercise 2.1.9 from [BLL1998]_:: + + sage: P = PolynomialSpecies(ZZ, ["X"]) + sage: C3 = P(CyclicPermutationGroup(3)) + sage: X = P(SymmetricGroup(1)) + sage: E2 = P(SymmetricGroup(2)) + sage: C3.hadamard_product(C3) + 2*C_3 + sage: (X^3).hadamard_product(C3) + 2*X^3 + sage: (X*E2).hadamard_product(X*E2) + X*E_2 + X^3 + + TESTS:: + + sage: C3.hadamard_product(-C3) + -2*C_3 + """ + P = self.parent() + if P is not other.parent(): + raise ValueError("the factors of a Hadamard product must have the same parent") + + result = P.zero() + # we should first collect matching multicardinalities. + for L, c in self: + mc = L.grade() + tc = sum(mc) + S = SymmetricGroup(tc).young_subgroup(mc) + # conjugate L and R to match S + G, dompart = L.group_and_partition() + g = list(chain.from_iterable(dompart)) + conj_L = PermutationGroupElement(g).inverse() + G = libgap.ConjugateGroup(G, conj_L) + dompart = {i: range(x - mc[i] + 1, x + 1) + for i, x in enumerate(accumulate(mc))} + for R, d in other: + if mc != R.grade(): + continue + G_R, dompart_R = R.group_and_partition() + g = list(chain.from_iterable(dompart_R)) + conj_R = PermutationGroupElement(g).inverse() + H = libgap.ConjugateGroup(G_R, conj_R) + taus = libgap.DoubleCosetRepsAndSizes(S, G, H) + # loop over representatives + new = P.zero() + for tau, _ in taus: + F = libgap.Intersection(libgap.ConjugateGroup(H, tau), G) + new += P(PermutationGroup(gap_group=F, domain=range(1, tc + 1)), + dompart) + result += c * d * new + + return result + + def _compose_with_singletons(self, names, args): + r""" + Return the inner sum of Exercise 2.6.16 in [BLL1998]_, + generalized to the case of arbitrary arity. + + The `k`-sort species ``self`` should be homogeneous. + + INPUT: + + - ``names``, the (flat) list of names of the result + + - ``args``, the sequence of `k` compositions, each of + which sums to the corresponding degree of ``self``, + where `k` is the arity of ``self``. + + OUTPUT: + + - the polynomial species `self(X_1 + \dots + X_{m_1}, Y_1 + + \dots + Y_{m_2}, \dots)`, where `m_i` is the number + of parts of the `i`-th composition, restricted to the + degrees given by ``args``. + + EXAMPLES:: + + sage: P = PolynomialSpecies(ZZ, "X") + sage: C4 = P(CyclicPermutationGroup(4)) + sage: C4._compose_with_singletons("X, Y", [[2, 2]]) + X^2*Y^2 + E_2(XY) + + sage: P = PolynomialSpecies(ZZ, ["X", "Y"]) + sage: F = P(PermutationGroup([[(1,2,3), (4,5,6)]]), {0: [1,2,3], 1: [4,5,6]}) + sage: F + {((1,2,3)(4,5,6),): ({1, 2, 3}, {4, 5, 6})} + sage: F._compose_with_singletons("X1, X2, X3, Y1, Y2", [[1, 1, 1], [2, 1]]) + 6*X1*X2*X3*Y1^2*Y2 + + TESTS:: + + sage: P = PolynomialSpecies(ZZ, "X") + sage: O = P.one() + sage: O._compose_with_singletons("X", [[]]) + 1 + + sage: F = P(SymmetricGroup(1)) * P(SymmetricGroup(2)) + sage: F._compose_with_singletons(["T", "S"], [[2, 1]]) + T^2*S + E_2(T)*S + sage: F._compose_with_singletons(["T", "S"], [[1, 2]]) + T*E_2(S) + T*S^2 + + """ + # TODO: possibly check that all args are compositions, + # and that sums match cardinalities + comp = list(chain.from_iterable(args)) + result_dompart = {i: range(x - comp[i] + 1, x + 1) + for i, x in enumerate(accumulate(comp))} + S_down = SymmetricGroup(sum(comp)).young_subgroup(comp) + + Pn = PolynomialSpecies(self.parent().base_ring(), names) + result = Pn.zero() + for M, c in self: + # Create group of the composition + # conjugate self.group() so that [1..k] is sort 1, [k+1,..] is sort 2, so on + G, dompart = M.group_and_partition() + conj = PermutationGroupElement(list(chain.from_iterable(dompart))).inverse() + G = libgap.ConjugateGroup(G, conj) + + mc = M.grade() + tc = sum(mc) + S_up = SymmetricGroup(tc).young_subgroup(mc) + taus = libgap.DoubleCosetRepsAndSizes(S_up, S_down, G) + + # sum over double coset representatives. + summand = Pn.zero() + for tau, _ in taus: + H = libgap.Intersection(libgap.ConjugateGroup(G, tau.Inverse()), + S_down) + K = PermutationGroup(gap_group=H, domain=range(1, tc + 1)) + summand += Pn(K, result_dompart) + result += c*summand + return result + + def _compose_with_weighted_singletons(self, names, multiplicities, degrees): + r""" + Compute the composition with + `(\sum_j m_{1,j} X_{1,j}, \sum_j m_{2,j} X_{2,j}, \dots)` + in the specified degrees. + + The `k`-sort species ``self`` should be homogeneous. + + INPUT: + + - ``names``, the (flat) list of names of the result + + - ``multiplicities``, a (flat) list of constants + + - ``degrees``, a `k`-tuple of compositions `c_1, + \dots, c_k`, such that the size of `c_i` is the + degree of self in sort `i`. + + EXAMPLES: + + Equation (2.5.41) in [BLL1998]_:: + + sage: P = PolynomialSpecies(QQ, ["X"]) + sage: E2 = P(SymmetricGroup(2)) + sage: E2._compose_with_weighted_singletons(["X"], [-1], [[2]]) + -E_2 + X^2 + + sage: C4 = P(CyclicPermutationGroup(4)) + sage: C4._compose_with_weighted_singletons(["X"], [-1], [[4]]) + -C_4 + {((1,2)(3,4),)} + + Exercise (2.5.17) in [BLL1998]_:: + + sage: C4._compose_with_weighted_singletons(["X", "Y"], [1, 1], [[2, 2]]) + X^2*Y^2 + E_2(XY) + sage: C4._compose_with_weighted_singletons(["X", "Y"], [1, 1], [[3, 1]]) + X^3*Y + sage: C4._compose_with_weighted_singletons(["X", "Y"], [1, 1], [[4, 0]]) + C_4(X) + + Auger et al., Equation (4.60):: + + sage: C4._compose_with_weighted_singletons(["X", "Y"], [1, -1], [[2, 2]]) + 2*X^2*Y^2 - E_2(XY) + + TESTS:: + + sage: (C4+E2^2)._compose_with_weighted_singletons(["X"], [-1], [[4]]) + -C_4 + {((1,2)(3,4),)} + E_2^2 - 2*X^2*E_2 + X^4 + + """ + P = self.parent() + if not self.support(): + return P.zero() + if not self.is_homogeneous(): + raise ValueError("element is not homogeneous") + + left = self._compose_with_singletons(names, degrees) + Pn = left.parent() + right = Pn.exponential(multiplicities, + list(chain.from_iterable(degrees))) + return left.hadamard_product(right) + + def __call__(self, *args): + """ + + EXAMPLES:: + + sage: P = PolynomialSpecies(QQ, ["X"]) + sage: X = P(SymmetricGroup(1)) + sage: E2 = P(SymmetricGroup(2)) + sage: E2(-X) + -E_2 + X^2 + sage: E2(X^2) + {((1,2)(3,4),)} + + sage: E2(X + X^2) + E_2 + X^3 + {((1,2)(3,4),)} + + sage: P2 = PolynomialSpecies(QQ, ["X", "Y"]) + sage: X = P2(SymmetricGroup(1), {0: [1]}) + sage: Y = P2(SymmetricGroup(1), {1: [1]}) + sage: E2(X + Y) + E_2(Y) + Y*X + E_2(X) + + sage: E2(X*Y)(E2(X), E2(Y)) + {((7,8), (5,6), (3,4), (1,2), (1,3)(2,4)(5,7)(6,8)): ({1, 2, 3, 4}, {5, 6, 7, 8})} + + sage: R. = QQ[] + sage: P = PolynomialSpecies(R, ["X"]) + sage: X = P(SymmetricGroup(1)) + sage: E2 = P(SymmetricGroup(2)) + sage: E2(q*X) + q^2*E_2 + + """ + P = self.parent() + if len(args) != P._arity: + raise ValueError("number of args must match arity of self") + if len(set(arg.parent() for arg in args)) > 1: + raise ValueError("all args must have the same parent") + + P0 = args[0].parent() + if not self.support(): + return P0.zero() + + args = [sorted(g, key=lambda x: x[0].grade()) for g in args] + multiplicities = list(chain.from_iterable([[c for _, c in g] for g in args])) + molecules = list(chain.from_iterable([[M for M, _ in g] for g in args])) + F_degrees = sorted(set(M.grade() for M, _ in self)) + names = ["X%s" % i for i in range(sum(len(arg) for arg in args))] + + result = P0.zero() + for n in F_degrees: + F = P.sum_of_terms((M, c) for M, c in self if M.grade() == n) + for degrees in cartesian_product([IntegerVectors(n_i, length=len(arg)) + for n_i, arg in zip(n, args)]): + # each degree is a weak composition of the degree of F in sort i + FX = F._compose_with_weighted_singletons(names, + multiplicities, + degrees) + FG = [(M(*molecules), c) for M, c in FX] + result += P0.sum_of_terms(FG) + return result class PolynomialSpecies(CombinatorialFreeModule): @@ -1279,23 +1562,21 @@ def __init__(self, base_ring, names): prefix='', bracket=False) self._arity = len(names) - def degree_on_basis(self, m): + def _repr_(self): r""" - Return the degree of the molecular species indexed by ``m``. + Return a string representation of ``self``. EXAMPLES:: - sage: P = PolynomialSpecies(ZZ, ["X", "Y"]) - sage: E4X = P(SymmetricGroup(4), {0: range(1, 5)}); E4X - E_4(X) - sage: E4Y = P(SymmetricGroup(4), {1: range(1, 5)}); E4Y - E_4(Y) - sage: P.degree_on_basis(E4X.support()[0]) - 4 - sage: P.degree_on_basis(E4Y.support()[0]) - 4 + sage: PolynomialSpecies(ZZ, "X") + Polynomial species in X over Integer Ring + sage: PolynomialSpecies(ZZ, "X, Y") + Polynomial species in X, Y over Integer Ring """ - return sum(m.grade()) + names = self._indices._indices._names + if len(names) == 1: + return f"Polynomial species in {names[0]} over {self.base_ring()}" + return f"Polynomial species in {', '.join(names)} over {self.base_ring()}" def _element_constructor_(self, G, pi=None): r""" @@ -1346,8 +1627,25 @@ def _element_constructor_(self, G, pi=None): L = [len(pi.get(i, [])) for i in range(self._arity)] S = SymmetricGroup(sum(L)).young_subgroup(L) Hs = _stabilizer_subgroups(S, X, a) - res = self._from_dict({self._indices(H, pi): ZZ.one() for H in Hs}) - return res + return self._from_dict({self._indices(H, pi): ZZ.one() for H in Hs}) + + def degree_on_basis(self, m): + r""" + Return the degree of the molecular species indexed by ``m``. + + EXAMPLES:: + + sage: P = PolynomialSpecies(ZZ, ["X", "Y"]) + sage: E4X = P(SymmetricGroup(4), {0: range(1, 5)}); E4X + E_4(X) + sage: E4Y = P(SymmetricGroup(4), {1: range(1, 5)}); E4Y + E_4(Y) + sage: P.degree_on_basis(E4X.support()[0]) + 4 + sage: P.degree_on_basis(E4Y.support()[0]) + 4 + """ + return sum(m.grade()) @cached_method def one_basis(self): @@ -1402,22 +1700,6 @@ def product_on_basis(self, H, K): """ return self._from_dict({H * K: ZZ(1)}) - def _repr_(self): - r""" - Return a string representation of ``self``. - - EXAMPLES:: - - sage: PolynomialSpecies(ZZ, "X") - Polynomial species in X over Integer Ring - sage: PolynomialSpecies(ZZ, "X, Y") - Polynomial species in X, Y over Integer Ring - """ - names = self._indices._indices._names - if len(names) == 1: - return f"Polynomial species in {names[0]} over {self.base_ring()}" - return f"Polynomial species in {', '.join(names)} over {self.base_ring()}" - @cached_method def powersum(self, s, n): r""" @@ -1497,282 +1779,4 @@ def factor(s, c, d): return self.prod(factor(s, multiplicities[s], degrees[s]) for s in range(self._arity)) - class Element(CombinatorialFreeModule.Element): - r""" - Multivariate polynomial (virtual) species. - - TESTS:: - - sage: P = PolynomialSpecies(ZZ, ["X"]) - sage: C3 = P(CyclicPermutationGroup(3)) - sage: X = P(SymmetricGroup(1)) - sage: E2 = P(SymmetricGroup(2)) - sage: (E2*X + C3).homogeneous_degree() - 3 - """ - - def is_constant(self): - """ - Return ``True`` if this is a constant polynomial species. - - EXAMPLES:: - - sage: P = PolynomialSpecies(ZZ, ["X", "Y"]) - sage: X = P(SymmetricGroup(1), {0: [1]}) - sage: X.is_constant() - False - sage: (3*P.one()).is_constant() - True - sage: P(0).is_constant() - True - sage: (1 + X).is_constant() - False - """ - return self.is_zero() or not self.maximal_degree() - - def is_virtual(self): - r""" - Return if ``self`` is a virtual species. - - TESTS:: - - sage: P = PolynomialSpecies(ZZ, ["X", "Y"]) - sage: X = P(SymmetricGroup(1), {0: [1]}) - sage: Y = P(SymmetricGroup(1), {1: [1]}) - sage: V = 2 * X - 3 * Y; V - 2*X - 3*Y - sage: V.is_virtual() - True - sage: (X * Y).is_virtual() - False - """ - return any(x < 0 for x in self.coefficients(sort=False)) - - def is_molecular(self): - r""" - Return if ``self`` is a molecular species. - - TESTS:: - - sage: P = PolynomialSpecies(ZZ, ["X", "Y"]) - sage: X = P(SymmetricGroup(1), {0: [1]}) - sage: Y = P(SymmetricGroup(1), {1: [1]}) - sage: V = 2 * X - 3 * Y; V - 2*X - 3*Y - sage: V.is_molecular() - False - sage: (2 * X).is_molecular() - False - sage: (X * Y).is_molecular() - True - """ - return len(self.coefficients(sort=False)) == 1 and self.coefficients(sort=False)[0] == 1 - - def is_atomic(self): - r""" - Return if ``self`` is an atomic species. - - TESTS:: - - sage: P = PolynomialSpecies(ZZ, ["X", "Y"]) - sage: X = P(SymmetricGroup(1), {0: [1]}) - sage: Y = P(SymmetricGroup(1), {1: [1]}) - sage: V = 2 * X - 3 * Y; V - 2*X - 3*Y - sage: V.is_atomic() - False - sage: (2 * X).is_atomic() - False - sage: (X * Y).is_atomic() - False - sage: Y.is_atomic() - True - """ - return self.is_molecular() and len(self.support()[0]) == 1 - - def hadamard_product(self, other): - r""" - Compute the hadamard product of ``self`` and ``other``. - - EXAMPLES: - - Exercise 2.1.9 from [BLL1998]_:: - - sage: P = PolynomialSpecies(ZZ, ["X"]) - sage: C3 = P(CyclicPermutationGroup(3)) - sage: X = P(SymmetricGroup(1)) - sage: E2 = P(SymmetricGroup(2)) - sage: C3.hadamard_product(C3) - 2*C_3 - sage: (X^3).hadamard_product(C3) - 2*X^3 - sage: (X*E2).hadamard_product(X*E2) - X*E_2 + X^3 - - TESTS:: - - sage: C3.hadamard_product(-C3) - -2*C_3 - """ - P = self.parent() - if P is not other.parent(): - raise ValueError("the factors of a Hadamard product must have the same parent") - - res = P.zero() - # we should first collect matching multicardinalities. - for L, c in self: - mc = L.grade() - tc = sum(mc) - S = SymmetricGroup(tc).young_subgroup(mc) - # conjugate L and R to match S - G, dompart = L.group_and_partition() - g = list(chain.from_iterable(dompart)) - conj_L = PermutationGroupElement(g).inverse() - G = libgap.ConjugateGroup(G, conj_L) - dompart = {i: range(x - mc[i] + 1, x + 1) - for i, x in enumerate(accumulate(mc))} - for R, d in other: - if mc != R.grade(): - continue - G_R, dompart_R = R.group_and_partition() - g = list(chain.from_iterable(dompart_R)) - conj_R = PermutationGroupElement(g).inverse() - H = libgap.ConjugateGroup(G_R, conj_R) - taus = libgap.DoubleCosetRepsAndSizes(S, G, H) - # loop over representatives - new = P.zero() - for tau, _ in taus: - F = libgap.Intersection(libgap.ConjugateGroup(H, tau), G) - new += P(PermutationGroup(gap_group=F, domain=range(1, tc + 1)), - dompart) - res += c * d * new - - return res - - def _compose_with_weighted_singletons(self, names, multiplicities, degrees): - r""" - Compute the composition with - `(\sum_j m_{1,j} X_{1,j}, \sum_j m_{2,j} X_{2,j}, \dots)` - in the specified degrees. - - The `k`-sort species ``self`` should be homogeneous. - - INPUT: - - - ``names``, the (flat) list of names of the result - - - ``multiplicities``, a (flat) list of constants - - - ``degrees``, a `k`-tuple of compositions `c_1, - \dots, c_k`, such that the size of `c_i` is the - degree of self in sort `i`. - - EXAMPLES: - - Equation (2.5.41) in [BLL1998]_:: - - sage: P = PolynomialSpecies(QQ, ["X"]) - sage: E2 = P(SymmetricGroup(2)) - sage: E2._compose_with_weighted_singletons(["X"], [-1], [[2]]) - -E_2 + X^2 - - sage: C4 = P(CyclicPermutationGroup(4)) - sage: C4._compose_with_weighted_singletons(["X"], [-1], [[4]]) - -C_4 + {((1,2)(3,4),)} - - Exercise (2.5.17) in [BLL1998]_:: - - sage: C4._compose_with_weighted_singletons(["X", "Y"], [1, 1], [[2, 2]]) - X^2*Y^2 + E_2(XY) - sage: C4._compose_with_weighted_singletons(["X", "Y"], [1, 1], [[3, 1]]) - X^3*Y - sage: C4._compose_with_weighted_singletons(["X", "Y"], [1, 1], [[4, 0]]) - C_4(X) - - Auger et al., Equation (4.60):: - - sage: C4._compose_with_weighted_singletons(["X", "Y"], [1, -1], [[2, 2]]) - 2*X^2*Y^2 - E_2(XY) - - TESTS:: - - sage: (C4+E2^2)._compose_with_weighted_singletons(["X"], [-1], [[4]]) - -C_4 + {((1,2)(3,4),)} + E_2^2 - 2*X^2*E_2 + X^4 - - """ - P = self.parent() - if not self.support(): - return P.zero() - if not self.is_homogeneous(): - raise ValueError("element is not homogeneous") - - left = sum(c * M._compose_with_singletons(P.base_ring(), - names, - degrees) - for M, c in self) - P = left.parent() - right = P.exponential(multiplicities, - list(chain.from_iterable(degrees))) - return left.hadamard_product(right) - - def __call__(self, *args): - """ - - EXAMPLES:: - - sage: P = PolynomialSpecies(QQ, ["X"]) - sage: X = P(SymmetricGroup(1)) - sage: E2 = P(SymmetricGroup(2)) - sage: E2(-X) - -E_2 + X^2 - sage: E2(X^2) - {((1,2)(3,4),)} - - sage: E2(X + X^2) - E_2 + X^3 + {((1,2)(3,4),)} - - sage: P2 = PolynomialSpecies(QQ, ["X", "Y"]) - sage: X = P2(SymmetricGroup(1), {0: [1]}) - sage: Y = P2(SymmetricGroup(1), {1: [1]}) - sage: E2(X + Y) - E_2(Y) + Y*X + E_2(X) - - sage: E2(X*Y)(E2(X), E2(Y)) - {((7,8), (5,6), (3,4), (1,2), (1,3)(2,4)(5,7)(6,8)): ({1, 2, 3, 4}, {5, 6, 7, 8})} - - sage: R. = QQ[] - sage: P = PolynomialSpecies(R, ["X"]) - sage: X = P(SymmetricGroup(1)) - sage: E2 = P(SymmetricGroup(2)) - sage: E2(q*X) - q^2*E_2 - - """ - P = self.parent() - if len(args) != P._arity: - raise ValueError("number of args must match arity of self") - if len(set(arg.parent() for arg in args)) > 1: - raise ValueError("all args must have the same parent") - - P0 = args[0].parent() - if not self.support(): - return P0.zero() - - args = [sorted(g, key=lambda x: x[0].grade()) for g in args] - multiplicities = list(chain.from_iterable([[c for _, c in g] for g in args])) - molecules = list(chain.from_iterable([[M for M, _ in g] for g in args])) - F_degrees = sorted(set(M.grade() for M, _ in self)) - names = ["X%s" % i for i in range(sum(len(arg) for arg in args))] - - result = P0.zero() - for n in F_degrees: - F = P.sum_of_terms((M, c) for M, c in self if M.grade() == n) - for degrees in cartesian_product([IntegerVectors(n_i, length=len(arg)) - for n_i, arg in zip(n, args)]): - # each degree is a weak composition of the degree of F in sort i - FX = F._compose_with_weighted_singletons(names, - multiplicities, - degrees) - FG = [(M(*molecules), c) for M, c in FX] - result += P0.sum_of_terms(FG) - return result + Element = PolynomialSpeciesElement From 383170ce496a5739e0449fe36a0409df413b0766 Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Thu, 26 Sep 2024 15:01:21 +0200 Subject: [PATCH 224/537] update references, do not put AtomicSpecies and PolynomialSpecies into global namespace --- src/doc/en/reference/references/index.rst | 4 ++ src/sage/rings/all.py | 2 - src/sage/rings/species.py | 63 ++++++++++++++++++++--- 3 files changed, 59 insertions(+), 10 deletions(-) diff --git a/src/doc/en/reference/references/index.rst b/src/doc/en/reference/references/index.rst index 35aa8735933..395fe7642d0 100644 --- a/src/doc/en/reference/references/index.rst +++ b/src/doc/en/reference/references/index.rst @@ -104,6 +104,10 @@ REFERENCES: graphs and isoperimetric inequalities*, The Annals of Probability 32 (2004), no. 3A, 1727-1745. +.. [ALL2002] P. Auger, G. Labelle and P. Leroux, *Combinatorial + addition formulas and applications*, Advances in Applied + Mathematics 28 (2002) 302-342. + .. [ASV2020] Federico Ardila, Mariel Supina, and Andrés R. Vindas-Meléndez, *The Equivariant Ehrhart Theory of the Permutahedron*, Proc. Amer. Math. Soc. Volume 148, Number 12, 2020, pp. 5091--5107. diff --git a/src/sage/rings/all.py b/src/sage/rings/all.py index 8cc4b2ccf0e..e3c7167fe12 100644 --- a/src/sage/rings/all.py +++ b/src/sage/rings/all.py @@ -166,7 +166,5 @@ # asymptotic ring from sage.rings.asymptotic.all import * -lazy_import('sage.rings.species', ['PolynomialSpecies', 'AtomicSpecies']) - # Register classes in numbers abc from sage.rings import numbers_abc diff --git a/src/sage/rings/species.py b/src/sage/rings/species.py index 3c916b9eff9..a8aca820954 100644 --- a/src/sage/rings/species.py +++ b/src/sage/rings/species.py @@ -256,13 +256,27 @@ def __classcall__(cls, parent, dis, domain_partition): TESTS:: + sage: from sage.rings.species import AtomicSpecies sage: A = AtomicSpecies("X, Y") Check that the domain is irrelevant:: sage: G = PermutationGroup([[("a", "b", "c", "d"), ("e", "f")]]) - sage: A(G, {0: "abcd", 1: "ef"}) + sage: a = A(G, {0: "abcd", 1: "ef"}); a {((1,2,3,4)(5,6),): ({1, 2, 3, 4}, {5, 6})} + sage: H = PermutationGroup([[(1,2,3,4), (5,6)]]) + sage: a is A(H, {0: [1,2,3,4], 1: [5,6]}) + True + + The advantage of the unique representation is that we can + rename the species:: + + sage: a.rename("CD(X,Y)"); a + CD(X,Y) + + We create two different atomic species `a` and `b` with the + same multicardinality and the same underlying permutation + group:: sage: G = PermutationGroup([[(1,2),(3,4),(5,6),(7,8,9,10)]]); G Permutation Group with generators [(1,2)(3,4)(5,6)(7,8,9,10)] @@ -278,6 +292,7 @@ def __classcall__(cls, parent, dis, domain_partition): False sage: a is c True + """ mc = tuple(len(v) for v in domain_partition) domain = list(chain(*map(sorted, domain_partition))) @@ -322,6 +337,7 @@ def __init__(self, parent, dis, domain_partition): TESTS:: + sage: from sage.rings.species import AtomicSpecies sage: A = AtomicSpecies("X") sage: G = PermutationGroup([[(1,3),(4,7)], [(2,5),(6,8)], [(1,4),(2,5),(3,7)]]) sage: TestSuite(A(G)).run() @@ -341,6 +357,7 @@ def _repr_(self): TESTS:: + sage: from sage.rings.species import AtomicSpecies sage: A = AtomicSpecies("X, Y") sage: G = PermutationGroup([[(1,2),(3,4),(5,6),(7,8,9,10)]]); G Permutation Group with generators [(1,2)(3,4)(5,6)(7,8,9,10)] @@ -361,6 +378,7 @@ def grade(self): EXAMPLES:: + sage: from sage.rings.species import AtomicSpecies sage: A = AtomicSpecies("X, Y") sage: G = PermutationGroup([[(1,2),(3,4),(5,6),(7,8,9,10)]]) sage: a = A(G, {0: [1,2,3,4], 1: [5,6,7,8,9,10]}) @@ -382,11 +400,12 @@ def __classcall__(cls, names): TESTS:: + sage: from sage.rings.species import AtomicSpecies sage: A1 = AtomicSpecies("X") sage: A2 = AtomicSpecies("Y") sage: A3 = AtomicSpecies("X, Y") sage: A4 = AtomicSpecies(["X", "Y"]) - sage: A1 is A2 + sage: A1 == A2 False sage: A3 is A4 True @@ -404,6 +423,7 @@ def __init__(self, names): TESTS:: + sage: from sage.rings.species import AtomicSpecies sage: A1 = AtomicSpecies(["X"]) sage: A2 = AtomicSpecies(["X", "Y"]) sage: TestSuite(A1).run(skip="_test_graded_components") @@ -421,6 +441,7 @@ def _repr_(self): TESTS:: + sage: from sage.rings.species import AtomicSpecies sage: AtomicSpecies("X") Atomic species in X sage: AtomicSpecies("X, Y") @@ -445,6 +466,7 @@ def _element_constructor_(self, G, pi=None): EXAMPLES:: + sage: from sage.rings.species import AtomicSpecies sage: A = AtomicSpecies("X, Y") sage: A(DihedralGroup(5), {0: [1,2,3,4,5]}) P_5(X) @@ -500,6 +522,7 @@ def _rename(self, n): EXAMPLES:: + sage: from sage.rings.species import AtomicSpecies sage: A = AtomicSpecies(["X", "Y"]) sage: A(SymmetricGroup(4), {0: range(1, 5)}) # indirect doctest E_4(X) @@ -563,6 +586,7 @@ def __contains__(self, x): TESTS:: + sage: from sage.rings.species import AtomicSpecies sage: A = AtomicSpecies("X") sage: G = PermutationGroup([[(1,2)], [(3,4)]]); G Permutation Group with generators [(3,4), (1,2)] @@ -573,7 +597,6 @@ def __contains__(self, x): """ if parent(x) == self: return True - G, pi = None, None if isinstance(x, PermutationGroup_generic): if self._arity == 1: G = x @@ -600,6 +623,7 @@ def grading_set(self): EXAMPLES:: + sage: from sage.rings.species import AtomicSpecies sage: AtomicSpecies(["X"]).grading_set() Integer vectors of length 1 """ @@ -612,6 +636,7 @@ def an_element(self): TESTS:: + sage: from sage.rings.species import AtomicSpecies sage: A = AtomicSpecies("X") sage: A.an_element() E_2 @@ -1171,6 +1196,7 @@ class PolynomialSpeciesElement(CombinatorialFreeModule.Element): TESTS:: + sage: from sage.rings.species import PolynomialSpecies sage: P = PolynomialSpecies(ZZ, ["X"]) sage: C3 = P(CyclicPermutationGroup(3)) sage: X = P(SymmetricGroup(1)) @@ -1184,6 +1210,7 @@ def is_constant(self): EXAMPLES:: + sage: from sage.rings.species import PolynomialSpecies sage: P = PolynomialSpecies(ZZ, ["X", "Y"]) sage: X = P(SymmetricGroup(1), {0: [1]}) sage: X.is_constant() @@ -1203,6 +1230,7 @@ def is_virtual(self): TESTS:: + sage: from sage.rings.species import PolynomialSpecies sage: P = PolynomialSpecies(ZZ, ["X", "Y"]) sage: X = P(SymmetricGroup(1), {0: [1]}) sage: Y = P(SymmetricGroup(1), {1: [1]}) @@ -1221,6 +1249,7 @@ def is_molecular(self): TESTS:: + sage: from sage.rings.species import PolynomialSpecies sage: P = PolynomialSpecies(ZZ, ["X", "Y"]) sage: X = P(SymmetricGroup(1), {0: [1]}) sage: Y = P(SymmetricGroup(1), {1: [1]}) @@ -1241,6 +1270,7 @@ def is_atomic(self): TESTS:: + sage: from sage.rings.species import PolynomialSpecies sage: P = PolynomialSpecies(ZZ, ["X", "Y"]) sage: X = P(SymmetricGroup(1), {0: [1]}) sage: Y = P(SymmetricGroup(1), {1: [1]}) @@ -1265,6 +1295,7 @@ def hadamard_product(self, other): Exercise 2.1.9 from [BLL1998]_:: + sage: from sage.rings.species import PolynomialSpecies sage: P = PolynomialSpecies(ZZ, ["X"]) sage: C3 = P(CyclicPermutationGroup(3)) sage: X = P(SymmetricGroup(1)) @@ -1340,6 +1371,7 @@ def _compose_with_singletons(self, names, args): EXAMPLES:: + sage: from sage.rings.species import PolynomialSpecies sage: P = PolynomialSpecies(ZZ, "X") sage: C4 = P(CyclicPermutationGroup(4)) sage: C4._compose_with_singletons("X, Y", [[2, 2]]) @@ -1419,6 +1451,7 @@ def _compose_with_weighted_singletons(self, names, multiplicities, degrees): Equation (2.5.41) in [BLL1998]_:: + sage: from sage.rings.species import PolynomialSpecies sage: P = PolynomialSpecies(QQ, ["X"]) sage: E2 = P(SymmetricGroup(2)) sage: E2._compose_with_weighted_singletons(["X"], [-1], [[2]]) @@ -1437,7 +1470,7 @@ def _compose_with_weighted_singletons(self, names, multiplicities, degrees): sage: C4._compose_with_weighted_singletons(["X", "Y"], [1, 1], [[4, 0]]) C_4(X) - Auger et al., Equation (4.60):: + Equation (4.60) in [ALL2002]_:: sage: C4._compose_with_weighted_singletons(["X", "Y"], [1, -1], [[2, 2]]) 2*X^2*Y^2 - E_2(XY) @@ -1465,6 +1498,7 @@ def __call__(self, *args): EXAMPLES:: + sage: from sage.rings.species import PolynomialSpecies sage: P = PolynomialSpecies(QQ, ["X"]) sage: X = P(SymmetricGroup(1)) sage: E2 = P(SymmetricGroup(2)) @@ -1530,12 +1564,13 @@ def __classcall__(cls, base_ring, names): TESTS:: + sage: from sage.rings.species import PolynomialSpecies sage: P1 = PolynomialSpecies(ZZ, "X, Y") sage: P2 = PolynomialSpecies(ZZ, "X, Y") sage: P3 = PolynomialSpecies(ZZ, ["X", "Z"]) sage: P1 is P2 True - sage: P1 is P3 + sage: P1 == P3 False """ from sage.structure.category_object import normalize_names @@ -1548,6 +1583,7 @@ def __init__(self, base_ring, names): TESTS:: + sage: from sage.rings.species import PolynomialSpecies sage: P = PolynomialSpecies(ZZ, "X") sage: TestSuite(P).run() sage: P2 = PolynomialSpecies(ZZ, "X, Y") @@ -1568,6 +1604,7 @@ def _repr_(self): EXAMPLES:: + sage: from sage.rings.species import PolynomialSpecies sage: PolynomialSpecies(ZZ, "X") Polynomial species in X over Integer Ring sage: PolynomialSpecies(ZZ, "X, Y") @@ -1594,6 +1631,7 @@ def _element_constructor_(self, G, pi=None): EXAMPLES:: + sage: from sage.rings.species import PolynomialSpecies sage: P = PolynomialSpecies(ZZ, ["X", "Y"]) sage: P(SymmetricGroup(4).young_subgroup([2, 2]), ([1,2], [3,4])) E_2(X)*E_2(Y) @@ -1635,6 +1673,7 @@ def degree_on_basis(self, m): EXAMPLES:: + sage: from sage.rings.species import PolynomialSpecies sage: P = PolynomialSpecies(ZZ, ["X", "Y"]) sage: E4X = P(SymmetricGroup(4), {0: range(1, 5)}); E4X E_4(X) @@ -1655,6 +1694,7 @@ def one_basis(self): EXAMPLES:: + sage: from sage.rings.species import PolynomialSpecies sage: P = PolynomialSpecies(ZZ, "X") sage: P.one_basis() 1 @@ -1669,6 +1709,7 @@ def an_element(self): """ Return an element of ``self``. + sage: from sage.rings.species import PolynomialSpecies sage: P = PolynomialSpecies(ZZ, "X") sage: P.an_element() 1 @@ -1684,6 +1725,7 @@ def product_on_basis(self, H, K): EXAMPLES:: + sage: from sage.rings.species import PolynomialSpecies sage: P = PolynomialSpecies(ZZ, "X") sage: L1 = [P(H) for H in SymmetricGroup(3).conjugacy_classes_subgroups()] sage: L2 = [P(H) for H in SymmetricGroup(2).conjugacy_classes_subgroups()] @@ -1703,10 +1745,15 @@ def product_on_basis(self, H, K): @cached_method def powersum(self, s, n): r""" - Return `P_n(X_s)`. + Return the combinatorial powersum species `P_n(X_s)`. + + The species `P_n(X)` is introduced in [Labelle2008]_ as the + coefficient of `t^n/n` in `\log E(tX)`, where `E` is the + species of sets. EXAMPLES:: + sage: from sage.rings.species import PolynomialSpecies sage: P = PolynomialSpecies(ZZ, "X") sage: P.powersum(0, 4) 4*E_4 - 4*X*E_3 + 4*X^2*E_2 - X^4 - 2*E_2^2 @@ -1725,6 +1772,7 @@ def exponential(self, multiplicities, degrees): EXAMPLES:: + sage: from sage.rings.species import PolynomialSpecies sage: P = PolynomialSpecies(QQ, ["X"]) sage: P.exponential([3/2], [7]) # random 3/2*E_7 + 3/4*X*E_6 - 3/16*X^2*E_5 + 3/32*X^3*E_4 - 15/256*E_3*X^4 @@ -1768,8 +1816,7 @@ def factor(s, c, d): r""" Return `E(c X_s)_d`. - We use Proposition 2 in Labelle, New combinatorial - computational methods arising from pseudo-singletons. + We use Proposition 2 in [Labelle2008]_. """ return self.sum(~ mu.centralizer_size() * self.prod(stretch(c, k) From 4189ceb62882ddf9f5fef328c0a3a729f3b17e91 Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Fri, 27 Sep 2024 22:24:20 +0200 Subject: [PATCH 225/537] provide subset (to also get homogeneous_degree_basis) and change_ring --- src/sage/rings/species.py | 37 +++++++++++++++++++++++++++++++++---- 1 file changed, 33 insertions(+), 4 deletions(-) diff --git a/src/sage/rings/species.py b/src/sage/rings/species.py index a8aca820954..2952d2f44f8 100644 --- a/src/sage/rings/species.py +++ b/src/sage/rings/species.py @@ -22,6 +22,7 @@ IndexedFreeAbelianMonoidElement) from sage.rings.rational_field import QQ from sage.rings.integer_ring import ZZ +from sage.sets.set import Set from sage.structure.category_object import normalize_names from sage.structure.element import Element, parent from sage.structure.parent import Parent @@ -895,13 +896,27 @@ def grading_set(self): """ return IntegerVectors(length=self._arity) + def subset(self, size): + """ + Return the set of molecular species with given total cardinality. + + EXAMPLES:: + + sage: from sage.rings.species import MolecularSpecies + sage: M = MolecularSpecies(["X", "Y"]) + sage: M.subset(3) # random + {X*E_2(Y), X*Y^2, C_3(Y), E_3(X), Y^3, Y*E_2(Y), C_3(X), X^2*Y, + E_3(Y), E_2(X)*Y, X*E_2(X), X^3} + """ + result = Set() + for grade in IntegerVectors(size, length=self._arity): + result = result.union(self.graded_component(grade)) + return result + def graded_component(self, grade): """ Return the set of molecular species with given multicardinality. - The default implementation just calls the method :meth:`subset()` - with the first argument ``grade``. - EXAMPLES:: sage: from sage.rings.species import MolecularSpecies @@ -912,7 +927,6 @@ def graded_component(self, grade): X*{((1,2)(3,4),): ({1, 2}, {3, 4})}, X*E_2(X)*Y^2, E_3(X)*E_2(Y), C_3(X)*Y^2, C_3(X)*E_2(Y)} """ - from sage.sets.set import Set assert len(grade) == self._arity n = sum(grade) S = SymmetricGroup(n).young_subgroup(grade) @@ -1667,6 +1681,21 @@ def _element_constructor_(self, G, pi=None): Hs = _stabilizer_subgroups(S, X, a) return self._from_dict({self._indices(H, pi): ZZ.one() for H in Hs}) + def change_ring(self, R): + r""" + Return the base change of ``self`` to `R`. + + EXAMPLES:: + + sage: from sage.rings.species import PolynomialSpecies + sage: P = PolynomialSpecies(ZZ, ["X", "Y"]) + sage: P.change_ring(QQ) + Polynomial species in X, Y over Rational Field + """ + if R is self.base_ring(): + return self + return PolynomialSpecies(R, self._indices._indices._names) + def degree_on_basis(self, m): r""" Return the degree of the molecular species indexed by ``m``. From de60b5a13002d860a2d396fd451895f1a3b93016 Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Sat, 28 Sep 2024 04:34:43 +0000 Subject: [PATCH 226/537] Improve conda setup --- .devcontainer/onCreate-conda.sh | 7 +- .github/workflows/ci-conda.yml | 4 +- .github/workflows/conda-lock-update.py | 45 +- .gitignore | 5 +- .gitpod.yml | 2 +- .vscode/settings.json | 4 +- bootstrap-conda | 56 +- condarc.yml | 1 - environment-3.10-linux-aarch64.yml | 263 +++++++++- environment-3.10-linux.yml | 311 ++++++++++- environment-3.10-macos-x86_64.yml | 246 ++++++++- environment-3.10-macos.yml | 244 ++++++++- environment-3.11-linux-aarch64.yml | 262 +++++++++- environment-3.11-linux.yml | 310 ++++++++++- environment-3.11-macos-x86_64.yml | 245 ++++++++- environment-3.11-macos.yml | 243 ++++++++- environment-3.9-linux-aarch64.yml | 263 +++++++++- environment-3.9-linux.yml | 311 ++++++++++- environment-3.9-macos-x86_64.yml | 246 ++++++++- environment-3.9-macos.yml | 244 ++++++++- ... => environment-dev-3.10-linux-aarch64.yml | 1 + ...inux.yml => environment-dev-3.10-linux.yml | 1 + ...l => environment-dev-3.10-macos-x86_64.yml | 1 + ...acos.yml => environment-dev-3.10-macos.yml | 1 + ... => environment-dev-3.11-linux-aarch64.yml | 1 + ...inux.yml => environment-dev-3.11-linux.yml | 1 + ...l => environment-dev-3.11-macos-x86_64.yml | 1 + ...acos.yml => environment-dev-3.11-macos.yml | 1 + ...l => environment-dev-3.9-linux-aarch64.yml | 1 + ...linux.yml => environment-dev-3.9-linux.yml | 1 + ...ml => environment-dev-3.9-macos-x86_64.yml | 1 + ...macos.yml => environment-dev-3.9-macos.yml | 1 + src/doc/en/installation/conda.rst | 44 +- src/environment-3.10-linux-aarch64.yml | 435 ---------------- src/environment-3.10-linux.yml | 483 ------------------ src/environment-3.10-macos-x86_64.yml | 423 --------------- src/environment-3.10-macos.yml | 423 --------------- src/environment-3.11-linux-aarch64.yml | 434 ---------------- src/environment-3.11-linux.yml | 482 ----------------- src/environment-3.11-macos-x86_64.yml | 422 --------------- src/environment-3.11-macos.yml | 422 --------------- src/environment-3.9-linux-aarch64.yml | 435 ---------------- src/environment-3.9-linux.yml | 483 ------------------ src/environment-3.9-macos-x86_64.yml | 423 --------------- src/environment-3.9-macos.yml | 423 --------------- 45 files changed, 3129 insertions(+), 5527 deletions(-) rename src/environment-dev-3.10-linux-aarch64.yml => environment-dev-3.10-linux-aarch64.yml (99%) rename src/environment-dev-3.10-linux.yml => environment-dev-3.10-linux.yml (99%) rename src/environment-dev-3.10-macos-x86_64.yml => environment-dev-3.10-macos-x86_64.yml (99%) rename src/environment-dev-3.10-macos.yml => environment-dev-3.10-macos.yml (99%) rename src/environment-dev-3.11-linux-aarch64.yml => environment-dev-3.11-linux-aarch64.yml (99%) rename src/environment-dev-3.11-linux.yml => environment-dev-3.11-linux.yml (99%) rename src/environment-dev-3.11-macos-x86_64.yml => environment-dev-3.11-macos-x86_64.yml (99%) rename src/environment-dev-3.11-macos.yml => environment-dev-3.11-macos.yml (99%) rename src/environment-dev-3.9-linux-aarch64.yml => environment-dev-3.9-linux-aarch64.yml (99%) rename src/environment-dev-3.9-linux.yml => environment-dev-3.9-linux.yml (99%) rename src/environment-dev-3.9-macos-x86_64.yml => environment-dev-3.9-macos-x86_64.yml (99%) rename src/environment-dev-3.9-macos.yml => environment-dev-3.9-macos.yml (99%) delete mode 100644 src/environment-3.10-linux-aarch64.yml delete mode 100644 src/environment-3.10-linux.yml delete mode 100644 src/environment-3.10-macos-x86_64.yml delete mode 100644 src/environment-3.10-macos.yml delete mode 100644 src/environment-3.11-linux-aarch64.yml delete mode 100644 src/environment-3.11-linux.yml delete mode 100644 src/environment-3.11-macos-x86_64.yml delete mode 100644 src/environment-3.11-macos.yml delete mode 100644 src/environment-3.9-linux-aarch64.yml delete mode 100644 src/environment-3.9-linux.yml delete mode 100644 src/environment-3.9-macos-x86_64.yml delete mode 100644 src/environment-3.9-macos.yml diff --git a/.devcontainer/onCreate-conda.sh b/.devcontainer/onCreate-conda.sh index 0904ebe7c16..214570f76e8 100755 --- a/.devcontainer/onCreate-conda.sh +++ b/.devcontainer/onCreate-conda.sh @@ -2,8 +2,11 @@ set -e # Create conda environment -conda install mamba -n base -c conda-forge -y -mamba env create --file src/environment-dev-3.11-linux.yml || mamba env update --file src/environment-dev-3.11-linux.yml +conda config --env --add channels conda-forge +conda config --env --set channel_priority strict +conda update -y --all --override-channels -c conda-forge +conda install mamba=1 -n base -y +mamba env create -y --file environment-dev-3.11-linux.yml || mamba env update -y --file environment-dev-3.11-linux.yml conda init bash # Build sage diff --git a/.github/workflows/ci-conda.yml b/.github/workflows/ci-conda.yml index 7b06217e295..f620820ae68 100644 --- a/.github/workflows/ci-conda.yml +++ b/.github/workflows/ci-conda.yml @@ -59,7 +59,7 @@ jobs: with: path: ~/conda_pkgs_dir key: - ${{ runner.os }}-conda-${{ hashFiles('src/environment-3.11.yml') }} + ${{ runner.os }}-conda-${{ hashFiles('environment-3.11.yml') }} - name: Setup Conda environment uses: conda-incubator/setup-miniconda@v3 @@ -70,7 +70,7 @@ jobs: channels: conda-forge channel-priority: true activate-environment: sage - environment-file: src/${{ matrix.conda-env }}-${{ matrix.python }}-${{ startsWith(matrix.os, 'macos') && (startsWith(runner.arch, 'ARM') && 'macos' || 'macos-x86_64') || 'linux' }}.yml + environment-file: ${{ matrix.conda-env }}-${{ matrix.python }}-${{ startsWith(matrix.os, 'macos') && (startsWith(runner.arch, 'ARM') && 'macos' || 'macos-x86_64') || 'linux' }}.yml - name: Print Conda environment shell: bash -l {0} diff --git a/.github/workflows/conda-lock-update.py b/.github/workflows/conda-lock-update.py index b620d8aaf52..ca71b631db3 100755 --- a/.github/workflows/conda-lock-update.py +++ b/.github/workflows/conda-lock-update.py @@ -4,7 +4,7 @@ import subprocess script_dir = Path(__file__).resolve().parent -root_dir = script_dir / '..' / '..' +root_dir = script_dir / ".." / ".." subprocess.run([str(root_dir / "bootstrap-conda")]) @@ -12,22 +12,45 @@ "linux-64": "linux", "linux-aarch64": "linux-aarch64", "osx-64": "macos-x86_64", - "osx-arm64": "macos" - #"win-64": "win", + "osx-arm64": "macos", + # "win-64": "win", } pythons = ["3.9", "3.10", "3.11"] tags = ["", "-dev"] -sources = ["", "src"] for platform_key, platform_value in platforms.items(): for python in pythons: for tag in tags: - for src in sources: - env_file = root_dir / src / f"environment{tag}-{python}.yml" - lock_file = root_dir / src / f"environment{tag}-{python}-{platform_value}" + env_file = root_dir / f"environment{tag}-{python}.yml" + lock_file = root_dir / f"environment{tag}-{python}-{platform_value}" + lock_file_gen = root_dir / f"environment{tag}-{python}-{platform_value}.yml" - if not env_file.exists(): - continue + if not env_file.exists(): + continue - print(f"Updating lock file for {env_file} at {lock_file}", flush=True) - subprocess.run(["conda-lock", "--channel", "conda-forge", "--kind", "env", "--platform", platform_key, "--file", str(env_file), "--lockfile", str(lock_file), "--filename-template", str(lock_file)]) + print(f"Updating lock file for {env_file} at {lock_file_gen}", flush=True) + subprocess.run( + [ + "conda-lock", + "--mamba", + "--channel", + "conda-forge", + "--kind", + "env", + "--platform", + platform_key, + "--file", + str(env_file), + "--lockfile", + str(lock_file), + "--filename-template", + str(lock_file), + ], + check=True, + ) + + # Add conda env name to lock file at beginning + with open(lock_file_gen, "r+") as f: + content = f.read() + f.seek(0, 0) + f.write(f"name: sage{tag}\n{content}") diff --git a/.gitignore b/.gitignore index 70a6739c33b..96973ce89ab 100644 --- a/.gitignore +++ b/.gitignore @@ -28,12 +28,15 @@ /src/lib/pkgconfig # Environment files generated by bootstrap-conda. -# The files without Python version are no longer generated +# The files without Python version and in src 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 /environment-optional.yml /environment-optional-3.9.yml /environment-optional-3.10.yml diff --git a/.gitpod.yml b/.gitpod.yml index 6d7c9ec93df..6ebcf7f67a4 100644 --- a/.gitpod.yml +++ b/.gitpod.yml @@ -7,7 +7,7 @@ tasks: - name: Setup # Create conda environment, then configure and build sage init: >- - && mamba env create --file src/environment-dev-3.11-linux.yml --prefix venv + && mamba env create --file environment-dev-3.11-linux.yml --prefix venv && conda config --append envs_dirs $(pwd) && conda activate $(pwd)/venv && ./bootstrap diff --git a/.vscode/settings.json b/.vscode/settings.json index 86eac03ffe9..eb0736473cc 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,7 +1,5 @@ { - // This settings file is not ignored by git. It should be kept in sync with - // the trac repo. - "python.defaultInterpreterPath": "./venv/bin/python3", + // This settings file is not ignored by git. "files.exclude": { "**/__pycache__": true, "src/**/*.cpp": true, diff --git a/bootstrap-conda b/bootstrap-conda index c64e2a72b6c..fda21157b11 100755 --- a/bootstrap-conda +++ b/bootstrap-conda @@ -84,7 +84,7 @@ unset ENABLE_SYSTEM_SITE_PACKAGES echo >&2 $0:$LINENO: generate conda environment files ( - echo "name: sage-build" + echo "name: sage" echo "channels:" echo " - conda-forge" echo " - nodefaults" @@ -96,65 +96,25 @@ echo >&2 $0:$LINENO: generate conda environment files for pkg in $BOOTSTRAP_SYSTEM_PACKAGES; do echo " - $pkg" done - ) > environment-template.yml - ( - sed 's/name: sage-build/name: sage/' environment-template.yml + echo " - meson" + echo " - meson-python" + echo " - pytest" echo " # Additional packages providing all dependencies for the Sage library" for pkg in $SAGELIB_SYSTEM_PACKAGES; do echo " - $pkg" done - ) > src/environment-template.yml - - ( - cat environment-template.yml - echo " # optional packages" - for pkg in $OPTIONAL_SYSTEM_PACKAGES; do - echo " - $pkg" - done - ) > environment-optional-template.yml + ) > environment-template.yml ( - sed 's/name: sage/name: sage-dev/' src/environment-template.yml + sed 's/name: sage/name: sage-dev/' environment-template.yml echo " # Additional dev tools" echo " - conda-lock" for pkg in $DEVELOP_SYSTEM_PACKAGES; do echo " - $pkg" done - ) > src/environment-dev-template.yml - - ( - cat src/environment-template.yml - echo " # optional packages" - for pkg in $OPTIONAL_SYSTEM_PACKAGES $SAGELIB_OPTIONAL_SYSTEM_PACKAGES; do - echo " - $pkg" - done - ) > src/environment-optional-template.yml - - ( - echo >&4 " - pip:" - echo >&5 " - pip:" - for PKG_BASE in $(sage-package list :standard: :optional: --has-file requirements.txt --no-file distros/conda.txt --no-file src; sage-package list :standard: :optional: --has-file version_requirements.txt --no-file requirements.txt --no-file distros/conda.txt --no-file src); do - eval PKG_SCRIPTS=\$path_$PKG_BASE PKG_TYPE=\$type_$PKG_BASE - SYSTEM_PACKAGES_FILE=$PKG_SCRIPTS/requirements.txt - if [ ! -f $SYSTEM_PACKAGES_FILE ]; then - SYSTEM_PACKAGES_FILE=$PKG_SCRIPTS/version_requirements.txt - fi - if grep -q SAGERUNTIME $PKG_SCRIPTS/dependencies $PKG_SCRIPTS/dependencies_order_only 2>/dev/null; then - : # cannot install packages that depend on the Sage library - else - case "$PKG_BASE:$PKG_TYPE" in - $DEVELOP_SPKG_PATTERN:*) FD=4;; - *:standard) FD="4 5";; - *) FD=5;; - esac - ${STRIP_COMMENTS} $SYSTEM_PACKAGES_FILE | while read -r line; do - [ -n "$line" ] && for fd in $FD; do echo >&$fd " - $line"; done - done - fi - done - ) 4>> /dev/null 5>> src/environment-optional-template.yml + ) > environment-dev-template.yml -for f in environment environment-optional src/environment src/environment-optional src/environment-dev; do +for f in environment environment-dev; do for python_version in 3.9 3.10 3.11; do sed -E 's/^( *- *)python *$/\1python='$python_version'/' $f-template.yml > $f-$python_version.yml done diff --git a/condarc.yml b/condarc.yml index 9538902cacd..dd5a6e34a16 100644 --- a/condarc.yml +++ b/condarc.yml @@ -3,4 +3,3 @@ channel_priority: strict channels: - conda-forge - - defaults diff --git a/environment-3.10-linux-aarch64.yml b/environment-3.10-linux-aarch64.yml index bddb9bbef02..1ec845735bf 100644 --- a/environment-3.10-linux-aarch64.yml +++ b/environment-3.10-linux-aarch64.yml @@ -1,45 +1,92 @@ +name: sage # Generated by conda-lock. # platform: linux-aarch64 -# input_hash: ed05f748f5bf9a763c86991a78f0e77da34cbbe3d1568b666f3476c19d899843 +# input_hash: 50ecbf09a118347f6c002960a184cf81c369d83e8e8555c2db3282013254eca1 channels: - conda-forge dependencies: - _openmp_mutex=4.5=2_kmp_llvm + - _r-mutex=1.0.1=anacondar_1 - _sysroot_linux-aarch64_curr_repodata_hack=4=h57d6b7b_14 + - alabaster=0.7.16=pyhd8ed1ab_0 + - alsa-lib=1.2.11=h31becfc_1 + - anyio=4.4.0=pyhd8ed1ab_0 - appdirs=1.4.4=pyh9f0ad1d_0 + - appnope=0.1.4=pyhd8ed1ab_0 + - argon2-cffi=23.1.0=pyhd8ed1ab_0 + - argon2-cffi-bindings=21.2.0=py310hb299538_4 - arpack=3.9.1=nompi_hd363cd0_101 + - arrow=1.3.0=pyhd8ed1ab_0 + - asttokens=2.4.1=pyhd8ed1ab_0 + - async-lru=2.0.4=pyhd8ed1ab_0 + - attrs=23.2.0=pyh71513ae_0 - autoconf=2.71=pl5321h2148fe1_1 - automake=1.16.5=pl5321h8af1aa0_0 + - babel=2.14.0=pyhd8ed1ab_0 - bc=1.07.1=hf897c2e_0 - bdw-gc=8.0.6=hd62202e_0 + - beautifulsoup4=4.12.3=pyha770c72_0 + - beniget=0.4.1=pyhd8ed1ab_0 - binutils=2.40=hf1166c9_7 - binutils_impl_linux-aarch64=2.40=hf54a868_7 - binutils_linux-aarch64=2.40=h1f91aba_9 - - blas=2.122=openblas - - blas-devel=3.9.0=22_linuxaarch64_openblas + - blas=2.120=openblas + - blas-devel=3.9.0=20_linuxaarch64_openblas + - bleach=6.1.0=pyhd8ed1ab_0 - boost-cpp=1.85.0=ha990451_2 - brial=1.2.12=pyh694c41f_3 + - brotli=1.1.0=h31becfc_1 + - brotli-bin=1.1.0=h31becfc_1 + - brotli-python=1.1.0=py310hbb3657e_1 + - bwidget=1.9.14=h8af1aa0_1 - bzip2=1.0.8=h31becfc_5 - c-ares=1.28.1=h31becfc_0 - c-compiler=1.7.0=h31becfc_1 - ca-certificates=2024.6.2=hcefe29a_0 + - cached-property=1.5.2=hd8ed1ab_1 + - cached_property=1.5.2=pyha770c72_1 - cachetools=5.3.3=pyhd8ed1ab_0 + - cairo=1.18.0=h5c54ea9_2 - cddlib=1!0.94m=h719063d_0 + - certifi=2024.6.2=pyhd8ed1ab_0 + - cffi=1.16.0=py310hce94938_0 - chardet=5.2.0=py310hbbe02a8_1 + - charset-normalizer=3.3.2=pyhd8ed1ab_0 - cliquer=1.22=h31becfc_1 - cmake=3.29.6=h7042e5d_0 - colorama=0.4.6=pyhd8ed1ab_0 + - colorlog=6.8.2=py310h4c7bcd0_0 + - comm=0.2.2=pyhd8ed1ab_0 - compilers=1.7.0=h8af1aa0_1 + - contourpy=1.2.1=py310h586407a_0 + - conway-polynomials=0.9=pyhd8ed1ab_0 + - cppy=1.2.1=pyhd8ed1ab_0 - curl=8.8.0=h7daf2e0_0 + - cvxopt=1.3.2=py310he29a27f_2 - cxx-compiler=1.7.0=h2a328a1_1 + - cycler=0.12.1=pyhd8ed1ab_0 + - cypari2=2.1.5=py310h4cbba44_0 + - cysignals=1.11.2=py310h485802a_3 + - cython=3.0.10=py310hbb3657e_0 + - debugpy=1.8.1=py310hbb3657e_0 + - decorator=5.1.1=pyhd8ed1ab_0 + - defusedxml=0.7.1=pyhd8ed1ab_0 - distlib=0.3.8=pyhd8ed1ab_0 + - docutils=0.21.2=pyhd8ed1ab_0 + - dsdp=5.8=hb12102e_1203 - ecl=23.9.9=h6475f26_0 - eclib=20231212=he26bab5_0 - ecm=7.0.5=ha2d0fc4_0 + - editables=0.5=pyhd8ed1ab_0 + - entrypoints=0.4=pyhd8ed1ab_0 + - exceptiongroup=1.2.0=pyhd8ed1ab_2 + - executing=2.0.1=pyhd8ed1ab_0 - expat=2.6.2=h2f0025b_0 - fflas-ffpack=2.5.0=h503e619_0 + - fftw=3.3.10=nompi_h020dacd_110 - filelock=3.15.4=pyhd8ed1ab_0 + - flit-core=3.9.0=pyhd8ed1ab_1 - 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 @@ -47,11 +94,17 @@ dependencies: - fontconfig=2.14.2=ha9a116f_0 - fonts-conda-ecosystem=1=0 - fonts-conda-forge=1=0 + - fonttools=4.53.0=py310hb52b2da_0 - fortran-compiler=1.7.0=h7048d53_1 - fplll=5.4.5=hb3a790e_0 + - fpylll=0.6.1=py310hfdbf2a6_0 + - fqdn=1.5.1=pyhd8ed1ab_0 - freetype=2.12.1=hf0a5ef3_2 + - fribidi=1.0.10=hb9de7d4_0 + - furo=2024.5.6=pyhd8ed1ab_0 - gap-core=4.12.2=h597289e_3 - gap-defaults=4.12.2=h8af1aa0_3 + - gast=0.5.4=pyhd8ed1ab_0 - gcc=12.3.0=hdb0cc85_13 - gcc_impl_linux-aarch64=12.3.0=h3d98823_13 - gcc_linux-aarch64=12.3.0=ha52a6ea_9 @@ -66,29 +119,76 @@ dependencies: - givaro=4.2.0=h364d21b_0 - glpk=5.0=h66325d0_0 - gmp=6.3.0=h0a1ffab_2 + - gmpy2=2.1.5=py310h05bcf56_1 + - graphite2=1.3.13=h2f0025b_1003 - gsl=2.7=h294027d_0 - gxx=12.3.0=hdb0cc85_13 - gxx_impl_linux-aarch64=12.3.0=hba91e99_13 - gxx_linux-aarch64=12.3.0=h9d1f256_9 + - h11=0.14.0=pyhd8ed1ab_0 + - h2=4.1.0=pyhd8ed1ab_0 + - harfbuzz=8.5.0=h9812418_0 + - hatchling=1.25.0=pyhd8ed1ab_0 + - hpack=4.0.0=pyh9f0ad1d_0 + - httpcore=1.0.5=pyhd8ed1ab_0 + - httpx=0.27.0=pyhd8ed1ab_0 + - hyperframe=6.0.1=pyhd8ed1ab_0 - icu=73.2=h787c7f5_0 + - idna=3.7=pyhd8ed1ab_0 - igraph=0.10.12=h197073e_1 + - imagesize=1.4.1=pyhd8ed1ab_0 - iml=1.0.5=h15043fe_1004 - importlib-metadata=8.0.0=pyha770c72_0 + - importlib-resources=6.4.0=pyhd8ed1ab_0 - importlib_metadata=8.0.0=hd8ed1ab_0 + - importlib_resources=6.4.0=pyhd8ed1ab_0 + - ipykernel=6.29.4=pyh3099207_0 + - ipympl=0.9.4=pyhd8ed1ab_0 + - ipython=8.25.0=pyh707e725_0 + - ipython_genutils=0.2.0=pyhd8ed1ab_1 + - ipywidgets=8.1.3=pyhd8ed1ab_0 + - isoduration=20.11.0=pyhd8ed1ab_0 + - jedi=0.19.1=pyhd8ed1ab_0 + - jinja2=3.1.4=pyhd8ed1ab_0 + - jmol=14.32.10=h8af1aa0_0 + - json5=0.9.25=pyhd8ed1ab_0 + - jsonpointer=3.0.0=py310h4c7bcd0_0 + - jsonschema=4.22.0=pyhd8ed1ab_0 + - jsonschema-specifications=2023.12.1=pyhd8ed1ab_0 + - jsonschema-with-format-nongpl=4.22.0=pyhd8ed1ab_0 + - jupyter-jsmol=2022.1.0=pyhd8ed1ab_0 + - jupyter-lsp=2.2.5=pyhd8ed1ab_0 + - jupyter-sphinx=0.5.3=pyha770c72_4 + - jupyter_client=8.6.2=pyhd8ed1ab_0 + - jupyter_core=5.7.2=py310h4c7bcd0_0 + - jupyter_events=0.10.0=pyhd8ed1ab_0 + - jupyter_server=2.14.1=pyhd8ed1ab_0 + - jupyter_server_terminals=0.5.3=pyhd8ed1ab_0 + - jupyter_sphinx=0.5.3=hd8ed1ab_4 + - jupyterlab=4.2.2=pyhd8ed1ab_0 + - jupyterlab_pygments=0.3.0=pyhd8ed1ab_1 + - jupyterlab_server=2.27.2=pyhd8ed1ab_0 + - jupyterlab_widgets=3.0.11=pyhd8ed1ab_0 - kernel-headers_linux-aarch64=4.18.0=h5b4a56d_14 - keyutils=1.6.1=h4e544f5_0 + - kiwisolver=1.4.5=py310he290b8a_1 - krb5=1.21.2=hc419048_0 - lcalc=2.0.5=he588f68_2 + - lcms2=2.16=h922389a_0 - ld_impl_linux-aarch64=2.40=h9fc2d93_7 - lerc=4.0.0=h4de3ea5_0 - libatomic_ops=7.6.14=h4e544f5_0 - - libblas=3.9.0=22_linuxaarch64_openblas + - libblas=3.9.0=20_linuxaarch64_openblas - libboost=1.85.0=hb41fec8_2 - libboost-devel=1.85.0=h37bb5a9_2 - libboost-headers=1.85.0=h8af1aa0_2 - libbraiding=1.2=hd600fc2_0 - libbrial=1.2.12=h9429f74_3 - - libcblas=3.9.0=22_linuxaarch64_openblas + - libbrotlicommon=1.1.0=h31becfc_1 + - libbrotlidec=1.1.0=h31becfc_1 + - libbrotlienc=1.1.0=h31becfc_1 + - libcblas=3.9.0=20_linuxaarch64_openblas + - libcups=2.3.3=h405e4a8_4 - libcurl=8.8.0=h4e8248e_0 - libdeflate=1.20=h31becfc_0 - libedit=3.1.20191231=he28a2e2_2 @@ -101,16 +201,17 @@ dependencies: - libgd=2.3.3=hcd22fd5_9 - libgfortran-ng=13.2.0=he9431aa_13 - libgfortran5=13.2.0=h2af0866_13 + - libglib=2.80.2=haee52c6_1 - libgomp=13.2.0=he277a41_13 - libhomfly=1.02r6=h31becfc_1 - libhwloc=2.10.0=default_h3030c0e_1001 - libiconv=1.17=h31becfc_2 - libjpeg-turbo=3.0.0=h31becfc_1 - - liblapack=3.9.0=22_linuxaarch64_openblas - - liblapacke=3.9.0=22_linuxaarch64_openblas + - liblapack=3.9.0=20_linuxaarch64_openblas + - liblapacke=3.9.0=20_linuxaarch64_openblas - libnghttp2=1.58.0=hb0e430d_1 - libnsl=2.0.1=h31becfc_0 - - libopenblas=0.3.27=pthreads_h5a5ec62_0 + - libopenblas=0.3.25=pthreads_h5a5ec62_0 - libpng=1.6.43=h194ca79_0 - libsanitizer=12.3.0=h57e2e72_13 - libsodium=1.0.18=hb9de7d4_1 @@ -124,6 +225,7 @@ dependencies: - libuv=1.48.0=h31becfc_0 - libwebp=1.4.0=h8b4e01b_0 - libwebp-base=1.4.0=h31becfc_0 + - libxcb=1.16=h7935292_0 - libxcrypt=4.4.36=h31becfc_1 - libxml2=2.12.7=h49dc7a2_1 - libzlib=1.3.1=h68df207_1 @@ -134,61 +236,200 @@ dependencies: - m4ri=20140914=hedfd65a_1006 - m4rie=20150908=hf0a5ef3_1002 - make=4.3=h309ac5b_1 + - markupsafe=2.1.5=py310h7c1f4a2_0 - mathjax=3.2.2=h8af1aa0_0 + - matplotlib=3.8.4=py310hbbe02a8_2 + - matplotlib-base=3.8.4=py310h84f21c1_2 + - matplotlib-inline=0.1.7=pyhd8ed1ab_0 - maxima=5.47.0=h6475f26_2 + - memory-allocator=0.1.3=py310hb299538_0 - metis=5.1.0=h2f0025b_1007 + - mistune=3.0.2=pyhd8ed1ab_0 - mpc=1.3.1=hf4c8f4c_0 - mpfi=1.5.4=h846f343_1001 - mpfr=4.2.1=ha2d0fc4_1 + - mpmath=1.3.0=pyhd8ed1ab_0 + - munkres=1.1.4=pyh9f0ad1d_0 - nauty=2.8.8=h31becfc_1 + - nbclient=0.10.0=pyhd8ed1ab_0 + - nbconvert=7.16.4=hd8ed1ab_1 + - nbconvert-core=7.16.4=pyhd8ed1ab_1 + - nbconvert-pandoc=7.16.4=hd8ed1ab_1 + - nbformat=5.10.4=pyhd8ed1ab_0 - ncurses=6.5=h0425590_0 + - nest-asyncio=1.6.0=pyhd8ed1ab_0 + - networkx=3.2.1=pyhd8ed1ab_0 - ninja=1.12.1=h70be974_0 + - notebook=7.2.1=pyhd8ed1ab_0 + - notebook-shim=0.2.4=pyhd8ed1ab_0 - ntl=11.4.3=h0d7519b_1 - - openblas=0.3.27=pthreads_h339cbfa_0 + - numpy=1.26.4=py310hcbab775_0 + - openblas=0.3.25=pthreads_h339cbfa_0 + - openjdk=22.0.1=h3d4cd67_0 + - openjpeg=2.5.2=h0d9d63b_0 - openssl=3.3.1=h68df207_0 + - overrides=7.7.0=pyhd8ed1ab_0 - packaging=24.1=pyhd8ed1ab_0 - palp=2.20=hb9de7d4_0 + - pandoc=3.2.1=h8af1aa0_0 + - pandocfilters=1.5.0=pyhd8ed1ab_0 + - pango=1.54.0=h399c48b_0 - pari=2.15.5=h169c2a7_2_pthread - pari-elldata=0.0.20161017=0 - pari-galdata=0.0.20180411=0 - pari-galpol=0.0.20180625=0 - pari-seadata=0.0.20090618=0 - pari-seadata-small=0.0.20090618=0 + - parso=0.8.4=pyhd8ed1ab_0 - patch=2.7.6=hf897c2e_1002 + - pathspec=0.12.1=pyhd8ed1ab_0 + - pcre2=10.44=h070dd5b_0 + - pep517=0.13.0=pyhd8ed1ab_0 - perl=5.32.1=7_h31becfc_perl5 + - pexpect=4.9.0=pyhd8ed1ab_0 + - pickleshare=0.7.5=py_1003 + - pillow=10.3.0=py310h611336f_1 + - pip=24.0=pyhd8ed1ab_0 + - pixman=0.43.4=h2f0025b_0 - pkg-config=0.29.2=hb9de7d4_1008 + - pkgconfig=1.5.5=pyhd8ed1ab_4 + - pkgutil-resolve-name=1.3.10=pyhd8ed1ab_1 - planarity=3.0.2.0=h31becfc_0 - platformdirs=4.2.2=pyhd8ed1ab_0 - pluggy=1.5.0=pyhd8ed1ab_0 + - ply=3.11=pyhd8ed1ab_2 - ppl=1.2=h984aac9_1006 - - primecount=7.13=hfe4b40e_0 - - primesieve=12.1=h2f0025b_0 + - pplpy=0.8.9=py310h6665419_1 + - primecount=7.9=hd600fc2_0 + - primecountpy=0.1.0=py310h586407a_4 + - primesieve=11.1=h2f0025b_0 + - prometheus_client=0.20.0=pyhd8ed1ab_0 + - prompt-toolkit=3.0.47=pyha770c72_0 + - prompt_toolkit=3.0.47=hd8ed1ab_0 + - psutil=6.0.0=py310hb52b2da_0 + - pthread-stubs=0.4=hb9de7d4_1001 + - ptyprocess=0.7.0=pyhd3deb0d_0 + - pure_eval=0.2.2=pyhd8ed1ab_0 + - py=1.11.0=pyh6c4a22f_0 + - pybind11=2.12.0=py310h586407a_0 + - pybind11-global=2.12.0=py310h586407a_0 + - pycparser=2.22=pyhd8ed1ab_0 + - pygments=2.18.0=pyhd8ed1ab_0 + - pyparsing=3.1.2=pyhd8ed1ab_0 - pyproject-api=1.7.1=pyhd8ed1ab_0 + - pyrsistent=0.20.0=py310h7c1f4a2_0 + - pysocks=1.7.1=pyha2e5f31_6 - python=3.10.14=hbbe8eec_0_cpython + - python-build=1.2.1=pyhd8ed1ab_0 + - python-dateutil=2.9.0=pyhd8ed1ab_0 + - python-fastjsonschema=2.20.0=pyhd8ed1ab_0 + - python-json-logger=2.0.7=pyhd8ed1ab_0 + - python-lrcalc=2.1=py310hbb3657e_6 + - python-tzdata=2024.1=pyhd8ed1ab_0 - python_abi=3.10=4_cp310 + - pythran=0.15.0=py310h5e48e15_1 + - pytz=2024.1=pyhd8ed1ab_0 + - pytz-deprecation-shim=0.1.0.post0=py310h4c7bcd0_4 + - pyyaml=6.0.1=py310hb299538_1 + - pyzmq=26.0.3=py310he875deb_0 - qd=2.3.22=h05efe27_1004 - qhull=2020.2=hd62202e_2 + - r-base=4.3.3=h7f20121_3 + - r-lattice=0.22_6=r43h25e906a_0 - readline=8.2=h8fc344f_1 + - referencing=0.35.1=pyhd8ed1ab_0 + - requests=2.32.3=pyhd8ed1ab_0 + - rfc3339-validator=0.1.4=pyhd8ed1ab_0 + - rfc3986-validator=0.1.1=pyh9f0ad1d_0 - rhash=1.4.4=h31becfc_0 + - rpds-py=0.18.1=py310h59d1b7a_0 + - rpy2=3.5.11=py310r43h8b6b5fc_3 - rw=0.9=h31becfc_2 + - sagemath-db-combinatorial-designs=20140630=1 + - sagemath-db-elliptic-curves=0.8.1=hecc5488_0 + - sagemath-db-graphs=20210214=hd8ed1ab_0 + - sagemath-db-polytopes=20170220=1 + - sagetex=3.6.1=pyhd8ed1ab_0 + - scipy=1.11.3=py310hcbab775_1 + - sed=4.8=ha0d5d3d_0 + - send2trash=1.8.3=pyh0d859eb_0 + - setuptools=70.1.1=pyhd8ed1ab_0 + - setuptools-scm=8.1.0=pyhd8ed1ab_0 + - setuptools_scm=8.1.0=hd8ed1ab_0 + - simplegeneric=0.8.1=py_1 - singular=4.3.2.p8=hbe76a8a_1 + - six=1.16.0=pyh6c4a22f_0 + - sniffio=1.3.1=pyhd8ed1ab_0 + - snowballstemmer=2.2.0=pyhd8ed1ab_0 + - soupsieve=2.5=pyhd8ed1ab_1 + - sphinx=7.3.7=pyhd8ed1ab_0 + - sphinx-basic-ng=1.0.0b2=pyhd8ed1ab_1 + - sphinx-copybutton=0.5.2=pyhd8ed1ab_0 + - sphinxcontrib-applehelp=1.0.8=pyhd8ed1ab_0 + - sphinxcontrib-devhelp=1.0.6=pyhd8ed1ab_0 + - sphinxcontrib-htmlhelp=2.0.5=pyhd8ed1ab_0 + - sphinxcontrib-jsmath=1.0.1=pyhd8ed1ab_0 + - sphinxcontrib-qthelp=1.0.7=pyhd8ed1ab_0 + - sphinxcontrib-serializinghtml=1.1.10=pyhd8ed1ab_0 + - sphinxcontrib-websupport=1.2.7=pyhd8ed1ab_0 - sqlite=3.46.0=hdc7ab3c_0 + - stack_data=0.6.2=pyhd8ed1ab_0 - suitesparse=7.7.0=h3944111_1 - symmetrica=3.0.1=hd600fc2_0 - sympow=2.023.6=h157afb5_3 + - sympy=1.12.1=pypyh2585a3b_103 - sysroot_linux-aarch64=2.17=h5b4a56d_14 - tachyon=0.99b6=ha0bfc61_1002 - tar=1.34=h048efde_0 - tbb=2021.12.0=h70be974_1 + - terminado=0.18.1=pyh0d859eb_0 - texinfo=7.0=pl5321h17f021e_0 + - three.js=122=hd8ed1ab_2 + - threejs-sage=122=hd8ed1ab_2 + - tinycss2=1.3.0=pyhd8ed1ab_0 - tk=8.6.13=h194ca79_0 + - tktable=2.10=h52f7bd3_6 - tomli=2.0.1=pyhd8ed1ab_0 + - tornado=6.4.1=py310h03727f4_0 - tox=4.15.1=pyhd8ed1ab_0 + - traitlets=5.14.3=pyhd8ed1ab_0 + - trove-classifiers=2024.5.22=pyhd8ed1ab_0 + - types-python-dateutil=2.9.0.20240316=pyhd8ed1ab_0 - typing-extensions=4.12.2=hd8ed1ab_0 - typing_extensions=4.12.2=pyha770c72_0 + - typing_utils=0.1.0=pyhd8ed1ab_0 - tzdata=2024a=h0c530f3_0 + - tzlocal=5.2=py310h4c7bcd0_0 + - unicodedata2=15.1.0=py310hb299538_0 + - uri-template=1.3.0=pyhd8ed1ab_0 + - urllib3=2.2.2=pyhd8ed1ab_0 - virtualenv=20.26.3=pyhd8ed1ab_0 + - wcwidth=0.2.13=pyhd8ed1ab_0 + - webcolors=24.6.0=pyhd8ed1ab_0 + - webencodings=0.5.1=pyhd8ed1ab_2 + - websocket-client=1.8.0=pyhd8ed1ab_0 + - wheel=0.43.0=pyhd8ed1ab_1 + - widgetsnbextension=4.0.11=pyhd8ed1ab_0 + - xorg-fixesproto=5.0=h3557bc0_1002 + - xorg-inputproto=2.3.2=h3557bc0_1002 + - xorg-kbproto=1.0.7=h3557bc0_1002 + - xorg-libice=1.1.1=h7935292_0 + - xorg-libsm=1.2.4=h5a01bc2_0 + - xorg-libx11=1.8.9=h08be655_1 + - xorg-libxau=1.0.11=h31becfc_0 + - xorg-libxdmcp=1.1.3=h3557bc0_0 + - xorg-libxext=1.3.4=h2a766a3_2 + - xorg-libxfixes=5.0.3=h3557bc0_1004 + - xorg-libxi=1.7.10=h3557bc0_0 + - xorg-libxrender=0.9.11=h7935292_0 + - xorg-libxt=1.3.0=h7935292_1 + - xorg-libxtst=1.2.3=hf897c2e_1002 + - xorg-recordproto=1.14.2=hf897c2e_1002 + - xorg-renderproto=0.11.1=h3557bc0_1002 + - xorg-xextproto=7.3.0=h2a766a3_1003 + - xorg-xproto=7.0.31=h3557bc0_1007 - xz=5.2.6=h9cdd2b7_0 + - yaml=0.2.5=hf897c2e_2 - zeromq=4.3.5=h28faeed_4 - zipp=3.19.2=pyhd8ed1ab_0 - zlib=1.3.1=h68df207_1 diff --git a/environment-3.10-linux.yml b/environment-3.10-linux.yml index badbe1b8209..b764f92d2d7 100644 --- a/environment-3.10-linux.yml +++ b/environment-3.10-linux.yml @@ -1,45 +1,94 @@ +name: sage # Generated by conda-lock. # platform: linux-64 -# input_hash: 7e2837b2f3969db9c4c0a0a3300952924326a440d181dde256ca0291c70eb8dc +# input_hash: 5dc443f6ceb3674d099e0ec613ba37acf67d72b0b26699816fc7afb3c9523b1f channels: - conda-forge dependencies: - _libgcc_mutex=0.1=conda_forge - _openmp_mutex=4.5=2_kmp_llvm + - _r-mutex=1.0.1=anacondar_1 + - alabaster=0.7.16=pyhd8ed1ab_0 + - alsa-lib=1.2.12=h4ab18f5_0 + - anyio=4.4.0=pyhd8ed1ab_0 - appdirs=1.4.4=pyh9f0ad1d_0 + - appnope=0.1.4=pyhd8ed1ab_0 + - argon2-cffi=23.1.0=pyhd8ed1ab_0 + - argon2-cffi-bindings=21.2.0=py310h2372a71_4 - arpack=3.9.1=nompi_h77f6705_101 + - arrow=1.3.0=pyhd8ed1ab_0 + - asttokens=2.4.1=pyhd8ed1ab_0 + - async-lru=2.0.4=pyhd8ed1ab_0 + - attr=2.5.1=h166bdaf_1 + - attrs=23.2.0=pyh71513ae_0 - autoconf=2.71=pl5321h2b4cb7a_1 - automake=1.16.5=pl5321ha770c72_0 + - babel=2.14.0=pyhd8ed1ab_0 - bc=1.07.1=h7f98852_0 - bdw-gc=8.0.6=h4bd325d_0 + - beautifulsoup4=4.12.3=pyha770c72_0 + - beniget=0.4.1=pyhd8ed1ab_0 - binutils=2.40=h4852527_7 - binutils_impl_linux-64=2.40=ha1999f0_7 - binutils_linux-64=2.40=hb3c18ed_9 - - blas=2.122=openblas - - blas-devel=3.9.0=22_linux64_openblas + - blas=2.120=openblas + - blas-devel=3.9.0=20_linux64_openblas + - bleach=6.1.0=pyhd8ed1ab_0 - boost-cpp=1.85.0=h44aadfe_2 - brial=1.2.12=pyh694c41f_3 + - brotli=1.1.0=hd590300_1 + - brotli-bin=1.1.0=hd590300_1 + - brotli-python=1.1.0=py310hc6cd4ac_1 + - bwidget=1.9.14=ha770c72_1 - bzip2=1.0.8=hd590300_5 - c-ares=1.28.1=hd590300_0 - c-compiler=1.7.0=hd590300_1 - ca-certificates=2024.6.2=hbcca054_0 + - cached-property=1.5.2=hd8ed1ab_1 + - cached_property=1.5.2=pyha770c72_1 - cachetools=5.3.3=pyhd8ed1ab_0 + - cairo=1.18.0=hbb29018_2 - cddlib=1!0.94m=h9202a9a_0 + - certifi=2024.6.2=pyhd8ed1ab_0 + - cffi=1.16.0=py310h2fee648_0 - chardet=5.2.0=py310hff52083_1 + - charset-normalizer=3.3.2=pyhd8ed1ab_0 - cliquer=1.22=hd590300_1 - cmake=3.29.6=hcafd917_0 - colorama=0.4.6=pyhd8ed1ab_0 + - colorlog=6.8.2=py310hff52083_0 + - comm=0.2.2=pyhd8ed1ab_0 - compilers=1.7.0=ha770c72_1 + - contourpy=1.2.1=py310hd41b1e2_0 + - conway-polynomials=0.9=pyhd8ed1ab_0 + - cppy=1.2.1=pyhd8ed1ab_0 - curl=8.8.0=he654da7_0 + - cvxopt=1.3.2=py310h7b0674a_2 - cxx-compiler=1.7.0=h00ab1b0_1 + - cycler=0.12.1=pyhd8ed1ab_0 + - cypari2=2.1.5=py310h14ed79e_0 + - cysignals=1.11.2=py310h945e7c7_3 + - cython=3.0.10=py310hc6cd4ac_0 + - dbus=1.13.6=h5008d03_3 + - debugpy=1.8.1=py310hc6cd4ac_0 + - decorator=5.1.1=pyhd8ed1ab_0 + - defusedxml=0.7.1=pyhd8ed1ab_0 - distlib=0.3.8=pyhd8ed1ab_0 + - docutils=0.21.2=pyhd8ed1ab_0 + - dsdp=5.8=hd9d9efa_1203 - ecl=23.9.9=hed6455c_0 - eclib=20231212=h96f522a_0 - ecm=7.0.5=h9458935_0 + - editables=0.5=pyhd8ed1ab_0 + - entrypoints=0.4=pyhd8ed1ab_0 + - exceptiongroup=1.2.0=pyhd8ed1ab_2 + - executing=2.0.1=pyhd8ed1ab_0 - expat=2.6.2=h59595ed_0 - fflas-ffpack=2.5.0=h4f9960b_0 + - fftw=3.3.10=nompi_hf1063bd_110 - filelock=3.15.4=pyhd8ed1ab_0 + - flit-core=3.9.0=pyhd8ed1ab_1 - 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 @@ -47,15 +96,23 @@ dependencies: - fontconfig=2.14.2=h14ed4e7_0 - fonts-conda-ecosystem=1=0 - fonts-conda-forge=1=0 + - fonttools=4.53.0=py310hc51659f_0 - fortran-compiler=1.7.0=heb67821_1 - fplll=5.4.5=h384768b_0 + - fpylll=0.6.1=py310h7e26f94_0 + - fqdn=1.5.1=pyhd8ed1ab_0 - freetype=2.12.1=h267a509_2 + - fribidi=1.0.10=h36c2ea0_0 + - furo=2024.5.6=pyhd8ed1ab_0 - gap-core=4.12.2=he9a28a4_3 - gap-defaults=4.12.2=ha770c72_3 + - gast=0.5.4=pyhd8ed1ab_0 - gcc=12.3.0=h915e2ae_13 - gcc_impl_linux-64=12.3.0=h58ffeeb_13 - gcc_linux-64=12.3.0=h9528a6a_9 - gengetopt=2.23=h9c3ff4c_0 + - gettext=0.22.5=h59595ed_2 + - gettext-tools=0.22.5=h59595ed_2 - gf2x=1.3.0=ha476b99_2 - gfan=0.6.2=hb86e20a_1003 - gfortran=12.3.0=h915e2ae_13 @@ -64,131 +121,363 @@ dependencies: - giac=1.9.0.21=h673759e_1 - giflib=5.2.2=hd590300_0 - givaro=4.2.0=hb789bce_0 + - glib=2.80.2=h8a4344b_1 + - glib-tools=2.80.2=h73ef956_1 - glpk=5.0=h445213a_0 - gmp=6.3.0=hac33072_2 + - gmpy2=2.1.5=py310hc7909c9_1 + - graphite2=1.3.13=h59595ed_1003 - gsl=2.7=he838d99_0 + - gst-plugins-base=1.24.5=hbaaba92_0 + - gstreamer=1.24.5=haf2f30d_0 - gxx=12.3.0=h915e2ae_13 - gxx_impl_linux-64=12.3.0=h2a574ab_13 - gxx_linux-64=12.3.0=ha28b414_9 + - h11=0.14.0=pyhd8ed1ab_0 + - h2=4.1.0=pyhd8ed1ab_0 + - harfbuzz=8.5.0=hfac3d4d_0 + - hatchling=1.25.0=pyhd8ed1ab_0 + - hpack=4.0.0=pyh9f0ad1d_0 + - httpcore=1.0.5=pyhd8ed1ab_0 + - httpx=0.27.0=pyhd8ed1ab_0 + - hyperframe=6.0.1=pyhd8ed1ab_0 - icu=73.2=h59595ed_0 + - idna=3.7=pyhd8ed1ab_0 - igraph=0.10.12=hef0740d_1 + - imagesize=1.4.1=pyhd8ed1ab_0 - iml=1.0.5=h623f65a_1004 - importlib-metadata=8.0.0=pyha770c72_0 + - importlib-resources=6.4.0=pyhd8ed1ab_0 - importlib_metadata=8.0.0=hd8ed1ab_0 + - importlib_resources=6.4.0=pyhd8ed1ab_0 + - ipykernel=6.29.4=pyh3099207_0 + - ipympl=0.9.4=pyhd8ed1ab_0 + - ipython=8.25.0=pyh707e725_0 + - ipython_genutils=0.2.0=pyhd8ed1ab_1 + - ipywidgets=8.1.3=pyhd8ed1ab_0 + - isoduration=20.11.0=pyhd8ed1ab_0 + - jedi=0.19.1=pyhd8ed1ab_0 + - jinja2=3.1.4=pyhd8ed1ab_0 + - jmol=14.32.10=ha770c72_0 + - json5=0.9.25=pyhd8ed1ab_0 + - jsonpointer=3.0.0=py310hff52083_0 + - jsonschema=4.22.0=pyhd8ed1ab_0 + - jsonschema-specifications=2023.12.1=pyhd8ed1ab_0 + - jsonschema-with-format-nongpl=4.22.0=pyhd8ed1ab_0 + - jupyter-jsmol=2022.1.0=pyhd8ed1ab_0 + - jupyter-lsp=2.2.5=pyhd8ed1ab_0 + - jupyter-sphinx=0.5.3=pyha770c72_4 + - jupyter_client=8.6.2=pyhd8ed1ab_0 + - jupyter_core=5.7.2=py310hff52083_0 + - jupyter_events=0.10.0=pyhd8ed1ab_0 + - jupyter_server=2.14.1=pyhd8ed1ab_0 + - jupyter_server_terminals=0.5.3=pyhd8ed1ab_0 + - jupyter_sphinx=0.5.3=hd8ed1ab_4 + - jupyterlab=4.2.2=pyhd8ed1ab_0 + - jupyterlab_pygments=0.3.0=pyhd8ed1ab_1 + - jupyterlab_server=2.27.2=pyhd8ed1ab_0 + - jupyterlab_widgets=3.0.11=pyhd8ed1ab_0 - kernel-headers_linux-64=2.6.32=he073ed8_17 - keyutils=1.6.1=h166bdaf_0 + - kiwisolver=1.4.5=py310hd41b1e2_1 - krb5=1.21.2=h659d440_0 + - lame=3.100=h166bdaf_1003 - lcalc=2.0.5=h5aac1b6_2 + - lcms2=2.16=hb7c19ff_0 - ld_impl_linux-64=2.40=hf3520f5_7 - lerc=4.0.0=h27087fc_0 + - libasprintf=0.22.5=h661eb56_2 + - libasprintf-devel=0.22.5=h661eb56_2 - libatomic_ops=7.6.14=h166bdaf_0 - - libblas=3.9.0=22_linux64_openblas + - libblas=3.9.0=20_linux64_openblas - libboost=1.85.0=hba137d9_2 - libboost-devel=1.85.0=h00ab1b0_2 - libboost-headers=1.85.0=ha770c72_2 - libbraiding=1.2=hcb278e6_0 - libbrial=1.2.12=h76af697_3 - - libcblas=3.9.0=22_linux64_openblas + - libbrotlicommon=1.1.0=hd590300_1 + - libbrotlidec=1.1.0=hd590300_1 + - libbrotlienc=1.1.0=hd590300_1 + - libcap=2.69=h0f662aa_0 + - libcblas=3.9.0=20_linux64_openblas + - libclang-cpp15=15.0.7=default_h127d8a8_5 + - libclang13=18.1.8=default_h6ae225f_0 + - libcups=2.3.3=h4637d8d_4 - libcurl=8.8.0=hca28451_0 - libdeflate=1.20=hd590300_0 - libedit=3.1.20191231=he28a2e2_2 - libev=4.33=hd590300_2 + - libevent=2.1.12=hf998b51_1 - libexpat=2.6.2=h59595ed_0 - libffi=3.4.2=h7f98852_5 + - libflac=1.4.3=h59595ed_0 - libflint=3.0.1=h5f2e117_ntl_100 - libgcc-devel_linux-64=12.3.0=h6b66f73_113 - libgcc-ng=13.2.0=h77fa898_13 + - libgcrypt=1.10.3=hd590300_0 - libgd=2.3.3=h119a65a_9 + - libgettextpo=0.22.5=h59595ed_2 + - libgettextpo-devel=0.22.5=h59595ed_2 - libgfortran-ng=13.2.0=h69a702a_13 - libgfortran5=13.2.0=h3d2ce59_13 + - libglib=2.80.2=h8a4344b_1 - libgomp=13.2.0=h77fa898_13 + - libgpg-error=1.49=h4f305b6_0 - libhomfly=1.02r6=hd590300_1 - libhwloc=2.10.0=default_h5622ce7_1001 - libiconv=1.17=hd590300_2 - libjpeg-turbo=3.0.0=hd590300_1 - - liblapack=3.9.0=22_linux64_openblas - - liblapacke=3.9.0=22_linux64_openblas + - liblapack=3.9.0=20_linux64_openblas + - liblapacke=3.9.0=20_linux64_openblas + - libllvm15=15.0.7=hb3ce162_4 + - libllvm18=18.1.8=hc9dba70_0 - libnghttp2=1.58.0=h47da74e_1 - libnsl=2.0.1=hd590300_0 - - libopenblas=0.3.27=pthreads_h413a1c8_0 + - libogg=1.3.5=h4ab18f5_0 + - libopenblas=0.3.25=pthreads_h413a1c8_0 + - libopus=1.3.1=h7f98852_1 - libpng=1.6.43=h2797004_0 + - libpq=16.3=ha72fbe1_0 - libsanitizer=12.3.0=hb8811af_13 + - libsndfile=1.2.2=hc60ed4a_1 - libsodium=1.0.18=h36c2ea0_1 - libsqlite=3.46.0=hde9e2c9_0 - libssh2=1.11.0=h0841786_0 - libstdcxx-devel_linux-64=12.3.0=h6b66f73_113 - libstdcxx-ng=13.2.0=hc0a3c3a_13 + - libsystemd0=255=h3516f8a_1 - libtiff=4.6.0=h1dd3fc0_3 - libtool=2.4.7=h27087fc_0 - libuuid=2.38.1=h0b41bf4_0 - libuv=1.48.0=hd590300_0 + - libvorbis=1.3.7=h9c3ff4c_0 - libwebp=1.4.0=h2c329e2_0 - libwebp-base=1.4.0=hd590300_0 + - libxcb=1.16=hd590300_0 - libxcrypt=4.4.36=hd590300_1 + - libxkbcommon=1.7.0=h2c5496b_1 - libxml2=2.12.7=hc051c1a_1 - libzlib=1.3.1=h4ab18f5_1 - linbox=1.7.0=ha329b40_0 - llvm-openmp=18.1.8=hf5423f3_0 - lrcalc=2.1=h59595ed_6 + - lz4-c=1.9.4=hcb278e6_0 - m4=1.4.18=h516909a_1001 - m4ri=20140914=hae5d5c5_1006 - m4rie=20150908=h267a509_1002 - make=4.3=hd18ef5c_1 + - markupsafe=2.1.5=py310h2372a71_0 - mathjax=3.2.2=ha770c72_0 + - matplotlib=3.8.4=py310hff52083_2 + - matplotlib-base=3.8.4=py310hef631a5_2 + - matplotlib-inline=0.1.7=pyhd8ed1ab_0 - maxima=5.47.0=hed6455c_2 + - memory-allocator=0.1.3=py310h2372a71_0 - metis=5.1.0=h59595ed_1007 + - mistune=3.0.2=pyhd8ed1ab_0 - mpc=1.3.1=hfe3b2da_0 - mpfi=1.5.4=h9f54685_1001 - mpfr=4.2.1=h9458935_1 + - mpg123=1.32.6=h59595ed_0 + - mpmath=1.3.0=pyhd8ed1ab_0 + - munkres=1.1.4=pyh9f0ad1d_0 + - mysql-common=8.3.0=hf1915f5_4 + - mysql-libs=8.3.0=hca2cd23_4 - nauty=2.8.8=hd590300_1 + - nbclient=0.10.0=pyhd8ed1ab_0 + - nbconvert=7.16.4=hd8ed1ab_1 + - nbconvert-core=7.16.4=pyhd8ed1ab_1 + - nbconvert-pandoc=7.16.4=hd8ed1ab_1 + - nbformat=5.10.4=pyhd8ed1ab_0 - ncurses=6.5=h59595ed_0 + - nest-asyncio=1.6.0=pyhd8ed1ab_0 + - networkx=3.2.1=pyhd8ed1ab_0 - ninja=1.12.1=h297d8ca_0 + - notebook=7.2.1=pyhd8ed1ab_0 + - notebook-shim=0.2.4=pyhd8ed1ab_0 + - nspr=4.35=h27087fc_0 + - nss=3.101=h593d115_0 - ntl=11.4.3=hef3c4d3_1 - - openblas=0.3.27=pthreads_h7a3da1a_0 + - numpy=1.26.4=py310hb13e2d6_0 + - openblas=0.3.25=pthreads_h7a3da1a_0 + - openjdk=21.0.2=haa376d0_0 + - openjpeg=2.5.2=h488ebb8_0 - openssl=3.3.1=h4ab18f5_0 + - overrides=7.7.0=pyhd8ed1ab_0 - packaging=24.1=pyhd8ed1ab_0 - palp=2.20=h36c2ea0_0 + - pandoc=3.2.1=ha770c72_0 + - pandocfilters=1.5.0=pyhd8ed1ab_0 + - pango=1.54.0=h84a9a3c_0 - pari=2.15.5=h4d4ae9b_2_pthread - pari-elldata=0.0.20161017=0 - pari-galdata=0.0.20180411=0 - pari-galpol=0.0.20180625=0 - pari-seadata=0.0.20090618=0 - pari-seadata-small=0.0.20090618=0 + - parso=0.8.4=pyhd8ed1ab_0 - patch=2.7.6=h7f98852_1002 + - pathspec=0.12.1=pyhd8ed1ab_0 + - pcre2=10.44=h0f59acf_0 + - pep517=0.13.0=pyhd8ed1ab_0 - perl=5.32.1=7_hd590300_perl5 + - pexpect=4.9.0=pyhd8ed1ab_0 + - pickleshare=0.7.5=py_1003 + - pillow=10.3.0=py310hebfe307_1 + - pip=24.0=pyhd8ed1ab_0 + - pixman=0.43.2=h59595ed_0 - pkg-config=0.29.2=h36c2ea0_1008 + - pkgconfig=1.5.5=pyhd8ed1ab_4 + - pkgutil-resolve-name=1.3.10=pyhd8ed1ab_1 - planarity=3.0.2.0=hd590300_0 - platformdirs=4.2.2=pyhd8ed1ab_0 - pluggy=1.5.0=pyhd8ed1ab_0 + - ply=3.11=pyhd8ed1ab_2 - ppl=1.2=h6ec01c2_1006 - - primecount=7.13=hb0181e5_0 - - primesieve=12.1=h59595ed_0 + - pplpy=0.8.9=py310h18554fa_1 + - primecount=7.9=hcb278e6_0 + - primecountpy=0.1.0=py310hd41b1e2_4 + - primesieve=11.1=h59595ed_0 + - prometheus_client=0.20.0=pyhd8ed1ab_0 + - prompt-toolkit=3.0.47=pyha770c72_0 + - prompt_toolkit=3.0.47=hd8ed1ab_0 + - psutil=6.0.0=py310hc51659f_0 + - pthread-stubs=0.4=h36c2ea0_1001 + - ptyprocess=0.7.0=pyhd3deb0d_0 + - pulseaudio-client=17.0=hb77b528_0 + - pure_eval=0.2.2=pyhd8ed1ab_0 + - py=1.11.0=pyh6c4a22f_0 + - pybind11=2.12.0=py310hd41b1e2_0 + - pybind11-global=2.12.0=py310hd41b1e2_0 + - pycparser=2.22=pyhd8ed1ab_0 + - pygments=2.18.0=pyhd8ed1ab_0 + - pyparsing=3.1.2=pyhd8ed1ab_0 - pyproject-api=1.7.1=pyhd8ed1ab_0 + - pyqt=5.15.9=py310h04931ad_5 + - pyqt5-sip=12.12.2=py310hc6cd4ac_5 + - pyrsistent=0.20.0=py310h2372a71_0 + - pysocks=1.7.1=pyha2e5f31_6 - python=3.10.14=hd12c33a_0_cpython + - python-build=1.2.1=pyhd8ed1ab_0 + - python-dateutil=2.9.0=pyhd8ed1ab_0 + - python-fastjsonschema=2.20.0=pyhd8ed1ab_0 + - python-json-logger=2.0.7=pyhd8ed1ab_0 + - python-lrcalc=2.1=py310hc6cd4ac_6 + - python-tzdata=2024.1=pyhd8ed1ab_0 - python_abi=3.10=4_cp310 + - pythran=0.15.0=py310hcb52e73_1 + - pytz=2024.1=pyhd8ed1ab_0 + - pytz-deprecation-shim=0.1.0.post0=py310hff52083_4 + - pyyaml=6.0.1=py310h2372a71_1 + - pyzmq=26.0.3=py310h6883aea_0 - qd=2.3.22=h2cc385e_1004 - qhull=2020.2=h4bd325d_2 + - qt-main=5.15.8=ha2b5568_22 + - r-base=4.3.3=he2d9a6e_3 + - r-lattice=0.22_6=r43h57805ef_0 - readline=8.2=h8228510_1 + - referencing=0.35.1=pyhd8ed1ab_0 + - requests=2.32.3=pyhd8ed1ab_0 + - rfc3339-validator=0.1.4=pyhd8ed1ab_0 + - rfc3986-validator=0.1.1=pyh9f0ad1d_0 - rhash=1.4.4=hd590300_0 + - rpds-py=0.18.1=py310he421c4c_0 + - rpy2=3.5.11=py310r43h1f7b6fc_3 - rw=0.9=hd590300_2 + - sagemath-db-combinatorial-designs=20140630=1 + - sagemath-db-elliptic-curves=0.8.1=hecc5488_0 + - sagemath-db-graphs=20210214=hd8ed1ab_0 + - sagemath-db-polytopes=20170220=1 + - sagetex=3.6.1=pyhd8ed1ab_0 + - scipy=1.11.4=py310hb13e2d6_0 + - sed=4.8=he412f7d_0 + - send2trash=1.8.3=pyh0d859eb_0 + - setuptools=70.1.1=pyhd8ed1ab_0 + - setuptools-scm=8.1.0=pyhd8ed1ab_0 + - setuptools_scm=8.1.0=hd8ed1ab_0 + - simplegeneric=0.8.1=py_1 - singular=4.3.2.p8=h33f5c3f_1 + - sip=6.7.12=py310hc6cd4ac_0 + - six=1.16.0=pyh6c4a22f_0 + - sniffio=1.3.1=pyhd8ed1ab_0 + - snowballstemmer=2.2.0=pyhd8ed1ab_0 + - soupsieve=2.5=pyhd8ed1ab_1 + - sphinx=7.3.7=pyhd8ed1ab_0 + - sphinx-basic-ng=1.0.0b2=pyhd8ed1ab_1 + - sphinx-copybutton=0.5.2=pyhd8ed1ab_0 + - sphinxcontrib-applehelp=1.0.8=pyhd8ed1ab_0 + - sphinxcontrib-devhelp=1.0.6=pyhd8ed1ab_0 + - sphinxcontrib-htmlhelp=2.0.5=pyhd8ed1ab_0 + - sphinxcontrib-jsmath=1.0.1=pyhd8ed1ab_0 + - sphinxcontrib-qthelp=1.0.7=pyhd8ed1ab_0 + - sphinxcontrib-serializinghtml=1.1.10=pyhd8ed1ab_0 + - sphinxcontrib-websupport=1.2.7=pyhd8ed1ab_0 - sqlite=3.46.0=h6d4b2fc_0 + - stack_data=0.6.2=pyhd8ed1ab_0 - suitesparse=7.7.0=hf4753ba_1 - symmetrica=3.0.1=hcb278e6_0 - sympow=2.023.6=hc6ab17c_3 + - sympy=1.12.1=pypyh2585a3b_103 - sysroot_linux-64=2.12=he073ed8_17 - tachyon=0.99b6=hba7d16a_1002 - tar=1.34=hb2e2bae_1 - tbb=2021.12.0=h297d8ca_1 + - terminado=0.18.1=pyh0d859eb_0 - texinfo=7.0=pl5321h0f457ee_0 + - three.js=122=hd8ed1ab_2 + - threejs-sage=122=hd8ed1ab_2 + - tinycss2=1.3.0=pyhd8ed1ab_0 - tk=8.6.13=noxft_h4845f30_101 + - tktable=2.10=h8bc8fbc_6 + - toml=0.10.2=pyhd8ed1ab_0 - tomli=2.0.1=pyhd8ed1ab_0 + - tornado=6.4.1=py310hc51659f_0 - tox=4.15.1=pyhd8ed1ab_0 + - traitlets=5.14.3=pyhd8ed1ab_0 + - trove-classifiers=2024.5.22=pyhd8ed1ab_0 + - types-python-dateutil=2.9.0.20240316=pyhd8ed1ab_0 - typing-extensions=4.12.2=hd8ed1ab_0 - typing_extensions=4.12.2=pyha770c72_0 + - typing_utils=0.1.0=pyhd8ed1ab_0 - tzdata=2024a=h0c530f3_0 + - tzlocal=5.2=py310hff52083_0 + - unicodedata2=15.1.0=py310h2372a71_0 + - uri-template=1.3.0=pyhd8ed1ab_0 + - urllib3=2.2.2=pyhd8ed1ab_0 - virtualenv=20.26.3=pyhd8ed1ab_0 + - wcwidth=0.2.13=pyhd8ed1ab_0 + - webcolors=24.6.0=pyhd8ed1ab_0 + - webencodings=0.5.1=pyhd8ed1ab_2 + - websocket-client=1.8.0=pyhd8ed1ab_0 + - wheel=0.43.0=pyhd8ed1ab_1 + - widgetsnbextension=4.0.11=pyhd8ed1ab_0 + - xcb-util=0.4.1=hb711507_2 + - 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.42=h4ab18f5_0 + - xorg-fixesproto=5.0=h7f98852_1002 + - xorg-inputproto=2.3.2=h7f98852_1002 + - xorg-kbproto=1.0.7=h7f98852_1002 + - xorg-libice=1.1.1=hd590300_0 + - xorg-libsm=1.2.4=h7391055_0 + - xorg-libx11=1.8.9=hb711507_1 + - xorg-libxau=1.0.11=hd590300_0 + - xorg-libxdmcp=1.1.3=h7f98852_0 + - xorg-libxext=1.3.4=h0b41bf4_2 + - xorg-libxfixes=5.0.3=h7f98852_1004 + - xorg-libxi=1.7.10=h7f98852_0 + - xorg-libxrender=0.9.11=hd590300_0 + - xorg-libxt=1.3.0=hd590300_1 + - xorg-libxtst=1.2.3=h7f98852_1002 + - xorg-recordproto=1.14.2=h7f98852_1002 + - xorg-renderproto=0.11.1=h7f98852_1002 + - xorg-xextproto=7.3.0=h0b41bf4_1003 + - xorg-xf86vidmodeproto=2.3.1=h7f98852_1002 + - xorg-xproto=7.0.31=h7f98852_1007 - xz=5.2.6=h166bdaf_0 + - yaml=0.2.5=h7f98852_2 - zeromq=4.3.5=h75354e8_4 - zipp=3.19.2=pyhd8ed1ab_0 - zlib=1.3.1=h4ab18f5_1 diff --git a/environment-3.10-macos-x86_64.yml b/environment-3.10-macos-x86_64.yml index 8e71e6930d6..ebac3ba4872 100644 --- a/environment-3.10-macos-x86_64.yml +++ b/environment-3.10-macos-x86_64.yml @@ -1,29 +1,54 @@ +name: sage # Generated by conda-lock. # platform: osx-64 -# input_hash: 3fe6c9a3bde225a21413e3fbc72cea580ff915d2921ab0980a2f5220ab0e2884 +# input_hash: 831a1103cbcd8c06cbae982446953e3de30517fdd302ac5aa70454b8d19f63d9 channels: - conda-forge dependencies: + - _r-mutex=1.0.1=anacondar_1 + - alabaster=0.7.16=pyhd8ed1ab_0 + - anyio=4.4.0=pyhd8ed1ab_0 - appdirs=1.4.4=pyh9f0ad1d_0 + - appnope=0.1.4=pyhd8ed1ab_0 + - argon2-cffi=23.1.0=pyhd8ed1ab_0 + - argon2-cffi-bindings=21.2.0=py310h6729b98_4 - arpack=3.9.1=nompi_hf81eadf_101 + - arrow=1.3.0=pyhd8ed1ab_0 + - asttokens=2.4.1=pyhd8ed1ab_0 + - async-lru=2.0.4=pyhd8ed1ab_0 + - attrs=23.2.0=pyh71513ae_0 - autoconf=2.71=pl5321hed12c24_1 - automake=1.16.5=pl5321h694c41f_0 + - babel=2.14.0=pyhd8ed1ab_0 - bc=1.07.1=h0d85af4_0 - bdw-gc=8.0.6=h940c156_0 - - blas=2.122=openblas - - blas-devel=3.9.0=22_osx64_openblas + - beautifulsoup4=4.12.3=pyha770c72_0 + - beniget=0.4.1=pyhd8ed1ab_0 + - blas=2.120=openblas + - blas-devel=3.9.0=20_osx64_openblas + - bleach=6.1.0=pyhd8ed1ab_0 - boost-cpp=1.85.0=h07eb623_2 - brial=1.2.12=pyh694c41f_3 + - brotli=1.1.0=h0dc2134_1 + - brotli-bin=1.1.0=h0dc2134_1 + - brotli-python=1.1.0=py310h9e9d8ca_1 + - bwidget=1.9.14=h694c41f_1 - bzip2=1.0.8=h10d778d_5 - c-ares=1.28.1=h10d778d_0 - c-compiler=1.7.0=h282daa2_1 - ca-certificates=2024.6.2=h8857fd0_0 + - cached-property=1.5.2=hd8ed1ab_1 + - cached_property=1.5.2=pyha770c72_1 - cachetools=5.3.3=pyhd8ed1ab_0 + - cairo=1.18.0=h9f650ed_2 - cctools=986=h40f6528_0 - cctools_osx-64=986=ha1c5b94_0 - cddlib=1!0.94m=h0f52abe_0 + - certifi=2024.6.2=pyhd8ed1ab_0 + - cffi=1.16.0=py310hdca579f_0 - chardet=5.2.0=py310h2ec42d9_1 + - charset-normalizer=3.3.2=pyhd8ed1ab_0 - clang=16.0.6=default_ha3b9224_8 - clang-16=16.0.6=default_h4c8afb6_8 - clang_impl_osx-64=16.0.6=h8787910_16 @@ -34,18 +59,39 @@ dependencies: - cliquer=1.22=h10d778d_1 - cmake=3.29.6=h749d262_0 - colorama=0.4.6=pyhd8ed1ab_0 + - colorlog=6.8.2=py310h2ec42d9_0 + - comm=0.2.2=pyhd8ed1ab_0 - compiler-rt=16.0.6=ha38d28d_2 - compiler-rt_osx-64=16.0.6=ha38d28d_2 - compilers=1.7.0=h694c41f_1 + - contourpy=1.2.1=py310hb3b189b_0 + - conway-polynomials=0.9=pyhd8ed1ab_0 + - cppy=1.2.1=pyhd8ed1ab_0 - curl=8.8.0=hea67d85_0 + - cvxopt=1.3.2=py310h1fac3e1_2 - cxx-compiler=1.7.0=h7728843_1 + - cycler=0.12.1=pyhd8ed1ab_0 + - cypari2=2.1.5=py310hc7df965_0 + - cysignals=1.11.2=py310h8c82e65_3 + - cython=3.0.10=py310h5daac23_0 + - debugpy=1.8.1=py310h5daac23_0 + - decorator=5.1.1=pyhd8ed1ab_0 + - defusedxml=0.7.1=pyhd8ed1ab_0 - distlib=0.3.8=pyhd8ed1ab_0 + - docutils=0.21.2=pyhd8ed1ab_0 + - dsdp=5.8=h6e329d1_1203 - ecl=23.9.9=h2b27fa8_0 - eclib=20231212=h02435c3_0 - ecm=7.0.5=h4f6b447_0 + - editables=0.5=pyhd8ed1ab_0 + - entrypoints=0.4=pyhd8ed1ab_0 + - exceptiongroup=1.2.0=pyhd8ed1ab_2 + - executing=2.0.1=pyhd8ed1ab_0 - expat=2.6.2=h73e2aa4_0 - fflas-ffpack=2.5.0=h5898d61_0 + - fftw=3.3.10=nompi_h292e606_110 - filelock=3.15.4=pyhd8ed1ab_0 + - flit-core=3.9.0=pyhd8ed1ab_1 - 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 @@ -53,11 +99,17 @@ dependencies: - fontconfig=2.14.2=h5bb23bf_0 - fonts-conda-ecosystem=1=0 - fonts-conda-forge=1=0 + - fonttools=4.53.0=py310h936d840_0 - fortran-compiler=1.7.0=h6c2ab21_1 - fplll=5.4.5=hb7981ad_0 + - fpylll=0.6.1=py310h65a3d7e_0 + - fqdn=1.5.1=pyhd8ed1ab_0 - freetype=2.12.1=h60636b9_2 + - fribidi=1.0.10=hbcb3906_0 + - furo=2024.5.6=pyhd8ed1ab_0 - gap-core=4.12.2=hc16eb5f_3 - gap-defaults=4.12.2=h694c41f_3 + - gast=0.5.4=pyhd8ed1ab_0 - gengetopt=2.23=he49afe7_0 - gettext=0.22.5=h5ff76d1_2 - gettext-tools=0.22.5=h5ff76d1_2 @@ -71,28 +123,74 @@ dependencies: - givaro=4.2.0=h1b3d6f7_0 - glpk=5.0=h3cb5acd_0 - gmp=6.3.0=hf036a51_2 + - gmpy2=2.1.5=py310h0310db1_1 + - graphite2=1.3.13=h73e2aa4_1003 - gsl=2.7=h93259b0_0 + - h11=0.14.0=pyhd8ed1ab_0 + - h2=4.1.0=pyhd8ed1ab_0 + - harfbuzz=8.5.0=h053f038_0 + - hatchling=1.25.0=pyhd8ed1ab_0 + - hpack=4.0.0=pyh9f0ad1d_0 + - httpcore=1.0.5=pyhd8ed1ab_0 + - httpx=0.27.0=pyhd8ed1ab_0 + - hyperframe=6.0.1=pyhd8ed1ab_0 - icu=73.2=hf5e326d_0 + - idna=3.7=pyhd8ed1ab_0 - igraph=0.10.12=hde4452d_1 + - imagesize=1.4.1=pyhd8ed1ab_0 - iml=1.0.5=h61918c1_1004 - importlib-metadata=8.0.0=pyha770c72_0 + - importlib-resources=6.4.0=pyhd8ed1ab_0 - importlib_metadata=8.0.0=hd8ed1ab_0 + - importlib_resources=6.4.0=pyhd8ed1ab_0 + - ipykernel=6.29.4=pyh57ce528_0 + - ipympl=0.9.4=pyhd8ed1ab_0 + - ipython=8.25.0=pyh707e725_0 + - ipython_genutils=0.2.0=pyhd8ed1ab_1 + - ipywidgets=8.1.3=pyhd8ed1ab_0 - isl=0.26=imath32_h2e86a7b_101 + - isoduration=20.11.0=pyhd8ed1ab_0 + - jedi=0.19.1=pyhd8ed1ab_0 + - jinja2=3.1.4=pyhd8ed1ab_0 + - jmol=14.32.9=h694c41f_0 + - json5=0.9.25=pyhd8ed1ab_0 + - jsonpointer=3.0.0=py310h2ec42d9_0 + - jsonschema=4.22.0=pyhd8ed1ab_0 + - jsonschema-specifications=2023.12.1=pyhd8ed1ab_0 + - jsonschema-with-format-nongpl=4.22.0=pyhd8ed1ab_0 + - jupyter-jsmol=2022.1.0=pyhd8ed1ab_0 + - jupyter-lsp=2.2.5=pyhd8ed1ab_0 + - jupyter-sphinx=0.5.3=pyha770c72_4 + - jupyter_client=8.6.2=pyhd8ed1ab_0 + - jupyter_core=5.7.2=py310h2ec42d9_0 + - jupyter_events=0.10.0=pyhd8ed1ab_0 + - jupyter_server=2.14.1=pyhd8ed1ab_0 + - jupyter_server_terminals=0.5.3=pyhd8ed1ab_0 + - jupyter_sphinx=0.5.3=hd8ed1ab_4 + - jupyterlab=4.2.2=pyhd8ed1ab_0 + - jupyterlab_pygments=0.3.0=pyhd8ed1ab_1 + - jupyterlab_server=2.27.2=pyhd8ed1ab_0 + - jupyterlab_widgets=3.0.11=pyhd8ed1ab_0 + - kiwisolver=1.4.5=py310h88cfcbd_1 - krb5=1.21.2=hb884880_0 - lcalc=2.0.5=h547a6ed_2 + - lcms2=2.16=ha2f27b4_0 - ld64=711=ha02d983_0 - ld64_osx-64=711=ha20a434_0 - lerc=4.0.0=hb486fe8_0 - libasprintf=0.22.5=h5ff76d1_2 - libasprintf-devel=0.22.5=h5ff76d1_2 - libatomic_ops=7.6.14=hb7f2c08_0 - - libblas=3.9.0=22_osx64_openblas + - libblas=3.9.0=20_osx64_openblas - libboost=1.85.0=h739af76_2 - libboost-devel=1.85.0=h2b186f8_2 - libboost-headers=1.85.0=h694c41f_2 - libbraiding=1.2=hf0c8a7f_0 - libbrial=1.2.12=h81e9653_3 - - libcblas=3.9.0=22_osx64_openblas + - libbrotlicommon=1.1.0=h0dc2134_1 + - libbrotlidec=1.1.0=h0dc2134_1 + - libbrotlienc=1.1.0=h0dc2134_1 + - libcblas=3.9.0=20_osx64_openblas - libclang-cpp16=16.0.6=default_h4c8afb6_8 - libcurl=8.8.0=hf9fcc65_0 - libcxx=17.0.6=h88467a6_0 @@ -108,17 +206,18 @@ dependencies: - libgfortran=5.0.0=13_2_0_h97931a8_3 - libgfortran-devel_osx-64=12.3.0=h0b6f5ec_3 - libgfortran5=13.2.0=h2873a65_3 + - libglib=2.80.2=h736d271_1 - libhomfly=1.02r6=h10d778d_1 - libhwloc=2.10.0=default_h456cccd_1001 - libiconv=1.17=hd75f5a5_2 - libintl=0.22.5=h5ff76d1_2 - libintl-devel=0.22.5=h5ff76d1_2 - libjpeg-turbo=3.0.0=h0dc2134_1 - - liblapack=3.9.0=22_osx64_openblas - - liblapacke=3.9.0=22_osx64_openblas + - liblapack=3.9.0=20_osx64_openblas + - liblapacke=3.9.0=20_osx64_openblas - libllvm16=16.0.6=hbedff68_3 - libnghttp2=1.58.0=h64cf6d3_1 - - libopenblas=0.3.27=openmp_hfef2a42_0 + - libopenblas=0.3.25=openmp_hfef2a42_0 - libpng=1.6.43=h92b6c6a_0 - libsodium=1.0.18=hbcb3906_1 - libsqlite=3.46.0=h1b8f9f3_0 @@ -128,6 +227,7 @@ dependencies: - libuv=1.48.0=h67532ce_0 - libwebp=1.4.0=hc207709_0 - libwebp-base=1.4.0=h10d778d_0 + - libxcb=1.16=h0dc2134_0 - libxml2=2.12.7=h3e169fe_1 - libzlib=1.3.1=h87427d6_1 - linbox=1.7.0=h7061c92_0 @@ -138,62 +238,186 @@ dependencies: - m4ri=20140914=hd82a5f3_1006 - m4rie=20150908=hc616cfc_1002 - make=4.3=h22f3db7_1 + - markupsafe=2.1.5=py310hb372a2b_0 - mathjax=3.2.2=h694c41f_0 + - matplotlib=3.8.4=py310h2ec42d9_2 + - matplotlib-base=3.8.4=py310h7ea1ff3_2 + - matplotlib-inline=0.1.7=pyhd8ed1ab_0 - maxima=5.47.0=h2b27fa8_2 + - memory-allocator=0.1.3=py310h6729b98_0 - metis=5.1.0=he965462_1007 + - mistune=3.0.2=pyhd8ed1ab_0 - mpc=1.3.1=h81bd1dd_0 - mpfi=1.5.4=h52b28e3_1001 - mpfr=4.2.1=h4f6b447_1 + - mpmath=1.3.0=pyhd8ed1ab_0 + - munkres=1.1.4=pyh9f0ad1d_0 - nauty=2.8.8=h10d778d_1 + - nbclient=0.10.0=pyhd8ed1ab_0 + - nbconvert=7.16.4=hd8ed1ab_1 + - nbconvert-core=7.16.4=pyhd8ed1ab_1 + - nbconvert-pandoc=7.16.4=hd8ed1ab_1 + - nbformat=5.10.4=pyhd8ed1ab_0 - ncurses=6.5=h5846eda_0 + - nest-asyncio=1.6.0=pyhd8ed1ab_0 + - networkx=3.2.1=pyhd8ed1ab_0 - ninja=1.12.1=h3c5361c_0 + - notebook=7.2.1=pyhd8ed1ab_0 + - notebook-shim=0.2.4=pyhd8ed1ab_0 - ntl=11.4.3=h0ab3c2f_1 - - openblas=0.3.27=openmp_h6794695_0 + - numpy=1.26.4=py310h4bfa8fc_0 + - openblas=0.3.25=openmp_h6794695_0 + - openjdk=22.0.1=h2d185b6_0 + - openjpeg=2.5.2=h7310d3a_0 - openssl=3.3.1=h87427d6_0 + - overrides=7.7.0=pyhd8ed1ab_0 - packaging=24.1=pyhd8ed1ab_0 - palp=2.20=hbcb3906_0 + - pandoc=3.2.1=h694c41f_0 + - pandocfilters=1.5.0=pyhd8ed1ab_0 + - pango=1.54.0=h880b76c_0 - pari=2.15.5=h7ba67ff_2_pthread - pari-elldata=0.0.20161017=0 - pari-galdata=0.0.20180411=0 - pari-galpol=0.0.20180625=0 - pari-seadata=0.0.20090618=0 - pari-seadata-small=0.0.20090618=0 + - parso=0.8.4=pyhd8ed1ab_0 - patch=2.7.6=hbcf498f_1002 + - pathspec=0.12.1=pyhd8ed1ab_0 + - pcre2=10.44=h7634a1b_0 + - pep517=0.13.0=pyhd8ed1ab_0 - perl=5.32.1=7_h10d778d_perl5 + - pexpect=4.9.0=pyhd8ed1ab_0 + - pickleshare=0.7.5=py_1003 + - pillow=10.3.0=py310h2fdc51f_1 + - pip=24.0=pyhd8ed1ab_0 + - pixman=0.43.4=h73e2aa4_0 - pkg-config=0.29.2=ha3d46e9_1008 + - pkgconfig=1.5.5=pyhd8ed1ab_4 + - pkgutil-resolve-name=1.3.10=pyhd8ed1ab_1 - planarity=3.0.2.0=h10d778d_0 - platformdirs=4.2.2=pyhd8ed1ab_0 - pluggy=1.5.0=pyhd8ed1ab_0 + - ply=3.11=pyhd8ed1ab_2 - ppl=1.2=ha60d53e_1006 - - primecount=7.13=hf455435_0 - - primesieve=12.1=h73e2aa4_0 + - pplpy=0.8.9=py310hbe8aec3_1 + - primecount=7.6=ha894c9a_0 + - primecountpy=0.1.0=py310h88cfcbd_4 + - primesieve=11.0=hf0c8a7f_0 + - prometheus_client=0.20.0=pyhd8ed1ab_0 + - prompt-toolkit=3.0.47=pyha770c72_0 + - prompt_toolkit=3.0.47=hd8ed1ab_0 + - psutil=6.0.0=py310h936d840_0 + - pthread-stubs=0.4=hc929b4f_1001 + - ptyprocess=0.7.0=pyhd3deb0d_0 + - pure_eval=0.2.2=pyhd8ed1ab_0 + - py=1.11.0=pyh6c4a22f_0 + - pybind11=2.12.0=py310hb3b189b_0 + - pybind11-global=2.12.0=py310hb3b189b_0 + - pycparser=2.22=pyhd8ed1ab_0 + - pygments=2.18.0=pyhd8ed1ab_0 + - pyobjc-core=10.3.1=py310h445dc1f_0 + - pyobjc-framework-cocoa=10.3.1=py310h445dc1f_0 + - pyparsing=3.1.2=pyhd8ed1ab_0 - pyproject-api=1.7.1=pyhd8ed1ab_0 + - pyrsistent=0.20.0=py310hb372a2b_0 + - pysocks=1.7.1=pyha2e5f31_6 - python=3.10.14=h00d2728_0_cpython + - python-build=1.2.1=pyhd8ed1ab_0 + - python-dateutil=2.9.0=pyhd8ed1ab_0 + - python-fastjsonschema=2.20.0=pyhd8ed1ab_0 + - python-json-logger=2.0.7=pyhd8ed1ab_0 + - python-lrcalc=2.1=py310h5daac23_6 + - python-tzdata=2024.1=pyhd8ed1ab_0 - python_abi=3.10=4_cp310 + - pythran=0.15.0=py310h076e4b7_1 + - pytz=2024.1=pyhd8ed1ab_0 + - pytz-deprecation-shim=0.1.0.post0=py310h2ec42d9_4 + - pyyaml=6.0.1=py310h6729b98_1 + - pyzmq=26.0.3=py310he0bbd50_0 - qd=2.3.22=h2beb688_1004 - qhull=2020.2=h940c156_2 + - r-base=4.3.3=h4648a1f_3 + - r-lattice=0.22_6=r43hb2c329c_0 - readline=8.2=h9e318b2_1 + - referencing=0.35.1=pyhd8ed1ab_0 + - requests=2.32.3=pyhd8ed1ab_0 + - rfc3339-validator=0.1.4=pyhd8ed1ab_0 + - rfc3986-validator=0.1.1=pyh9f0ad1d_0 - rhash=1.4.4=h0dc2134_0 + - rpds-py=0.18.1=py310h12a1ced_0 + - rpy2=3.5.11=py310r43hf0b6da5_3 - rw=0.9=h10d778d_2 + - sagemath-db-combinatorial-designs=20140630=1 + - sagemath-db-elliptic-curves=0.8.1=hecc5488_0 + - sagemath-db-graphs=20210214=hd8ed1ab_0 + - sagemath-db-polytopes=20170220=1 + - sagetex=3.6.1=pyhd8ed1ab_0 + - scipy=1.11.4=py310h3f1db6d_0 + - send2trash=1.8.3=pyh31c8845_0 + - setuptools=70.1.1=pyhd8ed1ab_0 + - setuptools-scm=8.1.0=pyhd8ed1ab_0 + - setuptools_scm=8.1.0=hd8ed1ab_0 - sigtool=0.1.3=h88f4db0_0 + - simplegeneric=0.8.1=py_1 - singular=4.3.2.p8=h0d51a9f_1 + - six=1.16.0=pyh6c4a22f_0 + - sniffio=1.3.1=pyhd8ed1ab_0 + - snowballstemmer=2.2.0=pyhd8ed1ab_0 + - soupsieve=2.5=pyhd8ed1ab_1 + - sphinx=7.3.7=pyhd8ed1ab_0 + - sphinx-basic-ng=1.0.0b2=pyhd8ed1ab_1 + - sphinx-copybutton=0.5.2=pyhd8ed1ab_0 + - sphinxcontrib-applehelp=1.0.8=pyhd8ed1ab_0 + - sphinxcontrib-devhelp=1.0.6=pyhd8ed1ab_0 + - sphinxcontrib-htmlhelp=2.0.5=pyhd8ed1ab_0 + - sphinxcontrib-jsmath=1.0.1=pyhd8ed1ab_0 + - sphinxcontrib-qthelp=1.0.7=pyhd8ed1ab_0 + - sphinxcontrib-serializinghtml=1.1.10=pyhd8ed1ab_0 + - sphinxcontrib-websupport=1.2.7=pyhd8ed1ab_0 - sqlite=3.46.0=h28673e1_0 + - stack_data=0.6.2=pyhd8ed1ab_0 - suitesparse=7.7.0=hd2b2131_1 - symmetrica=3.0.1=hf0c8a7f_0 - sympow=2.023.6=h115ba6a_3 + - sympy=1.12.1=pypyh2585a3b_103 - tachyon=0.99b6=h3a1d103_1002 - tapi=1100.0.11=h9ce4665_0 - tar=1.34=hcb2f6ea_1 - tbb=2021.12.0=h3c5361c_1 + - terminado=0.18.1=pyh31c8845_0 - texinfo=7.0=pl5321hc47821c_0 + - three.js=122=hd8ed1ab_2 + - threejs-sage=122=hd8ed1ab_2 + - tinycss2=1.3.0=pyhd8ed1ab_0 - tk=8.6.13=h1abcd95_1 + - tktable=2.10=hba9d6f1_6 - tomli=2.0.1=pyhd8ed1ab_0 + - tornado=6.4.1=py310h936d840_0 - tox=4.15.1=pyhd8ed1ab_0 + - traitlets=5.14.3=pyhd8ed1ab_0 + - trove-classifiers=2024.5.22=pyhd8ed1ab_0 + - types-python-dateutil=2.9.0.20240316=pyhd8ed1ab_0 - typing-extensions=4.12.2=hd8ed1ab_0 - typing_extensions=4.12.2=pyha770c72_0 + - typing_utils=0.1.0=pyhd8ed1ab_0 - tzdata=2024a=h0c530f3_0 + - tzlocal=5.2=py310h2ec42d9_0 + - unicodedata2=15.1.0=py310h6729b98_0 + - uri-template=1.3.0=pyhd8ed1ab_0 + - urllib3=2.2.2=pyhd8ed1ab_0 - virtualenv=20.26.3=pyhd8ed1ab_0 + - wcwidth=0.2.13=pyhd8ed1ab_0 + - webcolors=24.6.0=pyhd8ed1ab_0 + - webencodings=0.5.1=pyhd8ed1ab_2 + - websocket-client=1.8.0=pyhd8ed1ab_0 + - wheel=0.43.0=pyhd8ed1ab_1 + - widgetsnbextension=4.0.11=pyhd8ed1ab_0 + - xorg-libxau=1.0.11=h0dc2134_0 + - xorg-libxdmcp=1.1.3=h35c211d_0 - xz=5.2.6=h775f41a_0 + - yaml=0.2.5=h0d85af4_2 - zeromq=4.3.5=hde137ed_4 - zipp=3.19.2=pyhd8ed1ab_0 - zlib=1.3.1=h87427d6_1 diff --git a/environment-3.10-macos.yml b/environment-3.10-macos.yml index 2e0fda6d7d9..0c5d09880a1 100644 --- a/environment-3.10-macos.yml +++ b/environment-3.10-macos.yml @@ -1,29 +1,54 @@ +name: sage # Generated by conda-lock. # platform: osx-arm64 -# input_hash: a06693a6e2cbe8750043277b860bd29ad235bdc75a55b7ab3b2aa27a56ca3cd4 +# input_hash: fce4b9b5cdb20ebb2d93612fa27b4d6584379772c37a8cccd6c2390e2ce5f3b1 channels: - conda-forge dependencies: + - _r-mutex=1.0.1=anacondar_1 + - alabaster=0.7.16=pyhd8ed1ab_0 + - anyio=4.4.0=pyhd8ed1ab_0 - appdirs=1.4.4=pyh9f0ad1d_0 + - appnope=0.1.4=pyhd8ed1ab_0 + - argon2-cffi=23.1.0=pyhd8ed1ab_0 + - argon2-cffi-bindings=21.2.0=py310h2aa6e3c_4 - arpack=3.9.1=nompi_h593882a_101 + - arrow=1.3.0=pyhd8ed1ab_0 + - asttokens=2.4.1=pyhd8ed1ab_0 + - async-lru=2.0.4=pyhd8ed1ab_0 + - attrs=23.2.0=pyh71513ae_0 - autoconf=2.71=pl5321hcd07c0c_1 - automake=1.16.5=pl5321hce30654_0 + - babel=2.14.0=pyhd8ed1ab_0 - bc=1.07.1=h3422bc3_0 - bdw-gc=8.0.6=hc021e02_0 - - blas=2.122=openblas - - blas-devel=3.9.0=22_osxarm64_openblas + - beautifulsoup4=4.12.3=pyha770c72_0 + - beniget=0.4.1=pyhd8ed1ab_0 + - blas=2.120=openblas + - blas-devel=3.9.0=20_osxarm64_openblas + - bleach=6.1.0=pyhd8ed1ab_0 - boost-cpp=1.85.0=hca5e981_2 - brial=1.2.12=pyh694c41f_3 + - brotli=1.1.0=hb547adb_1 + - brotli-bin=1.1.0=hb547adb_1 + - brotli-python=1.1.0=py310h1253130_1 + - bwidget=1.9.14=hce30654_1 - bzip2=1.0.8=h93a5062_5 - c-ares=1.28.1=h93a5062_0 - c-compiler=1.7.0=h6aa9301_1 - ca-certificates=2024.6.2=hf0a4a13_0 + - cached-property=1.5.2=hd8ed1ab_1 + - cached_property=1.5.2=pyha770c72_1 - cachetools=5.3.3=pyhd8ed1ab_0 + - cairo=1.18.0=hc6c324b_2 - cctools=986=h4faf515_0 - cctools_osx-arm64=986=h62378fb_0 - cddlib=1!0.94m=h6d7a090_0 + - certifi=2024.6.2=pyhd8ed1ab_0 + - cffi=1.16.0=py310hdcd7c05_0 - chardet=5.2.0=py310hbe9552e_1 + - charset-normalizer=3.3.2=pyhd8ed1ab_0 - clang=16.0.6=default_h095aff0_8 - clang-16=16.0.6=default_hb63da90_8 - clang_impl_osx-arm64=16.0.6=hc421ffc_16 @@ -34,18 +59,39 @@ dependencies: - cliquer=1.22=h93a5062_1 - cmake=3.29.6=had79d8f_0 - colorama=0.4.6=pyhd8ed1ab_0 + - colorlog=6.8.2=py310hbe9552e_0 + - comm=0.2.2=pyhd8ed1ab_0 - compiler-rt=16.0.6=h3808999_2 - compiler-rt_osx-arm64=16.0.6=h3808999_2 - compilers=1.7.0=hce30654_1 + - contourpy=1.2.1=py310h21239e6_0 + - conway-polynomials=0.9=pyhd8ed1ab_0 + - cppy=1.2.1=pyhd8ed1ab_0 - curl=8.8.0=h653d890_0 + - cvxopt=1.3.2=py310h7e4e7d1_2 - cxx-compiler=1.7.0=h2ffa867_1 + - cycler=0.12.1=pyhd8ed1ab_0 + - cypari2=2.1.5=py310h5e3d6bc_0 + - cysignals=1.11.2=py310hfd3b3fe_3 + - cython=3.0.10=py310h692a8b6_0 + - debugpy=1.8.1=py310h692a8b6_0 + - decorator=5.1.1=pyhd8ed1ab_0 + - defusedxml=0.7.1=pyhd8ed1ab_0 - distlib=0.3.8=pyhd8ed1ab_0 + - docutils=0.21.2=pyhd8ed1ab_0 + - dsdp=5.8=h9397a75_1203 - ecl=23.9.9=h1d9728a_0 - eclib=20231212=h7f07de4_0 - ecm=7.0.5=h41d338b_0 + - editables=0.5=pyhd8ed1ab_0 + - entrypoints=0.4=pyhd8ed1ab_0 + - exceptiongroup=1.2.0=pyhd8ed1ab_2 + - executing=2.0.1=pyhd8ed1ab_0 - expat=2.6.2=hebf3989_0 - fflas-ffpack=2.5.0=h4bc3318_0 + - fftw=3.3.10=nompi_h6637ab6_110 - filelock=3.15.4=pyhd8ed1ab_0 + - flit-core=3.9.0=pyhd8ed1ab_1 - 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 @@ -53,11 +99,17 @@ dependencies: - fontconfig=2.14.2=h82840c6_0 - fonts-conda-ecosystem=1=0 - fonts-conda-forge=1=0 + - fonttools=4.53.0=py310ha6dd24b_0 - fortran-compiler=1.7.0=hafb19e3_1 - fplll=5.4.5=hb7d509d_0 + - fpylll=0.6.1=py310hd9be144_0 + - fqdn=1.5.1=pyhd8ed1ab_0 - freetype=2.12.1=hadb7bae_2 + - fribidi=1.0.10=h27ca646_0 + - furo=2024.5.6=pyhd8ed1ab_0 - gap-core=4.12.2=he8f4e70_3 - gap-defaults=4.12.2=hce30654_3 + - gast=0.5.4=pyhd8ed1ab_0 - gengetopt=2.23=hbdafb3b_0 - gettext=0.22.5=h8fbad5d_2 - gettext-tools=0.22.5=h8fbad5d_2 @@ -71,28 +123,74 @@ dependencies: - givaro=4.2.0=h018886a_0 - glpk=5.0=h6d7a090_0 - gmp=6.3.0=h7bae524_2 + - gmpy2=2.1.5=py310h3bc658a_1 + - graphite2=1.3.13=hebf3989_1003 - gsl=2.7=h6e638da_0 + - h11=0.14.0=pyhd8ed1ab_0 + - h2=4.1.0=pyhd8ed1ab_0 + - harfbuzz=8.5.0=h1836168_0 + - hatchling=1.25.0=pyhd8ed1ab_0 + - hpack=4.0.0=pyh9f0ad1d_0 + - httpcore=1.0.5=pyhd8ed1ab_0 + - httpx=0.27.0=pyhd8ed1ab_0 + - hyperframe=6.0.1=pyhd8ed1ab_0 - icu=73.2=hc8870d7_0 + - idna=3.7=pyhd8ed1ab_0 - igraph=0.10.12=h762ac30_1 + - imagesize=1.4.1=pyhd8ed1ab_0 - iml=1.0.5=hd73f12c_1004 - importlib-metadata=8.0.0=pyha770c72_0 + - importlib-resources=6.4.0=pyhd8ed1ab_0 - importlib_metadata=8.0.0=hd8ed1ab_0 + - importlib_resources=6.4.0=pyhd8ed1ab_0 + - ipykernel=6.29.4=pyh57ce528_0 + - ipympl=0.9.4=pyhd8ed1ab_0 + - ipython=8.25.0=pyh707e725_0 + - ipython_genutils=0.2.0=pyhd8ed1ab_1 + - ipywidgets=8.1.3=pyhd8ed1ab_0 - isl=0.26=imath32_h347afa1_101 + - isoduration=20.11.0=pyhd8ed1ab_0 + - jedi=0.19.1=pyhd8ed1ab_0 + - jinja2=3.1.4=pyhd8ed1ab_0 + - jmol=14.32.10=hce30654_0 + - json5=0.9.25=pyhd8ed1ab_0 + - jsonpointer=3.0.0=py310hbe9552e_0 + - jsonschema=4.22.0=pyhd8ed1ab_0 + - jsonschema-specifications=2023.12.1=pyhd8ed1ab_0 + - jsonschema-with-format-nongpl=4.22.0=pyhd8ed1ab_0 + - jupyter-jsmol=2022.1.0=pyhd8ed1ab_0 + - jupyter-lsp=2.2.5=pyhd8ed1ab_0 + - jupyter-sphinx=0.5.3=pyha770c72_4 + - jupyter_client=8.6.2=pyhd8ed1ab_0 + - jupyter_core=5.7.2=py310hbe9552e_0 + - jupyter_events=0.10.0=pyhd8ed1ab_0 + - jupyter_server=2.14.1=pyhd8ed1ab_0 + - jupyter_server_terminals=0.5.3=pyhd8ed1ab_0 + - jupyter_sphinx=0.5.3=hd8ed1ab_4 + - jupyterlab=4.2.2=pyhd8ed1ab_0 + - jupyterlab_pygments=0.3.0=pyhd8ed1ab_1 + - jupyterlab_server=2.27.2=pyhd8ed1ab_0 + - jupyterlab_widgets=3.0.11=pyhd8ed1ab_0 + - kiwisolver=1.4.5=py310h38f39d4_1 - krb5=1.21.2=h92f50d5_0 - lcalc=2.0.5=h4a402bc_2 + - lcms2=2.16=ha0e7c42_0 - ld64=711=h634c8be_0 - ld64_osx-arm64=711=ha4bd21c_0 - lerc=4.0.0=h9a09cb3_0 - libasprintf=0.22.5=h8fbad5d_2 - libasprintf-devel=0.22.5=h8fbad5d_2 - libatomic_ops=7.6.14=h1a8c8d9_0 - - libblas=3.9.0=22_osxarm64_openblas + - libblas=3.9.0=20_osxarm64_openblas - libboost=1.85.0=h17eb2be_2 - libboost-devel=1.85.0=hf450f58_2 - libboost-headers=1.85.0=hce30654_2 - libbraiding=1.2=hb7217d7_0 - libbrial=1.2.12=h56a29cd_3 - - libcblas=3.9.0=22_osxarm64_openblas + - libbrotlicommon=1.1.0=hb547adb_1 + - libbrotlidec=1.1.0=hb547adb_1 + - libbrotlienc=1.1.0=hb547adb_1 + - libcblas=3.9.0=20_osxarm64_openblas - libclang-cpp16=16.0.6=default_hb63da90_8 - libcurl=8.8.0=h7b6f9a7_0 - libcxx=17.0.6=h5f092b4_0 @@ -115,11 +213,11 @@ dependencies: - libintl=0.22.5=h8fbad5d_2 - libintl-devel=0.22.5=h8fbad5d_2 - libjpeg-turbo=3.0.0=hb547adb_1 - - liblapack=3.9.0=22_osxarm64_openblas - - liblapacke=3.9.0=22_osxarm64_openblas + - liblapack=3.9.0=20_osxarm64_openblas + - liblapacke=3.9.0=20_osxarm64_openblas - libllvm16=16.0.6=haab561b_3 - libnghttp2=1.58.0=ha4dd798_1 - - libopenblas=0.3.27=openmp_h6c19121_0 + - libopenblas=0.3.25=openmp_h6c19121_0 - libpng=1.6.43=h091b4b1_0 - libsodium=1.0.18=h27ca646_1 - libsqlite=3.46.0=hfb93653_0 @@ -129,6 +227,7 @@ dependencies: - libuv=1.48.0=h93a5062_0 - libwebp=1.4.0=h54798ee_0 - libwebp-base=1.4.0=h93a5062_0 + - libxcb=1.16=hf2054a2_0 - libxml2=2.12.7=ha661575_1 - libzlib=1.3.1=hfb2fe0b_1 - linbox=1.7.0=h3afee3a_0 @@ -139,63 +238,186 @@ dependencies: - m4ri=20140914=hc97c1ff_1006 - m4rie=20150908=h22b9e9d_1002 - make=4.3=he57ea6c_1 + - markupsafe=2.1.5=py310hd125d64_0 - mathjax=3.2.2=hce30654_0 + - matplotlib=3.8.4=py310hb6292c7_2 + - matplotlib-base=3.8.4=py310hedb7998_2 + - matplotlib-inline=0.1.7=pyhd8ed1ab_0 - maxima=5.47.0=h2bbcd85_2 + - memory-allocator=0.1.3=py310h2aa6e3c_0 - metis=5.1.0=h13dd4ca_1007 + - mistune=3.0.2=pyhd8ed1ab_0 - mpc=1.3.1=h91ba8db_0 - mpfi=1.5.4=hbde5f5b_1001 - mpfr=4.2.1=h41d338b_1 + - mpmath=1.3.0=pyhd8ed1ab_0 + - munkres=1.1.4=pyh9f0ad1d_0 - nauty=2.8.8=h93a5062_1 + - nbclient=0.10.0=pyhd8ed1ab_0 + - nbconvert=7.16.4=hd8ed1ab_1 + - nbconvert-core=7.16.4=pyhd8ed1ab_1 + - nbconvert-pandoc=7.16.4=hd8ed1ab_1 + - nbformat=5.10.4=pyhd8ed1ab_0 - ncurses=6.5=hb89a1cb_0 + - nest-asyncio=1.6.0=pyhd8ed1ab_0 + - networkx=3.2.1=pyhd8ed1ab_0 - ninja=1.12.1=h420ef59_0 + - notebook=7.2.1=pyhd8ed1ab_0 + - notebook-shim=0.2.4=pyhd8ed1ab_0 - ntl=11.4.3=hbb3f309_1 - - openblas=0.3.27=openmp_h55c453e_0 + - numpy=1.26.4=py310hd45542a_0 + - openblas=0.3.25=openmp_h55c453e_0 + - openjdk=22.0.1=hbeb2e11_0 + - openjpeg=2.5.2=h9f1df11_0 - openssl=3.3.1=hfb2fe0b_0 + - overrides=7.7.0=pyhd8ed1ab_0 - packaging=24.1=pyhd8ed1ab_0 - palp=2.20=h27ca646_0 + - pandoc=3.2.1=hce30654_0 + - pandocfilters=1.5.0=pyhd8ed1ab_0 + - pango=1.54.0=h5cb9fbc_0 - pari=2.15.5=h4f2304c_2_pthread - pari-elldata=0.0.20161017=0 - pari-galdata=0.0.20180411=0 - pari-galpol=0.0.20180625=0 - pari-seadata=0.0.20090618=0 - pari-seadata-small=0.0.20090618=0 + - parso=0.8.4=pyhd8ed1ab_0 - patch=2.7.6=h27ca646_1002 + - pathspec=0.12.1=pyhd8ed1ab_0 - pcre2=10.44=h297a79d_0 + - pep517=0.13.0=pyhd8ed1ab_0 - perl=5.32.1=7_h4614cfb_perl5 + - pexpect=4.9.0=pyhd8ed1ab_0 + - pickleshare=0.7.5=py_1003 + - pillow=10.3.0=py310h01af8b1_1 + - pip=24.0=pyhd8ed1ab_0 + - pixman=0.43.4=hebf3989_0 - pkg-config=0.29.2=hab62308_1008 + - pkgconfig=1.5.5=pyhd8ed1ab_4 + - pkgutil-resolve-name=1.3.10=pyhd8ed1ab_1 - planarity=3.0.2.0=h93a5062_0 - platformdirs=4.2.2=pyhd8ed1ab_0 - pluggy=1.5.0=pyhd8ed1ab_0 + - ply=3.11=pyhd8ed1ab_2 - ppl=1.2=h8b147cf_1006 - - primecount=7.13=ha9cb33e_0 - - primesieve=12.1=hebf3989_0 + - pplpy=0.8.9=py310hc3af9bb_1 + - primecount=7.6=hb6e4faa_0 + - primecountpy=0.1.0=py310h38f39d4_4 + - primesieve=11.0=hb7217d7_0 + - prometheus_client=0.20.0=pyhd8ed1ab_0 + - prompt-toolkit=3.0.47=pyha770c72_0 + - prompt_toolkit=3.0.47=hd8ed1ab_0 + - psutil=6.0.0=py310ha6dd24b_0 + - pthread-stubs=0.4=h27ca646_1001 + - ptyprocess=0.7.0=pyhd3deb0d_0 + - pure_eval=0.2.2=pyhd8ed1ab_0 + - py=1.11.0=pyh6c4a22f_0 + - pybind11=2.12.0=py310h21239e6_0 + - pybind11-global=2.12.0=py310h21239e6_0 + - pycparser=2.22=pyhd8ed1ab_0 + - pygments=2.18.0=pyhd8ed1ab_0 + - pyobjc-core=10.3.1=py310h4b7648a_0 + - pyobjc-framework-cocoa=10.3.1=py310h4b7648a_0 + - pyparsing=3.1.2=pyhd8ed1ab_0 - pyproject-api=1.7.1=pyhd8ed1ab_0 + - pyrsistent=0.20.0=py310hd125d64_0 + - pysocks=1.7.1=pyha2e5f31_6 - python=3.10.14=h2469fbe_0_cpython + - python-build=1.2.1=pyhd8ed1ab_0 + - python-dateutil=2.9.0=pyhd8ed1ab_0 + - python-fastjsonschema=2.20.0=pyhd8ed1ab_0 + - python-json-logger=2.0.7=pyhd8ed1ab_0 + - python-lrcalc=2.1=py310h692a8b6_6 + - python-tzdata=2024.1=pyhd8ed1ab_0 - python_abi=3.10=4_cp310 + - pythran=0.15.0=py310h1359cc7_1 + - pytz=2024.1=pyhd8ed1ab_0 + - pytz-deprecation-shim=0.1.0.post0=py310hbe9552e_4 + - pyyaml=6.0.1=py310h2aa6e3c_1 + - pyzmq=26.0.3=py310h16e08c9_0 - qd=2.3.22=hbec66e7_1004 - qhull=2020.2=hc021e02_2 + - r-base=4.3.3=h8112bfe_3 + - r-lattice=0.22_6=r43hd2d937b_0 - readline=8.2=h92ec313_1 + - referencing=0.35.1=pyhd8ed1ab_0 + - requests=2.32.3=pyhd8ed1ab_0 + - rfc3339-validator=0.1.4=pyhd8ed1ab_0 + - rfc3986-validator=0.1.1=pyh9f0ad1d_0 - rhash=1.4.4=hb547adb_0 + - rpds-py=0.18.1=py310h947b723_0 + - rpy2=3.5.11=py310r43h280b8fa_3 - rw=0.9=h93a5062_2 + - sagemath-db-combinatorial-designs=20140630=1 + - sagemath-db-elliptic-curves=0.8.1=hecc5488_0 + - sagemath-db-graphs=20210214=hd8ed1ab_0 + - sagemath-db-polytopes=20170220=1 + - sagetex=3.6.1=pyhd8ed1ab_0 + - scipy=1.11.4=py310h2b794db_0 + - send2trash=1.8.3=pyh31c8845_0 + - setuptools=70.1.1=pyhd8ed1ab_0 + - setuptools-scm=8.1.0=pyhd8ed1ab_0 + - setuptools_scm=8.1.0=hd8ed1ab_0 - sigtool=0.1.3=h44b9a77_0 + - simplegeneric=0.8.1=py_1 - singular=4.3.2.p8=hb460b52_1 + - six=1.16.0=pyh6c4a22f_0 + - sniffio=1.3.1=pyhd8ed1ab_0 + - snowballstemmer=2.2.0=pyhd8ed1ab_0 + - soupsieve=2.5=pyhd8ed1ab_1 + - sphinx=7.3.7=pyhd8ed1ab_0 + - sphinx-basic-ng=1.0.0b2=pyhd8ed1ab_1 + - sphinx-copybutton=0.5.2=pyhd8ed1ab_0 + - sphinxcontrib-applehelp=1.0.8=pyhd8ed1ab_0 + - sphinxcontrib-devhelp=1.0.6=pyhd8ed1ab_0 + - sphinxcontrib-htmlhelp=2.0.5=pyhd8ed1ab_0 + - sphinxcontrib-jsmath=1.0.1=pyhd8ed1ab_0 + - sphinxcontrib-qthelp=1.0.7=pyhd8ed1ab_0 + - sphinxcontrib-serializinghtml=1.1.10=pyhd8ed1ab_0 + - sphinxcontrib-websupport=1.2.7=pyhd8ed1ab_0 - sqlite=3.46.0=h5838104_0 + - stack_data=0.6.2=pyhd8ed1ab_0 - suitesparse=7.7.0=hf6fcff2_1 - symmetrica=3.0.1=hb7217d7_0 - sympow=2.023.6=hb0babe8_3 + - sympy=1.12.1=pypyh2585a3b_103 - tachyon=0.99b6=hb8a568e_1002 - tapi=1100.0.11=he4954df_0 - tar=1.34=h7cb298e_1 - tbb=2021.12.0=h420ef59_1 + - terminado=0.18.1=pyh31c8845_0 - texinfo=7.0=pl5321h9ea1dce_0 + - three.js=122=hd8ed1ab_2 + - threejs-sage=122=hd8ed1ab_2 + - tinycss2=1.3.0=pyhd8ed1ab_0 - tk=8.6.13=h5083fa2_1 + - tktable=2.10=h1e387b8_6 - tomli=2.0.1=pyhd8ed1ab_0 + - tornado=6.4.1=py310ha6dd24b_0 - tox=4.15.1=pyhd8ed1ab_0 + - traitlets=5.14.3=pyhd8ed1ab_0 + - trove-classifiers=2024.5.22=pyhd8ed1ab_0 + - types-python-dateutil=2.9.0.20240316=pyhd8ed1ab_0 - typing-extensions=4.12.2=hd8ed1ab_0 - typing_extensions=4.12.2=pyha770c72_0 + - typing_utils=0.1.0=pyhd8ed1ab_0 - tzdata=2024a=h0c530f3_0 + - tzlocal=5.2=py310hbe9552e_0 + - unicodedata2=15.1.0=py310h2aa6e3c_0 + - uri-template=1.3.0=pyhd8ed1ab_0 + - urllib3=2.2.2=pyhd8ed1ab_0 - virtualenv=20.26.3=pyhd8ed1ab_0 + - wcwidth=0.2.13=pyhd8ed1ab_0 + - webcolors=24.6.0=pyhd8ed1ab_0 + - webencodings=0.5.1=pyhd8ed1ab_2 + - websocket-client=1.8.0=pyhd8ed1ab_0 + - wheel=0.43.0=pyhd8ed1ab_1 + - widgetsnbextension=4.0.11=pyhd8ed1ab_0 + - xorg-libxau=1.0.11=hb547adb_0 + - xorg-libxdmcp=1.1.3=h27ca646_0 - xz=5.2.6=h57fd34a_0 + - yaml=0.2.5=h3422bc3_2 - zeromq=4.3.5=hcc0f68c_4 - zipp=3.19.2=pyhd8ed1ab_0 - zlib=1.3.1=hfb2fe0b_1 diff --git a/environment-3.11-linux-aarch64.yml b/environment-3.11-linux-aarch64.yml index 3970a5aea4a..e6a24cbe706 100644 --- a/environment-3.11-linux-aarch64.yml +++ b/environment-3.11-linux-aarch64.yml @@ -1,45 +1,92 @@ +name: sage # Generated by conda-lock. # platform: linux-aarch64 -# input_hash: fd6848a5bc52d32f3c524926e0147fd146e2d4a45005cf8c499acb7f7e864140 +# input_hash: 53cce21c9c8a4b11b84e96405de20cc945c84809a7997b8508761fc9ca727ee0 channels: - conda-forge dependencies: - _openmp_mutex=4.5=2_kmp_llvm + - _r-mutex=1.0.1=anacondar_1 - _sysroot_linux-aarch64_curr_repodata_hack=4=h57d6b7b_14 + - alabaster=0.7.16=pyhd8ed1ab_0 + - alsa-lib=1.2.11=h31becfc_1 + - anyio=4.4.0=pyhd8ed1ab_0 - appdirs=1.4.4=pyh9f0ad1d_0 + - appnope=0.1.4=pyhd8ed1ab_0 + - argon2-cffi=23.1.0=pyhd8ed1ab_0 + - argon2-cffi-bindings=21.2.0=py311hcd402e7_4 - arpack=3.9.1=nompi_hd363cd0_101 + - arrow=1.3.0=pyhd8ed1ab_0 + - asttokens=2.4.1=pyhd8ed1ab_0 + - async-lru=2.0.4=pyhd8ed1ab_0 + - attrs=23.2.0=pyh71513ae_0 - autoconf=2.71=pl5321h2148fe1_1 - automake=1.16.5=pl5321h8af1aa0_0 + - babel=2.14.0=pyhd8ed1ab_0 - bc=1.07.1=hf897c2e_0 - bdw-gc=8.0.6=hd62202e_0 + - beautifulsoup4=4.12.3=pyha770c72_0 + - beniget=0.4.1=pyhd8ed1ab_0 - binutils=2.40=hf1166c9_7 - binutils_impl_linux-aarch64=2.40=hf54a868_7 - binutils_linux-aarch64=2.40=h1f91aba_9 - - blas=2.122=openblas - - blas-devel=3.9.0=22_linuxaarch64_openblas + - blas=2.120=openblas + - blas-devel=3.9.0=20_linuxaarch64_openblas + - bleach=6.1.0=pyhd8ed1ab_0 - boost-cpp=1.85.0=ha990451_2 - brial=1.2.12=pyh694c41f_3 + - brotli=1.1.0=h31becfc_1 + - brotli-bin=1.1.0=h31becfc_1 + - brotli-python=1.1.0=py311h8715677_1 + - bwidget=1.9.14=h8af1aa0_1 - bzip2=1.0.8=h31becfc_5 - c-ares=1.28.1=h31becfc_0 - c-compiler=1.7.0=h31becfc_1 - ca-certificates=2024.6.2=hcefe29a_0 + - cached-property=1.5.2=hd8ed1ab_1 + - cached_property=1.5.2=pyha770c72_1 - cachetools=5.3.3=pyhd8ed1ab_0 + - cairo=1.18.0=h5c54ea9_2 - cddlib=1!0.94m=h719063d_0 + - certifi=2024.6.2=pyhd8ed1ab_0 + - cffi=1.16.0=py311h7963103_0 - chardet=5.2.0=py311hfecb2dc_1 + - charset-normalizer=3.3.2=pyhd8ed1ab_0 - cliquer=1.22=h31becfc_1 - cmake=3.29.6=h7042e5d_0 - colorama=0.4.6=pyhd8ed1ab_0 + - colorlog=6.8.2=py311hec3470c_0 + - comm=0.2.2=pyhd8ed1ab_0 - compilers=1.7.0=h8af1aa0_1 + - contourpy=1.2.1=py311h098ece5_0 + - conway-polynomials=0.9=pyhd8ed1ab_0 + - cppy=1.2.1=pyhd8ed1ab_0 - curl=8.8.0=h7daf2e0_0 + - cvxopt=1.3.2=py311ha095bbf_2 - cxx-compiler=1.7.0=h2a328a1_1 + - cycler=0.12.1=pyhd8ed1ab_0 + - cypari2=2.1.5=py311h5ab95f0_0 + - cysignals=1.11.2=py311h644d908_3 + - cython=3.0.10=py311h8715677_0 + - debugpy=1.8.1=py311h8715677_0 + - decorator=5.1.1=pyhd8ed1ab_0 + - defusedxml=0.7.1=pyhd8ed1ab_0 - distlib=0.3.8=pyhd8ed1ab_0 + - docutils=0.21.2=pyhd8ed1ab_0 + - dsdp=5.8=hb12102e_1203 - ecl=23.9.9=h6475f26_0 - eclib=20231212=he26bab5_0 - ecm=7.0.5=ha2d0fc4_0 + - editables=0.5=pyhd8ed1ab_0 + - entrypoints=0.4=pyhd8ed1ab_0 + - exceptiongroup=1.2.0=pyhd8ed1ab_2 + - executing=2.0.1=pyhd8ed1ab_0 - expat=2.6.2=h2f0025b_0 - fflas-ffpack=2.5.0=h503e619_0 + - fftw=3.3.10=nompi_h020dacd_110 - filelock=3.15.4=pyhd8ed1ab_0 + - flit-core=3.9.0=pyhd8ed1ab_1 - 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 @@ -47,11 +94,17 @@ dependencies: - fontconfig=2.14.2=ha9a116f_0 - fonts-conda-ecosystem=1=0 - fonts-conda-forge=1=0 + - fonttools=4.53.0=py311hf4892ed_0 - fortran-compiler=1.7.0=h7048d53_1 - fplll=5.4.5=hb3a790e_0 + - fpylll=0.6.1=py311h5d3d69a_0 + - fqdn=1.5.1=pyhd8ed1ab_0 - freetype=2.12.1=hf0a5ef3_2 + - fribidi=1.0.10=hb9de7d4_0 + - furo=2024.5.6=pyhd8ed1ab_0 - gap-core=4.12.2=h597289e_3 - gap-defaults=4.12.2=h8af1aa0_3 + - gast=0.5.4=pyhd8ed1ab_0 - gcc=12.3.0=hdb0cc85_13 - gcc_impl_linux-aarch64=12.3.0=h3d98823_13 - gcc_linux-aarch64=12.3.0=ha52a6ea_9 @@ -66,29 +119,76 @@ dependencies: - givaro=4.2.0=h364d21b_0 - glpk=5.0=h66325d0_0 - gmp=6.3.0=h0a1ffab_2 + - gmpy2=2.1.5=py311h3c136a7_1 + - graphite2=1.3.13=h2f0025b_1003 - gsl=2.7=h294027d_0 - gxx=12.3.0=hdb0cc85_13 - gxx_impl_linux-aarch64=12.3.0=hba91e99_13 - gxx_linux-aarch64=12.3.0=h9d1f256_9 + - h11=0.14.0=pyhd8ed1ab_0 + - h2=4.1.0=pyhd8ed1ab_0 + - harfbuzz=8.5.0=h9812418_0 + - hatchling=1.25.0=pyhd8ed1ab_0 + - hpack=4.0.0=pyh9f0ad1d_0 + - httpcore=1.0.5=pyhd8ed1ab_0 + - httpx=0.27.0=pyhd8ed1ab_0 + - hyperframe=6.0.1=pyhd8ed1ab_0 - icu=73.2=h787c7f5_0 + - idna=3.7=pyhd8ed1ab_0 - igraph=0.10.12=h197073e_1 + - imagesize=1.4.1=pyhd8ed1ab_0 - iml=1.0.5=h15043fe_1004 - importlib-metadata=8.0.0=pyha770c72_0 + - importlib-resources=6.4.0=pyhd8ed1ab_0 - importlib_metadata=8.0.0=hd8ed1ab_0 + - importlib_resources=6.4.0=pyhd8ed1ab_0 + - ipykernel=6.29.4=pyh3099207_0 + - ipympl=0.9.4=pyhd8ed1ab_0 + - ipython=8.25.0=pyh707e725_0 + - ipython_genutils=0.2.0=pyhd8ed1ab_1 + - ipywidgets=8.1.3=pyhd8ed1ab_0 + - isoduration=20.11.0=pyhd8ed1ab_0 + - jedi=0.19.1=pyhd8ed1ab_0 + - jinja2=3.1.4=pyhd8ed1ab_0 + - jmol=14.32.10=h8af1aa0_0 + - json5=0.9.25=pyhd8ed1ab_0 + - jsonpointer=3.0.0=py311hec3470c_0 + - jsonschema=4.22.0=pyhd8ed1ab_0 + - jsonschema-specifications=2023.12.1=pyhd8ed1ab_0 + - jsonschema-with-format-nongpl=4.22.0=pyhd8ed1ab_0 + - jupyter-jsmol=2022.1.0=pyhd8ed1ab_0 + - jupyter-lsp=2.2.5=pyhd8ed1ab_0 + - jupyter-sphinx=0.5.3=pyha770c72_4 + - jupyter_client=8.6.2=pyhd8ed1ab_0 + - jupyter_core=5.7.2=py311hec3470c_0 + - jupyter_events=0.10.0=pyhd8ed1ab_0 + - jupyter_server=2.14.1=pyhd8ed1ab_0 + - jupyter_server_terminals=0.5.3=pyhd8ed1ab_0 + - jupyter_sphinx=0.5.3=hd8ed1ab_4 + - jupyterlab=4.2.2=pyhd8ed1ab_0 + - jupyterlab_pygments=0.3.0=pyhd8ed1ab_1 + - jupyterlab_server=2.27.2=pyhd8ed1ab_0 + - jupyterlab_widgets=3.0.11=pyhd8ed1ab_0 - kernel-headers_linux-aarch64=4.18.0=h5b4a56d_14 - keyutils=1.6.1=h4e544f5_0 + - kiwisolver=1.4.5=py311h0d5d7b0_1 - krb5=1.21.2=hc419048_0 - lcalc=2.0.5=he588f68_2 + - lcms2=2.16=h922389a_0 - ld_impl_linux-aarch64=2.40=h9fc2d93_7 - lerc=4.0.0=h4de3ea5_0 - libatomic_ops=7.6.14=h4e544f5_0 - - libblas=3.9.0=22_linuxaarch64_openblas + - libblas=3.9.0=20_linuxaarch64_openblas - libboost=1.85.0=hb41fec8_2 - libboost-devel=1.85.0=h37bb5a9_2 - libboost-headers=1.85.0=h8af1aa0_2 - libbraiding=1.2=hd600fc2_0 - libbrial=1.2.12=h9429f74_3 - - libcblas=3.9.0=22_linuxaarch64_openblas + - libbrotlicommon=1.1.0=h31becfc_1 + - libbrotlidec=1.1.0=h31becfc_1 + - libbrotlienc=1.1.0=h31becfc_1 + - libcblas=3.9.0=20_linuxaarch64_openblas + - libcups=2.3.3=h405e4a8_4 - libcurl=8.8.0=h4e8248e_0 - libdeflate=1.20=h31becfc_0 - libedit=3.1.20191231=he28a2e2_2 @@ -101,16 +201,17 @@ dependencies: - libgd=2.3.3=hcd22fd5_9 - libgfortran-ng=13.2.0=he9431aa_13 - libgfortran5=13.2.0=h2af0866_13 + - libglib=2.80.2=haee52c6_1 - libgomp=13.2.0=he277a41_13 - libhomfly=1.02r6=h31becfc_1 - libhwloc=2.10.0=default_h3030c0e_1001 - libiconv=1.17=h31becfc_2 - libjpeg-turbo=3.0.0=h31becfc_1 - - liblapack=3.9.0=22_linuxaarch64_openblas - - liblapacke=3.9.0=22_linuxaarch64_openblas + - liblapack=3.9.0=20_linuxaarch64_openblas + - liblapacke=3.9.0=20_linuxaarch64_openblas - libnghttp2=1.58.0=hb0e430d_1 - libnsl=2.0.1=h31becfc_0 - - libopenblas=0.3.27=pthreads_h5a5ec62_0 + - libopenblas=0.3.25=pthreads_h5a5ec62_0 - libpng=1.6.43=h194ca79_0 - libsanitizer=12.3.0=h57e2e72_13 - libsodium=1.0.18=hb9de7d4_1 @@ -124,6 +225,7 @@ dependencies: - libuv=1.48.0=h31becfc_0 - libwebp=1.4.0=h8b4e01b_0 - libwebp-base=1.4.0=h31becfc_0 + - libxcb=1.16=h7935292_0 - libxcrypt=4.4.36=h31becfc_1 - libxml2=2.12.7=h49dc7a2_1 - libzlib=1.3.1=h68df207_1 @@ -134,61 +236,199 @@ dependencies: - m4ri=20140914=hedfd65a_1006 - m4rie=20150908=hf0a5ef3_1002 - make=4.3=h309ac5b_1 + - markupsafe=2.1.5=py311hc8f2f60_0 - mathjax=3.2.2=h8af1aa0_0 + - matplotlib=3.8.4=py311hfecb2dc_2 + - matplotlib-base=3.8.4=py311h55059f0_2 + - matplotlib-inline=0.1.7=pyhd8ed1ab_0 - maxima=5.47.0=h6475f26_2 + - memory-allocator=0.1.3=py311hcd402e7_0 - metis=5.1.0=h2f0025b_1007 + - mistune=3.0.2=pyhd8ed1ab_0 - mpc=1.3.1=hf4c8f4c_0 - mpfi=1.5.4=h846f343_1001 - mpfr=4.2.1=ha2d0fc4_1 + - mpmath=1.3.0=pyhd8ed1ab_0 + - munkres=1.1.4=pyh9f0ad1d_0 - nauty=2.8.8=h31becfc_1 + - nbclient=0.10.0=pyhd8ed1ab_0 + - nbconvert=7.16.4=hd8ed1ab_1 + - nbconvert-core=7.16.4=pyhd8ed1ab_1 + - nbconvert-pandoc=7.16.4=hd8ed1ab_1 + - nbformat=5.10.4=pyhd8ed1ab_0 - ncurses=6.5=h0425590_0 + - nest-asyncio=1.6.0=pyhd8ed1ab_0 + - networkx=3.2.1=pyhd8ed1ab_0 - ninja=1.12.1=h70be974_0 + - notebook=7.2.1=pyhd8ed1ab_0 + - notebook-shim=0.2.4=pyhd8ed1ab_0 - ntl=11.4.3=h0d7519b_1 - - openblas=0.3.27=pthreads_h339cbfa_0 + - numpy=1.26.4=py311h69ead2a_0 + - openblas=0.3.25=pthreads_h339cbfa_0 + - openjdk=22.0.1=h3d4cd67_0 + - openjpeg=2.5.2=h0d9d63b_0 - openssl=3.3.1=h68df207_0 + - overrides=7.7.0=pyhd8ed1ab_0 - packaging=24.1=pyhd8ed1ab_0 - palp=2.20=hb9de7d4_0 + - pandoc=3.2.1=h8af1aa0_0 + - pandocfilters=1.5.0=pyhd8ed1ab_0 + - pango=1.54.0=h399c48b_0 - pari=2.15.5=h169c2a7_2_pthread - pari-elldata=0.0.20161017=0 - pari-galdata=0.0.20180411=0 - pari-galpol=0.0.20180625=0 - pari-seadata=0.0.20090618=0 - pari-seadata-small=0.0.20090618=0 + - parso=0.8.4=pyhd8ed1ab_0 - patch=2.7.6=hf897c2e_1002 + - pathspec=0.12.1=pyhd8ed1ab_0 + - pcre2=10.44=h070dd5b_0 + - pep517=0.13.0=pyhd8ed1ab_0 - perl=5.32.1=7_h31becfc_perl5 + - pexpect=4.9.0=pyhd8ed1ab_0 + - pickleshare=0.7.5=py_1003 + - pillow=10.3.0=py311h54289d1_1 + - pip=24.0=pyhd8ed1ab_0 + - pixman=0.43.4=h2f0025b_0 - pkg-config=0.29.2=hb9de7d4_1008 + - pkgconfig=1.5.5=pyhd8ed1ab_4 + - pkgutil-resolve-name=1.3.10=pyhd8ed1ab_1 - planarity=3.0.2.0=h31becfc_0 - platformdirs=4.2.2=pyhd8ed1ab_0 - pluggy=1.5.0=pyhd8ed1ab_0 + - ply=3.11=pyhd8ed1ab_2 - ppl=1.2=h984aac9_1006 - - primecount=7.13=hfe4b40e_0 - - primesieve=12.1=h2f0025b_0 + - pplpy=0.8.9=py311ha3770eb_1 + - primecount=7.9=hd600fc2_0 + - primecountpy=0.1.0=py311h098ece5_4 + - primesieve=11.1=h2f0025b_0 + - prometheus_client=0.20.0=pyhd8ed1ab_0 + - prompt-toolkit=3.0.47=pyha770c72_0 + - prompt_toolkit=3.0.47=hd8ed1ab_0 + - psutil=6.0.0=py311hf4892ed_0 + - pthread-stubs=0.4=hb9de7d4_1001 + - ptyprocess=0.7.0=pyhd3deb0d_0 + - pure_eval=0.2.2=pyhd8ed1ab_0 + - py=1.11.0=pyh6c4a22f_0 + - pybind11=2.12.0=py311h098ece5_0 + - pybind11-global=2.12.0=py311h098ece5_0 + - pycparser=2.22=pyhd8ed1ab_0 + - pygments=2.18.0=pyhd8ed1ab_0 + - pyparsing=3.1.2=pyhd8ed1ab_0 - pyproject-api=1.7.1=pyhd8ed1ab_0 + - pyrsistent=0.20.0=py311hc8f2f60_0 + - pysocks=1.7.1=pyha2e5f31_6 - python=3.11.9=hddfb980_0_cpython + - python-build=1.2.1=pyhd8ed1ab_0 + - python-dateutil=2.9.0=pyhd8ed1ab_0 + - python-fastjsonschema=2.20.0=pyhd8ed1ab_0 + - python-json-logger=2.0.7=pyhd8ed1ab_0 + - python-lrcalc=2.1=py311h8715677_6 + - python-tzdata=2024.1=pyhd8ed1ab_0 - python_abi=3.11=4_cp311 + - pythran=0.15.0=py311hec5c23b_1 + - pytz=2024.1=pyhd8ed1ab_0 + - pytz-deprecation-shim=0.1.0.post0=py311hec3470c_4 + - pyyaml=6.0.1=py311hcd402e7_1 + - pyzmq=26.0.3=py311hb8d4657_0 - qd=2.3.22=h05efe27_1004 - qhull=2020.2=hd62202e_2 + - r-base=4.3.3=h7f20121_3 + - r-lattice=0.22_6=r43h25e906a_0 - readline=8.2=h8fc344f_1 + - referencing=0.35.1=pyhd8ed1ab_0 + - requests=2.32.3=pyhd8ed1ab_0 + - rfc3339-validator=0.1.4=pyhd8ed1ab_0 + - rfc3986-validator=0.1.1=pyh9f0ad1d_0 - rhash=1.4.4=h31becfc_0 + - rpds-py=0.18.1=py311h949f54a_0 + - rpy2=3.5.11=py311r43hf13da56_3 - rw=0.9=h31becfc_2 + - sagemath-db-combinatorial-designs=20140630=1 + - sagemath-db-elliptic-curves=0.8.1=hecc5488_0 + - sagemath-db-graphs=20210214=hd8ed1ab_0 + - sagemath-db-polytopes=20170220=1 + - sagetex=3.6.1=pyhd8ed1ab_0 + - scipy=1.11.3=py311h69ead2a_1 + - sed=4.8=ha0d5d3d_0 + - send2trash=1.8.3=pyh0d859eb_0 + - setuptools=70.1.1=pyhd8ed1ab_0 + - setuptools-scm=8.1.0=pyhd8ed1ab_0 + - setuptools_scm=8.1.0=hd8ed1ab_0 + - simplegeneric=0.8.1=py_1 - singular=4.3.2.p8=hbe76a8a_1 + - six=1.16.0=pyh6c4a22f_0 + - sniffio=1.3.1=pyhd8ed1ab_0 + - snowballstemmer=2.2.0=pyhd8ed1ab_0 + - soupsieve=2.5=pyhd8ed1ab_1 + - sphinx=7.3.7=pyhd8ed1ab_0 + - sphinx-basic-ng=1.0.0b2=pyhd8ed1ab_1 + - sphinx-copybutton=0.5.2=pyhd8ed1ab_0 + - sphinxcontrib-applehelp=1.0.8=pyhd8ed1ab_0 + - sphinxcontrib-devhelp=1.0.6=pyhd8ed1ab_0 + - sphinxcontrib-htmlhelp=2.0.5=pyhd8ed1ab_0 + - sphinxcontrib-jsmath=1.0.1=pyhd8ed1ab_0 + - sphinxcontrib-qthelp=1.0.7=pyhd8ed1ab_0 + - sphinxcontrib-serializinghtml=1.1.10=pyhd8ed1ab_0 + - sphinxcontrib-websupport=1.2.7=pyhd8ed1ab_0 - sqlite=3.46.0=hdc7ab3c_0 + - stack_data=0.6.2=pyhd8ed1ab_0 - suitesparse=7.7.0=h3944111_1 - symmetrica=3.0.1=hd600fc2_0 - sympow=2.023.6=h157afb5_3 + - sympy=1.12.1=pypyh2585a3b_103 - sysroot_linux-aarch64=2.17=h5b4a56d_14 - tachyon=0.99b6=ha0bfc61_1002 - tar=1.34=h048efde_0 - tbb=2021.12.0=h70be974_1 + - terminado=0.18.1=pyh0d859eb_0 - texinfo=7.0=pl5321h17f021e_0 + - three.js=122=hd8ed1ab_2 + - threejs-sage=122=hd8ed1ab_2 + - tinycss2=1.3.0=pyhd8ed1ab_0 - tk=8.6.13=h194ca79_0 + - tktable=2.10=h52f7bd3_6 - tomli=2.0.1=pyhd8ed1ab_0 + - tornado=6.4.1=py311h323e239_0 - tox=4.15.1=pyhd8ed1ab_0 + - traitlets=5.14.3=pyhd8ed1ab_0 + - trove-classifiers=2024.5.22=pyhd8ed1ab_0 + - types-python-dateutil=2.9.0.20240316=pyhd8ed1ab_0 - typing-extensions=4.12.2=hd8ed1ab_0 - typing_extensions=4.12.2=pyha770c72_0 + - typing_utils=0.1.0=pyhd8ed1ab_0 - tzdata=2024a=h0c530f3_0 + - tzlocal=5.2=py311hec3470c_0 + - uri-template=1.3.0=pyhd8ed1ab_0 + - urllib3=2.2.2=pyhd8ed1ab_0 - virtualenv=20.26.3=pyhd8ed1ab_0 + - wcwidth=0.2.13=pyhd8ed1ab_0 + - webcolors=24.6.0=pyhd8ed1ab_0 + - webencodings=0.5.1=pyhd8ed1ab_2 + - websocket-client=1.8.0=pyhd8ed1ab_0 + - wheel=0.43.0=pyhd8ed1ab_1 + - widgetsnbextension=4.0.11=pyhd8ed1ab_0 + - xorg-fixesproto=5.0=h3557bc0_1002 + - xorg-inputproto=2.3.2=h3557bc0_1002 + - xorg-kbproto=1.0.7=h3557bc0_1002 + - xorg-libice=1.1.1=h7935292_0 + - xorg-libsm=1.2.4=h5a01bc2_0 + - xorg-libx11=1.8.9=h08be655_1 + - xorg-libxau=1.0.11=h31becfc_0 + - xorg-libxdmcp=1.1.3=h3557bc0_0 + - xorg-libxext=1.3.4=h2a766a3_2 + - xorg-libxfixes=5.0.3=h3557bc0_1004 + - xorg-libxi=1.7.10=h3557bc0_0 + - xorg-libxrender=0.9.11=h7935292_0 + - xorg-libxt=1.3.0=h7935292_1 + - xorg-libxtst=1.2.3=hf897c2e_1002 + - xorg-recordproto=1.14.2=hf897c2e_1002 + - xorg-renderproto=0.11.1=h3557bc0_1002 + - xorg-xextproto=7.3.0=h2a766a3_1003 + - xorg-xproto=7.0.31=h3557bc0_1007 - xz=5.2.6=h9cdd2b7_0 + - yaml=0.2.5=hf897c2e_2 - zeromq=4.3.5=h28faeed_4 - zipp=3.19.2=pyhd8ed1ab_0 - zlib=1.3.1=h68df207_1 diff --git a/environment-3.11-linux.yml b/environment-3.11-linux.yml index 9f2a41a5a28..e169439f85d 100644 --- a/environment-3.11-linux.yml +++ b/environment-3.11-linux.yml @@ -1,45 +1,94 @@ +name: sage # Generated by conda-lock. # platform: linux-64 -# input_hash: 03f617f14f4f3c44d76a4218e41fa67dc9ba330ebfcd054a10dd4fabf1d57704 +# input_hash: 042b3b9a5ce5e44ed6334284078d156e424e41f02852c8c6a155cb9b4e620e60 channels: - conda-forge dependencies: - _libgcc_mutex=0.1=conda_forge - _openmp_mutex=4.5=2_kmp_llvm + - _r-mutex=1.0.1=anacondar_1 + - alabaster=0.7.16=pyhd8ed1ab_0 + - alsa-lib=1.2.12=h4ab18f5_0 + - anyio=4.4.0=pyhd8ed1ab_0 - appdirs=1.4.4=pyh9f0ad1d_0 + - appnope=0.1.4=pyhd8ed1ab_0 + - argon2-cffi=23.1.0=pyhd8ed1ab_0 + - argon2-cffi-bindings=21.2.0=py311h459d7ec_4 - arpack=3.9.1=nompi_h77f6705_101 + - arrow=1.3.0=pyhd8ed1ab_0 + - asttokens=2.4.1=pyhd8ed1ab_0 + - async-lru=2.0.4=pyhd8ed1ab_0 + - attr=2.5.1=h166bdaf_1 + - attrs=23.2.0=pyh71513ae_0 - autoconf=2.71=pl5321h2b4cb7a_1 - automake=1.16.5=pl5321ha770c72_0 + - babel=2.14.0=pyhd8ed1ab_0 - bc=1.07.1=h7f98852_0 - bdw-gc=8.0.6=h4bd325d_0 + - beautifulsoup4=4.12.3=pyha770c72_0 + - beniget=0.4.1=pyhd8ed1ab_0 - binutils=2.40=h4852527_7 - binutils_impl_linux-64=2.40=ha1999f0_7 - binutils_linux-64=2.40=hb3c18ed_9 - - blas=2.122=openblas - - blas-devel=3.9.0=22_linux64_openblas + - blas=2.120=openblas + - blas-devel=3.9.0=20_linux64_openblas + - bleach=6.1.0=pyhd8ed1ab_0 - boost-cpp=1.85.0=h44aadfe_2 - brial=1.2.12=pyh694c41f_3 + - brotli=1.1.0=hd590300_1 + - brotli-bin=1.1.0=hd590300_1 + - brotli-python=1.1.0=py311hb755f60_1 + - bwidget=1.9.14=ha770c72_1 - bzip2=1.0.8=hd590300_5 - c-ares=1.28.1=hd590300_0 - c-compiler=1.7.0=hd590300_1 - ca-certificates=2024.6.2=hbcca054_0 + - cached-property=1.5.2=hd8ed1ab_1 + - cached_property=1.5.2=pyha770c72_1 - cachetools=5.3.3=pyhd8ed1ab_0 + - cairo=1.18.0=hbb29018_2 - cddlib=1!0.94m=h9202a9a_0 + - certifi=2024.6.2=pyhd8ed1ab_0 + - cffi=1.16.0=py311hb3a22ac_0 - chardet=5.2.0=py311h38be061_1 + - charset-normalizer=3.3.2=pyhd8ed1ab_0 - cliquer=1.22=hd590300_1 - cmake=3.29.6=hcafd917_0 - colorama=0.4.6=pyhd8ed1ab_0 + - colorlog=6.8.2=py311h38be061_0 + - comm=0.2.2=pyhd8ed1ab_0 - compilers=1.7.0=ha770c72_1 + - contourpy=1.2.1=py311h9547e67_0 + - conway-polynomials=0.9=pyhd8ed1ab_0 + - cppy=1.2.1=pyhd8ed1ab_0 - curl=8.8.0=he654da7_0 + - cvxopt=1.3.2=py311hec6cc1f_2 - cxx-compiler=1.7.0=h00ab1b0_1 + - cycler=0.12.1=pyhd8ed1ab_0 + - cypari2=2.1.5=py311hd2352ae_0 + - cysignals=1.11.2=py311h82528dc_3 + - cython=3.0.10=py311hb755f60_0 + - dbus=1.13.6=h5008d03_3 + - debugpy=1.8.1=py311hb755f60_0 + - decorator=5.1.1=pyhd8ed1ab_0 + - defusedxml=0.7.1=pyhd8ed1ab_0 - distlib=0.3.8=pyhd8ed1ab_0 + - docutils=0.21.2=pyhd8ed1ab_0 + - dsdp=5.8=hd9d9efa_1203 - ecl=23.9.9=hed6455c_0 - eclib=20231212=h96f522a_0 - ecm=7.0.5=h9458935_0 + - editables=0.5=pyhd8ed1ab_0 + - entrypoints=0.4=pyhd8ed1ab_0 + - exceptiongroup=1.2.0=pyhd8ed1ab_2 + - executing=2.0.1=pyhd8ed1ab_0 - expat=2.6.2=h59595ed_0 - fflas-ffpack=2.5.0=h4f9960b_0 + - fftw=3.3.10=nompi_hf1063bd_110 - filelock=3.15.4=pyhd8ed1ab_0 + - flit-core=3.9.0=pyhd8ed1ab_1 - 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 @@ -47,15 +96,23 @@ dependencies: - fontconfig=2.14.2=h14ed4e7_0 - fonts-conda-ecosystem=1=0 - fonts-conda-forge=1=0 + - fonttools=4.53.0=py311h331c9d8_0 - fortran-compiler=1.7.0=heb67821_1 - fplll=5.4.5=h384768b_0 + - fpylll=0.6.1=py311hcfae7cf_0 + - fqdn=1.5.1=pyhd8ed1ab_0 - freetype=2.12.1=h267a509_2 + - fribidi=1.0.10=h36c2ea0_0 + - furo=2024.5.6=pyhd8ed1ab_0 - gap-core=4.12.2=he9a28a4_3 - gap-defaults=4.12.2=ha770c72_3 + - gast=0.5.4=pyhd8ed1ab_0 - gcc=12.3.0=h915e2ae_13 - gcc_impl_linux-64=12.3.0=h58ffeeb_13 - gcc_linux-64=12.3.0=h9528a6a_9 - gengetopt=2.23=h9c3ff4c_0 + - gettext=0.22.5=h59595ed_2 + - gettext-tools=0.22.5=h59595ed_2 - gf2x=1.3.0=ha476b99_2 - gfan=0.6.2=hb86e20a_1003 - gfortran=12.3.0=h915e2ae_13 @@ -64,131 +121,362 @@ dependencies: - giac=1.9.0.21=h673759e_1 - giflib=5.2.2=hd590300_0 - givaro=4.2.0=hb789bce_0 + - glib=2.80.2=h8a4344b_1 + - glib-tools=2.80.2=h73ef956_1 - glpk=5.0=h445213a_0 - gmp=6.3.0=hac33072_2 + - gmpy2=2.1.5=py311hc4f1f91_1 + - graphite2=1.3.13=h59595ed_1003 - gsl=2.7=he838d99_0 + - gst-plugins-base=1.24.5=hbaaba92_0 + - gstreamer=1.24.5=haf2f30d_0 - gxx=12.3.0=h915e2ae_13 - gxx_impl_linux-64=12.3.0=h2a574ab_13 - gxx_linux-64=12.3.0=ha28b414_9 + - h11=0.14.0=pyhd8ed1ab_0 + - h2=4.1.0=pyhd8ed1ab_0 + - harfbuzz=8.5.0=hfac3d4d_0 + - hatchling=1.25.0=pyhd8ed1ab_0 + - hpack=4.0.0=pyh9f0ad1d_0 + - httpcore=1.0.5=pyhd8ed1ab_0 + - httpx=0.27.0=pyhd8ed1ab_0 + - hyperframe=6.0.1=pyhd8ed1ab_0 - icu=73.2=h59595ed_0 + - idna=3.7=pyhd8ed1ab_0 - igraph=0.10.12=hef0740d_1 + - imagesize=1.4.1=pyhd8ed1ab_0 - iml=1.0.5=h623f65a_1004 - importlib-metadata=8.0.0=pyha770c72_0 + - importlib-resources=6.4.0=pyhd8ed1ab_0 - importlib_metadata=8.0.0=hd8ed1ab_0 + - importlib_resources=6.4.0=pyhd8ed1ab_0 + - ipykernel=6.29.4=pyh3099207_0 + - ipympl=0.9.4=pyhd8ed1ab_0 + - ipython=8.25.0=pyh707e725_0 + - ipython_genutils=0.2.0=pyhd8ed1ab_1 + - ipywidgets=8.1.3=pyhd8ed1ab_0 + - isoduration=20.11.0=pyhd8ed1ab_0 + - jedi=0.19.1=pyhd8ed1ab_0 + - jinja2=3.1.4=pyhd8ed1ab_0 + - jmol=14.32.10=ha770c72_0 + - json5=0.9.25=pyhd8ed1ab_0 + - jsonpointer=3.0.0=py311h38be061_0 + - jsonschema=4.22.0=pyhd8ed1ab_0 + - jsonschema-specifications=2023.12.1=pyhd8ed1ab_0 + - jsonschema-with-format-nongpl=4.22.0=pyhd8ed1ab_0 + - jupyter-jsmol=2022.1.0=pyhd8ed1ab_0 + - jupyter-lsp=2.2.5=pyhd8ed1ab_0 + - jupyter-sphinx=0.5.3=pyha770c72_4 + - jupyter_client=8.6.2=pyhd8ed1ab_0 + - jupyter_core=5.7.2=py311h38be061_0 + - jupyter_events=0.10.0=pyhd8ed1ab_0 + - jupyter_server=2.14.1=pyhd8ed1ab_0 + - jupyter_server_terminals=0.5.3=pyhd8ed1ab_0 + - jupyter_sphinx=0.5.3=hd8ed1ab_4 + - jupyterlab=4.2.2=pyhd8ed1ab_0 + - jupyterlab_pygments=0.3.0=pyhd8ed1ab_1 + - jupyterlab_server=2.27.2=pyhd8ed1ab_0 + - jupyterlab_widgets=3.0.11=pyhd8ed1ab_0 - kernel-headers_linux-64=2.6.32=he073ed8_17 - keyutils=1.6.1=h166bdaf_0 + - kiwisolver=1.4.5=py311h9547e67_1 - krb5=1.21.2=h659d440_0 + - lame=3.100=h166bdaf_1003 - lcalc=2.0.5=h5aac1b6_2 + - lcms2=2.16=hb7c19ff_0 - ld_impl_linux-64=2.40=hf3520f5_7 - lerc=4.0.0=h27087fc_0 + - libasprintf=0.22.5=h661eb56_2 + - libasprintf-devel=0.22.5=h661eb56_2 - libatomic_ops=7.6.14=h166bdaf_0 - - libblas=3.9.0=22_linux64_openblas + - libblas=3.9.0=20_linux64_openblas - libboost=1.85.0=hba137d9_2 - libboost-devel=1.85.0=h00ab1b0_2 - libboost-headers=1.85.0=ha770c72_2 - libbraiding=1.2=hcb278e6_0 - libbrial=1.2.12=h76af697_3 - - libcblas=3.9.0=22_linux64_openblas + - libbrotlicommon=1.1.0=hd590300_1 + - libbrotlidec=1.1.0=hd590300_1 + - libbrotlienc=1.1.0=hd590300_1 + - libcap=2.69=h0f662aa_0 + - libcblas=3.9.0=20_linux64_openblas + - libclang-cpp15=15.0.7=default_h127d8a8_5 + - libclang13=18.1.8=default_h6ae225f_0 + - libcups=2.3.3=h4637d8d_4 - libcurl=8.8.0=hca28451_0 - libdeflate=1.20=hd590300_0 - libedit=3.1.20191231=he28a2e2_2 - libev=4.33=hd590300_2 + - libevent=2.1.12=hf998b51_1 - libexpat=2.6.2=h59595ed_0 - libffi=3.4.2=h7f98852_5 + - libflac=1.4.3=h59595ed_0 - libflint=3.0.1=h5f2e117_ntl_100 - libgcc-devel_linux-64=12.3.0=h6b66f73_113 - libgcc-ng=13.2.0=h77fa898_13 + - libgcrypt=1.10.3=hd590300_0 - libgd=2.3.3=h119a65a_9 + - libgettextpo=0.22.5=h59595ed_2 + - libgettextpo-devel=0.22.5=h59595ed_2 - libgfortran-ng=13.2.0=h69a702a_13 - libgfortran5=13.2.0=h3d2ce59_13 + - libglib=2.80.2=h8a4344b_1 - libgomp=13.2.0=h77fa898_13 + - libgpg-error=1.49=h4f305b6_0 - libhomfly=1.02r6=hd590300_1 - libhwloc=2.10.0=default_h5622ce7_1001 - libiconv=1.17=hd590300_2 - libjpeg-turbo=3.0.0=hd590300_1 - - liblapack=3.9.0=22_linux64_openblas - - liblapacke=3.9.0=22_linux64_openblas + - liblapack=3.9.0=20_linux64_openblas + - liblapacke=3.9.0=20_linux64_openblas + - libllvm15=15.0.7=hb3ce162_4 + - libllvm18=18.1.8=hc9dba70_0 - libnghttp2=1.58.0=h47da74e_1 - libnsl=2.0.1=hd590300_0 - - libopenblas=0.3.27=pthreads_h413a1c8_0 + - libogg=1.3.5=h4ab18f5_0 + - libopenblas=0.3.25=pthreads_h413a1c8_0 + - libopus=1.3.1=h7f98852_1 - libpng=1.6.43=h2797004_0 + - libpq=16.3=ha72fbe1_0 - libsanitizer=12.3.0=hb8811af_13 + - libsndfile=1.2.2=hc60ed4a_1 - libsodium=1.0.18=h36c2ea0_1 - libsqlite=3.46.0=hde9e2c9_0 - libssh2=1.11.0=h0841786_0 - libstdcxx-devel_linux-64=12.3.0=h6b66f73_113 - libstdcxx-ng=13.2.0=hc0a3c3a_13 + - libsystemd0=255=h3516f8a_1 - libtiff=4.6.0=h1dd3fc0_3 - libtool=2.4.7=h27087fc_0 - libuuid=2.38.1=h0b41bf4_0 - libuv=1.48.0=hd590300_0 + - libvorbis=1.3.7=h9c3ff4c_0 - libwebp=1.4.0=h2c329e2_0 - libwebp-base=1.4.0=hd590300_0 + - libxcb=1.16=hd590300_0 - libxcrypt=4.4.36=hd590300_1 + - libxkbcommon=1.7.0=h2c5496b_1 - libxml2=2.12.7=hc051c1a_1 - libzlib=1.3.1=h4ab18f5_1 - linbox=1.7.0=ha329b40_0 - llvm-openmp=18.1.8=hf5423f3_0 - lrcalc=2.1=h59595ed_6 + - lz4-c=1.9.4=hcb278e6_0 - m4=1.4.18=h516909a_1001 - m4ri=20140914=hae5d5c5_1006 - m4rie=20150908=h267a509_1002 - make=4.3=hd18ef5c_1 + - markupsafe=2.1.5=py311h459d7ec_0 - mathjax=3.2.2=ha770c72_0 + - matplotlib=3.8.4=py311h38be061_2 + - matplotlib-base=3.8.4=py311ha4ca890_2 + - matplotlib-inline=0.1.7=pyhd8ed1ab_0 - maxima=5.47.0=hed6455c_2 + - memory-allocator=0.1.3=py311h459d7ec_0 - metis=5.1.0=h59595ed_1007 + - mistune=3.0.2=pyhd8ed1ab_0 - mpc=1.3.1=hfe3b2da_0 - mpfi=1.5.4=h9f54685_1001 - mpfr=4.2.1=h9458935_1 + - mpg123=1.32.6=h59595ed_0 + - mpmath=1.3.0=pyhd8ed1ab_0 + - munkres=1.1.4=pyh9f0ad1d_0 + - mysql-common=8.3.0=hf1915f5_4 + - mysql-libs=8.3.0=hca2cd23_4 - nauty=2.8.8=hd590300_1 + - nbclient=0.10.0=pyhd8ed1ab_0 + - nbconvert=7.16.4=hd8ed1ab_1 + - nbconvert-core=7.16.4=pyhd8ed1ab_1 + - nbconvert-pandoc=7.16.4=hd8ed1ab_1 + - nbformat=5.10.4=pyhd8ed1ab_0 - ncurses=6.5=h59595ed_0 + - nest-asyncio=1.6.0=pyhd8ed1ab_0 + - networkx=3.2.1=pyhd8ed1ab_0 - ninja=1.12.1=h297d8ca_0 + - notebook=7.2.1=pyhd8ed1ab_0 + - notebook-shim=0.2.4=pyhd8ed1ab_0 + - nspr=4.35=h27087fc_0 + - nss=3.101=h593d115_0 - ntl=11.4.3=hef3c4d3_1 - - openblas=0.3.27=pthreads_h7a3da1a_0 + - numpy=1.26.4=py311h64a7726_0 + - openblas=0.3.25=pthreads_h7a3da1a_0 + - openjdk=21.0.2=haa376d0_0 + - openjpeg=2.5.2=h488ebb8_0 - openssl=3.3.1=h4ab18f5_0 + - overrides=7.7.0=pyhd8ed1ab_0 - packaging=24.1=pyhd8ed1ab_0 - palp=2.20=h36c2ea0_0 + - pandoc=3.2.1=ha770c72_0 + - pandocfilters=1.5.0=pyhd8ed1ab_0 + - pango=1.54.0=h84a9a3c_0 - pari=2.15.5=h4d4ae9b_2_pthread - pari-elldata=0.0.20161017=0 - pari-galdata=0.0.20180411=0 - pari-galpol=0.0.20180625=0 - pari-seadata=0.0.20090618=0 - pari-seadata-small=0.0.20090618=0 + - parso=0.8.4=pyhd8ed1ab_0 - patch=2.7.6=h7f98852_1002 + - pathspec=0.12.1=pyhd8ed1ab_0 + - pcre2=10.44=h0f59acf_0 + - pep517=0.13.0=pyhd8ed1ab_0 - perl=5.32.1=7_hd590300_perl5 + - pexpect=4.9.0=pyhd8ed1ab_0 + - pickleshare=0.7.5=py_1003 + - pillow=10.3.0=py311h82a398c_1 + - pip=24.0=pyhd8ed1ab_0 + - pixman=0.43.2=h59595ed_0 - pkg-config=0.29.2=h36c2ea0_1008 + - pkgconfig=1.5.5=pyhd8ed1ab_4 + - pkgutil-resolve-name=1.3.10=pyhd8ed1ab_1 - planarity=3.0.2.0=hd590300_0 - platformdirs=4.2.2=pyhd8ed1ab_0 - pluggy=1.5.0=pyhd8ed1ab_0 + - ply=3.11=pyhd8ed1ab_2 - ppl=1.2=h6ec01c2_1006 - - primecount=7.13=hb0181e5_0 - - primesieve=12.1=h59595ed_0 + - pplpy=0.8.9=py311ha9f9f00_1 + - primecount=7.9=hcb278e6_0 + - primecountpy=0.1.0=py311h9547e67_4 + - primesieve=11.1=h59595ed_0 + - prometheus_client=0.20.0=pyhd8ed1ab_0 + - prompt-toolkit=3.0.47=pyha770c72_0 + - prompt_toolkit=3.0.47=hd8ed1ab_0 + - psutil=6.0.0=py311h331c9d8_0 + - pthread-stubs=0.4=h36c2ea0_1001 + - ptyprocess=0.7.0=pyhd3deb0d_0 + - pulseaudio-client=17.0=hb77b528_0 + - pure_eval=0.2.2=pyhd8ed1ab_0 + - py=1.11.0=pyh6c4a22f_0 + - pybind11=2.12.0=py311h9547e67_0 + - pybind11-global=2.12.0=py311h9547e67_0 + - pycparser=2.22=pyhd8ed1ab_0 + - pygments=2.18.0=pyhd8ed1ab_0 + - pyparsing=3.1.2=pyhd8ed1ab_0 - pyproject-api=1.7.1=pyhd8ed1ab_0 + - pyqt=5.15.9=py311hf0fb5b6_5 + - pyqt5-sip=12.12.2=py311hb755f60_5 + - pyrsistent=0.20.0=py311h459d7ec_0 + - pysocks=1.7.1=pyha2e5f31_6 - python=3.11.9=hb806964_0_cpython + - python-build=1.2.1=pyhd8ed1ab_0 + - python-dateutil=2.9.0=pyhd8ed1ab_0 + - python-fastjsonschema=2.20.0=pyhd8ed1ab_0 + - python-json-logger=2.0.7=pyhd8ed1ab_0 + - python-lrcalc=2.1=py311hb755f60_6 + - python-tzdata=2024.1=pyhd8ed1ab_0 - python_abi=3.11=4_cp311 + - pythran=0.15.0=py311h92ebd52_1 + - pytz=2024.1=pyhd8ed1ab_0 + - pytz-deprecation-shim=0.1.0.post0=py311h38be061_4 + - pyyaml=6.0.1=py311h459d7ec_1 + - pyzmq=26.0.3=py311h08a0b41_0 - qd=2.3.22=h2cc385e_1004 - qhull=2020.2=h4bd325d_2 + - qt-main=5.15.8=ha2b5568_22 + - r-base=4.3.3=he2d9a6e_3 + - r-lattice=0.22_6=r43h57805ef_0 - readline=8.2=h8228510_1 + - referencing=0.35.1=pyhd8ed1ab_0 + - requests=2.32.3=pyhd8ed1ab_0 + - rfc3339-validator=0.1.4=pyhd8ed1ab_0 + - rfc3986-validator=0.1.1=pyh9f0ad1d_0 - rhash=1.4.4=hd590300_0 + - rpds-py=0.18.1=py311h5ecf98a_0 + - rpy2=3.5.11=py311r43h1f0f07a_3 - rw=0.9=hd590300_2 + - sagemath-db-combinatorial-designs=20140630=1 + - sagemath-db-elliptic-curves=0.8.1=hecc5488_0 + - sagemath-db-graphs=20210214=hd8ed1ab_0 + - sagemath-db-polytopes=20170220=1 + - sagetex=3.6.1=pyhd8ed1ab_0 + - scipy=1.11.4=py311h64a7726_0 + - sed=4.8=he412f7d_0 + - send2trash=1.8.3=pyh0d859eb_0 + - setuptools=70.1.1=pyhd8ed1ab_0 + - setuptools-scm=8.1.0=pyhd8ed1ab_0 + - setuptools_scm=8.1.0=hd8ed1ab_0 + - simplegeneric=0.8.1=py_1 - singular=4.3.2.p8=h33f5c3f_1 + - sip=6.7.12=py311hb755f60_0 + - six=1.16.0=pyh6c4a22f_0 + - sniffio=1.3.1=pyhd8ed1ab_0 + - snowballstemmer=2.2.0=pyhd8ed1ab_0 + - soupsieve=2.5=pyhd8ed1ab_1 + - sphinx=7.3.7=pyhd8ed1ab_0 + - sphinx-basic-ng=1.0.0b2=pyhd8ed1ab_1 + - sphinx-copybutton=0.5.2=pyhd8ed1ab_0 + - sphinxcontrib-applehelp=1.0.8=pyhd8ed1ab_0 + - sphinxcontrib-devhelp=1.0.6=pyhd8ed1ab_0 + - sphinxcontrib-htmlhelp=2.0.5=pyhd8ed1ab_0 + - sphinxcontrib-jsmath=1.0.1=pyhd8ed1ab_0 + - sphinxcontrib-qthelp=1.0.7=pyhd8ed1ab_0 + - sphinxcontrib-serializinghtml=1.1.10=pyhd8ed1ab_0 + - sphinxcontrib-websupport=1.2.7=pyhd8ed1ab_0 - sqlite=3.46.0=h6d4b2fc_0 + - stack_data=0.6.2=pyhd8ed1ab_0 - suitesparse=7.7.0=hf4753ba_1 - symmetrica=3.0.1=hcb278e6_0 - sympow=2.023.6=hc6ab17c_3 + - sympy=1.12.1=pypyh2585a3b_103 - sysroot_linux-64=2.12=he073ed8_17 - tachyon=0.99b6=hba7d16a_1002 - tar=1.34=hb2e2bae_1 - tbb=2021.12.0=h297d8ca_1 + - terminado=0.18.1=pyh0d859eb_0 - texinfo=7.0=pl5321h0f457ee_0 + - three.js=122=hd8ed1ab_2 + - threejs-sage=122=hd8ed1ab_2 + - tinycss2=1.3.0=pyhd8ed1ab_0 - tk=8.6.13=noxft_h4845f30_101 + - tktable=2.10=h8bc8fbc_6 + - toml=0.10.2=pyhd8ed1ab_0 - tomli=2.0.1=pyhd8ed1ab_0 + - tornado=6.4.1=py311h331c9d8_0 - tox=4.15.1=pyhd8ed1ab_0 + - traitlets=5.14.3=pyhd8ed1ab_0 + - trove-classifiers=2024.5.22=pyhd8ed1ab_0 + - types-python-dateutil=2.9.0.20240316=pyhd8ed1ab_0 - typing-extensions=4.12.2=hd8ed1ab_0 - typing_extensions=4.12.2=pyha770c72_0 + - typing_utils=0.1.0=pyhd8ed1ab_0 - tzdata=2024a=h0c530f3_0 + - tzlocal=5.2=py311h38be061_0 + - uri-template=1.3.0=pyhd8ed1ab_0 + - urllib3=2.2.2=pyhd8ed1ab_0 - virtualenv=20.26.3=pyhd8ed1ab_0 + - wcwidth=0.2.13=pyhd8ed1ab_0 + - webcolors=24.6.0=pyhd8ed1ab_0 + - webencodings=0.5.1=pyhd8ed1ab_2 + - websocket-client=1.8.0=pyhd8ed1ab_0 + - wheel=0.43.0=pyhd8ed1ab_1 + - widgetsnbextension=4.0.11=pyhd8ed1ab_0 + - xcb-util=0.4.1=hb711507_2 + - 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.42=h4ab18f5_0 + - xorg-fixesproto=5.0=h7f98852_1002 + - xorg-inputproto=2.3.2=h7f98852_1002 + - xorg-kbproto=1.0.7=h7f98852_1002 + - xorg-libice=1.1.1=hd590300_0 + - xorg-libsm=1.2.4=h7391055_0 + - xorg-libx11=1.8.9=hb711507_1 + - xorg-libxau=1.0.11=hd590300_0 + - xorg-libxdmcp=1.1.3=h7f98852_0 + - xorg-libxext=1.3.4=h0b41bf4_2 + - xorg-libxfixes=5.0.3=h7f98852_1004 + - xorg-libxi=1.7.10=h7f98852_0 + - xorg-libxrender=0.9.11=hd590300_0 + - xorg-libxt=1.3.0=hd590300_1 + - xorg-libxtst=1.2.3=h7f98852_1002 + - xorg-recordproto=1.14.2=h7f98852_1002 + - xorg-renderproto=0.11.1=h7f98852_1002 + - xorg-xextproto=7.3.0=h0b41bf4_1003 + - xorg-xf86vidmodeproto=2.3.1=h7f98852_1002 + - xorg-xproto=7.0.31=h7f98852_1007 - xz=5.2.6=h166bdaf_0 + - yaml=0.2.5=h7f98852_2 - zeromq=4.3.5=h75354e8_4 - zipp=3.19.2=pyhd8ed1ab_0 - zlib=1.3.1=h4ab18f5_1 diff --git a/environment-3.11-macos-x86_64.yml b/environment-3.11-macos-x86_64.yml index 1935cbab259..ddfef2df9d4 100644 --- a/environment-3.11-macos-x86_64.yml +++ b/environment-3.11-macos-x86_64.yml @@ -1,29 +1,54 @@ +name: sage # Generated by conda-lock. # platform: osx-64 -# input_hash: 856274ce5e586028c8c54254d45d9abbf246ca6f94ff02b5e68590cd0a2256f3 +# input_hash: 2d3e06919a9241aca6e25ca728e3013423030e7220d74f404ad621f0ad0ff5bd channels: - conda-forge dependencies: + - _r-mutex=1.0.1=anacondar_1 + - alabaster=0.7.16=pyhd8ed1ab_0 + - anyio=4.4.0=pyhd8ed1ab_0 - appdirs=1.4.4=pyh9f0ad1d_0 + - appnope=0.1.4=pyhd8ed1ab_0 + - argon2-cffi=23.1.0=pyhd8ed1ab_0 + - argon2-cffi-bindings=21.2.0=py311h2725bcf_4 - arpack=3.9.1=nompi_hf81eadf_101 + - arrow=1.3.0=pyhd8ed1ab_0 + - asttokens=2.4.1=pyhd8ed1ab_0 + - async-lru=2.0.4=pyhd8ed1ab_0 + - attrs=23.2.0=pyh71513ae_0 - autoconf=2.71=pl5321hed12c24_1 - automake=1.16.5=pl5321h694c41f_0 + - babel=2.14.0=pyhd8ed1ab_0 - bc=1.07.1=h0d85af4_0 - bdw-gc=8.0.6=h940c156_0 - - blas=2.122=openblas - - blas-devel=3.9.0=22_osx64_openblas + - beautifulsoup4=4.12.3=pyha770c72_0 + - beniget=0.4.1=pyhd8ed1ab_0 + - blas=2.120=openblas + - blas-devel=3.9.0=20_osx64_openblas + - bleach=6.1.0=pyhd8ed1ab_0 - boost-cpp=1.85.0=h07eb623_2 - brial=1.2.12=pyh694c41f_3 + - brotli=1.1.0=h0dc2134_1 + - brotli-bin=1.1.0=h0dc2134_1 + - brotli-python=1.1.0=py311hdf8f085_1 + - bwidget=1.9.14=h694c41f_1 - bzip2=1.0.8=h10d778d_5 - c-ares=1.28.1=h10d778d_0 - c-compiler=1.7.0=h282daa2_1 - ca-certificates=2024.6.2=h8857fd0_0 + - cached-property=1.5.2=hd8ed1ab_1 + - cached_property=1.5.2=pyha770c72_1 - cachetools=5.3.3=pyhd8ed1ab_0 + - cairo=1.18.0=h9f650ed_2 - cctools=986=h40f6528_0 - cctools_osx-64=986=ha1c5b94_0 - cddlib=1!0.94m=h0f52abe_0 + - certifi=2024.6.2=pyhd8ed1ab_0 + - cffi=1.16.0=py311hc0b63fd_0 - chardet=5.2.0=py311h6eed73b_1 + - charset-normalizer=3.3.2=pyhd8ed1ab_0 - clang=16.0.6=default_ha3b9224_8 - clang-16=16.0.6=default_h4c8afb6_8 - clang_impl_osx-64=16.0.6=h8787910_16 @@ -34,18 +59,39 @@ dependencies: - cliquer=1.22=h10d778d_1 - cmake=3.29.6=h749d262_0 - colorama=0.4.6=pyhd8ed1ab_0 + - colorlog=6.8.2=py311h6eed73b_0 + - comm=0.2.2=pyhd8ed1ab_0 - compiler-rt=16.0.6=ha38d28d_2 - compiler-rt_osx-64=16.0.6=ha38d28d_2 - compilers=1.7.0=h694c41f_1 + - contourpy=1.2.1=py311h1d816ee_0 + - conway-polynomials=0.9=pyhd8ed1ab_0 + - cppy=1.2.1=pyhd8ed1ab_0 - curl=8.8.0=hea67d85_0 + - cvxopt=1.3.2=py311he94735a_2 - cxx-compiler=1.7.0=h7728843_1 + - cycler=0.12.1=pyhd8ed1ab_0 + - cypari2=2.1.5=py311h4fde0ae_0 + - cysignals=1.11.2=py311h8a58447_3 + - cython=3.0.10=py311hdd0406b_0 + - debugpy=1.8.1=py311hdd0406b_0 + - decorator=5.1.1=pyhd8ed1ab_0 + - defusedxml=0.7.1=pyhd8ed1ab_0 - distlib=0.3.8=pyhd8ed1ab_0 + - docutils=0.21.2=pyhd8ed1ab_0 + - dsdp=5.8=h6e329d1_1203 - ecl=23.9.9=h2b27fa8_0 - eclib=20231212=h02435c3_0 - ecm=7.0.5=h4f6b447_0 + - editables=0.5=pyhd8ed1ab_0 + - entrypoints=0.4=pyhd8ed1ab_0 + - exceptiongroup=1.2.0=pyhd8ed1ab_2 + - executing=2.0.1=pyhd8ed1ab_0 - expat=2.6.2=h73e2aa4_0 - fflas-ffpack=2.5.0=h5898d61_0 + - fftw=3.3.10=nompi_h292e606_110 - filelock=3.15.4=pyhd8ed1ab_0 + - flit-core=3.9.0=pyhd8ed1ab_1 - 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 @@ -53,11 +99,17 @@ dependencies: - fontconfig=2.14.2=h5bb23bf_0 - fonts-conda-ecosystem=1=0 - fonts-conda-forge=1=0 + - fonttools=4.53.0=py311h72ae277_0 - fortran-compiler=1.7.0=h6c2ab21_1 - fplll=5.4.5=hb7981ad_0 + - fpylll=0.6.1=py311h85fbf69_0 + - fqdn=1.5.1=pyhd8ed1ab_0 - freetype=2.12.1=h60636b9_2 + - fribidi=1.0.10=hbcb3906_0 + - furo=2024.5.6=pyhd8ed1ab_0 - gap-core=4.12.2=hc16eb5f_3 - gap-defaults=4.12.2=h694c41f_3 + - gast=0.5.4=pyhd8ed1ab_0 - gengetopt=2.23=he49afe7_0 - gettext=0.22.5=h5ff76d1_2 - gettext-tools=0.22.5=h5ff76d1_2 @@ -71,28 +123,74 @@ dependencies: - givaro=4.2.0=h1b3d6f7_0 - glpk=5.0=h3cb5acd_0 - gmp=6.3.0=hf036a51_2 + - gmpy2=2.1.5=py311hab17429_1 + - graphite2=1.3.13=h73e2aa4_1003 - gsl=2.7=h93259b0_0 + - h11=0.14.0=pyhd8ed1ab_0 + - h2=4.1.0=pyhd8ed1ab_0 + - harfbuzz=8.5.0=h053f038_0 + - hatchling=1.25.0=pyhd8ed1ab_0 + - hpack=4.0.0=pyh9f0ad1d_0 + - httpcore=1.0.5=pyhd8ed1ab_0 + - httpx=0.27.0=pyhd8ed1ab_0 + - hyperframe=6.0.1=pyhd8ed1ab_0 - icu=73.2=hf5e326d_0 + - idna=3.7=pyhd8ed1ab_0 - igraph=0.10.12=hde4452d_1 + - imagesize=1.4.1=pyhd8ed1ab_0 - iml=1.0.5=h61918c1_1004 - importlib-metadata=8.0.0=pyha770c72_0 + - importlib-resources=6.4.0=pyhd8ed1ab_0 - importlib_metadata=8.0.0=hd8ed1ab_0 + - importlib_resources=6.4.0=pyhd8ed1ab_0 + - ipykernel=6.29.4=pyh57ce528_0 + - ipympl=0.9.4=pyhd8ed1ab_0 + - ipython=8.25.0=pyh707e725_0 + - ipython_genutils=0.2.0=pyhd8ed1ab_1 + - ipywidgets=8.1.3=pyhd8ed1ab_0 - isl=0.26=imath32_h2e86a7b_101 + - isoduration=20.11.0=pyhd8ed1ab_0 + - jedi=0.19.1=pyhd8ed1ab_0 + - jinja2=3.1.4=pyhd8ed1ab_0 + - jmol=14.32.9=h694c41f_0 + - json5=0.9.25=pyhd8ed1ab_0 + - jsonpointer=3.0.0=py311h6eed73b_0 + - jsonschema=4.22.0=pyhd8ed1ab_0 + - jsonschema-specifications=2023.12.1=pyhd8ed1ab_0 + - jsonschema-with-format-nongpl=4.22.0=pyhd8ed1ab_0 + - jupyter-jsmol=2022.1.0=pyhd8ed1ab_0 + - jupyter-lsp=2.2.5=pyhd8ed1ab_0 + - jupyter-sphinx=0.5.3=pyha770c72_4 + - jupyter_client=8.6.2=pyhd8ed1ab_0 + - jupyter_core=5.7.2=py311h6eed73b_0 + - jupyter_events=0.10.0=pyhd8ed1ab_0 + - jupyter_server=2.14.1=pyhd8ed1ab_0 + - jupyter_server_terminals=0.5.3=pyhd8ed1ab_0 + - jupyter_sphinx=0.5.3=hd8ed1ab_4 + - jupyterlab=4.2.2=pyhd8ed1ab_0 + - jupyterlab_pygments=0.3.0=pyhd8ed1ab_1 + - jupyterlab_server=2.27.2=pyhd8ed1ab_0 + - jupyterlab_widgets=3.0.11=pyhd8ed1ab_0 + - kiwisolver=1.4.5=py311h5fe6e05_1 - krb5=1.21.2=hb884880_0 - lcalc=2.0.5=h547a6ed_2 + - lcms2=2.16=ha2f27b4_0 - ld64=711=ha02d983_0 - ld64_osx-64=711=ha20a434_0 - lerc=4.0.0=hb486fe8_0 - libasprintf=0.22.5=h5ff76d1_2 - libasprintf-devel=0.22.5=h5ff76d1_2 - libatomic_ops=7.6.14=hb7f2c08_0 - - libblas=3.9.0=22_osx64_openblas + - libblas=3.9.0=20_osx64_openblas - libboost=1.85.0=h739af76_2 - libboost-devel=1.85.0=h2b186f8_2 - libboost-headers=1.85.0=h694c41f_2 - libbraiding=1.2=hf0c8a7f_0 - libbrial=1.2.12=h81e9653_3 - - libcblas=3.9.0=22_osx64_openblas + - libbrotlicommon=1.1.0=h0dc2134_1 + - libbrotlidec=1.1.0=h0dc2134_1 + - libbrotlienc=1.1.0=h0dc2134_1 + - libcblas=3.9.0=20_osx64_openblas - libclang-cpp16=16.0.6=default_h4c8afb6_8 - libcurl=8.8.0=hf9fcc65_0 - libcxx=17.0.6=h88467a6_0 @@ -108,17 +206,18 @@ dependencies: - libgfortran=5.0.0=13_2_0_h97931a8_3 - libgfortran-devel_osx-64=12.3.0=h0b6f5ec_3 - libgfortran5=13.2.0=h2873a65_3 + - libglib=2.80.2=h736d271_1 - libhomfly=1.02r6=h10d778d_1 - libhwloc=2.10.0=default_h456cccd_1001 - libiconv=1.17=hd75f5a5_2 - libintl=0.22.5=h5ff76d1_2 - libintl-devel=0.22.5=h5ff76d1_2 - libjpeg-turbo=3.0.0=h0dc2134_1 - - liblapack=3.9.0=22_osx64_openblas - - liblapacke=3.9.0=22_osx64_openblas + - liblapack=3.9.0=20_osx64_openblas + - liblapacke=3.9.0=20_osx64_openblas - libllvm16=16.0.6=hbedff68_3 - libnghttp2=1.58.0=h64cf6d3_1 - - libopenblas=0.3.27=openmp_hfef2a42_0 + - libopenblas=0.3.25=openmp_hfef2a42_0 - libpng=1.6.43=h92b6c6a_0 - libsodium=1.0.18=hbcb3906_1 - libsqlite=3.46.0=h1b8f9f3_0 @@ -128,6 +227,7 @@ dependencies: - libuv=1.48.0=h67532ce_0 - libwebp=1.4.0=hc207709_0 - libwebp-base=1.4.0=h10d778d_0 + - libxcb=1.16=h0dc2134_0 - libxml2=2.12.7=h3e169fe_1 - libzlib=1.3.1=h87427d6_1 - linbox=1.7.0=h7061c92_0 @@ -138,62 +238,185 @@ dependencies: - m4ri=20140914=hd82a5f3_1006 - m4rie=20150908=hc616cfc_1002 - make=4.3=h22f3db7_1 + - markupsafe=2.1.5=py311he705e18_0 - mathjax=3.2.2=h694c41f_0 + - matplotlib=3.8.4=py311h6eed73b_2 + - matplotlib-base=3.8.4=py311hff79762_2 + - matplotlib-inline=0.1.7=pyhd8ed1ab_0 - maxima=5.47.0=h2b27fa8_2 + - memory-allocator=0.1.3=py311h2725bcf_0 - metis=5.1.0=he965462_1007 + - mistune=3.0.2=pyhd8ed1ab_0 - mpc=1.3.1=h81bd1dd_0 - mpfi=1.5.4=h52b28e3_1001 - mpfr=4.2.1=h4f6b447_1 + - mpmath=1.3.0=pyhd8ed1ab_0 + - munkres=1.1.4=pyh9f0ad1d_0 - nauty=2.8.8=h10d778d_1 + - nbclient=0.10.0=pyhd8ed1ab_0 + - nbconvert=7.16.4=hd8ed1ab_1 + - nbconvert-core=7.16.4=pyhd8ed1ab_1 + - nbconvert-pandoc=7.16.4=hd8ed1ab_1 + - nbformat=5.10.4=pyhd8ed1ab_0 - ncurses=6.5=h5846eda_0 + - nest-asyncio=1.6.0=pyhd8ed1ab_0 + - networkx=3.2.1=pyhd8ed1ab_0 - ninja=1.12.1=h3c5361c_0 + - notebook=7.2.1=pyhd8ed1ab_0 + - notebook-shim=0.2.4=pyhd8ed1ab_0 - ntl=11.4.3=h0ab3c2f_1 - - openblas=0.3.27=openmp_h6794695_0 + - numpy=1.26.4=py311hc43a94b_0 + - openblas=0.3.25=openmp_h6794695_0 + - openjdk=22.0.1=h2d185b6_0 + - openjpeg=2.5.2=h7310d3a_0 - openssl=3.3.1=h87427d6_0 + - overrides=7.7.0=pyhd8ed1ab_0 - packaging=24.1=pyhd8ed1ab_0 - palp=2.20=hbcb3906_0 + - pandoc=3.2.1=h694c41f_0 + - pandocfilters=1.5.0=pyhd8ed1ab_0 + - pango=1.54.0=h880b76c_0 - pari=2.15.5=h7ba67ff_2_pthread - pari-elldata=0.0.20161017=0 - pari-galdata=0.0.20180411=0 - pari-galpol=0.0.20180625=0 - pari-seadata=0.0.20090618=0 - pari-seadata-small=0.0.20090618=0 + - parso=0.8.4=pyhd8ed1ab_0 - patch=2.7.6=hbcf498f_1002 + - pathspec=0.12.1=pyhd8ed1ab_0 + - pcre2=10.44=h7634a1b_0 + - pep517=0.13.0=pyhd8ed1ab_0 - perl=5.32.1=7_h10d778d_perl5 + - pexpect=4.9.0=pyhd8ed1ab_0 + - pickleshare=0.7.5=py_1003 + - pillow=10.3.0=py311h2755ac0_1 + - pip=24.0=pyhd8ed1ab_0 + - pixman=0.43.4=h73e2aa4_0 - pkg-config=0.29.2=ha3d46e9_1008 + - pkgconfig=1.5.5=pyhd8ed1ab_4 + - pkgutil-resolve-name=1.3.10=pyhd8ed1ab_1 - planarity=3.0.2.0=h10d778d_0 - platformdirs=4.2.2=pyhd8ed1ab_0 - pluggy=1.5.0=pyhd8ed1ab_0 + - ply=3.11=pyhd8ed1ab_2 - ppl=1.2=ha60d53e_1006 - - primecount=7.13=hf455435_0 - - primesieve=12.1=h73e2aa4_0 + - pplpy=0.8.9=py311h922ec50_1 + - primecount=7.6=ha894c9a_0 + - primecountpy=0.1.0=py311h5fe6e05_4 + - primesieve=11.0=hf0c8a7f_0 + - prometheus_client=0.20.0=pyhd8ed1ab_0 + - prompt-toolkit=3.0.47=pyha770c72_0 + - prompt_toolkit=3.0.47=hd8ed1ab_0 + - psutil=6.0.0=py311h72ae277_0 + - pthread-stubs=0.4=hc929b4f_1001 + - ptyprocess=0.7.0=pyhd3deb0d_0 + - pure_eval=0.2.2=pyhd8ed1ab_0 + - py=1.11.0=pyh6c4a22f_0 + - pybind11=2.12.0=py311h1d816ee_0 + - pybind11-global=2.12.0=py311h1d816ee_0 + - pycparser=2.22=pyhd8ed1ab_0 + - pygments=2.18.0=pyhd8ed1ab_0 + - pyobjc-core=10.3.1=py311h9d23797_0 + - pyobjc-framework-cocoa=10.3.1=py311h9d23797_0 + - pyparsing=3.1.2=pyhd8ed1ab_0 - pyproject-api=1.7.1=pyhd8ed1ab_0 + - pyrsistent=0.20.0=py311he705e18_0 + - pysocks=1.7.1=pyha2e5f31_6 - python=3.11.9=h657bba9_0_cpython + - python-build=1.2.1=pyhd8ed1ab_0 + - python-dateutil=2.9.0=pyhd8ed1ab_0 + - python-fastjsonschema=2.20.0=pyhd8ed1ab_0 + - python-json-logger=2.0.7=pyhd8ed1ab_0 + - python-lrcalc=2.1=py311hdd0406b_6 + - python-tzdata=2024.1=pyhd8ed1ab_0 - python_abi=3.11=4_cp311 + - pythran=0.15.0=py311ha853786_1 + - pytz=2024.1=pyhd8ed1ab_0 + - pytz-deprecation-shim=0.1.0.post0=py311h6eed73b_4 + - pyyaml=6.0.1=py311h2725bcf_1 + - pyzmq=26.0.3=py311h89e2aaa_0 - qd=2.3.22=h2beb688_1004 - qhull=2020.2=h940c156_2 + - r-base=4.3.3=h4648a1f_3 + - r-lattice=0.22_6=r43hb2c329c_0 - readline=8.2=h9e318b2_1 + - referencing=0.35.1=pyhd8ed1ab_0 + - requests=2.32.3=pyhd8ed1ab_0 + - rfc3339-validator=0.1.4=pyhd8ed1ab_0 + - rfc3986-validator=0.1.1=pyh9f0ad1d_0 - rhash=1.4.4=h0dc2134_0 + - rpds-py=0.18.1=py311h295b1db_0 + - rpy2=3.5.11=py311r43h4a70a88_3 - rw=0.9=h10d778d_2 + - sagemath-db-combinatorial-designs=20140630=1 + - sagemath-db-elliptic-curves=0.8.1=hecc5488_0 + - sagemath-db-graphs=20210214=hd8ed1ab_0 + - sagemath-db-polytopes=20170220=1 + - sagetex=3.6.1=pyhd8ed1ab_0 + - scipy=1.11.4=py311he0bea55_0 + - send2trash=1.8.3=pyh31c8845_0 + - setuptools=70.1.1=pyhd8ed1ab_0 + - setuptools-scm=8.1.0=pyhd8ed1ab_0 + - setuptools_scm=8.1.0=hd8ed1ab_0 - sigtool=0.1.3=h88f4db0_0 + - simplegeneric=0.8.1=py_1 - singular=4.3.2.p8=h0d51a9f_1 + - six=1.16.0=pyh6c4a22f_0 + - sniffio=1.3.1=pyhd8ed1ab_0 + - snowballstemmer=2.2.0=pyhd8ed1ab_0 + - soupsieve=2.5=pyhd8ed1ab_1 + - sphinx=7.3.7=pyhd8ed1ab_0 + - sphinx-basic-ng=1.0.0b2=pyhd8ed1ab_1 + - sphinx-copybutton=0.5.2=pyhd8ed1ab_0 + - sphinxcontrib-applehelp=1.0.8=pyhd8ed1ab_0 + - sphinxcontrib-devhelp=1.0.6=pyhd8ed1ab_0 + - sphinxcontrib-htmlhelp=2.0.5=pyhd8ed1ab_0 + - sphinxcontrib-jsmath=1.0.1=pyhd8ed1ab_0 + - sphinxcontrib-qthelp=1.0.7=pyhd8ed1ab_0 + - sphinxcontrib-serializinghtml=1.1.10=pyhd8ed1ab_0 + - sphinxcontrib-websupport=1.2.7=pyhd8ed1ab_0 - sqlite=3.46.0=h28673e1_0 + - stack_data=0.6.2=pyhd8ed1ab_0 - suitesparse=7.7.0=hd2b2131_1 - symmetrica=3.0.1=hf0c8a7f_0 - sympow=2.023.6=h115ba6a_3 + - sympy=1.12.1=pypyh2585a3b_103 - tachyon=0.99b6=h3a1d103_1002 - tapi=1100.0.11=h9ce4665_0 - tar=1.34=hcb2f6ea_1 - tbb=2021.12.0=h3c5361c_1 + - terminado=0.18.1=pyh31c8845_0 - texinfo=7.0=pl5321hc47821c_0 + - three.js=122=hd8ed1ab_2 + - threejs-sage=122=hd8ed1ab_2 + - tinycss2=1.3.0=pyhd8ed1ab_0 - tk=8.6.13=h1abcd95_1 + - tktable=2.10=hba9d6f1_6 - tomli=2.0.1=pyhd8ed1ab_0 + - tornado=6.4.1=py311h72ae277_0 - tox=4.15.1=pyhd8ed1ab_0 + - traitlets=5.14.3=pyhd8ed1ab_0 + - trove-classifiers=2024.5.22=pyhd8ed1ab_0 + - types-python-dateutil=2.9.0.20240316=pyhd8ed1ab_0 - typing-extensions=4.12.2=hd8ed1ab_0 - typing_extensions=4.12.2=pyha770c72_0 + - typing_utils=0.1.0=pyhd8ed1ab_0 - tzdata=2024a=h0c530f3_0 + - tzlocal=5.2=py311h6eed73b_0 + - uri-template=1.3.0=pyhd8ed1ab_0 + - urllib3=2.2.2=pyhd8ed1ab_0 - virtualenv=20.26.3=pyhd8ed1ab_0 + - wcwidth=0.2.13=pyhd8ed1ab_0 + - webcolors=24.6.0=pyhd8ed1ab_0 + - webencodings=0.5.1=pyhd8ed1ab_2 + - websocket-client=1.8.0=pyhd8ed1ab_0 + - wheel=0.43.0=pyhd8ed1ab_1 + - widgetsnbextension=4.0.11=pyhd8ed1ab_0 + - xorg-libxau=1.0.11=h0dc2134_0 + - xorg-libxdmcp=1.1.3=h35c211d_0 - xz=5.2.6=h775f41a_0 + - yaml=0.2.5=h0d85af4_2 - zeromq=4.3.5=hde137ed_4 - zipp=3.19.2=pyhd8ed1ab_0 - zlib=1.3.1=h87427d6_1 diff --git a/environment-3.11-macos.yml b/environment-3.11-macos.yml index 81ffaf75561..8ae6a449026 100644 --- a/environment-3.11-macos.yml +++ b/environment-3.11-macos.yml @@ -1,29 +1,54 @@ +name: sage # Generated by conda-lock. # platform: osx-arm64 -# input_hash: 89cd404032a652917b0945cf0be063b4b555387589d82447a4ee1f01f3f5ce58 +# input_hash: fd2f5edaba32b4c1f22d499071de74bde7eb804a27ac64e89ee82df0d733a829 channels: - conda-forge dependencies: + - _r-mutex=1.0.1=anacondar_1 + - alabaster=0.7.16=pyhd8ed1ab_0 + - anyio=4.4.0=pyhd8ed1ab_0 - appdirs=1.4.4=pyh9f0ad1d_0 + - appnope=0.1.4=pyhd8ed1ab_0 + - argon2-cffi=23.1.0=pyhd8ed1ab_0 + - argon2-cffi-bindings=21.2.0=py311heffc1b2_4 - arpack=3.9.1=nompi_h593882a_101 + - arrow=1.3.0=pyhd8ed1ab_0 + - asttokens=2.4.1=pyhd8ed1ab_0 + - async-lru=2.0.4=pyhd8ed1ab_0 + - attrs=23.2.0=pyh71513ae_0 - autoconf=2.71=pl5321hcd07c0c_1 - automake=1.16.5=pl5321hce30654_0 + - babel=2.14.0=pyhd8ed1ab_0 - bc=1.07.1=h3422bc3_0 - bdw-gc=8.0.6=hc021e02_0 - - blas=2.122=openblas - - blas-devel=3.9.0=22_osxarm64_openblas + - beautifulsoup4=4.12.3=pyha770c72_0 + - beniget=0.4.1=pyhd8ed1ab_0 + - blas=2.120=openblas + - blas-devel=3.9.0=20_osxarm64_openblas + - bleach=6.1.0=pyhd8ed1ab_0 - boost-cpp=1.85.0=hca5e981_2 - brial=1.2.12=pyh694c41f_3 + - brotli=1.1.0=hb547adb_1 + - brotli-bin=1.1.0=hb547adb_1 + - brotli-python=1.1.0=py311ha891d26_1 + - bwidget=1.9.14=hce30654_1 - bzip2=1.0.8=h93a5062_5 - c-ares=1.28.1=h93a5062_0 - c-compiler=1.7.0=h6aa9301_1 - ca-certificates=2024.6.2=hf0a4a13_0 + - cached-property=1.5.2=hd8ed1ab_1 + - cached_property=1.5.2=pyha770c72_1 - cachetools=5.3.3=pyhd8ed1ab_0 + - cairo=1.18.0=hc6c324b_2 - cctools=986=h4faf515_0 - cctools_osx-arm64=986=h62378fb_0 - cddlib=1!0.94m=h6d7a090_0 + - certifi=2024.6.2=pyhd8ed1ab_0 + - cffi=1.16.0=py311h4a08483_0 - chardet=5.2.0=py311h267d04e_1 + - charset-normalizer=3.3.2=pyhd8ed1ab_0 - clang=16.0.6=default_h095aff0_8 - clang-16=16.0.6=default_hb63da90_8 - clang_impl_osx-arm64=16.0.6=hc421ffc_16 @@ -34,18 +59,39 @@ dependencies: - cliquer=1.22=h93a5062_1 - cmake=3.29.6=had79d8f_0 - colorama=0.4.6=pyhd8ed1ab_0 + - colorlog=6.8.2=py311h267d04e_0 + - comm=0.2.2=pyhd8ed1ab_0 - compiler-rt=16.0.6=h3808999_2 - compiler-rt_osx-arm64=16.0.6=h3808999_2 - compilers=1.7.0=hce30654_1 + - contourpy=1.2.1=py311hcc98501_0 + - conway-polynomials=0.9=pyhd8ed1ab_0 + - cppy=1.2.1=pyhd8ed1ab_0 - curl=8.8.0=h653d890_0 + - cvxopt=1.3.2=py311h77cf4c7_2 - cxx-compiler=1.7.0=h2ffa867_1 + - cycler=0.12.1=pyhd8ed1ab_0 + - cypari2=2.1.5=py311h2c49a9d_0 + - cysignals=1.11.2=py311he42fc87_3 + - cython=3.0.10=py311h92babd0_0 + - debugpy=1.8.1=py311h92babd0_0 + - decorator=5.1.1=pyhd8ed1ab_0 + - defusedxml=0.7.1=pyhd8ed1ab_0 - distlib=0.3.8=pyhd8ed1ab_0 + - docutils=0.21.2=pyhd8ed1ab_0 + - dsdp=5.8=h9397a75_1203 - ecl=23.9.9=h1d9728a_0 - eclib=20231212=h7f07de4_0 - ecm=7.0.5=h41d338b_0 + - editables=0.5=pyhd8ed1ab_0 + - entrypoints=0.4=pyhd8ed1ab_0 + - exceptiongroup=1.2.0=pyhd8ed1ab_2 + - executing=2.0.1=pyhd8ed1ab_0 - expat=2.6.2=hebf3989_0 - fflas-ffpack=2.5.0=h4bc3318_0 + - fftw=3.3.10=nompi_h6637ab6_110 - filelock=3.15.4=pyhd8ed1ab_0 + - flit-core=3.9.0=pyhd8ed1ab_1 - 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 @@ -53,11 +99,17 @@ dependencies: - fontconfig=2.14.2=h82840c6_0 - fonts-conda-ecosystem=1=0 - fonts-conda-forge=1=0 + - fonttools=4.53.0=py311hd3f4193_0 - fortran-compiler=1.7.0=hafb19e3_1 - fplll=5.4.5=hb7d509d_0 + - fpylll=0.6.1=py311h341b96b_0 + - fqdn=1.5.1=pyhd8ed1ab_0 - freetype=2.12.1=hadb7bae_2 + - fribidi=1.0.10=h27ca646_0 + - furo=2024.5.6=pyhd8ed1ab_0 - gap-core=4.12.2=he8f4e70_3 - gap-defaults=4.12.2=hce30654_3 + - gast=0.5.4=pyhd8ed1ab_0 - gengetopt=2.23=hbdafb3b_0 - gettext=0.22.5=h8fbad5d_2 - gettext-tools=0.22.5=h8fbad5d_2 @@ -71,28 +123,74 @@ dependencies: - givaro=4.2.0=h018886a_0 - glpk=5.0=h6d7a090_0 - gmp=6.3.0=h7bae524_2 + - gmpy2=2.1.5=py311h1e33d93_1 + - graphite2=1.3.13=hebf3989_1003 - gsl=2.7=h6e638da_0 + - h11=0.14.0=pyhd8ed1ab_0 + - h2=4.1.0=pyhd8ed1ab_0 + - harfbuzz=8.5.0=h1836168_0 + - hatchling=1.25.0=pyhd8ed1ab_0 + - hpack=4.0.0=pyh9f0ad1d_0 + - httpcore=1.0.5=pyhd8ed1ab_0 + - httpx=0.27.0=pyhd8ed1ab_0 + - hyperframe=6.0.1=pyhd8ed1ab_0 - icu=73.2=hc8870d7_0 + - idna=3.7=pyhd8ed1ab_0 - igraph=0.10.12=h762ac30_1 + - imagesize=1.4.1=pyhd8ed1ab_0 - iml=1.0.5=hd73f12c_1004 - importlib-metadata=8.0.0=pyha770c72_0 + - importlib-resources=6.4.0=pyhd8ed1ab_0 - importlib_metadata=8.0.0=hd8ed1ab_0 + - importlib_resources=6.4.0=pyhd8ed1ab_0 + - ipykernel=6.29.4=pyh57ce528_0 + - ipympl=0.9.4=pyhd8ed1ab_0 + - ipython=8.25.0=pyh707e725_0 + - ipython_genutils=0.2.0=pyhd8ed1ab_1 + - ipywidgets=8.1.3=pyhd8ed1ab_0 - isl=0.26=imath32_h347afa1_101 + - isoduration=20.11.0=pyhd8ed1ab_0 + - jedi=0.19.1=pyhd8ed1ab_0 + - jinja2=3.1.4=pyhd8ed1ab_0 + - jmol=14.32.10=hce30654_0 + - json5=0.9.25=pyhd8ed1ab_0 + - jsonpointer=3.0.0=py311h267d04e_0 + - jsonschema=4.22.0=pyhd8ed1ab_0 + - jsonschema-specifications=2023.12.1=pyhd8ed1ab_0 + - jsonschema-with-format-nongpl=4.22.0=pyhd8ed1ab_0 + - jupyter-jsmol=2022.1.0=pyhd8ed1ab_0 + - jupyter-lsp=2.2.5=pyhd8ed1ab_0 + - jupyter-sphinx=0.5.3=pyha770c72_4 + - jupyter_client=8.6.2=pyhd8ed1ab_0 + - jupyter_core=5.7.2=py311h267d04e_0 + - jupyter_events=0.10.0=pyhd8ed1ab_0 + - jupyter_server=2.14.1=pyhd8ed1ab_0 + - jupyter_server_terminals=0.5.3=pyhd8ed1ab_0 + - jupyter_sphinx=0.5.3=hd8ed1ab_4 + - jupyterlab=4.2.2=pyhd8ed1ab_0 + - jupyterlab_pygments=0.3.0=pyhd8ed1ab_1 + - jupyterlab_server=2.27.2=pyhd8ed1ab_0 + - jupyterlab_widgets=3.0.11=pyhd8ed1ab_0 + - kiwisolver=1.4.5=py311he4fd1f5_1 - krb5=1.21.2=h92f50d5_0 - lcalc=2.0.5=h4a402bc_2 + - lcms2=2.16=ha0e7c42_0 - ld64=711=h634c8be_0 - ld64_osx-arm64=711=ha4bd21c_0 - lerc=4.0.0=h9a09cb3_0 - libasprintf=0.22.5=h8fbad5d_2 - libasprintf-devel=0.22.5=h8fbad5d_2 - libatomic_ops=7.6.14=h1a8c8d9_0 - - libblas=3.9.0=22_osxarm64_openblas + - libblas=3.9.0=20_osxarm64_openblas - libboost=1.85.0=h17eb2be_2 - libboost-devel=1.85.0=hf450f58_2 - libboost-headers=1.85.0=hce30654_2 - libbraiding=1.2=hb7217d7_0 - libbrial=1.2.12=h56a29cd_3 - - libcblas=3.9.0=22_osxarm64_openblas + - libbrotlicommon=1.1.0=hb547adb_1 + - libbrotlidec=1.1.0=hb547adb_1 + - libbrotlienc=1.1.0=hb547adb_1 + - libcblas=3.9.0=20_osxarm64_openblas - libclang-cpp16=16.0.6=default_hb63da90_8 - libcurl=8.8.0=h7b6f9a7_0 - libcxx=17.0.6=h5f092b4_0 @@ -115,11 +213,11 @@ dependencies: - libintl=0.22.5=h8fbad5d_2 - libintl-devel=0.22.5=h8fbad5d_2 - libjpeg-turbo=3.0.0=hb547adb_1 - - liblapack=3.9.0=22_osxarm64_openblas - - liblapacke=3.9.0=22_osxarm64_openblas + - liblapack=3.9.0=20_osxarm64_openblas + - liblapacke=3.9.0=20_osxarm64_openblas - libllvm16=16.0.6=haab561b_3 - libnghttp2=1.58.0=ha4dd798_1 - - libopenblas=0.3.27=openmp_h6c19121_0 + - libopenblas=0.3.25=openmp_h6c19121_0 - libpng=1.6.43=h091b4b1_0 - libsodium=1.0.18=h27ca646_1 - libsqlite=3.46.0=hfb93653_0 @@ -129,6 +227,7 @@ dependencies: - libuv=1.48.0=h93a5062_0 - libwebp=1.4.0=h54798ee_0 - libwebp-base=1.4.0=h93a5062_0 + - libxcb=1.16=hf2054a2_0 - libxml2=2.12.7=ha661575_1 - libzlib=1.3.1=hfb2fe0b_1 - linbox=1.7.0=h3afee3a_0 @@ -139,63 +238,185 @@ dependencies: - m4ri=20140914=hc97c1ff_1006 - m4rie=20150908=h22b9e9d_1002 - make=4.3=he57ea6c_1 + - markupsafe=2.1.5=py311h05b510d_0 - mathjax=3.2.2=hce30654_0 + - matplotlib=3.8.4=py311ha1ab1f8_2 + - matplotlib-base=3.8.4=py311h000fb6e_2 + - matplotlib-inline=0.1.7=pyhd8ed1ab_0 - maxima=5.47.0=h2bbcd85_2 + - memory-allocator=0.1.3=py311heffc1b2_0 - metis=5.1.0=h13dd4ca_1007 + - mistune=3.0.2=pyhd8ed1ab_0 - mpc=1.3.1=h91ba8db_0 - mpfi=1.5.4=hbde5f5b_1001 - mpfr=4.2.1=h41d338b_1 + - mpmath=1.3.0=pyhd8ed1ab_0 + - munkres=1.1.4=pyh9f0ad1d_0 - nauty=2.8.8=h93a5062_1 + - nbclient=0.10.0=pyhd8ed1ab_0 + - nbconvert=7.16.4=hd8ed1ab_1 + - nbconvert-core=7.16.4=pyhd8ed1ab_1 + - nbconvert-pandoc=7.16.4=hd8ed1ab_1 + - nbformat=5.10.4=pyhd8ed1ab_0 - ncurses=6.5=hb89a1cb_0 + - nest-asyncio=1.6.0=pyhd8ed1ab_0 + - networkx=3.2.1=pyhd8ed1ab_0 - ninja=1.12.1=h420ef59_0 + - notebook=7.2.1=pyhd8ed1ab_0 + - notebook-shim=0.2.4=pyhd8ed1ab_0 - ntl=11.4.3=hbb3f309_1 - - openblas=0.3.27=openmp_h55c453e_0 + - numpy=1.26.4=py311h7125741_0 + - openblas=0.3.25=openmp_h55c453e_0 + - openjdk=22.0.1=hbeb2e11_0 + - openjpeg=2.5.2=h9f1df11_0 - openssl=3.3.1=hfb2fe0b_0 + - overrides=7.7.0=pyhd8ed1ab_0 - packaging=24.1=pyhd8ed1ab_0 - palp=2.20=h27ca646_0 + - pandoc=3.2.1=hce30654_0 + - pandocfilters=1.5.0=pyhd8ed1ab_0 + - pango=1.54.0=h5cb9fbc_0 - pari=2.15.5=h4f2304c_2_pthread - pari-elldata=0.0.20161017=0 - pari-galdata=0.0.20180411=0 - pari-galpol=0.0.20180625=0 - pari-seadata=0.0.20090618=0 - pari-seadata-small=0.0.20090618=0 + - parso=0.8.4=pyhd8ed1ab_0 - patch=2.7.6=h27ca646_1002 + - pathspec=0.12.1=pyhd8ed1ab_0 - pcre2=10.44=h297a79d_0 + - pep517=0.13.0=pyhd8ed1ab_0 - perl=5.32.1=7_h4614cfb_perl5 + - pexpect=4.9.0=pyhd8ed1ab_0 + - pickleshare=0.7.5=py_1003 + - pillow=10.3.0=py311hd7951ec_1 + - pip=24.0=pyhd8ed1ab_0 + - pixman=0.43.4=hebf3989_0 - pkg-config=0.29.2=hab62308_1008 + - pkgconfig=1.5.5=pyhd8ed1ab_4 + - pkgutil-resolve-name=1.3.10=pyhd8ed1ab_1 - planarity=3.0.2.0=h93a5062_0 - platformdirs=4.2.2=pyhd8ed1ab_0 - pluggy=1.5.0=pyhd8ed1ab_0 + - ply=3.11=pyhd8ed1ab_2 - ppl=1.2=h8b147cf_1006 - - primecount=7.13=ha9cb33e_0 - - primesieve=12.1=hebf3989_0 + - pplpy=0.8.9=py311h3d77d83_1 + - primecount=7.6=hb6e4faa_0 + - primecountpy=0.1.0=py311he4fd1f5_4 + - primesieve=11.0=hb7217d7_0 + - prometheus_client=0.20.0=pyhd8ed1ab_0 + - prompt-toolkit=3.0.47=pyha770c72_0 + - prompt_toolkit=3.0.47=hd8ed1ab_0 + - psutil=6.0.0=py311hd3f4193_0 + - pthread-stubs=0.4=h27ca646_1001 + - ptyprocess=0.7.0=pyhd3deb0d_0 + - pure_eval=0.2.2=pyhd8ed1ab_0 + - py=1.11.0=pyh6c4a22f_0 + - pybind11=2.12.0=py311hcc98501_0 + - pybind11-global=2.12.0=py311hcc98501_0 + - pycparser=2.22=pyhd8ed1ab_0 + - pygments=2.18.0=pyhd8ed1ab_0 + - pyobjc-core=10.3.1=py311h5f135c3_0 + - pyobjc-framework-cocoa=10.3.1=py311h5f135c3_0 + - pyparsing=3.1.2=pyhd8ed1ab_0 - pyproject-api=1.7.1=pyhd8ed1ab_0 + - pyrsistent=0.20.0=py311h05b510d_0 + - pysocks=1.7.1=pyha2e5f31_6 - python=3.11.9=h932a869_0_cpython + - python-build=1.2.1=pyhd8ed1ab_0 + - python-dateutil=2.9.0=pyhd8ed1ab_0 + - python-fastjsonschema=2.20.0=pyhd8ed1ab_0 + - python-json-logger=2.0.7=pyhd8ed1ab_0 + - python-lrcalc=2.1=py311h92babd0_6 + - python-tzdata=2024.1=pyhd8ed1ab_0 - python_abi=3.11=4_cp311 + - pythran=0.15.0=py311hceb3b21_1 + - pytz=2024.1=pyhd8ed1ab_0 + - pytz-deprecation-shim=0.1.0.post0=py311h267d04e_4 + - pyyaml=6.0.1=py311heffc1b2_1 + - pyzmq=26.0.3=py311h9bed540_0 - qd=2.3.22=hbec66e7_1004 - qhull=2020.2=hc021e02_2 + - r-base=4.3.3=h8112bfe_3 + - r-lattice=0.22_6=r43hd2d937b_0 - readline=8.2=h92ec313_1 + - referencing=0.35.1=pyhd8ed1ab_0 + - requests=2.32.3=pyhd8ed1ab_0 + - rfc3339-validator=0.1.4=pyhd8ed1ab_0 + - rfc3986-validator=0.1.1=pyh9f0ad1d_0 - rhash=1.4.4=hb547adb_0 + - rpds-py=0.18.1=py311h98c6a39_0 + - rpy2=3.5.11=py311r43hb49d859_3 - rw=0.9=h93a5062_2 + - sagemath-db-combinatorial-designs=20140630=1 + - sagemath-db-elliptic-curves=0.8.1=hecc5488_0 + - sagemath-db-graphs=20210214=hd8ed1ab_0 + - sagemath-db-polytopes=20170220=1 + - sagetex=3.6.1=pyhd8ed1ab_0 + - scipy=1.11.4=py311h2b215a9_0 + - send2trash=1.8.3=pyh31c8845_0 + - setuptools=70.1.1=pyhd8ed1ab_0 + - setuptools-scm=8.1.0=pyhd8ed1ab_0 + - setuptools_scm=8.1.0=hd8ed1ab_0 - sigtool=0.1.3=h44b9a77_0 + - simplegeneric=0.8.1=py_1 - singular=4.3.2.p8=hb460b52_1 + - six=1.16.0=pyh6c4a22f_0 + - sniffio=1.3.1=pyhd8ed1ab_0 + - snowballstemmer=2.2.0=pyhd8ed1ab_0 + - soupsieve=2.5=pyhd8ed1ab_1 + - sphinx=7.3.7=pyhd8ed1ab_0 + - sphinx-basic-ng=1.0.0b2=pyhd8ed1ab_1 + - sphinx-copybutton=0.5.2=pyhd8ed1ab_0 + - sphinxcontrib-applehelp=1.0.8=pyhd8ed1ab_0 + - sphinxcontrib-devhelp=1.0.6=pyhd8ed1ab_0 + - sphinxcontrib-htmlhelp=2.0.5=pyhd8ed1ab_0 + - sphinxcontrib-jsmath=1.0.1=pyhd8ed1ab_0 + - sphinxcontrib-qthelp=1.0.7=pyhd8ed1ab_0 + - sphinxcontrib-serializinghtml=1.1.10=pyhd8ed1ab_0 + - sphinxcontrib-websupport=1.2.7=pyhd8ed1ab_0 - sqlite=3.46.0=h5838104_0 + - stack_data=0.6.2=pyhd8ed1ab_0 - suitesparse=7.7.0=hf6fcff2_1 - symmetrica=3.0.1=hb7217d7_0 - sympow=2.023.6=hb0babe8_3 + - sympy=1.12.1=pypyh2585a3b_103 - tachyon=0.99b6=hb8a568e_1002 - tapi=1100.0.11=he4954df_0 - tar=1.34=h7cb298e_1 - tbb=2021.12.0=h420ef59_1 + - terminado=0.18.1=pyh31c8845_0 - texinfo=7.0=pl5321h9ea1dce_0 + - three.js=122=hd8ed1ab_2 + - threejs-sage=122=hd8ed1ab_2 + - tinycss2=1.3.0=pyhd8ed1ab_0 - tk=8.6.13=h5083fa2_1 + - tktable=2.10=h1e387b8_6 - tomli=2.0.1=pyhd8ed1ab_0 + - tornado=6.4.1=py311hd3f4193_0 - tox=4.15.1=pyhd8ed1ab_0 + - traitlets=5.14.3=pyhd8ed1ab_0 + - trove-classifiers=2024.5.22=pyhd8ed1ab_0 + - types-python-dateutil=2.9.0.20240316=pyhd8ed1ab_0 - typing-extensions=4.12.2=hd8ed1ab_0 - typing_extensions=4.12.2=pyha770c72_0 + - typing_utils=0.1.0=pyhd8ed1ab_0 - tzdata=2024a=h0c530f3_0 + - tzlocal=5.2=py311h267d04e_0 + - uri-template=1.3.0=pyhd8ed1ab_0 + - urllib3=2.2.2=pyhd8ed1ab_0 - virtualenv=20.26.3=pyhd8ed1ab_0 + - wcwidth=0.2.13=pyhd8ed1ab_0 + - webcolors=24.6.0=pyhd8ed1ab_0 + - webencodings=0.5.1=pyhd8ed1ab_2 + - websocket-client=1.8.0=pyhd8ed1ab_0 + - wheel=0.43.0=pyhd8ed1ab_1 + - widgetsnbextension=4.0.11=pyhd8ed1ab_0 + - xorg-libxau=1.0.11=hb547adb_0 + - xorg-libxdmcp=1.1.3=h27ca646_0 - xz=5.2.6=h57fd34a_0 + - yaml=0.2.5=h3422bc3_2 - zeromq=4.3.5=hcc0f68c_4 - zipp=3.19.2=pyhd8ed1ab_0 - zlib=1.3.1=hfb2fe0b_1 diff --git a/environment-3.9-linux-aarch64.yml b/environment-3.9-linux-aarch64.yml index e5ab529364a..97c6b302ce6 100644 --- a/environment-3.9-linux-aarch64.yml +++ b/environment-3.9-linux-aarch64.yml @@ -1,45 +1,92 @@ +name: sage # Generated by conda-lock. # platform: linux-aarch64 -# input_hash: aac498141a64c4d1a68eece8322bfc4de4ab998d89d4c4c60d240ccd07ab5dd7 +# input_hash: ff1dc47da14265a884b6d8aae2cde457456f547babfa735ad39ad330bb83aa6a channels: - conda-forge dependencies: - _openmp_mutex=4.5=2_kmp_llvm + - _r-mutex=1.0.1=anacondar_1 - _sysroot_linux-aarch64_curr_repodata_hack=4=h57d6b7b_14 + - alabaster=0.7.16=pyhd8ed1ab_0 + - alsa-lib=1.2.11=h31becfc_1 + - anyio=4.4.0=pyhd8ed1ab_0 - appdirs=1.4.4=pyh9f0ad1d_0 + - appnope=0.1.4=pyhd8ed1ab_0 + - argon2-cffi=23.1.0=pyhd8ed1ab_0 + - argon2-cffi-bindings=21.2.0=py39h898b7ef_4 - arpack=3.9.1=nompi_hd363cd0_101 + - arrow=1.3.0=pyhd8ed1ab_0 + - asttokens=2.4.1=pyhd8ed1ab_0 + - async-lru=2.0.4=pyhd8ed1ab_0 + - attrs=23.2.0=pyh71513ae_0 - autoconf=2.71=pl5321h2148fe1_1 - automake=1.16.5=pl5321h8af1aa0_0 + - babel=2.14.0=pyhd8ed1ab_0 - bc=1.07.1=hf897c2e_0 - bdw-gc=8.0.6=hd62202e_0 + - beautifulsoup4=4.12.3=pyha770c72_0 + - beniget=0.4.1=pyhd8ed1ab_0 - binutils=2.40=hf1166c9_7 - binutils_impl_linux-aarch64=2.40=hf54a868_7 - binutils_linux-aarch64=2.40=h1f91aba_9 - - blas=2.122=openblas - - blas-devel=3.9.0=22_linuxaarch64_openblas + - blas=2.120=openblas + - blas-devel=3.9.0=20_linuxaarch64_openblas + - bleach=6.1.0=pyhd8ed1ab_0 - boost-cpp=1.85.0=ha990451_2 - brial=1.2.12=pyh694c41f_3 + - brotli=1.1.0=h31becfc_1 + - brotli-bin=1.1.0=h31becfc_1 + - brotli-python=1.1.0=py39h387a81e_1 + - bwidget=1.9.14=h8af1aa0_1 - bzip2=1.0.8=h31becfc_5 - c-ares=1.28.1=h31becfc_0 - c-compiler=1.7.0=h31becfc_1 - ca-certificates=2024.6.2=hcefe29a_0 + - cached-property=1.5.2=hd8ed1ab_1 + - cached_property=1.5.2=pyha770c72_1 - cachetools=5.3.3=pyhd8ed1ab_0 + - cairo=1.18.0=h5c54ea9_2 - cddlib=1!0.94m=h719063d_0 + - certifi=2024.6.2=pyhd8ed1ab_0 + - cffi=1.16.0=py39hdf53b9e_0 - chardet=5.2.0=py39ha65689a_1 + - charset-normalizer=3.3.2=pyhd8ed1ab_0 - cliquer=1.22=h31becfc_1 - cmake=3.29.6=h7042e5d_0 - colorama=0.4.6=pyhd8ed1ab_0 + - colorlog=6.8.2=py39h4420490_0 + - comm=0.2.2=pyhd8ed1ab_0 - compilers=1.7.0=h8af1aa0_1 + - contourpy=1.2.1=py39hd16970a_0 + - conway-polynomials=0.9=pyhd8ed1ab_0 + - cppy=1.2.1=pyhd8ed1ab_0 - curl=8.8.0=h7daf2e0_0 + - cvxopt=1.3.2=py39h093dae0_2 - cxx-compiler=1.7.0=h2a328a1_1 + - cycler=0.12.1=pyhd8ed1ab_0 + - cypari2=2.1.5=py39h532d932_0 + - cysignals=1.11.2=py39hfa81392_3 + - cython=3.0.10=py39h387a81e_0 + - debugpy=1.8.1=py39h387a81e_0 + - decorator=5.1.1=pyhd8ed1ab_0 + - defusedxml=0.7.1=pyhd8ed1ab_0 - distlib=0.3.8=pyhd8ed1ab_0 + - docutils=0.21.2=pyhd8ed1ab_0 + - dsdp=5.8=hb12102e_1203 - ecl=23.9.9=h6475f26_0 - eclib=20231212=he26bab5_0 - ecm=7.0.5=ha2d0fc4_0 + - editables=0.5=pyhd8ed1ab_0 + - entrypoints=0.4=pyhd8ed1ab_0 + - exceptiongroup=1.2.0=pyhd8ed1ab_2 + - executing=2.0.1=pyhd8ed1ab_0 - expat=2.6.2=h2f0025b_0 - fflas-ffpack=2.5.0=h503e619_0 + - fftw=3.3.10=nompi_h020dacd_110 - filelock=3.15.4=pyhd8ed1ab_0 + - flit-core=3.9.0=pyhd8ed1ab_1 - 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 @@ -47,11 +94,17 @@ dependencies: - fontconfig=2.14.2=ha9a116f_0 - fonts-conda-ecosystem=1=0 - fonts-conda-forge=1=0 + - fonttools=4.53.0=py39he257ee7_0 - fortran-compiler=1.7.0=h7048d53_1 - fplll=5.4.5=hb3a790e_0 + - fpylll=0.6.1=py39h97065f7_0 + - fqdn=1.5.1=pyhd8ed1ab_0 - freetype=2.12.1=hf0a5ef3_2 + - fribidi=1.0.10=hb9de7d4_0 + - furo=2024.5.6=pyhd8ed1ab_0 - gap-core=4.12.2=h597289e_3 - gap-defaults=4.12.2=h8af1aa0_3 + - gast=0.5.4=pyhd8ed1ab_0 - gcc=12.3.0=hdb0cc85_13 - gcc_impl_linux-aarch64=12.3.0=h3d98823_13 - gcc_linux-aarch64=12.3.0=ha52a6ea_9 @@ -66,29 +119,76 @@ dependencies: - givaro=4.2.0=h364d21b_0 - glpk=5.0=h66325d0_0 - gmp=6.3.0=h0a1ffab_2 + - gmpy2=2.1.5=py39hcc1b389_1 + - graphite2=1.3.13=h2f0025b_1003 - gsl=2.7=h294027d_0 - gxx=12.3.0=hdb0cc85_13 - gxx_impl_linux-aarch64=12.3.0=hba91e99_13 - gxx_linux-aarch64=12.3.0=h9d1f256_9 + - h11=0.14.0=pyhd8ed1ab_0 + - h2=4.1.0=pyhd8ed1ab_0 + - harfbuzz=8.5.0=h9812418_0 + - hatchling=1.25.0=pyhd8ed1ab_0 + - hpack=4.0.0=pyh9f0ad1d_0 + - httpcore=1.0.5=pyhd8ed1ab_0 + - httpx=0.27.0=pyhd8ed1ab_0 + - hyperframe=6.0.1=pyhd8ed1ab_0 - icu=73.2=h787c7f5_0 + - idna=3.7=pyhd8ed1ab_0 - igraph=0.10.12=h197073e_1 + - imagesize=1.4.1=pyhd8ed1ab_0 - iml=1.0.5=h15043fe_1004 - importlib-metadata=8.0.0=pyha770c72_0 + - importlib-resources=6.4.0=pyhd8ed1ab_0 - importlib_metadata=8.0.0=hd8ed1ab_0 + - importlib_resources=6.4.0=pyhd8ed1ab_0 + - ipykernel=6.29.4=pyh3099207_0 + - ipympl=0.9.4=pyhd8ed1ab_0 + - ipython=8.18.1=pyh707e725_3 + - ipython_genutils=0.2.0=pyhd8ed1ab_1 + - ipywidgets=8.1.3=pyhd8ed1ab_0 + - isoduration=20.11.0=pyhd8ed1ab_0 + - jedi=0.19.1=pyhd8ed1ab_0 + - jinja2=3.1.4=pyhd8ed1ab_0 + - jmol=14.32.10=h8af1aa0_0 + - json5=0.9.25=pyhd8ed1ab_0 + - jsonpointer=3.0.0=py39h4420490_0 + - jsonschema=4.22.0=pyhd8ed1ab_0 + - jsonschema-specifications=2023.12.1=pyhd8ed1ab_0 + - jsonschema-with-format-nongpl=4.22.0=pyhd8ed1ab_0 + - jupyter-jsmol=2022.1.0=pyhd8ed1ab_0 + - jupyter-lsp=2.2.5=pyhd8ed1ab_0 + - jupyter-sphinx=0.5.3=pyha770c72_4 + - jupyter_client=8.6.2=pyhd8ed1ab_0 + - jupyter_core=5.7.2=py39h4420490_0 + - jupyter_events=0.10.0=pyhd8ed1ab_0 + - jupyter_server=2.14.1=pyhd8ed1ab_0 + - jupyter_server_terminals=0.5.3=pyhd8ed1ab_0 + - jupyter_sphinx=0.5.3=hd8ed1ab_4 + - jupyterlab=4.2.2=pyhd8ed1ab_0 + - jupyterlab_pygments=0.3.0=pyhd8ed1ab_1 + - jupyterlab_server=2.27.2=pyhd8ed1ab_0 + - jupyterlab_widgets=3.0.11=pyhd8ed1ab_0 - kernel-headers_linux-aarch64=4.18.0=h5b4a56d_14 - keyutils=1.6.1=h4e544f5_0 + - kiwisolver=1.4.5=py39had2cf8c_1 - krb5=1.21.2=hc419048_0 - lcalc=2.0.5=he588f68_2 + - lcms2=2.16=h922389a_0 - ld_impl_linux-aarch64=2.40=h9fc2d93_7 - lerc=4.0.0=h4de3ea5_0 - libatomic_ops=7.6.14=h4e544f5_0 - - libblas=3.9.0=22_linuxaarch64_openblas + - libblas=3.9.0=20_linuxaarch64_openblas - libboost=1.85.0=hb41fec8_2 - libboost-devel=1.85.0=h37bb5a9_2 - libboost-headers=1.85.0=h8af1aa0_2 - libbraiding=1.2=hd600fc2_0 - libbrial=1.2.12=h9429f74_3 - - libcblas=3.9.0=22_linuxaarch64_openblas + - libbrotlicommon=1.1.0=h31becfc_1 + - libbrotlidec=1.1.0=h31becfc_1 + - libbrotlienc=1.1.0=h31becfc_1 + - libcblas=3.9.0=20_linuxaarch64_openblas + - libcups=2.3.3=h405e4a8_4 - libcurl=8.8.0=h4e8248e_0 - libdeflate=1.20=h31becfc_0 - libedit=3.1.20191231=he28a2e2_2 @@ -101,16 +201,17 @@ dependencies: - libgd=2.3.3=hcd22fd5_9 - libgfortran-ng=13.2.0=he9431aa_13 - libgfortran5=13.2.0=h2af0866_13 + - libglib=2.80.2=haee52c6_1 - libgomp=13.2.0=he277a41_13 - libhomfly=1.02r6=h31becfc_1 - libhwloc=2.10.0=default_h3030c0e_1001 - libiconv=1.17=h31becfc_2 - libjpeg-turbo=3.0.0=h31becfc_1 - - liblapack=3.9.0=22_linuxaarch64_openblas - - liblapacke=3.9.0=22_linuxaarch64_openblas + - liblapack=3.9.0=20_linuxaarch64_openblas + - liblapacke=3.9.0=20_linuxaarch64_openblas - libnghttp2=1.58.0=hb0e430d_1 - libnsl=2.0.1=h31becfc_0 - - libopenblas=0.3.27=pthreads_h5a5ec62_0 + - libopenblas=0.3.25=pthreads_h5a5ec62_0 - libpng=1.6.43=h194ca79_0 - libsanitizer=12.3.0=h57e2e72_13 - libsodium=1.0.18=hb9de7d4_1 @@ -124,6 +225,7 @@ dependencies: - libuv=1.48.0=h31becfc_0 - libwebp=1.4.0=h8b4e01b_0 - libwebp-base=1.4.0=h31becfc_0 + - libxcb=1.16=h7935292_0 - libxcrypt=4.4.36=h31becfc_1 - libxml2=2.12.7=h49dc7a2_1 - libzlib=1.3.1=h68df207_1 @@ -134,61 +236,200 @@ dependencies: - m4ri=20140914=hedfd65a_1006 - m4rie=20150908=hf0a5ef3_1002 - make=4.3=h309ac5b_1 + - markupsafe=2.1.5=py39h7cc1d5f_0 - mathjax=3.2.2=h8af1aa0_0 + - matplotlib=3.8.4=py39ha65689a_2 + - matplotlib-base=3.8.4=py39hf44f4b6_2 + - matplotlib-inline=0.1.7=pyhd8ed1ab_0 - maxima=5.47.0=h6475f26_2 + - memory-allocator=0.1.3=py39h898b7ef_0 - metis=5.1.0=h2f0025b_1007 + - mistune=3.0.2=pyhd8ed1ab_0 - mpc=1.3.1=hf4c8f4c_0 - mpfi=1.5.4=h846f343_1001 - mpfr=4.2.1=ha2d0fc4_1 + - mpmath=1.3.0=pyhd8ed1ab_0 + - munkres=1.1.4=pyh9f0ad1d_0 - nauty=2.8.8=h31becfc_1 + - nbclient=0.10.0=pyhd8ed1ab_0 + - nbconvert=7.16.4=hd8ed1ab_1 + - nbconvert-core=7.16.4=pyhd8ed1ab_1 + - nbconvert-pandoc=7.16.4=hd8ed1ab_1 + - nbformat=5.10.4=pyhd8ed1ab_0 - ncurses=6.5=h0425590_0 + - nest-asyncio=1.6.0=pyhd8ed1ab_0 + - networkx=3.2.1=pyhd8ed1ab_0 - ninja=1.12.1=h70be974_0 + - notebook=7.2.1=pyhd8ed1ab_0 + - notebook-shim=0.2.4=pyhd8ed1ab_0 - ntl=11.4.3=h0d7519b_1 - - openblas=0.3.27=pthreads_h339cbfa_0 + - numpy=1.26.4=py39h91c28bb_0 + - openblas=0.3.25=pthreads_h339cbfa_0 + - openjdk=22.0.1=h3d4cd67_0 + - openjpeg=2.5.2=h0d9d63b_0 - openssl=3.3.1=h68df207_0 + - overrides=7.7.0=pyhd8ed1ab_0 - packaging=24.1=pyhd8ed1ab_0 - palp=2.20=hb9de7d4_0 + - pandoc=3.2.1=h8af1aa0_0 + - pandocfilters=1.5.0=pyhd8ed1ab_0 + - pango=1.54.0=h399c48b_0 - pari=2.15.5=h169c2a7_2_pthread - pari-elldata=0.0.20161017=0 - pari-galdata=0.0.20180411=0 - pari-galpol=0.0.20180625=0 - pari-seadata=0.0.20090618=0 - pari-seadata-small=0.0.20090618=0 + - parso=0.8.4=pyhd8ed1ab_0 - patch=2.7.6=hf897c2e_1002 + - pathspec=0.12.1=pyhd8ed1ab_0 + - pcre2=10.44=h070dd5b_0 + - pep517=0.13.0=pyhd8ed1ab_0 - perl=5.32.1=7_h31becfc_perl5 + - pexpect=4.9.0=pyhd8ed1ab_0 + - pickleshare=0.7.5=py_1003 + - pillow=10.3.0=py39h4a8821f_1 + - pip=24.0=pyhd8ed1ab_0 + - pixman=0.43.4=h2f0025b_0 - pkg-config=0.29.2=hb9de7d4_1008 + - pkgconfig=1.5.5=pyhd8ed1ab_4 + - pkgutil-resolve-name=1.3.10=pyhd8ed1ab_1 - planarity=3.0.2.0=h31becfc_0 - platformdirs=4.2.2=pyhd8ed1ab_0 - pluggy=1.5.0=pyhd8ed1ab_0 + - ply=3.11=pyhd8ed1ab_2 - ppl=1.2=h984aac9_1006 - - primecount=7.13=hfe4b40e_0 - - primesieve=12.1=h2f0025b_0 + - pplpy=0.8.9=py39hf652505_1 + - primecount=7.6=hd600fc2_0 + - primecountpy=0.1.0=py39hd16970a_3 + - primesieve=11.0=hd600fc2_0 + - prometheus_client=0.20.0=pyhd8ed1ab_0 + - prompt-toolkit=3.0.47=pyha770c72_0 + - prompt_toolkit=3.0.47=hd8ed1ab_0 + - psutil=6.0.0=py39he257ee7_0 + - pthread-stubs=0.4=hb9de7d4_1001 + - ptyprocess=0.7.0=pyhd3deb0d_0 + - pure_eval=0.2.2=pyhd8ed1ab_0 + - py=1.11.0=pyh6c4a22f_0 + - pybind11=2.12.0=py39hd16970a_0 + - pybind11-global=2.12.0=py39hd16970a_0 + - pycparser=2.22=pyhd8ed1ab_0 + - pygments=2.18.0=pyhd8ed1ab_0 + - pyparsing=3.1.2=pyhd8ed1ab_0 - pyproject-api=1.7.1=pyhd8ed1ab_0 + - pyrsistent=0.20.0=py39h7cc1d5f_0 + - pysocks=1.7.1=pyha2e5f31_6 - python=3.9.19=h4ac3b42_0_cpython + - python-build=1.2.1=pyhd8ed1ab_0 + - python-dateutil=2.9.0=pyhd8ed1ab_0 + - python-fastjsonschema=2.20.0=pyhd8ed1ab_0 + - python-json-logger=2.0.7=pyhd8ed1ab_0 + - python-lrcalc=2.1=py39h387a81e_6 + - python-tzdata=2024.1=pyhd8ed1ab_0 - python_abi=3.9=4_cp39 + - pythran=0.15.0=py39hc2250db_1 + - pytz=2024.1=pyhd8ed1ab_0 + - pytz-deprecation-shim=0.1.0.post0=py39h4420490_4 + - pyyaml=6.0.1=py39h898b7ef_1 + - pyzmq=26.0.3=py39h866fef3_0 - qd=2.3.22=h05efe27_1004 - qhull=2020.2=hd62202e_2 + - r-base=4.3.3=h7f20121_3 + - r-lattice=0.22_6=r43h25e906a_0 - readline=8.2=h8fc344f_1 + - referencing=0.35.1=pyhd8ed1ab_0 + - requests=2.32.3=pyhd8ed1ab_0 + - rfc3339-validator=0.1.4=pyhd8ed1ab_0 + - rfc3986-validator=0.1.1=pyh9f0ad1d_0 - rhash=1.4.4=h31becfc_0 + - rpds-py=0.18.1=py39hb8f4057_0 + - rpy2=3.5.11=py39r43h1ae4408_3 - rw=0.9=h31becfc_2 + - sagemath-db-combinatorial-designs=20140630=1 + - sagemath-db-elliptic-curves=0.8.1=hecc5488_0 + - sagemath-db-graphs=20210214=hd8ed1ab_0 + - sagemath-db-polytopes=20170220=1 + - sagetex=3.6.1=pyhd8ed1ab_0 + - scipy=1.11.3=py39h91c28bb_1 + - sed=4.8=ha0d5d3d_0 + - send2trash=1.8.3=pyh0d859eb_0 + - setuptools=70.1.1=pyhd8ed1ab_0 + - setuptools-scm=8.1.0=pyhd8ed1ab_0 + - setuptools_scm=8.1.0=hd8ed1ab_0 + - simplegeneric=0.8.1=py_1 - singular=4.3.2.p8=hbe76a8a_1 + - six=1.16.0=pyh6c4a22f_0 + - sniffio=1.3.1=pyhd8ed1ab_0 + - snowballstemmer=2.2.0=pyhd8ed1ab_0 + - soupsieve=2.5=pyhd8ed1ab_1 + - sphinx=7.3.7=pyhd8ed1ab_0 + - sphinx-basic-ng=1.0.0b2=pyhd8ed1ab_1 + - sphinx-copybutton=0.5.2=pyhd8ed1ab_0 + - sphinxcontrib-applehelp=1.0.8=pyhd8ed1ab_0 + - sphinxcontrib-devhelp=1.0.6=pyhd8ed1ab_0 + - sphinxcontrib-htmlhelp=2.0.5=pyhd8ed1ab_0 + - sphinxcontrib-jsmath=1.0.1=pyhd8ed1ab_0 + - sphinxcontrib-qthelp=1.0.7=pyhd8ed1ab_0 + - sphinxcontrib-serializinghtml=1.1.10=pyhd8ed1ab_0 + - sphinxcontrib-websupport=1.2.7=pyhd8ed1ab_0 - sqlite=3.46.0=hdc7ab3c_0 + - stack_data=0.6.2=pyhd8ed1ab_0 - suitesparse=7.7.0=h3944111_1 - symmetrica=3.0.1=hd600fc2_0 - sympow=2.023.6=h157afb5_3 + - sympy=1.12.1=pypyh2585a3b_103 - sysroot_linux-aarch64=2.17=h5b4a56d_14 - tachyon=0.99b6=ha0bfc61_1002 - tar=1.34=h048efde_0 - tbb=2021.12.0=h70be974_1 + - terminado=0.18.1=pyh0d859eb_0 - texinfo=7.0=pl5321h17f021e_0 + - three.js=122=hd8ed1ab_2 + - threejs-sage=122=hd8ed1ab_2 + - tinycss2=1.3.0=pyhd8ed1ab_0 - tk=8.6.13=h194ca79_0 + - tktable=2.10=h52f7bd3_6 - tomli=2.0.1=pyhd8ed1ab_0 + - tornado=6.4.1=py39ha3e8b56_0 - tox=4.15.1=pyhd8ed1ab_0 + - traitlets=5.14.3=pyhd8ed1ab_0 + - trove-classifiers=2024.5.22=pyhd8ed1ab_0 + - types-python-dateutil=2.9.0.20240316=pyhd8ed1ab_0 - typing-extensions=4.12.2=hd8ed1ab_0 - typing_extensions=4.12.2=pyha770c72_0 + - typing_utils=0.1.0=pyhd8ed1ab_0 - tzdata=2024a=h0c530f3_0 + - tzlocal=5.2=py39h4420490_0 + - unicodedata2=15.1.0=py39h898b7ef_0 + - uri-template=1.3.0=pyhd8ed1ab_0 + - urllib3=2.2.2=pyhd8ed1ab_0 - virtualenv=20.26.3=pyhd8ed1ab_0 + - wcwidth=0.2.13=pyhd8ed1ab_0 + - webcolors=24.6.0=pyhd8ed1ab_0 + - webencodings=0.5.1=pyhd8ed1ab_2 + - websocket-client=1.8.0=pyhd8ed1ab_0 + - wheel=0.43.0=pyhd8ed1ab_1 + - widgetsnbextension=4.0.11=pyhd8ed1ab_0 + - xorg-fixesproto=5.0=h3557bc0_1002 + - xorg-inputproto=2.3.2=h3557bc0_1002 + - xorg-kbproto=1.0.7=h3557bc0_1002 + - xorg-libice=1.1.1=h7935292_0 + - xorg-libsm=1.2.4=h5a01bc2_0 + - xorg-libx11=1.8.9=h08be655_1 + - xorg-libxau=1.0.11=h31becfc_0 + - xorg-libxdmcp=1.1.3=h3557bc0_0 + - xorg-libxext=1.3.4=h2a766a3_2 + - xorg-libxfixes=5.0.3=h3557bc0_1004 + - xorg-libxi=1.7.10=h3557bc0_0 + - xorg-libxrender=0.9.11=h7935292_0 + - xorg-libxt=1.3.0=h7935292_1 + - xorg-libxtst=1.2.3=hf897c2e_1002 + - xorg-recordproto=1.14.2=hf897c2e_1002 + - xorg-renderproto=0.11.1=h3557bc0_1002 + - xorg-xextproto=7.3.0=h2a766a3_1003 + - xorg-xproto=7.0.31=h3557bc0_1007 - xz=5.2.6=h9cdd2b7_0 + - yaml=0.2.5=hf897c2e_2 - zeromq=4.3.5=h28faeed_4 - zipp=3.19.2=pyhd8ed1ab_0 - zlib=1.3.1=h68df207_1 diff --git a/environment-3.9-linux.yml b/environment-3.9-linux.yml index 558fa62d818..7099a1eb01d 100644 --- a/environment-3.9-linux.yml +++ b/environment-3.9-linux.yml @@ -1,45 +1,94 @@ +name: sage # Generated by conda-lock. # platform: linux-64 -# input_hash: ba320b73ca09397135b112a282763d517960252747ae2c5b4159d1334911ebe7 +# input_hash: e864996ba609c3a06f1c78376812e9f6180653730f5c2e60df67268b3e2fb7d6 channels: - conda-forge dependencies: - _libgcc_mutex=0.1=conda_forge - _openmp_mutex=4.5=2_kmp_llvm + - _r-mutex=1.0.1=anacondar_1 + - alabaster=0.7.16=pyhd8ed1ab_0 + - alsa-lib=1.2.12=h4ab18f5_0 + - anyio=4.4.0=pyhd8ed1ab_0 - appdirs=1.4.4=pyh9f0ad1d_0 + - appnope=0.1.4=pyhd8ed1ab_0 + - argon2-cffi=23.1.0=pyhd8ed1ab_0 + - argon2-cffi-bindings=21.2.0=py39hd1e30aa_4 - arpack=3.9.1=nompi_h77f6705_101 + - arrow=1.3.0=pyhd8ed1ab_0 + - asttokens=2.4.1=pyhd8ed1ab_0 + - async-lru=2.0.4=pyhd8ed1ab_0 + - attr=2.5.1=h166bdaf_1 + - attrs=23.2.0=pyh71513ae_0 - autoconf=2.71=pl5321h2b4cb7a_1 - automake=1.16.5=pl5321ha770c72_0 + - babel=2.14.0=pyhd8ed1ab_0 - bc=1.07.1=h7f98852_0 - bdw-gc=8.0.6=h4bd325d_0 + - beautifulsoup4=4.12.3=pyha770c72_0 + - beniget=0.4.1=pyhd8ed1ab_0 - binutils=2.40=h4852527_7 - binutils_impl_linux-64=2.40=ha1999f0_7 - binutils_linux-64=2.40=hb3c18ed_9 - - blas=2.122=openblas - - blas-devel=3.9.0=22_linux64_openblas + - blas=2.120=openblas + - blas-devel=3.9.0=20_linux64_openblas + - bleach=6.1.0=pyhd8ed1ab_0 - boost-cpp=1.85.0=h44aadfe_2 - brial=1.2.12=pyh694c41f_3 + - brotli=1.1.0=hd590300_1 + - brotli-bin=1.1.0=hd590300_1 + - brotli-python=1.1.0=py39h3d6467e_1 + - bwidget=1.9.14=ha770c72_1 - bzip2=1.0.8=hd590300_5 - c-ares=1.28.1=hd590300_0 - c-compiler=1.7.0=hd590300_1 - ca-certificates=2024.6.2=hbcca054_0 + - cached-property=1.5.2=hd8ed1ab_1 + - cached_property=1.5.2=pyha770c72_1 - cachetools=5.3.3=pyhd8ed1ab_0 + - cairo=1.18.0=hbb29018_2 - cddlib=1!0.94m=h9202a9a_0 + - certifi=2024.6.2=pyhd8ed1ab_0 + - cffi=1.16.0=py39h7a31438_0 - chardet=5.2.0=py39hf3d152e_1 + - charset-normalizer=3.3.2=pyhd8ed1ab_0 - cliquer=1.22=hd590300_1 - cmake=3.29.6=hcafd917_0 - colorama=0.4.6=pyhd8ed1ab_0 + - colorlog=6.8.2=py39hf3d152e_0 + - comm=0.2.2=pyhd8ed1ab_0 - compilers=1.7.0=ha770c72_1 + - contourpy=1.2.1=py39h7633fee_0 + - conway-polynomials=0.9=pyhd8ed1ab_0 + - cppy=1.2.1=pyhd8ed1ab_0 - curl=8.8.0=he654da7_0 + - cvxopt=1.3.2=py39h640215f_2 - cxx-compiler=1.7.0=h00ab1b0_1 + - cycler=0.12.1=pyhd8ed1ab_0 + - cypari2=2.1.5=py39h1698a45_0 + - cysignals=1.11.2=py39h1ce0973_3 + - cython=3.0.10=py39h3d6467e_0 + - dbus=1.13.6=h5008d03_3 + - debugpy=1.8.1=py39h3d6467e_0 + - decorator=5.1.1=pyhd8ed1ab_0 + - defusedxml=0.7.1=pyhd8ed1ab_0 - distlib=0.3.8=pyhd8ed1ab_0 + - docutils=0.21.2=pyhd8ed1ab_0 + - dsdp=5.8=hd9d9efa_1203 - ecl=23.9.9=hed6455c_0 - eclib=20231212=h96f522a_0 - ecm=7.0.5=h9458935_0 + - editables=0.5=pyhd8ed1ab_0 + - entrypoints=0.4=pyhd8ed1ab_0 + - exceptiongroup=1.2.0=pyhd8ed1ab_2 + - executing=2.0.1=pyhd8ed1ab_0 - expat=2.6.2=h59595ed_0 - fflas-ffpack=2.5.0=h4f9960b_0 + - fftw=3.3.10=nompi_hf1063bd_110 - filelock=3.15.4=pyhd8ed1ab_0 + - flit-core=3.9.0=pyhd8ed1ab_1 - 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 @@ -47,15 +96,23 @@ dependencies: - fontconfig=2.14.2=h14ed4e7_0 - fonts-conda-ecosystem=1=0 - fonts-conda-forge=1=0 + - fonttools=4.53.0=py39hd3abc70_0 - fortran-compiler=1.7.0=heb67821_1 - fplll=5.4.5=h384768b_0 + - fpylll=0.6.1=py39h2525e16_0 + - fqdn=1.5.1=pyhd8ed1ab_0 - freetype=2.12.1=h267a509_2 + - fribidi=1.0.10=h36c2ea0_0 + - furo=2024.5.6=pyhd8ed1ab_0 - gap-core=4.12.2=he9a28a4_3 - gap-defaults=4.12.2=ha770c72_3 + - gast=0.5.4=pyhd8ed1ab_0 - gcc=12.3.0=h915e2ae_13 - gcc_impl_linux-64=12.3.0=h58ffeeb_13 - gcc_linux-64=12.3.0=h9528a6a_9 - gengetopt=2.23=h9c3ff4c_0 + - gettext=0.22.5=h59595ed_2 + - gettext-tools=0.22.5=h59595ed_2 - gf2x=1.3.0=ha476b99_2 - gfan=0.6.2=hb86e20a_1003 - gfortran=12.3.0=h915e2ae_13 @@ -64,131 +121,363 @@ dependencies: - giac=1.9.0.21=h673759e_1 - giflib=5.2.2=hd590300_0 - givaro=4.2.0=hb789bce_0 + - glib=2.80.2=h8a4344b_1 + - glib-tools=2.80.2=h73ef956_1 - glpk=5.0=h445213a_0 - gmp=6.3.0=hac33072_2 + - gmpy2=2.1.5=py39h048c657_1 + - graphite2=1.3.13=h59595ed_1003 - gsl=2.7=he838d99_0 + - gst-plugins-base=1.24.5=hbaaba92_0 + - gstreamer=1.24.5=haf2f30d_0 - gxx=12.3.0=h915e2ae_13 - gxx_impl_linux-64=12.3.0=h2a574ab_13 - gxx_linux-64=12.3.0=ha28b414_9 + - h11=0.14.0=pyhd8ed1ab_0 + - h2=4.1.0=pyhd8ed1ab_0 + - harfbuzz=8.5.0=hfac3d4d_0 + - hatchling=1.25.0=pyhd8ed1ab_0 + - hpack=4.0.0=pyh9f0ad1d_0 + - httpcore=1.0.5=pyhd8ed1ab_0 + - httpx=0.27.0=pyhd8ed1ab_0 + - hyperframe=6.0.1=pyhd8ed1ab_0 - icu=73.2=h59595ed_0 + - idna=3.7=pyhd8ed1ab_0 - igraph=0.10.12=hef0740d_1 + - imagesize=1.4.1=pyhd8ed1ab_0 - iml=1.0.5=h623f65a_1004 - importlib-metadata=8.0.0=pyha770c72_0 + - importlib-resources=6.4.0=pyhd8ed1ab_0 - importlib_metadata=8.0.0=hd8ed1ab_0 + - importlib_resources=6.4.0=pyhd8ed1ab_0 + - ipykernel=6.29.4=pyh3099207_0 + - ipympl=0.9.4=pyhd8ed1ab_0 + - ipython=8.18.1=pyh707e725_3 + - ipython_genutils=0.2.0=pyhd8ed1ab_1 + - ipywidgets=8.1.3=pyhd8ed1ab_0 + - isoduration=20.11.0=pyhd8ed1ab_0 + - jedi=0.19.1=pyhd8ed1ab_0 + - jinja2=3.1.4=pyhd8ed1ab_0 + - jmol=14.32.10=ha770c72_0 + - json5=0.9.25=pyhd8ed1ab_0 + - jsonpointer=3.0.0=py39hf3d152e_0 + - jsonschema=4.22.0=pyhd8ed1ab_0 + - jsonschema-specifications=2023.12.1=pyhd8ed1ab_0 + - jsonschema-with-format-nongpl=4.22.0=pyhd8ed1ab_0 + - jupyter-jsmol=2022.1.0=pyhd8ed1ab_0 + - jupyter-lsp=2.2.5=pyhd8ed1ab_0 + - jupyter-sphinx=0.5.3=pyha770c72_4 + - jupyter_client=8.6.2=pyhd8ed1ab_0 + - jupyter_core=5.7.2=py39hf3d152e_0 + - jupyter_events=0.10.0=pyhd8ed1ab_0 + - jupyter_server=2.14.1=pyhd8ed1ab_0 + - jupyter_server_terminals=0.5.3=pyhd8ed1ab_0 + - jupyter_sphinx=0.5.3=hd8ed1ab_4 + - jupyterlab=4.2.2=pyhd8ed1ab_0 + - jupyterlab_pygments=0.3.0=pyhd8ed1ab_1 + - jupyterlab_server=2.27.2=pyhd8ed1ab_0 + - jupyterlab_widgets=3.0.11=pyhd8ed1ab_0 - kernel-headers_linux-64=2.6.32=he073ed8_17 - keyutils=1.6.1=h166bdaf_0 + - kiwisolver=1.4.5=py39h7633fee_1 - krb5=1.21.2=h659d440_0 + - lame=3.100=h166bdaf_1003 - lcalc=2.0.5=h5aac1b6_2 + - lcms2=2.16=hb7c19ff_0 - ld_impl_linux-64=2.40=hf3520f5_7 - lerc=4.0.0=h27087fc_0 + - libasprintf=0.22.5=h661eb56_2 + - libasprintf-devel=0.22.5=h661eb56_2 - libatomic_ops=7.6.14=h166bdaf_0 - - libblas=3.9.0=22_linux64_openblas + - libblas=3.9.0=20_linux64_openblas - libboost=1.85.0=hba137d9_2 - libboost-devel=1.85.0=h00ab1b0_2 - libboost-headers=1.85.0=ha770c72_2 - libbraiding=1.2=hcb278e6_0 - libbrial=1.2.12=h76af697_3 - - libcblas=3.9.0=22_linux64_openblas + - libbrotlicommon=1.1.0=hd590300_1 + - libbrotlidec=1.1.0=hd590300_1 + - libbrotlienc=1.1.0=hd590300_1 + - libcap=2.69=h0f662aa_0 + - libcblas=3.9.0=20_linux64_openblas + - libclang-cpp15=15.0.7=default_h127d8a8_5 + - libclang13=18.1.8=default_h6ae225f_0 + - libcups=2.3.3=h4637d8d_4 - libcurl=8.8.0=hca28451_0 - libdeflate=1.20=hd590300_0 - libedit=3.1.20191231=he28a2e2_2 - libev=4.33=hd590300_2 + - libevent=2.1.12=hf998b51_1 - libexpat=2.6.2=h59595ed_0 - libffi=3.4.2=h7f98852_5 + - libflac=1.4.3=h59595ed_0 - libflint=3.0.1=h5f2e117_ntl_100 - libgcc-devel_linux-64=12.3.0=h6b66f73_113 - libgcc-ng=13.2.0=h77fa898_13 + - libgcrypt=1.10.3=hd590300_0 - libgd=2.3.3=h119a65a_9 + - libgettextpo=0.22.5=h59595ed_2 + - libgettextpo-devel=0.22.5=h59595ed_2 - libgfortran-ng=13.2.0=h69a702a_13 - libgfortran5=13.2.0=h3d2ce59_13 + - libglib=2.80.2=h8a4344b_1 - libgomp=13.2.0=h77fa898_13 + - libgpg-error=1.49=h4f305b6_0 - libhomfly=1.02r6=hd590300_1 - libhwloc=2.10.0=default_h5622ce7_1001 - libiconv=1.17=hd590300_2 - libjpeg-turbo=3.0.0=hd590300_1 - - liblapack=3.9.0=22_linux64_openblas - - liblapacke=3.9.0=22_linux64_openblas + - liblapack=3.9.0=20_linux64_openblas + - liblapacke=3.9.0=20_linux64_openblas + - libllvm15=15.0.7=hb3ce162_4 + - libllvm18=18.1.8=hc9dba70_0 - libnghttp2=1.58.0=h47da74e_1 - libnsl=2.0.1=hd590300_0 - - libopenblas=0.3.27=pthreads_h413a1c8_0 + - libogg=1.3.5=h4ab18f5_0 + - libopenblas=0.3.25=pthreads_h413a1c8_0 + - libopus=1.3.1=h7f98852_1 - libpng=1.6.43=h2797004_0 + - libpq=16.3=ha72fbe1_0 - libsanitizer=12.3.0=hb8811af_13 + - libsndfile=1.2.2=hc60ed4a_1 - libsodium=1.0.18=h36c2ea0_1 - libsqlite=3.46.0=hde9e2c9_0 - libssh2=1.11.0=h0841786_0 - libstdcxx-devel_linux-64=12.3.0=h6b66f73_113 - libstdcxx-ng=13.2.0=hc0a3c3a_13 + - libsystemd0=255=h3516f8a_1 - libtiff=4.6.0=h1dd3fc0_3 - libtool=2.4.7=h27087fc_0 - libuuid=2.38.1=h0b41bf4_0 - libuv=1.48.0=hd590300_0 + - libvorbis=1.3.7=h9c3ff4c_0 - libwebp=1.4.0=h2c329e2_0 - libwebp-base=1.4.0=hd590300_0 + - libxcb=1.16=hd590300_0 - libxcrypt=4.4.36=hd590300_1 + - libxkbcommon=1.7.0=h2c5496b_1 - libxml2=2.12.7=hc051c1a_1 - libzlib=1.3.1=h4ab18f5_1 - linbox=1.7.0=ha329b40_0 - llvm-openmp=18.1.8=hf5423f3_0 - lrcalc=2.1=h59595ed_6 + - lz4-c=1.9.4=hcb278e6_0 - m4=1.4.18=h516909a_1001 - m4ri=20140914=hae5d5c5_1006 - m4rie=20150908=h267a509_1002 - make=4.3=hd18ef5c_1 + - markupsafe=2.1.5=py39hd1e30aa_0 - mathjax=3.2.2=ha770c72_0 + - matplotlib=3.8.4=py39hf3d152e_2 + - matplotlib-base=3.8.4=py39h10d1fc8_2 + - matplotlib-inline=0.1.7=pyhd8ed1ab_0 - maxima=5.47.0=hed6455c_2 + - memory-allocator=0.1.3=py39hd1e30aa_0 - metis=5.1.0=h59595ed_1007 + - mistune=3.0.2=pyhd8ed1ab_0 - mpc=1.3.1=hfe3b2da_0 - mpfi=1.5.4=h9f54685_1001 - mpfr=4.2.1=h9458935_1 + - mpg123=1.32.6=h59595ed_0 + - mpmath=1.3.0=pyhd8ed1ab_0 + - munkres=1.1.4=pyh9f0ad1d_0 + - mysql-common=8.3.0=hf1915f5_4 + - mysql-libs=8.3.0=hca2cd23_4 - nauty=2.8.8=hd590300_1 + - nbclient=0.10.0=pyhd8ed1ab_0 + - nbconvert=7.16.4=hd8ed1ab_1 + - nbconvert-core=7.16.4=pyhd8ed1ab_1 + - nbconvert-pandoc=7.16.4=hd8ed1ab_1 + - nbformat=5.10.4=pyhd8ed1ab_0 - ncurses=6.5=h59595ed_0 + - nest-asyncio=1.6.0=pyhd8ed1ab_0 + - networkx=3.2.1=pyhd8ed1ab_0 - ninja=1.12.1=h297d8ca_0 + - notebook=7.2.1=pyhd8ed1ab_0 + - notebook-shim=0.2.4=pyhd8ed1ab_0 + - nspr=4.35=h27087fc_0 + - nss=3.101=h593d115_0 - ntl=11.4.3=hef3c4d3_1 - - openblas=0.3.27=pthreads_h7a3da1a_0 + - numpy=1.26.4=py39h474f0d3_0 + - openblas=0.3.25=pthreads_h7a3da1a_0 + - openjdk=21.0.2=haa376d0_0 + - openjpeg=2.5.2=h488ebb8_0 - openssl=3.3.1=h4ab18f5_0 + - overrides=7.7.0=pyhd8ed1ab_0 - packaging=24.1=pyhd8ed1ab_0 - palp=2.20=h36c2ea0_0 + - pandoc=3.2.1=ha770c72_0 + - pandocfilters=1.5.0=pyhd8ed1ab_0 + - pango=1.54.0=h84a9a3c_0 - pari=2.15.5=h4d4ae9b_2_pthread - pari-elldata=0.0.20161017=0 - pari-galdata=0.0.20180411=0 - pari-galpol=0.0.20180625=0 - pari-seadata=0.0.20090618=0 - pari-seadata-small=0.0.20090618=0 + - parso=0.8.4=pyhd8ed1ab_0 - patch=2.7.6=h7f98852_1002 + - pathspec=0.12.1=pyhd8ed1ab_0 + - pcre2=10.44=h0f59acf_0 + - pep517=0.13.0=pyhd8ed1ab_0 - perl=5.32.1=7_hd590300_perl5 + - pexpect=4.9.0=pyhd8ed1ab_0 + - pickleshare=0.7.5=py_1003 + - pillow=10.3.0=py39h16a7006_1 + - pip=24.0=pyhd8ed1ab_0 + - pixman=0.43.2=h59595ed_0 - pkg-config=0.29.2=h36c2ea0_1008 + - pkgconfig=1.5.5=pyhd8ed1ab_4 + - pkgutil-resolve-name=1.3.10=pyhd8ed1ab_1 - planarity=3.0.2.0=hd590300_0 - platformdirs=4.2.2=pyhd8ed1ab_0 - pluggy=1.5.0=pyhd8ed1ab_0 + - ply=3.11=pyhd8ed1ab_2 - ppl=1.2=h6ec01c2_1006 - - primecount=7.13=hb0181e5_0 - - primesieve=12.1=h59595ed_0 + - pplpy=0.8.9=py39h9e9cb73_1 + - primecount=7.9=hcb278e6_0 + - primecountpy=0.1.0=py39h7633fee_4 + - primesieve=11.1=h59595ed_0 + - prometheus_client=0.20.0=pyhd8ed1ab_0 + - prompt-toolkit=3.0.47=pyha770c72_0 + - prompt_toolkit=3.0.47=hd8ed1ab_0 + - psutil=6.0.0=py39hd3abc70_0 + - pthread-stubs=0.4=h36c2ea0_1001 + - ptyprocess=0.7.0=pyhd3deb0d_0 + - pulseaudio-client=17.0=hb77b528_0 + - pure_eval=0.2.2=pyhd8ed1ab_0 + - py=1.11.0=pyh6c4a22f_0 + - pybind11=2.12.0=py39h7633fee_0 + - pybind11-global=2.12.0=py39h7633fee_0 + - pycparser=2.22=pyhd8ed1ab_0 + - pygments=2.18.0=pyhd8ed1ab_0 + - pyparsing=3.1.2=pyhd8ed1ab_0 - pyproject-api=1.7.1=pyhd8ed1ab_0 + - pyqt=5.15.9=py39h52134e7_5 + - pyqt5-sip=12.12.2=py39h3d6467e_5 + - pyrsistent=0.20.0=py39hd1e30aa_0 + - pysocks=1.7.1=pyha2e5f31_6 - python=3.9.19=h0755675_0_cpython + - python-build=1.2.1=pyhd8ed1ab_0 + - python-dateutil=2.9.0=pyhd8ed1ab_0 + - python-fastjsonschema=2.20.0=pyhd8ed1ab_0 + - python-json-logger=2.0.7=pyhd8ed1ab_0 + - python-lrcalc=2.1=py39h3d6467e_6 + - python-tzdata=2024.1=pyhd8ed1ab_0 - python_abi=3.9=4_cp39 + - pythran=0.15.0=py39hda80f44_1 + - pytz=2024.1=pyhd8ed1ab_0 + - pytz-deprecation-shim=0.1.0.post0=py39hf3d152e_4 + - pyyaml=6.0.1=py39hd1e30aa_1 + - pyzmq=26.0.3=py39ha1047a2_0 - qd=2.3.22=h2cc385e_1004 - qhull=2020.2=h4bd325d_2 + - qt-main=5.15.8=ha2b5568_22 + - r-base=4.3.3=he2d9a6e_3 + - r-lattice=0.22_6=r43h57805ef_0 - readline=8.2=h8228510_1 + - referencing=0.35.1=pyhd8ed1ab_0 + - requests=2.32.3=pyhd8ed1ab_0 + - rfc3339-validator=0.1.4=pyhd8ed1ab_0 + - rfc3986-validator=0.1.1=pyh9f0ad1d_0 - rhash=1.4.4=hd590300_0 + - rpds-py=0.18.1=py39ha68c5e3_0 + - rpy2=3.5.11=py39r43h44dd56e_3 - rw=0.9=hd590300_2 + - sagemath-db-combinatorial-designs=20140630=1 + - sagemath-db-elliptic-curves=0.8.1=hecc5488_0 + - sagemath-db-graphs=20210214=hd8ed1ab_0 + - sagemath-db-polytopes=20170220=1 + - sagetex=3.6.1=pyhd8ed1ab_0 + - scipy=1.11.4=py39h474f0d3_0 + - sed=4.8=he412f7d_0 + - send2trash=1.8.3=pyh0d859eb_0 + - setuptools=70.1.1=pyhd8ed1ab_0 + - setuptools-scm=8.1.0=pyhd8ed1ab_0 + - setuptools_scm=8.1.0=hd8ed1ab_0 + - simplegeneric=0.8.1=py_1 - singular=4.3.2.p8=h33f5c3f_1 + - sip=6.7.12=py39h3d6467e_0 + - six=1.16.0=pyh6c4a22f_0 + - sniffio=1.3.1=pyhd8ed1ab_0 + - snowballstemmer=2.2.0=pyhd8ed1ab_0 + - soupsieve=2.5=pyhd8ed1ab_1 + - sphinx=7.3.7=pyhd8ed1ab_0 + - sphinx-basic-ng=1.0.0b2=pyhd8ed1ab_1 + - sphinx-copybutton=0.5.2=pyhd8ed1ab_0 + - sphinxcontrib-applehelp=1.0.8=pyhd8ed1ab_0 + - sphinxcontrib-devhelp=1.0.6=pyhd8ed1ab_0 + - sphinxcontrib-htmlhelp=2.0.5=pyhd8ed1ab_0 + - sphinxcontrib-jsmath=1.0.1=pyhd8ed1ab_0 + - sphinxcontrib-qthelp=1.0.7=pyhd8ed1ab_0 + - sphinxcontrib-serializinghtml=1.1.10=pyhd8ed1ab_0 + - sphinxcontrib-websupport=1.2.7=pyhd8ed1ab_0 - sqlite=3.46.0=h6d4b2fc_0 + - stack_data=0.6.2=pyhd8ed1ab_0 - suitesparse=7.7.0=hf4753ba_1 - symmetrica=3.0.1=hcb278e6_0 - sympow=2.023.6=hc6ab17c_3 + - sympy=1.12.1=pypyh2585a3b_103 - sysroot_linux-64=2.12=he073ed8_17 - tachyon=0.99b6=hba7d16a_1002 - tar=1.34=hb2e2bae_1 - tbb=2021.12.0=h297d8ca_1 + - terminado=0.18.1=pyh0d859eb_0 - texinfo=7.0=pl5321h0f457ee_0 + - three.js=122=hd8ed1ab_2 + - threejs-sage=122=hd8ed1ab_2 + - tinycss2=1.3.0=pyhd8ed1ab_0 - tk=8.6.13=noxft_h4845f30_101 + - tktable=2.10=h8bc8fbc_6 + - toml=0.10.2=pyhd8ed1ab_0 - tomli=2.0.1=pyhd8ed1ab_0 + - tornado=6.4.1=py39hd3abc70_0 - tox=4.15.1=pyhd8ed1ab_0 + - traitlets=5.14.3=pyhd8ed1ab_0 + - trove-classifiers=2024.5.22=pyhd8ed1ab_0 + - types-python-dateutil=2.9.0.20240316=pyhd8ed1ab_0 - typing-extensions=4.12.2=hd8ed1ab_0 - typing_extensions=4.12.2=pyha770c72_0 + - typing_utils=0.1.0=pyhd8ed1ab_0 - tzdata=2024a=h0c530f3_0 + - tzlocal=5.2=py39hf3d152e_0 + - unicodedata2=15.1.0=py39hd1e30aa_0 + - uri-template=1.3.0=pyhd8ed1ab_0 + - urllib3=2.2.2=pyhd8ed1ab_0 - virtualenv=20.26.3=pyhd8ed1ab_0 + - wcwidth=0.2.13=pyhd8ed1ab_0 + - webcolors=24.6.0=pyhd8ed1ab_0 + - webencodings=0.5.1=pyhd8ed1ab_2 + - websocket-client=1.8.0=pyhd8ed1ab_0 + - wheel=0.43.0=pyhd8ed1ab_1 + - widgetsnbextension=4.0.11=pyhd8ed1ab_0 + - xcb-util=0.4.1=hb711507_2 + - 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.42=h4ab18f5_0 + - xorg-fixesproto=5.0=h7f98852_1002 + - xorg-inputproto=2.3.2=h7f98852_1002 + - xorg-kbproto=1.0.7=h7f98852_1002 + - xorg-libice=1.1.1=hd590300_0 + - xorg-libsm=1.2.4=h7391055_0 + - xorg-libx11=1.8.9=hb711507_1 + - xorg-libxau=1.0.11=hd590300_0 + - xorg-libxdmcp=1.1.3=h7f98852_0 + - xorg-libxext=1.3.4=h0b41bf4_2 + - xorg-libxfixes=5.0.3=h7f98852_1004 + - xorg-libxi=1.7.10=h7f98852_0 + - xorg-libxrender=0.9.11=hd590300_0 + - xorg-libxt=1.3.0=hd590300_1 + - xorg-libxtst=1.2.3=h7f98852_1002 + - xorg-recordproto=1.14.2=h7f98852_1002 + - xorg-renderproto=0.11.1=h7f98852_1002 + - xorg-xextproto=7.3.0=h0b41bf4_1003 + - xorg-xf86vidmodeproto=2.3.1=h7f98852_1002 + - xorg-xproto=7.0.31=h7f98852_1007 - xz=5.2.6=h166bdaf_0 + - yaml=0.2.5=h7f98852_2 - zeromq=4.3.5=h75354e8_4 - zipp=3.19.2=pyhd8ed1ab_0 - zlib=1.3.1=h4ab18f5_1 diff --git a/environment-3.9-macos-x86_64.yml b/environment-3.9-macos-x86_64.yml index 6ac33e6d2ec..de8df57d291 100644 --- a/environment-3.9-macos-x86_64.yml +++ b/environment-3.9-macos-x86_64.yml @@ -1,29 +1,54 @@ +name: sage # Generated by conda-lock. # platform: osx-64 -# input_hash: 843f123465043acc18e0fe8c58c6afabd2e47ebad5f9ae6aea321eea0dd88571 +# input_hash: 7b973134e4e44170c953a71c99253450b079227c08993b2a49ae3ddd14d93fdb channels: - conda-forge dependencies: + - _r-mutex=1.0.1=anacondar_1 + - alabaster=0.7.16=pyhd8ed1ab_0 + - anyio=4.4.0=pyhd8ed1ab_0 - appdirs=1.4.4=pyh9f0ad1d_0 + - appnope=0.1.4=pyhd8ed1ab_0 + - argon2-cffi=23.1.0=pyhd8ed1ab_0 + - argon2-cffi-bindings=21.2.0=py39hdc70f33_4 - arpack=3.9.1=nompi_hf81eadf_101 + - arrow=1.3.0=pyhd8ed1ab_0 + - asttokens=2.4.1=pyhd8ed1ab_0 + - async-lru=2.0.4=pyhd8ed1ab_0 + - attrs=23.2.0=pyh71513ae_0 - autoconf=2.71=pl5321hed12c24_1 - automake=1.16.5=pl5321h694c41f_0 + - babel=2.14.0=pyhd8ed1ab_0 - bc=1.07.1=h0d85af4_0 - bdw-gc=8.0.6=h940c156_0 - - blas=2.122=openblas - - blas-devel=3.9.0=22_osx64_openblas + - beautifulsoup4=4.12.3=pyha770c72_0 + - beniget=0.4.1=pyhd8ed1ab_0 + - blas=2.120=openblas + - blas-devel=3.9.0=20_osx64_openblas + - bleach=6.1.0=pyhd8ed1ab_0 - boost-cpp=1.85.0=h07eb623_2 - brial=1.2.12=pyh694c41f_3 + - brotli=1.1.0=h0dc2134_1 + - brotli-bin=1.1.0=h0dc2134_1 + - brotli-python=1.1.0=py39h840bb9f_1 + - bwidget=1.9.14=h694c41f_1 - bzip2=1.0.8=h10d778d_5 - c-ares=1.28.1=h10d778d_0 - c-compiler=1.7.0=h282daa2_1 - ca-certificates=2024.6.2=h8857fd0_0 + - cached-property=1.5.2=hd8ed1ab_1 + - cached_property=1.5.2=pyha770c72_1 - cachetools=5.3.3=pyhd8ed1ab_0 + - cairo=1.18.0=h9f650ed_2 - cctools=986=h40f6528_0 - cctools_osx-64=986=ha1c5b94_0 - cddlib=1!0.94m=h0f52abe_0 + - certifi=2024.6.2=pyhd8ed1ab_0 + - cffi=1.16.0=py39h18ef598_0 - chardet=5.2.0=py39h6e9494a_1 + - charset-normalizer=3.3.2=pyhd8ed1ab_0 - clang=16.0.6=default_ha3b9224_8 - clang-16=16.0.6=default_h4c8afb6_8 - clang_impl_osx-64=16.0.6=h8787910_16 @@ -34,18 +59,39 @@ dependencies: - cliquer=1.22=h10d778d_1 - cmake=3.29.6=h749d262_0 - colorama=0.4.6=pyhd8ed1ab_0 + - colorlog=6.8.2=py39h6e9494a_0 + - comm=0.2.2=pyhd8ed1ab_0 - compiler-rt=16.0.6=ha38d28d_2 - compiler-rt_osx-64=16.0.6=ha38d28d_2 - compilers=1.7.0=h694c41f_1 + - contourpy=1.2.1=py39h0ca7971_0 + - conway-polynomials=0.9=pyhd8ed1ab_0 + - cppy=1.2.1=pyhd8ed1ab_0 - curl=8.8.0=hea67d85_0 + - cvxopt=1.3.2=py39hd66cc7a_2 - cxx-compiler=1.7.0=h7728843_1 + - cycler=0.12.1=pyhd8ed1ab_0 + - cypari2=2.1.5=py39hc0d7317_0 + - cysignals=1.11.2=py39hf6ae30e_3 + - cython=3.0.10=py39hd253f6c_0 + - debugpy=1.8.1=py39hd253f6c_0 + - decorator=5.1.1=pyhd8ed1ab_0 + - defusedxml=0.7.1=pyhd8ed1ab_0 - distlib=0.3.8=pyhd8ed1ab_0 + - docutils=0.21.2=pyhd8ed1ab_0 + - dsdp=5.8=h6e329d1_1203 - ecl=23.9.9=h2b27fa8_0 - eclib=20231212=h02435c3_0 - ecm=7.0.5=h4f6b447_0 + - editables=0.5=pyhd8ed1ab_0 + - entrypoints=0.4=pyhd8ed1ab_0 + - exceptiongroup=1.2.0=pyhd8ed1ab_2 + - executing=2.0.1=pyhd8ed1ab_0 - expat=2.6.2=h73e2aa4_0 - fflas-ffpack=2.5.0=h5898d61_0 + - fftw=3.3.10=nompi_h292e606_110 - filelock=3.15.4=pyhd8ed1ab_0 + - flit-core=3.9.0=pyhd8ed1ab_1 - 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 @@ -53,11 +99,17 @@ dependencies: - fontconfig=2.14.2=h5bb23bf_0 - fonts-conda-ecosystem=1=0 - fonts-conda-forge=1=0 + - fonttools=4.53.0=py39hded5825_0 - fortran-compiler=1.7.0=h6c2ab21_1 - fplll=5.4.5=hb7981ad_0 + - fpylll=0.6.1=py39h3b3ffec_0 + - fqdn=1.5.1=pyhd8ed1ab_0 - freetype=2.12.1=h60636b9_2 + - fribidi=1.0.10=hbcb3906_0 + - furo=2024.5.6=pyhd8ed1ab_0 - gap-core=4.12.2=hc16eb5f_3 - gap-defaults=4.12.2=h694c41f_3 + - gast=0.5.4=pyhd8ed1ab_0 - gengetopt=2.23=he49afe7_0 - gettext=0.22.5=h5ff76d1_2 - gettext-tools=0.22.5=h5ff76d1_2 @@ -71,28 +123,74 @@ dependencies: - givaro=4.2.0=h1b3d6f7_0 - glpk=5.0=h3cb5acd_0 - gmp=6.3.0=hf036a51_2 + - gmpy2=2.1.5=py39h87b48b1_1 + - graphite2=1.3.13=h73e2aa4_1003 - gsl=2.7=h93259b0_0 + - h11=0.14.0=pyhd8ed1ab_0 + - h2=4.1.0=pyhd8ed1ab_0 + - harfbuzz=8.5.0=h053f038_0 + - hatchling=1.25.0=pyhd8ed1ab_0 + - hpack=4.0.0=pyh9f0ad1d_0 + - httpcore=1.0.5=pyhd8ed1ab_0 + - httpx=0.27.0=pyhd8ed1ab_0 + - hyperframe=6.0.1=pyhd8ed1ab_0 - icu=73.2=hf5e326d_0 + - idna=3.7=pyhd8ed1ab_0 - igraph=0.10.12=hde4452d_1 + - imagesize=1.4.1=pyhd8ed1ab_0 - iml=1.0.5=h61918c1_1004 - importlib-metadata=8.0.0=pyha770c72_0 + - importlib-resources=6.4.0=pyhd8ed1ab_0 - importlib_metadata=8.0.0=hd8ed1ab_0 + - importlib_resources=6.4.0=pyhd8ed1ab_0 + - ipykernel=6.29.4=pyh57ce528_0 + - ipympl=0.9.4=pyhd8ed1ab_0 + - ipython=8.18.1=pyh707e725_3 + - ipython_genutils=0.2.0=pyhd8ed1ab_1 + - ipywidgets=8.1.3=pyhd8ed1ab_0 - isl=0.26=imath32_h2e86a7b_101 + - isoduration=20.11.0=pyhd8ed1ab_0 + - jedi=0.19.1=pyhd8ed1ab_0 + - jinja2=3.1.4=pyhd8ed1ab_0 + - jmol=14.32.9=h694c41f_0 + - json5=0.9.25=pyhd8ed1ab_0 + - jsonpointer=3.0.0=py39h6e9494a_0 + - jsonschema=4.22.0=pyhd8ed1ab_0 + - jsonschema-specifications=2023.12.1=pyhd8ed1ab_0 + - jsonschema-with-format-nongpl=4.22.0=pyhd8ed1ab_0 + - jupyter-jsmol=2022.1.0=pyhd8ed1ab_0 + - jupyter-lsp=2.2.5=pyhd8ed1ab_0 + - jupyter-sphinx=0.5.3=pyha770c72_4 + - jupyter_client=8.6.2=pyhd8ed1ab_0 + - jupyter_core=5.7.1=py39h6e9494a_0 + - jupyter_events=0.10.0=pyhd8ed1ab_0 + - jupyter_server=2.14.1=pyhd8ed1ab_0 + - jupyter_server_terminals=0.5.3=pyhd8ed1ab_0 + - jupyter_sphinx=0.5.3=hd8ed1ab_4 + - jupyterlab=4.2.2=pyhd8ed1ab_0 + - jupyterlab_pygments=0.3.0=pyhd8ed1ab_1 + - jupyterlab_server=2.27.2=pyhd8ed1ab_0 + - jupyterlab_widgets=3.0.11=pyhd8ed1ab_0 + - kiwisolver=1.4.5=py39h8ee36c8_1 - krb5=1.21.2=hb884880_0 - lcalc=2.0.5=h547a6ed_2 + - lcms2=2.16=ha2f27b4_0 - ld64=711=ha02d983_0 - ld64_osx-64=711=ha20a434_0 - lerc=4.0.0=hb486fe8_0 - libasprintf=0.22.5=h5ff76d1_2 - libasprintf-devel=0.22.5=h5ff76d1_2 - libatomic_ops=7.6.14=hb7f2c08_0 - - libblas=3.9.0=22_osx64_openblas + - libblas=3.9.0=20_osx64_openblas - libboost=1.85.0=h739af76_2 - libboost-devel=1.85.0=h2b186f8_2 - libboost-headers=1.85.0=h694c41f_2 - libbraiding=1.2=hf0c8a7f_0 - libbrial=1.2.12=h81e9653_3 - - libcblas=3.9.0=22_osx64_openblas + - libbrotlicommon=1.1.0=h0dc2134_1 + - libbrotlidec=1.1.0=h0dc2134_1 + - libbrotlienc=1.1.0=h0dc2134_1 + - libcblas=3.9.0=20_osx64_openblas - libclang-cpp16=16.0.6=default_h4c8afb6_8 - libcurl=8.8.0=hf9fcc65_0 - libcxx=17.0.6=h88467a6_0 @@ -108,17 +206,18 @@ dependencies: - libgfortran=5.0.0=13_2_0_h97931a8_3 - libgfortran-devel_osx-64=12.3.0=h0b6f5ec_3 - libgfortran5=13.2.0=h2873a65_3 + - libglib=2.80.2=h736d271_1 - libhomfly=1.02r6=h10d778d_1 - libhwloc=2.10.0=default_h456cccd_1001 - libiconv=1.17=hd75f5a5_2 - libintl=0.22.5=h5ff76d1_2 - libintl-devel=0.22.5=h5ff76d1_2 - libjpeg-turbo=3.0.0=h0dc2134_1 - - liblapack=3.9.0=22_osx64_openblas - - liblapacke=3.9.0=22_osx64_openblas + - liblapack=3.9.0=20_osx64_openblas + - liblapacke=3.9.0=20_osx64_openblas - libllvm16=16.0.6=hbedff68_3 - libnghttp2=1.58.0=h64cf6d3_1 - - libopenblas=0.3.27=openmp_hfef2a42_0 + - libopenblas=0.3.25=openmp_hfef2a42_0 - libpng=1.6.43=h92b6c6a_0 - libsodium=1.0.18=hbcb3906_1 - libsqlite=3.46.0=h1b8f9f3_0 @@ -128,6 +227,7 @@ dependencies: - libuv=1.48.0=h67532ce_0 - libwebp=1.4.0=hc207709_0 - libwebp-base=1.4.0=h10d778d_0 + - libxcb=1.16=h0dc2134_0 - libxml2=2.12.7=h3e169fe_1 - libzlib=1.3.1=h87427d6_1 - linbox=1.7.0=h7061c92_0 @@ -138,62 +238,186 @@ dependencies: - m4ri=20140914=hd82a5f3_1006 - m4rie=20150908=hc616cfc_1002 - make=4.3=h22f3db7_1 + - markupsafe=2.1.5=py39ha09f3b3_0 - mathjax=3.2.2=h694c41f_0 + - matplotlib=3.8.4=py39h6e9494a_2 + - matplotlib-base=3.8.4=py39hfca4cae_2 + - matplotlib-inline=0.1.7=pyhd8ed1ab_0 - maxima=5.47.0=h2b27fa8_2 + - memory-allocator=0.1.3=py39hdc70f33_0 - metis=5.1.0=he965462_1007 + - mistune=3.0.2=pyhd8ed1ab_0 - mpc=1.3.1=h81bd1dd_0 - mpfi=1.5.4=h52b28e3_1001 - mpfr=4.2.1=h4f6b447_1 + - mpmath=1.3.0=pyhd8ed1ab_0 + - munkres=1.1.4=pyh9f0ad1d_0 - nauty=2.8.8=h10d778d_1 + - nbclient=0.10.0=pyhd8ed1ab_0 + - nbconvert=7.16.4=hd8ed1ab_1 + - nbconvert-core=7.16.4=pyhd8ed1ab_1 + - nbconvert-pandoc=7.16.4=hd8ed1ab_1 + - nbformat=5.10.4=pyhd8ed1ab_0 - ncurses=6.5=h5846eda_0 + - nest-asyncio=1.6.0=pyhd8ed1ab_0 + - networkx=3.2.1=pyhd8ed1ab_0 - ninja=1.12.1=h3c5361c_0 + - notebook=7.2.1=pyhd8ed1ab_0 + - notebook-shim=0.2.4=pyhd8ed1ab_0 - ntl=11.4.3=h0ab3c2f_1 - - openblas=0.3.27=openmp_h6794695_0 + - numpy=1.26.4=py39h28c39a1_0 + - openblas=0.3.25=openmp_h6794695_0 + - openjdk=22.0.1=h2d185b6_0 + - openjpeg=2.5.2=h7310d3a_0 - openssl=3.3.1=h87427d6_0 + - overrides=7.7.0=pyhd8ed1ab_0 - packaging=24.1=pyhd8ed1ab_0 - palp=2.20=hbcb3906_0 + - pandoc=3.2.1=h694c41f_0 + - pandocfilters=1.5.0=pyhd8ed1ab_0 + - pango=1.54.0=h880b76c_0 - pari=2.15.5=h7ba67ff_2_pthread - pari-elldata=0.0.20161017=0 - pari-galdata=0.0.20180411=0 - pari-galpol=0.0.20180625=0 - pari-seadata=0.0.20090618=0 - pari-seadata-small=0.0.20090618=0 + - parso=0.8.4=pyhd8ed1ab_0 - patch=2.7.6=hbcf498f_1002 + - pathspec=0.12.1=pyhd8ed1ab_0 + - pcre2=10.44=h7634a1b_0 + - pep517=0.13.0=pyhd8ed1ab_0 - perl=5.32.1=7_h10d778d_perl5 + - pexpect=4.9.0=pyhd8ed1ab_0 + - pickleshare=0.7.5=py_1003 + - pillow=10.3.0=py39hc3a33ae_1 + - pip=24.0=pyhd8ed1ab_0 + - pixman=0.43.4=h73e2aa4_0 - pkg-config=0.29.2=ha3d46e9_1008 + - pkgconfig=1.5.5=pyhd8ed1ab_4 + - pkgutil-resolve-name=1.3.10=pyhd8ed1ab_1 - planarity=3.0.2.0=h10d778d_0 - platformdirs=4.2.2=pyhd8ed1ab_0 - pluggy=1.5.0=pyhd8ed1ab_0 + - ply=3.11=pyhd8ed1ab_2 - ppl=1.2=ha60d53e_1006 - - primecount=7.13=hf455435_0 - - primesieve=12.1=h73e2aa4_0 + - pplpy=0.8.9=py39hc385998_1 + - primecount=7.6=ha894c9a_0 + - primecountpy=0.1.0=py39h8ee36c8_4 + - primesieve=11.0=hf0c8a7f_0 + - prometheus_client=0.20.0=pyhd8ed1ab_0 + - prompt-toolkit=3.0.47=pyha770c72_0 + - prompt_toolkit=3.0.47=hd8ed1ab_0 + - psutil=6.0.0=py39hded5825_0 + - pthread-stubs=0.4=hc929b4f_1001 + - ptyprocess=0.7.0=pyhd3deb0d_0 + - pure_eval=0.2.2=pyhd8ed1ab_0 + - py=1.11.0=pyh6c4a22f_0 + - pybind11=2.12.0=py39h0ca7971_0 + - pybind11-global=2.12.0=py39h0ca7971_0 + - pycparser=2.22=pyhd8ed1ab_0 + - pygments=2.18.0=pyhd8ed1ab_0 + - pyobjc-core=10.3.1=py39hf8f43b1_0 + - pyobjc-framework-cocoa=10.3.1=py39hf8f43b1_0 + - pyparsing=3.1.2=pyhd8ed1ab_0 - pyproject-api=1.7.1=pyhd8ed1ab_0 + - pyrsistent=0.20.0=py39ha09f3b3_0 + - pysocks=1.7.1=pyha2e5f31_6 - python=3.9.19=h7a9c478_0_cpython + - python-build=1.2.1=pyhd8ed1ab_0 + - python-dateutil=2.9.0=pyhd8ed1ab_0 + - python-fastjsonschema=2.20.0=pyhd8ed1ab_0 + - python-json-logger=2.0.7=pyhd8ed1ab_0 + - python-lrcalc=2.1=py39hd253f6c_6 + - python-tzdata=2024.1=pyhd8ed1ab_0 - python_abi=3.9=4_cp39 + - pythran=0.15.0=py39h5d0c61a_1 + - pytz=2024.1=pyhd8ed1ab_0 + - pytz-deprecation-shim=0.1.0.post0=py39h6e9494a_4 + - pyyaml=6.0.1=py39hdc70f33_1 + - pyzmq=26.0.3=py39h304b177_0 - qd=2.3.22=h2beb688_1004 - qhull=2020.2=h940c156_2 + - r-base=4.3.3=h4648a1f_3 + - r-lattice=0.22_6=r43hb2c329c_0 - readline=8.2=h9e318b2_1 + - referencing=0.35.1=pyhd8ed1ab_0 + - requests=2.32.3=pyhd8ed1ab_0 + - rfc3339-validator=0.1.4=pyhd8ed1ab_0 + - rfc3986-validator=0.1.1=pyh9f0ad1d_0 - rhash=1.4.4=h0dc2134_0 + - rpds-py=0.18.1=py39hf59063a_0 + - rpy2=3.5.11=py39r43hd01001f_3 - rw=0.9=h10d778d_2 + - sagemath-db-combinatorial-designs=20140630=1 + - sagemath-db-elliptic-curves=0.8.1=hecc5488_0 + - sagemath-db-graphs=20210214=hd8ed1ab_0 + - sagemath-db-polytopes=20170220=1 + - sagetex=3.6.1=pyhd8ed1ab_0 + - scipy=1.11.4=py39ha321857_0 + - send2trash=1.8.3=pyh31c8845_0 + - setuptools=70.1.1=pyhd8ed1ab_0 + - setuptools-scm=8.1.0=pyhd8ed1ab_0 + - setuptools_scm=8.1.0=hd8ed1ab_0 - sigtool=0.1.3=h88f4db0_0 + - simplegeneric=0.8.1=py_1 - singular=4.3.2.p8=h0d51a9f_1 + - six=1.16.0=pyh6c4a22f_0 + - sniffio=1.3.1=pyhd8ed1ab_0 + - snowballstemmer=2.2.0=pyhd8ed1ab_0 + - soupsieve=2.5=pyhd8ed1ab_1 + - sphinx=7.3.7=pyhd8ed1ab_0 + - sphinx-basic-ng=1.0.0b2=pyhd8ed1ab_1 + - sphinx-copybutton=0.5.2=pyhd8ed1ab_0 + - sphinxcontrib-applehelp=1.0.8=pyhd8ed1ab_0 + - sphinxcontrib-devhelp=1.0.6=pyhd8ed1ab_0 + - sphinxcontrib-htmlhelp=2.0.5=pyhd8ed1ab_0 + - sphinxcontrib-jsmath=1.0.1=pyhd8ed1ab_0 + - sphinxcontrib-qthelp=1.0.7=pyhd8ed1ab_0 + - sphinxcontrib-serializinghtml=1.1.10=pyhd8ed1ab_0 + - sphinxcontrib-websupport=1.2.7=pyhd8ed1ab_0 - sqlite=3.46.0=h28673e1_0 + - stack_data=0.6.2=pyhd8ed1ab_0 - suitesparse=7.7.0=hd2b2131_1 - symmetrica=3.0.1=hf0c8a7f_0 - sympow=2.023.6=h115ba6a_3 + - sympy=1.12.1=pypyh2585a3b_103 - tachyon=0.99b6=h3a1d103_1002 - tapi=1100.0.11=h9ce4665_0 - tar=1.34=hcb2f6ea_1 - tbb=2021.12.0=h3c5361c_1 + - terminado=0.18.1=pyh31c8845_0 - texinfo=7.0=pl5321hc47821c_0 + - three.js=122=hd8ed1ab_2 + - threejs-sage=122=hd8ed1ab_2 + - tinycss2=1.3.0=pyhd8ed1ab_0 - tk=8.6.13=h1abcd95_1 + - tktable=2.10=hba9d6f1_6 - tomli=2.0.1=pyhd8ed1ab_0 + - tornado=6.4.1=py39hded5825_0 - tox=4.15.1=pyhd8ed1ab_0 + - traitlets=5.14.3=pyhd8ed1ab_0 + - trove-classifiers=2024.5.22=pyhd8ed1ab_0 + - types-python-dateutil=2.9.0.20240316=pyhd8ed1ab_0 - typing-extensions=4.12.2=hd8ed1ab_0 - typing_extensions=4.12.2=pyha770c72_0 + - typing_utils=0.1.0=pyhd8ed1ab_0 - tzdata=2024a=h0c530f3_0 + - tzlocal=5.2=py39h6e9494a_0 + - unicodedata2=15.1.0=py39hdc70f33_0 + - uri-template=1.3.0=pyhd8ed1ab_0 + - urllib3=2.2.2=pyhd8ed1ab_0 - virtualenv=20.26.3=pyhd8ed1ab_0 + - wcwidth=0.2.13=pyhd8ed1ab_0 + - webcolors=24.6.0=pyhd8ed1ab_0 + - webencodings=0.5.1=pyhd8ed1ab_2 + - websocket-client=1.8.0=pyhd8ed1ab_0 + - wheel=0.43.0=pyhd8ed1ab_1 + - widgetsnbextension=4.0.11=pyhd8ed1ab_0 + - xorg-libxau=1.0.11=h0dc2134_0 + - xorg-libxdmcp=1.1.3=h35c211d_0 - xz=5.2.6=h775f41a_0 + - yaml=0.2.5=h0d85af4_2 - zeromq=4.3.5=hde137ed_4 - zipp=3.19.2=pyhd8ed1ab_0 - zlib=1.3.1=h87427d6_1 diff --git a/environment-3.9-macos.yml b/environment-3.9-macos.yml index 7dd6e7237ae..612b41003c9 100644 --- a/environment-3.9-macos.yml +++ b/environment-3.9-macos.yml @@ -1,29 +1,54 @@ +name: sage # Generated by conda-lock. # platform: osx-arm64 -# input_hash: 13a4be4ea56a2c01fc235e07908fdf2aea729d6842a807f314ad093449113ac6 +# input_hash: c72df9df3a2c7c120e9ff1ca936ae3527692a0de782793536087f2041f57d700 channels: - conda-forge dependencies: + - _r-mutex=1.0.1=anacondar_1 + - alabaster=0.7.16=pyhd8ed1ab_0 + - anyio=4.4.0=pyhd8ed1ab_0 - appdirs=1.4.4=pyh9f0ad1d_0 + - appnope=0.1.4=pyhd8ed1ab_0 + - argon2-cffi=23.1.0=pyhd8ed1ab_0 + - argon2-cffi-bindings=21.2.0=py39h0f82c59_4 - arpack=3.9.1=nompi_h593882a_101 + - arrow=1.3.0=pyhd8ed1ab_0 + - asttokens=2.4.1=pyhd8ed1ab_0 + - async-lru=2.0.4=pyhd8ed1ab_0 + - attrs=23.2.0=pyh71513ae_0 - autoconf=2.71=pl5321hcd07c0c_1 - automake=1.16.5=pl5321hce30654_0 + - babel=2.14.0=pyhd8ed1ab_0 - bc=1.07.1=h3422bc3_0 - bdw-gc=8.0.6=hc021e02_0 - - blas=2.122=openblas - - blas-devel=3.9.0=22_osxarm64_openblas + - beautifulsoup4=4.12.3=pyha770c72_0 + - beniget=0.4.1=pyhd8ed1ab_0 + - blas=2.120=openblas + - blas-devel=3.9.0=20_osxarm64_openblas + - bleach=6.1.0=pyhd8ed1ab_0 - boost-cpp=1.85.0=hca5e981_2 - brial=1.2.12=pyh694c41f_3 + - brotli=1.1.0=hb547adb_1 + - brotli-bin=1.1.0=hb547adb_1 + - brotli-python=1.1.0=py39hb198ff7_1 + - bwidget=1.9.14=hce30654_1 - bzip2=1.0.8=h93a5062_5 - c-ares=1.28.1=h93a5062_0 - c-compiler=1.7.0=h6aa9301_1 - ca-certificates=2024.6.2=hf0a4a13_0 + - cached-property=1.5.2=hd8ed1ab_1 + - cached_property=1.5.2=pyha770c72_1 - cachetools=5.3.3=pyhd8ed1ab_0 + - cairo=1.18.0=hc6c324b_2 - cctools=986=h4faf515_0 - cctools_osx-arm64=986=h62378fb_0 - cddlib=1!0.94m=h6d7a090_0 + - certifi=2024.6.2=pyhd8ed1ab_0 + - cffi=1.16.0=py39he153c15_0 - chardet=5.2.0=py39h2804cbe_1 + - charset-normalizer=3.3.2=pyhd8ed1ab_0 - clang=16.0.6=default_h095aff0_8 - clang-16=16.0.6=default_hb63da90_8 - clang_impl_osx-arm64=16.0.6=hc421ffc_16 @@ -34,18 +59,39 @@ dependencies: - cliquer=1.22=h93a5062_1 - cmake=3.29.6=had79d8f_0 - colorama=0.4.6=pyhd8ed1ab_0 + - colorlog=6.8.2=py39h2804cbe_0 + - comm=0.2.2=pyhd8ed1ab_0 - compiler-rt=16.0.6=h3808999_2 - compiler-rt_osx-arm64=16.0.6=h3808999_2 - compilers=1.7.0=hce30654_1 + - contourpy=1.2.1=py39h48c5dd5_0 + - conway-polynomials=0.9=pyhd8ed1ab_0 + - cppy=1.2.1=pyhd8ed1ab_0 - curl=8.8.0=h653d890_0 + - cvxopt=1.3.2=py39hf9e8641_2 - cxx-compiler=1.7.0=h2ffa867_1 + - cycler=0.12.1=pyhd8ed1ab_0 + - cypari2=2.1.5=py39h070b2a8_0 + - cysignals=1.11.2=py39h65fc70a_3 + - cython=3.0.10=py39hf3050f2_0 + - debugpy=1.8.1=py39hf3050f2_0 + - decorator=5.1.1=pyhd8ed1ab_0 + - defusedxml=0.7.1=pyhd8ed1ab_0 - distlib=0.3.8=pyhd8ed1ab_0 + - docutils=0.21.2=pyhd8ed1ab_0 + - dsdp=5.8=h9397a75_1203 - ecl=23.9.9=h1d9728a_0 - eclib=20231212=h7f07de4_0 - ecm=7.0.5=h41d338b_0 + - editables=0.5=pyhd8ed1ab_0 + - entrypoints=0.4=pyhd8ed1ab_0 + - exceptiongroup=1.2.0=pyhd8ed1ab_2 + - executing=2.0.1=pyhd8ed1ab_0 - expat=2.6.2=hebf3989_0 - fflas-ffpack=2.5.0=h4bc3318_0 + - fftw=3.3.10=nompi_h6637ab6_110 - filelock=3.15.4=pyhd8ed1ab_0 + - flit-core=3.9.0=pyhd8ed1ab_1 - 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 @@ -53,11 +99,17 @@ dependencies: - fontconfig=2.14.2=h82840c6_0 - fonts-conda-ecosystem=1=0 - fonts-conda-forge=1=0 + - fonttools=4.53.0=py39hfea33bf_0 - fortran-compiler=1.7.0=hafb19e3_1 - fplll=5.4.5=hb7d509d_0 + - fpylll=0.6.1=py39h2eadeda_0 + - fqdn=1.5.1=pyhd8ed1ab_0 - freetype=2.12.1=hadb7bae_2 + - fribidi=1.0.10=h27ca646_0 + - furo=2024.5.6=pyhd8ed1ab_0 - gap-core=4.12.2=he8f4e70_3 - gap-defaults=4.12.2=hce30654_3 + - gast=0.5.4=pyhd8ed1ab_0 - gengetopt=2.23=hbdafb3b_0 - gettext=0.22.5=h8fbad5d_2 - gettext-tools=0.22.5=h8fbad5d_2 @@ -71,28 +123,74 @@ dependencies: - givaro=4.2.0=h018886a_0 - glpk=5.0=h6d7a090_0 - gmp=6.3.0=h7bae524_2 + - gmpy2=2.1.5=py39h9bb7c0c_1 + - graphite2=1.3.13=hebf3989_1003 - gsl=2.7=h6e638da_0 + - h11=0.14.0=pyhd8ed1ab_0 + - h2=4.1.0=pyhd8ed1ab_0 + - harfbuzz=8.5.0=h1836168_0 + - hatchling=1.25.0=pyhd8ed1ab_0 + - hpack=4.0.0=pyh9f0ad1d_0 + - httpcore=1.0.5=pyhd8ed1ab_0 + - httpx=0.27.0=pyhd8ed1ab_0 + - hyperframe=6.0.1=pyhd8ed1ab_0 - icu=73.2=hc8870d7_0 + - idna=3.7=pyhd8ed1ab_0 - igraph=0.10.12=h762ac30_1 + - imagesize=1.4.1=pyhd8ed1ab_0 - iml=1.0.5=hd73f12c_1004 - importlib-metadata=8.0.0=pyha770c72_0 + - importlib-resources=6.4.0=pyhd8ed1ab_0 - importlib_metadata=8.0.0=hd8ed1ab_0 + - importlib_resources=6.4.0=pyhd8ed1ab_0 + - ipykernel=6.29.4=pyh57ce528_0 + - ipympl=0.9.4=pyhd8ed1ab_0 + - ipython=8.18.1=pyh707e725_3 + - ipython_genutils=0.2.0=pyhd8ed1ab_1 + - ipywidgets=8.1.3=pyhd8ed1ab_0 - isl=0.26=imath32_h347afa1_101 + - isoduration=20.11.0=pyhd8ed1ab_0 + - jedi=0.19.1=pyhd8ed1ab_0 + - jinja2=3.1.4=pyhd8ed1ab_0 + - jmol=14.32.10=hce30654_0 + - json5=0.9.25=pyhd8ed1ab_0 + - jsonpointer=3.0.0=py39h2804cbe_0 + - jsonschema=4.22.0=pyhd8ed1ab_0 + - jsonschema-specifications=2023.12.1=pyhd8ed1ab_0 + - jsonschema-with-format-nongpl=4.22.0=pyhd8ed1ab_0 + - jupyter-jsmol=2022.1.0=pyhd8ed1ab_0 + - jupyter-lsp=2.2.5=pyhd8ed1ab_0 + - jupyter-sphinx=0.5.3=pyha770c72_4 + - jupyter_client=8.6.2=pyhd8ed1ab_0 + - jupyter_core=5.7.2=py39h2804cbe_0 + - jupyter_events=0.10.0=pyhd8ed1ab_0 + - jupyter_server=2.14.1=pyhd8ed1ab_0 + - jupyter_server_terminals=0.5.3=pyhd8ed1ab_0 + - jupyter_sphinx=0.5.3=hd8ed1ab_4 + - jupyterlab=4.2.2=pyhd8ed1ab_0 + - jupyterlab_pygments=0.3.0=pyhd8ed1ab_1 + - jupyterlab_server=2.27.2=pyhd8ed1ab_0 + - jupyterlab_widgets=3.0.11=pyhd8ed1ab_0 + - kiwisolver=1.4.5=py39hbd775c9_1 - krb5=1.21.2=h92f50d5_0 - lcalc=2.0.5=h4a402bc_2 + - lcms2=2.16=ha0e7c42_0 - ld64=711=h634c8be_0 - ld64_osx-arm64=711=ha4bd21c_0 - lerc=4.0.0=h9a09cb3_0 - libasprintf=0.22.5=h8fbad5d_2 - libasprintf-devel=0.22.5=h8fbad5d_2 - libatomic_ops=7.6.14=h1a8c8d9_0 - - libblas=3.9.0=22_osxarm64_openblas + - libblas=3.9.0=20_osxarm64_openblas - libboost=1.85.0=h17eb2be_2 - libboost-devel=1.85.0=hf450f58_2 - libboost-headers=1.85.0=hce30654_2 - libbraiding=1.2=hb7217d7_0 - libbrial=1.2.12=h56a29cd_3 - - libcblas=3.9.0=22_osxarm64_openblas + - libbrotlicommon=1.1.0=hb547adb_1 + - libbrotlidec=1.1.0=hb547adb_1 + - libbrotlienc=1.1.0=hb547adb_1 + - libcblas=3.9.0=20_osxarm64_openblas - libclang-cpp16=16.0.6=default_hb63da90_8 - libcurl=8.8.0=h7b6f9a7_0 - libcxx=17.0.6=h5f092b4_0 @@ -115,11 +213,11 @@ dependencies: - libintl=0.22.5=h8fbad5d_2 - libintl-devel=0.22.5=h8fbad5d_2 - libjpeg-turbo=3.0.0=hb547adb_1 - - liblapack=3.9.0=22_osxarm64_openblas - - liblapacke=3.9.0=22_osxarm64_openblas + - liblapack=3.9.0=20_osxarm64_openblas + - liblapacke=3.9.0=20_osxarm64_openblas - libllvm16=16.0.6=haab561b_3 - libnghttp2=1.58.0=ha4dd798_1 - - libopenblas=0.3.27=openmp_h6c19121_0 + - libopenblas=0.3.25=openmp_h6c19121_0 - libpng=1.6.43=h091b4b1_0 - libsodium=1.0.18=h27ca646_1 - libsqlite=3.46.0=hfb93653_0 @@ -129,6 +227,7 @@ dependencies: - libuv=1.48.0=h93a5062_0 - libwebp=1.4.0=h54798ee_0 - libwebp-base=1.4.0=h93a5062_0 + - libxcb=1.16=hf2054a2_0 - libxml2=2.12.7=ha661575_1 - libzlib=1.3.1=hfb2fe0b_1 - linbox=1.7.0=h3afee3a_0 @@ -139,63 +238,186 @@ dependencies: - m4ri=20140914=hc97c1ff_1006 - m4rie=20150908=h22b9e9d_1002 - make=4.3=he57ea6c_1 + - markupsafe=2.1.5=py39h17cfd9d_0 - mathjax=3.2.2=hce30654_0 + - matplotlib=3.8.4=py39hdf13c20_2 + - matplotlib-base=3.8.4=py39h15359f4_2 + - matplotlib-inline=0.1.7=pyhd8ed1ab_0 - maxima=5.47.0=h2bbcd85_2 + - memory-allocator=0.1.3=py39h0f82c59_0 - metis=5.1.0=h13dd4ca_1007 + - mistune=3.0.2=pyhd8ed1ab_0 - mpc=1.3.1=h91ba8db_0 - mpfi=1.5.4=hbde5f5b_1001 - mpfr=4.2.1=h41d338b_1 + - mpmath=1.3.0=pyhd8ed1ab_0 + - munkres=1.1.4=pyh9f0ad1d_0 - nauty=2.8.8=h93a5062_1 + - nbclient=0.10.0=pyhd8ed1ab_0 + - nbconvert=7.16.4=hd8ed1ab_1 + - nbconvert-core=7.16.4=pyhd8ed1ab_1 + - nbconvert-pandoc=7.16.4=hd8ed1ab_1 + - nbformat=5.10.4=pyhd8ed1ab_0 - ncurses=6.5=hb89a1cb_0 + - nest-asyncio=1.6.0=pyhd8ed1ab_0 + - networkx=3.2.1=pyhd8ed1ab_0 - ninja=1.12.1=h420ef59_0 + - notebook=7.2.1=pyhd8ed1ab_0 + - notebook-shim=0.2.4=pyhd8ed1ab_0 - ntl=11.4.3=hbb3f309_1 - - openblas=0.3.27=openmp_h55c453e_0 + - numpy=1.26.4=py39h7aa2656_0 + - openblas=0.3.25=openmp_h55c453e_0 + - openjdk=22.0.1=hbeb2e11_0 + - openjpeg=2.5.2=h9f1df11_0 - openssl=3.3.1=hfb2fe0b_0 + - overrides=7.7.0=pyhd8ed1ab_0 - packaging=24.1=pyhd8ed1ab_0 - palp=2.20=h27ca646_0 + - pandoc=3.2.1=hce30654_0 + - pandocfilters=1.5.0=pyhd8ed1ab_0 + - pango=1.54.0=h5cb9fbc_0 - pari=2.15.5=h4f2304c_2_pthread - pari-elldata=0.0.20161017=0 - pari-galdata=0.0.20180411=0 - pari-galpol=0.0.20180625=0 - pari-seadata=0.0.20090618=0 - pari-seadata-small=0.0.20090618=0 + - parso=0.8.4=pyhd8ed1ab_0 - patch=2.7.6=h27ca646_1002 + - pathspec=0.12.1=pyhd8ed1ab_0 - pcre2=10.44=h297a79d_0 + - pep517=0.13.0=pyhd8ed1ab_0 - perl=5.32.1=7_h4614cfb_perl5 + - pexpect=4.9.0=pyhd8ed1ab_0 + - pickleshare=0.7.5=py_1003 + - pillow=10.3.0=py39h3baf582_1 + - pip=24.0=pyhd8ed1ab_0 + - pixman=0.43.4=hebf3989_0 - pkg-config=0.29.2=hab62308_1008 + - pkgconfig=1.5.5=pyhd8ed1ab_4 + - pkgutil-resolve-name=1.3.10=pyhd8ed1ab_1 - planarity=3.0.2.0=h93a5062_0 - platformdirs=4.2.2=pyhd8ed1ab_0 - pluggy=1.5.0=pyhd8ed1ab_0 + - ply=3.11=pyhd8ed1ab_2 - ppl=1.2=h8b147cf_1006 - - primecount=7.13=ha9cb33e_0 - - primesieve=12.1=hebf3989_0 + - pplpy=0.8.9=py39ha497ee3_1 + - primecount=7.6=hb6e4faa_0 + - primecountpy=0.1.0=py39hbd775c9_4 + - primesieve=11.0=hb7217d7_0 + - prometheus_client=0.20.0=pyhd8ed1ab_0 + - prompt-toolkit=3.0.47=pyha770c72_0 + - prompt_toolkit=3.0.47=hd8ed1ab_0 + - psutil=6.0.0=py39hfea33bf_0 + - pthread-stubs=0.4=h27ca646_1001 + - ptyprocess=0.7.0=pyhd3deb0d_0 + - pure_eval=0.2.2=pyhd8ed1ab_0 + - py=1.11.0=pyh6c4a22f_0 + - pybind11=2.12.0=py39h48c5dd5_0 + - pybind11-global=2.12.0=py39h48c5dd5_0 + - pycparser=2.22=pyhd8ed1ab_0 + - pygments=2.18.0=pyhd8ed1ab_0 + - pyobjc-core=10.3.1=py39h336d860_0 + - pyobjc-framework-cocoa=10.3.1=py39h336d860_0 + - pyparsing=3.1.2=pyhd8ed1ab_0 - pyproject-api=1.7.1=pyhd8ed1ab_0 + - pyrsistent=0.20.0=py39h17cfd9d_0 + - pysocks=1.7.1=pyha2e5f31_6 - python=3.9.19=hd7ebdb9_0_cpython + - python-build=1.2.1=pyhd8ed1ab_0 + - python-dateutil=2.9.0=pyhd8ed1ab_0 + - python-fastjsonschema=2.20.0=pyhd8ed1ab_0 + - python-json-logger=2.0.7=pyhd8ed1ab_0 + - python-lrcalc=2.1=py39hf3050f2_6 + - python-tzdata=2024.1=pyhd8ed1ab_0 - python_abi=3.9=4_cp39 + - pythran=0.15.0=py39h1261dcd_1 + - pytz=2024.1=pyhd8ed1ab_0 + - pytz-deprecation-shim=0.1.0.post0=py39h2804cbe_4 + - pyyaml=6.0.1=py39h0f82c59_1 + - pyzmq=26.0.3=py39he7f0319_0 - qd=2.3.22=hbec66e7_1004 - qhull=2020.2=hc021e02_2 + - r-base=4.3.3=h8112bfe_3 + - r-lattice=0.22_6=r43hd2d937b_0 - readline=8.2=h92ec313_1 + - referencing=0.35.1=pyhd8ed1ab_0 + - requests=2.32.3=pyhd8ed1ab_0 + - rfc3339-validator=0.1.4=pyhd8ed1ab_0 + - rfc3986-validator=0.1.1=pyh9f0ad1d_0 - rhash=1.4.4=hb547adb_0 + - rpds-py=0.18.1=py39h0019b8a_0 + - rpy2=3.5.11=py39r43hf4a74a7_3 - rw=0.9=h93a5062_2 + - sagemath-db-combinatorial-designs=20140630=1 + - sagemath-db-elliptic-curves=0.8.1=hecc5488_0 + - sagemath-db-graphs=20210214=hd8ed1ab_0 + - sagemath-db-polytopes=20170220=1 + - sagetex=3.6.1=pyhd8ed1ab_0 + - scipy=1.11.4=py39h36c428d_0 + - send2trash=1.8.3=pyh31c8845_0 + - setuptools=70.1.1=pyhd8ed1ab_0 + - setuptools-scm=8.1.0=pyhd8ed1ab_0 + - setuptools_scm=8.1.0=hd8ed1ab_0 - sigtool=0.1.3=h44b9a77_0 + - simplegeneric=0.8.1=py_1 - singular=4.3.2.p8=hb460b52_1 + - six=1.16.0=pyh6c4a22f_0 + - sniffio=1.3.1=pyhd8ed1ab_0 + - snowballstemmer=2.2.0=pyhd8ed1ab_0 + - soupsieve=2.5=pyhd8ed1ab_1 + - sphinx=7.3.7=pyhd8ed1ab_0 + - sphinx-basic-ng=1.0.0b2=pyhd8ed1ab_1 + - sphinx-copybutton=0.5.2=pyhd8ed1ab_0 + - sphinxcontrib-applehelp=1.0.8=pyhd8ed1ab_0 + - sphinxcontrib-devhelp=1.0.6=pyhd8ed1ab_0 + - sphinxcontrib-htmlhelp=2.0.5=pyhd8ed1ab_0 + - sphinxcontrib-jsmath=1.0.1=pyhd8ed1ab_0 + - sphinxcontrib-qthelp=1.0.7=pyhd8ed1ab_0 + - sphinxcontrib-serializinghtml=1.1.10=pyhd8ed1ab_0 + - sphinxcontrib-websupport=1.2.7=pyhd8ed1ab_0 - sqlite=3.46.0=h5838104_0 + - stack_data=0.6.2=pyhd8ed1ab_0 - suitesparse=7.7.0=hf6fcff2_1 - symmetrica=3.0.1=hb7217d7_0 - sympow=2.023.6=hb0babe8_3 + - sympy=1.12.1=pypyh2585a3b_103 - tachyon=0.99b6=hb8a568e_1002 - tapi=1100.0.11=he4954df_0 - tar=1.34=h7cb298e_1 - tbb=2021.12.0=h420ef59_1 + - terminado=0.18.1=pyh31c8845_0 - texinfo=7.0=pl5321h9ea1dce_0 + - three.js=122=hd8ed1ab_2 + - threejs-sage=122=hd8ed1ab_2 + - tinycss2=1.3.0=pyhd8ed1ab_0 - tk=8.6.13=h5083fa2_1 + - tktable=2.10=h1e387b8_6 - tomli=2.0.1=pyhd8ed1ab_0 + - tornado=6.4.1=py39hfea33bf_0 - tox=4.15.1=pyhd8ed1ab_0 + - traitlets=5.14.3=pyhd8ed1ab_0 + - trove-classifiers=2024.5.22=pyhd8ed1ab_0 + - types-python-dateutil=2.9.0.20240316=pyhd8ed1ab_0 - typing-extensions=4.12.2=hd8ed1ab_0 - typing_extensions=4.12.2=pyha770c72_0 + - typing_utils=0.1.0=pyhd8ed1ab_0 - tzdata=2024a=h0c530f3_0 + - tzlocal=5.2=py39h2804cbe_0 + - unicodedata2=15.1.0=py39h0f82c59_0 + - uri-template=1.3.0=pyhd8ed1ab_0 + - urllib3=2.2.2=pyhd8ed1ab_0 - virtualenv=20.26.3=pyhd8ed1ab_0 + - wcwidth=0.2.13=pyhd8ed1ab_0 + - webcolors=24.6.0=pyhd8ed1ab_0 + - webencodings=0.5.1=pyhd8ed1ab_2 + - websocket-client=1.8.0=pyhd8ed1ab_0 + - wheel=0.43.0=pyhd8ed1ab_1 + - widgetsnbextension=4.0.11=pyhd8ed1ab_0 + - xorg-libxau=1.0.11=hb547adb_0 + - xorg-libxdmcp=1.1.3=h27ca646_0 - xz=5.2.6=h57fd34a_0 + - yaml=0.2.5=h3422bc3_2 - zeromq=4.3.5=hcc0f68c_4 - zipp=3.19.2=pyhd8ed1ab_0 - zlib=1.3.1=hfb2fe0b_1 diff --git a/src/environment-dev-3.10-linux-aarch64.yml b/environment-dev-3.10-linux-aarch64.yml similarity index 99% rename from src/environment-dev-3.10-linux-aarch64.yml rename to environment-dev-3.10-linux-aarch64.yml index 5cc9a611a2a..111950c3a42 100644 --- a/src/environment-dev-3.10-linux-aarch64.yml +++ b/environment-dev-3.10-linux-aarch64.yml @@ -1,3 +1,4 @@ +name: sage-dev # Generated by conda-lock. # platform: linux-aarch64 # input_hash: d36865ba776427275c808ea91ee0d71d1f653f57bf83e81fbb92003fd5db575e diff --git a/src/environment-dev-3.10-linux.yml b/environment-dev-3.10-linux.yml similarity index 99% rename from src/environment-dev-3.10-linux.yml rename to environment-dev-3.10-linux.yml index 90d8df80567..a3356dfc772 100644 --- a/src/environment-dev-3.10-linux.yml +++ b/environment-dev-3.10-linux.yml @@ -1,3 +1,4 @@ +name: sage-dev # Generated by conda-lock. # platform: linux-64 # input_hash: f5ac6bc66f134451e0ec73f0a00b8da508df8c7c642f57231ab559a7c63f8ee0 diff --git a/src/environment-dev-3.10-macos-x86_64.yml b/environment-dev-3.10-macos-x86_64.yml similarity index 99% rename from src/environment-dev-3.10-macos-x86_64.yml rename to environment-dev-3.10-macos-x86_64.yml index 6541d3ef7c8..c3f4696d491 100644 --- a/src/environment-dev-3.10-macos-x86_64.yml +++ b/environment-dev-3.10-macos-x86_64.yml @@ -1,3 +1,4 @@ +name: sage-dev # Generated by conda-lock. # platform: osx-64 # input_hash: 6f780a484a3cb4f5357ae4fc25f621ccf74f1cb625cb47cbd49f37ed9e7d3f46 diff --git a/src/environment-dev-3.10-macos.yml b/environment-dev-3.10-macos.yml similarity index 99% rename from src/environment-dev-3.10-macos.yml rename to environment-dev-3.10-macos.yml index 014df8bdc08..49656eea405 100644 --- a/src/environment-dev-3.10-macos.yml +++ b/environment-dev-3.10-macos.yml @@ -1,3 +1,4 @@ +name: sage-dev # Generated by conda-lock. # platform: osx-arm64 # input_hash: c03964bb63187e8dea2adbfa9332f08fbdb1b89d359248a94c39f3af0db26d90 diff --git a/src/environment-dev-3.11-linux-aarch64.yml b/environment-dev-3.11-linux-aarch64.yml similarity index 99% rename from src/environment-dev-3.11-linux-aarch64.yml rename to environment-dev-3.11-linux-aarch64.yml index 9772d14d173..d02836fc39b 100644 --- a/src/environment-dev-3.11-linux-aarch64.yml +++ b/environment-dev-3.11-linux-aarch64.yml @@ -1,3 +1,4 @@ +name: sage-dev # Generated by conda-lock. # platform: linux-aarch64 # input_hash: 66aaaed1c1f4084624510fb4e264813007a23f0c2a3526f277199a0ebc059af4 diff --git a/src/environment-dev-3.11-linux.yml b/environment-dev-3.11-linux.yml similarity index 99% rename from src/environment-dev-3.11-linux.yml rename to environment-dev-3.11-linux.yml index f59609c4b25..19bba7f512b 100644 --- a/src/environment-dev-3.11-linux.yml +++ b/environment-dev-3.11-linux.yml @@ -1,3 +1,4 @@ +name: sage-dev # Generated by conda-lock. # platform: linux-64 # input_hash: f63cac647504bbd824a745f50b79ed9af0d2c491bf359361fdaa0624827c7f36 diff --git a/src/environment-dev-3.11-macos-x86_64.yml b/environment-dev-3.11-macos-x86_64.yml similarity index 99% rename from src/environment-dev-3.11-macos-x86_64.yml rename to environment-dev-3.11-macos-x86_64.yml index 3368f995b8c..d49d10ccdd9 100644 --- a/src/environment-dev-3.11-macos-x86_64.yml +++ b/environment-dev-3.11-macos-x86_64.yml @@ -1,3 +1,4 @@ +name: sage-dev # Generated by conda-lock. # platform: osx-64 # input_hash: 76cbd25511c5f90d515f03ecbad120b0c890d6418428d7ee7d5cc0e82468e02a diff --git a/src/environment-dev-3.11-macos.yml b/environment-dev-3.11-macos.yml similarity index 99% rename from src/environment-dev-3.11-macos.yml rename to environment-dev-3.11-macos.yml index ba84799917e..5327c9d5424 100644 --- a/src/environment-dev-3.11-macos.yml +++ b/environment-dev-3.11-macos.yml @@ -1,3 +1,4 @@ +name: sage-dev # Generated by conda-lock. # platform: osx-arm64 # input_hash: 2a680a2d8d0e54717c485a773c614ef8a6102b81d2c396cd75bfe731f43e3b5f diff --git a/src/environment-dev-3.9-linux-aarch64.yml b/environment-dev-3.9-linux-aarch64.yml similarity index 99% rename from src/environment-dev-3.9-linux-aarch64.yml rename to environment-dev-3.9-linux-aarch64.yml index 39923130bc5..eaeb2644dcd 100644 --- a/src/environment-dev-3.9-linux-aarch64.yml +++ b/environment-dev-3.9-linux-aarch64.yml @@ -1,3 +1,4 @@ +name: sage-dev # Generated by conda-lock. # platform: linux-aarch64 # input_hash: ce794cc8451c14571ca9bfc8ecdd74ad09cf8a281a340df449678e0fed967078 diff --git a/src/environment-dev-3.9-linux.yml b/environment-dev-3.9-linux.yml similarity index 99% rename from src/environment-dev-3.9-linux.yml rename to environment-dev-3.9-linux.yml index 451a093512e..24f20d544de 100644 --- a/src/environment-dev-3.9-linux.yml +++ b/environment-dev-3.9-linux.yml @@ -1,3 +1,4 @@ +name: sage-dev # Generated by conda-lock. # platform: linux-64 # input_hash: 9434f8e084f9cad908d6fa3d6e7b5e95bb0546055588979176fb8fe260ae6d0f diff --git a/src/environment-dev-3.9-macos-x86_64.yml b/environment-dev-3.9-macos-x86_64.yml similarity index 99% rename from src/environment-dev-3.9-macos-x86_64.yml rename to environment-dev-3.9-macos-x86_64.yml index 92632f26f85..a09f7e4f3b1 100644 --- a/src/environment-dev-3.9-macos-x86_64.yml +++ b/environment-dev-3.9-macos-x86_64.yml @@ -1,3 +1,4 @@ +name: sage-dev # Generated by conda-lock. # platform: osx-64 # input_hash: 87145dff13f485d3cacd44987c6622d73ff7e5ebfdff843fe604d9835dead5f9 diff --git a/src/environment-dev-3.9-macos.yml b/environment-dev-3.9-macos.yml similarity index 99% rename from src/environment-dev-3.9-macos.yml rename to environment-dev-3.9-macos.yml index bcc3c684e61..44dc2d1cbde 100644 --- a/src/environment-dev-3.9-macos.yml +++ b/environment-dev-3.9-macos.yml @@ -1,3 +1,4 @@ +name: sage-dev # Generated by conda-lock. # platform: osx-arm64 # input_hash: 3e552281740b1a37b111ca4468f2f30142d4a3d4c041f3d342f28b36394c84de diff --git a/src/doc/en/installation/conda.rst b/src/doc/en/installation/conda.rst index 69369767854..e3cbf6b342c 100644 --- a/src/doc/en/installation/conda.rst +++ b/src/doc/en/installation/conda.rst @@ -61,38 +61,6 @@ If there are any installation failures, please report them to the conda-forge maintainers by opening a `GitHub Issue for conda-forge/sage-feedstock `_. - -.. _sec-installation-conda-source: - -Using conda to provide system packages for the Sage distribution -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -If Conda is installed (check by typing ``conda info``), one can install SageMath -from source as follows: - -- Create a new conda environment including all standard packages - recognized by sage, and activate it:: - - $ conda env create --file environment-3.11-linux.yml --name sage-build - $ conda activate sage-build - - If you use a different architecture, replace ``linux`` by ``macos``. - Alternatively, use ``environment-optional-3.11-linux.yml`` in place of - ``environment-3.11-linux.yml`` to create an environment with all standard and optional - packages recognized by sage. - - A different Python version can be selected by replacing ``3.11`` by ``3.9`` - or ``3.10`` in these commands. - -- Then the SageMath distribution will be built using the compilers provided by Conda - and using many packages installed by Conda:: - - $ ./bootstrap - $ ./configure --with-python=$CONDA_PREFIX/bin/python \ - --prefix=$CONDA_PREFIX - $ make - - .. _sec-installation-conda-develop: Using conda to provide all dependencies for the Sage library @@ -118,18 +86,18 @@ Here we assume that you are using a git checkout. .. code-block:: shell - $ mamba env create --file src/environment-dev-3.11-linux.yml --name sage-dev + $ mamba env create --file environment-dev-3.11-linux.yml --name sage-dev $ conda activate sage-dev .. tab:: conda .. code-block:: shell - $ conda env create --file src/environment-dev-3.11-linux.yml --name sage-dev + $ conda env create --file environment-dev-3.11-linux.yml --name sage-dev $ conda activate sage-dev - Alternatively, you can use ``src/environment-3.11-linux.yml`` or - ``src/environment-optional-3.11-linux.yml``, which will only install standard + Alternatively, you can use ``environment-3.11-linux.yml`` or + ``environment-optional-3.11-linux.yml``, which will only install standard (and optional) packages without any additional developer tools. A different Python version can be selected by replacing ``3.11`` by ``3.9`` @@ -169,7 +137,7 @@ After editing any Cython files, rebuild the Sage library using:: In order to update the conda environment later, you can run:: - $ mamba env update --file src/environment-dev-3.11-linux.yml --name sage-dev + $ mamba env update --file environment-dev-3.11-linux.yml --name sage-dev To build the documentation, use:: @@ -188,5 +156,5 @@ To build the documentation, use:: You can update the conda lock files by running ``.github/workflows/conda-lock-update.py`` or by running - ``conda-lock --platform linux-64 --filename src/environment-dev-3.11-linux.yml --lockfile src/environment-dev-3.11-linux.lock`` + ``conda-lock --platform linux-64 --filename environment-dev-3.11-linux.yml --lockfile environment-dev-3.11-linux.lock`` manually. diff --git a/src/environment-3.10-linux-aarch64.yml b/src/environment-3.10-linux-aarch64.yml deleted file mode 100644 index 7c6026a6b00..00000000000 --- a/src/environment-3.10-linux-aarch64.yml +++ /dev/null @@ -1,435 +0,0 @@ -# Generated by conda-lock. -# platform: linux-aarch64 -# input_hash: 50ecbf09a118347f6c002960a184cf81c369d83e8e8555c2db3282013254eca1 - -channels: - - conda-forge -dependencies: - - _openmp_mutex=4.5=2_kmp_llvm - - _r-mutex=1.0.1=anacondar_1 - - _sysroot_linux-aarch64_curr_repodata_hack=4=h57d6b7b_14 - - alabaster=0.7.16=pyhd8ed1ab_0 - - alsa-lib=1.2.11=h31becfc_1 - - anyio=4.4.0=pyhd8ed1ab_0 - - appdirs=1.4.4=pyh9f0ad1d_0 - - appnope=0.1.4=pyhd8ed1ab_0 - - argon2-cffi=23.1.0=pyhd8ed1ab_0 - - argon2-cffi-bindings=21.2.0=py310hb299538_4 - - arpack=3.9.1=nompi_hd363cd0_101 - - arrow=1.3.0=pyhd8ed1ab_0 - - asttokens=2.4.1=pyhd8ed1ab_0 - - async-lru=2.0.4=pyhd8ed1ab_0 - - attrs=23.2.0=pyh71513ae_0 - - autoconf=2.71=pl5321h2148fe1_1 - - automake=1.16.5=pl5321h8af1aa0_0 - - babel=2.14.0=pyhd8ed1ab_0 - - bc=1.07.1=hf897c2e_0 - - bdw-gc=8.0.6=hd62202e_0 - - beautifulsoup4=4.12.3=pyha770c72_0 - - beniget=0.4.1=pyhd8ed1ab_0 - - binutils=2.40=hf1166c9_7 - - binutils_impl_linux-aarch64=2.40=hf54a868_7 - - binutils_linux-aarch64=2.40=h1f91aba_9 - - blas=2.120=openblas - - blas-devel=3.9.0=20_linuxaarch64_openblas - - bleach=6.1.0=pyhd8ed1ab_0 - - boost-cpp=1.85.0=ha990451_2 - - brial=1.2.12=pyh694c41f_3 - - brotli=1.1.0=h31becfc_1 - - brotli-bin=1.1.0=h31becfc_1 - - brotli-python=1.1.0=py310hbb3657e_1 - - bwidget=1.9.14=h8af1aa0_1 - - bzip2=1.0.8=h31becfc_5 - - c-ares=1.28.1=h31becfc_0 - - c-compiler=1.7.0=h31becfc_1 - - ca-certificates=2024.6.2=hcefe29a_0 - - cached-property=1.5.2=hd8ed1ab_1 - - cached_property=1.5.2=pyha770c72_1 - - cachetools=5.3.3=pyhd8ed1ab_0 - - cairo=1.18.0=h5c54ea9_2 - - cddlib=1!0.94m=h719063d_0 - - certifi=2024.6.2=pyhd8ed1ab_0 - - cffi=1.16.0=py310hce94938_0 - - chardet=5.2.0=py310hbbe02a8_1 - - charset-normalizer=3.3.2=pyhd8ed1ab_0 - - cliquer=1.22=h31becfc_1 - - cmake=3.29.6=h7042e5d_0 - - colorama=0.4.6=pyhd8ed1ab_0 - - colorlog=6.8.2=py310h4c7bcd0_0 - - comm=0.2.2=pyhd8ed1ab_0 - - compilers=1.7.0=h8af1aa0_1 - - contourpy=1.2.1=py310h586407a_0 - - conway-polynomials=0.9=pyhd8ed1ab_0 - - cppy=1.2.1=pyhd8ed1ab_0 - - curl=8.8.0=h7daf2e0_0 - - cvxopt=1.3.2=py310he29a27f_2 - - cxx-compiler=1.7.0=h2a328a1_1 - - cycler=0.12.1=pyhd8ed1ab_0 - - cypari2=2.1.5=py310h4cbba44_0 - - cysignals=1.11.2=py310h485802a_3 - - cython=3.0.10=py310hbb3657e_0 - - debugpy=1.8.1=py310hbb3657e_0 - - decorator=5.1.1=pyhd8ed1ab_0 - - defusedxml=0.7.1=pyhd8ed1ab_0 - - distlib=0.3.8=pyhd8ed1ab_0 - - docutils=0.21.2=pyhd8ed1ab_0 - - dsdp=5.8=hb12102e_1203 - - ecl=23.9.9=h6475f26_0 - - eclib=20231212=he26bab5_0 - - ecm=7.0.5=ha2d0fc4_0 - - editables=0.5=pyhd8ed1ab_0 - - entrypoints=0.4=pyhd8ed1ab_0 - - exceptiongroup=1.2.0=pyhd8ed1ab_2 - - executing=2.0.1=pyhd8ed1ab_0 - - expat=2.6.2=h2f0025b_0 - - fflas-ffpack=2.5.0=h503e619_0 - - fftw=3.3.10=nompi_h020dacd_110 - - filelock=3.15.4=pyhd8ed1ab_0 - - flit-core=3.9.0=pyhd8ed1ab_1 - - 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_2 - - fontconfig=2.14.2=ha9a116f_0 - - fonts-conda-ecosystem=1=0 - - fonts-conda-forge=1=0 - - fonttools=4.53.0=py310hb52b2da_0 - - fortran-compiler=1.7.0=h7048d53_1 - - fplll=5.4.5=hb3a790e_0 - - fpylll=0.6.1=py310hfdbf2a6_0 - - fqdn=1.5.1=pyhd8ed1ab_0 - - freetype=2.12.1=hf0a5ef3_2 - - fribidi=1.0.10=hb9de7d4_0 - - furo=2024.5.6=pyhd8ed1ab_0 - - gap-core=4.12.2=h597289e_3 - - gap-defaults=4.12.2=h8af1aa0_3 - - gast=0.5.4=pyhd8ed1ab_0 - - gcc=12.3.0=hdb0cc85_13 - - gcc_impl_linux-aarch64=12.3.0=h3d98823_13 - - gcc_linux-aarch64=12.3.0=ha52a6ea_9 - - gengetopt=2.23=h01db608_0 - - gf2x=1.3.0=h1b3b3a3_2 - - gfan=0.6.2=h5f589ec_1003 - - gfortran=12.3.0=hdb0cc85_13 - - gfortran_impl_linux-aarch64=12.3.0=h97ebfd2_13 - - gfortran_linux-aarch64=12.3.0=ha7b8e4b_9 - - giac=1.9.0.21=h04922a4_1 - - giflib=5.2.2=h31becfc_0 - - givaro=4.2.0=h364d21b_0 - - glpk=5.0=h66325d0_0 - - gmp=6.3.0=h0a1ffab_2 - - gmpy2=2.1.5=py310h05bcf56_1 - - graphite2=1.3.13=h2f0025b_1003 - - gsl=2.7=h294027d_0 - - gxx=12.3.0=hdb0cc85_13 - - gxx_impl_linux-aarch64=12.3.0=hba91e99_13 - - gxx_linux-aarch64=12.3.0=h9d1f256_9 - - h11=0.14.0=pyhd8ed1ab_0 - - h2=4.1.0=pyhd8ed1ab_0 - - harfbuzz=8.5.0=h9812418_0 - - hatchling=1.25.0=pyhd8ed1ab_0 - - hpack=4.0.0=pyh9f0ad1d_0 - - httpcore=1.0.5=pyhd8ed1ab_0 - - httpx=0.27.0=pyhd8ed1ab_0 - - hyperframe=6.0.1=pyhd8ed1ab_0 - - icu=73.2=h787c7f5_0 - - idna=3.7=pyhd8ed1ab_0 - - igraph=0.10.12=h197073e_1 - - imagesize=1.4.1=pyhd8ed1ab_0 - - iml=1.0.5=h15043fe_1004 - - importlib-metadata=8.0.0=pyha770c72_0 - - importlib-resources=6.4.0=pyhd8ed1ab_0 - - importlib_metadata=8.0.0=hd8ed1ab_0 - - importlib_resources=6.4.0=pyhd8ed1ab_0 - - ipykernel=6.29.4=pyh3099207_0 - - ipympl=0.9.4=pyhd8ed1ab_0 - - ipython=8.25.0=pyh707e725_0 - - ipython_genutils=0.2.0=pyhd8ed1ab_1 - - ipywidgets=8.1.3=pyhd8ed1ab_0 - - isoduration=20.11.0=pyhd8ed1ab_0 - - jedi=0.19.1=pyhd8ed1ab_0 - - jinja2=3.1.4=pyhd8ed1ab_0 - - jmol=14.32.10=h8af1aa0_0 - - json5=0.9.25=pyhd8ed1ab_0 - - jsonpointer=3.0.0=py310h4c7bcd0_0 - - jsonschema=4.22.0=pyhd8ed1ab_0 - - jsonschema-specifications=2023.12.1=pyhd8ed1ab_0 - - jsonschema-with-format-nongpl=4.22.0=pyhd8ed1ab_0 - - jupyter-jsmol=2022.1.0=pyhd8ed1ab_0 - - jupyter-lsp=2.2.5=pyhd8ed1ab_0 - - jupyter-sphinx=0.5.3=pyha770c72_4 - - jupyter_client=8.6.2=pyhd8ed1ab_0 - - jupyter_core=5.7.2=py310h4c7bcd0_0 - - jupyter_events=0.10.0=pyhd8ed1ab_0 - - jupyter_server=2.14.1=pyhd8ed1ab_0 - - jupyter_server_terminals=0.5.3=pyhd8ed1ab_0 - - jupyter_sphinx=0.5.3=hd8ed1ab_4 - - jupyterlab=4.2.2=pyhd8ed1ab_0 - - jupyterlab_pygments=0.3.0=pyhd8ed1ab_1 - - jupyterlab_server=2.27.2=pyhd8ed1ab_0 - - jupyterlab_widgets=3.0.11=pyhd8ed1ab_0 - - kernel-headers_linux-aarch64=4.18.0=h5b4a56d_14 - - keyutils=1.6.1=h4e544f5_0 - - kiwisolver=1.4.5=py310he290b8a_1 - - krb5=1.21.2=hc419048_0 - - lcalc=2.0.5=he588f68_2 - - lcms2=2.16=h922389a_0 - - ld_impl_linux-aarch64=2.40=h9fc2d93_7 - - lerc=4.0.0=h4de3ea5_0 - - libatomic_ops=7.6.14=h4e544f5_0 - - libblas=3.9.0=20_linuxaarch64_openblas - - libboost=1.85.0=hb41fec8_2 - - libboost-devel=1.85.0=h37bb5a9_2 - - libboost-headers=1.85.0=h8af1aa0_2 - - libbraiding=1.2=hd600fc2_0 - - libbrial=1.2.12=h9429f74_3 - - libbrotlicommon=1.1.0=h31becfc_1 - - libbrotlidec=1.1.0=h31becfc_1 - - libbrotlienc=1.1.0=h31becfc_1 - - libcblas=3.9.0=20_linuxaarch64_openblas - - libcups=2.3.3=h405e4a8_4 - - libcurl=8.8.0=h4e8248e_0 - - libdeflate=1.20=h31becfc_0 - - libedit=3.1.20191231=he28a2e2_2 - - libev=4.33=h31becfc_2 - - libexpat=2.6.2=h2f0025b_0 - - libffi=3.4.2=h3557bc0_5 - - libflint=3.0.1=hc392af7_ntl_100 - - libgcc-devel_linux-aarch64=12.3.0=h6144e03_113 - - libgcc-ng=13.2.0=he277a41_13 - - libgd=2.3.3=hcd22fd5_9 - - libgfortran-ng=13.2.0=he9431aa_13 - - libgfortran5=13.2.0=h2af0866_13 - - libglib=2.80.2=haee52c6_1 - - libgomp=13.2.0=he277a41_13 - - libhomfly=1.02r6=h31becfc_1 - - libhwloc=2.10.0=default_h3030c0e_1001 - - libiconv=1.17=h31becfc_2 - - libjpeg-turbo=3.0.0=h31becfc_1 - - liblapack=3.9.0=20_linuxaarch64_openblas - - liblapacke=3.9.0=20_linuxaarch64_openblas - - libnghttp2=1.58.0=hb0e430d_1 - - libnsl=2.0.1=h31becfc_0 - - libopenblas=0.3.25=pthreads_h5a5ec62_0 - - libpng=1.6.43=h194ca79_0 - - libsanitizer=12.3.0=h57e2e72_13 - - libsodium=1.0.18=hb9de7d4_1 - - libsqlite=3.46.0=hf51ef55_0 - - libssh2=1.11.0=h492db2e_0 - - libstdcxx-devel_linux-aarch64=12.3.0=h6144e03_113 - - libstdcxx-ng=13.2.0=h3f4de04_13 - - libtiff=4.6.0=hf980d43_3 - - libtool=2.4.7=h4de3ea5_0 - - libuuid=2.38.1=hb4cce97_0 - - libuv=1.48.0=h31becfc_0 - - libwebp=1.4.0=h8b4e01b_0 - - libwebp-base=1.4.0=h31becfc_0 - - libxcb=1.16=h7935292_0 - - libxcrypt=4.4.36=h31becfc_1 - - libxml2=2.12.7=h49dc7a2_1 - - libzlib=1.3.1=h68df207_1 - - linbox=1.7.0=h681a5ee_0 - - llvm-openmp=18.1.8=hb063fc5_0 - - lrcalc=2.1=h2f0025b_6 - - m4=1.4.18=h516909a_1001 - - m4ri=20140914=hedfd65a_1006 - - m4rie=20150908=hf0a5ef3_1002 - - make=4.3=h309ac5b_1 - - markupsafe=2.1.5=py310h7c1f4a2_0 - - mathjax=3.2.2=h8af1aa0_0 - - matplotlib=3.8.4=py310hbbe02a8_2 - - matplotlib-base=3.8.4=py310h84f21c1_2 - - matplotlib-inline=0.1.7=pyhd8ed1ab_0 - - maxima=5.47.0=h6475f26_2 - - memory-allocator=0.1.3=py310hb299538_0 - - metis=5.1.0=h2f0025b_1007 - - mistune=3.0.2=pyhd8ed1ab_0 - - mpc=1.3.1=hf4c8f4c_0 - - mpfi=1.5.4=h846f343_1001 - - mpfr=4.2.1=ha2d0fc4_1 - - mpmath=1.3.0=pyhd8ed1ab_0 - - munkres=1.1.4=pyh9f0ad1d_0 - - nauty=2.8.8=h31becfc_1 - - nbclient=0.10.0=pyhd8ed1ab_0 - - nbconvert=7.16.4=hd8ed1ab_1 - - nbconvert-core=7.16.4=pyhd8ed1ab_1 - - nbconvert-pandoc=7.16.4=hd8ed1ab_1 - - nbformat=5.10.4=pyhd8ed1ab_0 - - ncurses=6.5=h0425590_0 - - nest-asyncio=1.6.0=pyhd8ed1ab_0 - - networkx=3.2.1=pyhd8ed1ab_0 - - ninja=1.12.1=h70be974_0 - - notebook=7.2.1=pyhd8ed1ab_0 - - notebook-shim=0.2.4=pyhd8ed1ab_0 - - ntl=11.4.3=h0d7519b_1 - - numpy=1.26.4=py310hcbab775_0 - - openblas=0.3.25=pthreads_h339cbfa_0 - - openjdk=22.0.1=h3d4cd67_0 - - openjpeg=2.5.2=h0d9d63b_0 - - openssl=3.3.1=h68df207_0 - - overrides=7.7.0=pyhd8ed1ab_0 - - packaging=24.1=pyhd8ed1ab_0 - - palp=2.20=hb9de7d4_0 - - pandoc=3.2.1=h8af1aa0_0 - - pandocfilters=1.5.0=pyhd8ed1ab_0 - - pango=1.54.0=h399c48b_0 - - pari=2.15.5=h169c2a7_2_pthread - - pari-elldata=0.0.20161017=0 - - pari-galdata=0.0.20180411=0 - - pari-galpol=0.0.20180625=0 - - pari-seadata=0.0.20090618=0 - - pari-seadata-small=0.0.20090618=0 - - parso=0.8.4=pyhd8ed1ab_0 - - patch=2.7.6=hf897c2e_1002 - - pathspec=0.12.1=pyhd8ed1ab_0 - - pcre2=10.44=h070dd5b_0 - - pep517=0.13.0=pyhd8ed1ab_0 - - perl=5.32.1=7_h31becfc_perl5 - - pexpect=4.9.0=pyhd8ed1ab_0 - - pickleshare=0.7.5=py_1003 - - pillow=10.3.0=py310h611336f_1 - - pip=24.0=pyhd8ed1ab_0 - - pixman=0.43.4=h2f0025b_0 - - pkg-config=0.29.2=hb9de7d4_1008 - - pkgconfig=1.5.5=pyhd8ed1ab_4 - - pkgutil-resolve-name=1.3.10=pyhd8ed1ab_1 - - planarity=3.0.2.0=h31becfc_0 - - platformdirs=4.2.2=pyhd8ed1ab_0 - - pluggy=1.5.0=pyhd8ed1ab_0 - - ply=3.11=pyhd8ed1ab_2 - - ppl=1.2=h984aac9_1006 - - pplpy=0.8.9=py310h6665419_1 - - primecount=7.9=hd600fc2_0 - - primecountpy=0.1.0=py310h586407a_4 - - primesieve=11.1=h2f0025b_0 - - prometheus_client=0.20.0=pyhd8ed1ab_0 - - prompt-toolkit=3.0.47=pyha770c72_0 - - prompt_toolkit=3.0.47=hd8ed1ab_0 - - psutil=6.0.0=py310hb52b2da_0 - - pthread-stubs=0.4=hb9de7d4_1001 - - ptyprocess=0.7.0=pyhd3deb0d_0 - - pure_eval=0.2.2=pyhd8ed1ab_0 - - py=1.11.0=pyh6c4a22f_0 - - pybind11=2.12.0=py310h586407a_0 - - pybind11-global=2.12.0=py310h586407a_0 - - pycparser=2.22=pyhd8ed1ab_0 - - pygments=2.18.0=pyhd8ed1ab_0 - - pyparsing=3.1.2=pyhd8ed1ab_0 - - pyproject-api=1.7.1=pyhd8ed1ab_0 - - pyrsistent=0.20.0=py310h7c1f4a2_0 - - pysocks=1.7.1=pyha2e5f31_6 - - python=3.10.14=hbbe8eec_0_cpython - - python-build=1.2.1=pyhd8ed1ab_0 - - python-dateutil=2.9.0=pyhd8ed1ab_0 - - python-fastjsonschema=2.20.0=pyhd8ed1ab_0 - - python-json-logger=2.0.7=pyhd8ed1ab_0 - - python-lrcalc=2.1=py310hbb3657e_6 - - python-tzdata=2024.1=pyhd8ed1ab_0 - - python_abi=3.10=4_cp310 - - pythran=0.15.0=py310h5e48e15_1 - - pytz=2024.1=pyhd8ed1ab_0 - - pytz-deprecation-shim=0.1.0.post0=py310h4c7bcd0_4 - - pyyaml=6.0.1=py310hb299538_1 - - pyzmq=26.0.3=py310he875deb_0 - - qd=2.3.22=h05efe27_1004 - - qhull=2020.2=hd62202e_2 - - r-base=4.3.3=h7f20121_3 - - r-lattice=0.22_6=r43h25e906a_0 - - readline=8.2=h8fc344f_1 - - referencing=0.35.1=pyhd8ed1ab_0 - - requests=2.32.3=pyhd8ed1ab_0 - - rfc3339-validator=0.1.4=pyhd8ed1ab_0 - - rfc3986-validator=0.1.1=pyh9f0ad1d_0 - - rhash=1.4.4=h31becfc_0 - - rpds-py=0.18.1=py310h59d1b7a_0 - - rpy2=3.5.11=py310r43h8b6b5fc_3 - - rw=0.9=h31becfc_2 - - sagemath-db-combinatorial-designs=20140630=1 - - sagemath-db-elliptic-curves=0.8.1=hecc5488_0 - - sagemath-db-graphs=20210214=hd8ed1ab_0 - - sagemath-db-polytopes=20170220=1 - - sagetex=3.6.1=pyhd8ed1ab_0 - - scipy=1.11.3=py310hcbab775_1 - - sed=4.8=ha0d5d3d_0 - - send2trash=1.8.3=pyh0d859eb_0 - - setuptools=70.1.1=pyhd8ed1ab_0 - - setuptools-scm=8.1.0=pyhd8ed1ab_0 - - setuptools_scm=8.1.0=hd8ed1ab_0 - - simplegeneric=0.8.1=py_1 - - singular=4.3.2.p8=hbe76a8a_1 - - six=1.16.0=pyh6c4a22f_0 - - sniffio=1.3.1=pyhd8ed1ab_0 - - snowballstemmer=2.2.0=pyhd8ed1ab_0 - - soupsieve=2.5=pyhd8ed1ab_1 - - sphinx=7.3.7=pyhd8ed1ab_0 - - sphinx-basic-ng=1.0.0b2=pyhd8ed1ab_1 - - sphinx-copybutton=0.5.2=pyhd8ed1ab_0 - - sphinxcontrib-applehelp=1.0.8=pyhd8ed1ab_0 - - sphinxcontrib-devhelp=1.0.6=pyhd8ed1ab_0 - - sphinxcontrib-htmlhelp=2.0.5=pyhd8ed1ab_0 - - sphinxcontrib-jsmath=1.0.1=pyhd8ed1ab_0 - - sphinxcontrib-qthelp=1.0.7=pyhd8ed1ab_0 - - sphinxcontrib-serializinghtml=1.1.10=pyhd8ed1ab_0 - - sphinxcontrib-websupport=1.2.7=pyhd8ed1ab_0 - - sqlite=3.46.0=hdc7ab3c_0 - - stack_data=0.6.2=pyhd8ed1ab_0 - - suitesparse=7.7.0=h3944111_1 - - symmetrica=3.0.1=hd600fc2_0 - - sympow=2.023.6=h157afb5_3 - - sympy=1.12.1=pypyh2585a3b_103 - - sysroot_linux-aarch64=2.17=h5b4a56d_14 - - tachyon=0.99b6=ha0bfc61_1002 - - tar=1.34=h048efde_0 - - tbb=2021.12.0=h70be974_1 - - terminado=0.18.1=pyh0d859eb_0 - - texinfo=7.0=pl5321h17f021e_0 - - three.js=122=hd8ed1ab_2 - - threejs-sage=122=hd8ed1ab_2 - - tinycss2=1.3.0=pyhd8ed1ab_0 - - tk=8.6.13=h194ca79_0 - - tktable=2.10=h52f7bd3_6 - - tomli=2.0.1=pyhd8ed1ab_0 - - tornado=6.4.1=py310h03727f4_0 - - tox=4.15.1=pyhd8ed1ab_0 - - traitlets=5.14.3=pyhd8ed1ab_0 - - trove-classifiers=2024.5.22=pyhd8ed1ab_0 - - types-python-dateutil=2.9.0.20240316=pyhd8ed1ab_0 - - typing-extensions=4.12.2=hd8ed1ab_0 - - typing_extensions=4.12.2=pyha770c72_0 - - typing_utils=0.1.0=pyhd8ed1ab_0 - - tzdata=2024a=h0c530f3_0 - - tzlocal=5.2=py310h4c7bcd0_0 - - unicodedata2=15.1.0=py310hb299538_0 - - uri-template=1.3.0=pyhd8ed1ab_0 - - urllib3=2.2.2=pyhd8ed1ab_0 - - virtualenv=20.26.3=pyhd8ed1ab_0 - - wcwidth=0.2.13=pyhd8ed1ab_0 - - webcolors=24.6.0=pyhd8ed1ab_0 - - webencodings=0.5.1=pyhd8ed1ab_2 - - websocket-client=1.8.0=pyhd8ed1ab_0 - - wheel=0.43.0=pyhd8ed1ab_1 - - widgetsnbextension=4.0.11=pyhd8ed1ab_0 - - xorg-fixesproto=5.0=h3557bc0_1002 - - xorg-inputproto=2.3.2=h3557bc0_1002 - - xorg-kbproto=1.0.7=h3557bc0_1002 - - xorg-libice=1.1.1=h7935292_0 - - xorg-libsm=1.2.4=h5a01bc2_0 - - xorg-libx11=1.8.9=h08be655_1 - - xorg-libxau=1.0.11=h31becfc_0 - - xorg-libxdmcp=1.1.3=h3557bc0_0 - - xorg-libxext=1.3.4=h2a766a3_2 - - xorg-libxfixes=5.0.3=h3557bc0_1004 - - xorg-libxi=1.7.10=h3557bc0_0 - - xorg-libxrender=0.9.11=h7935292_0 - - xorg-libxt=1.3.0=h7935292_1 - - xorg-libxtst=1.2.3=hf897c2e_1002 - - xorg-recordproto=1.14.2=hf897c2e_1002 - - xorg-renderproto=0.11.1=h3557bc0_1002 - - xorg-xextproto=7.3.0=h2a766a3_1003 - - xorg-xproto=7.0.31=h3557bc0_1007 - - xz=5.2.6=h9cdd2b7_0 - - yaml=0.2.5=hf897c2e_2 - - zeromq=4.3.5=h28faeed_4 - - zipp=3.19.2=pyhd8ed1ab_0 - - zlib=1.3.1=h68df207_1 - - zstd=1.5.6=h02f22dd_0 diff --git a/src/environment-3.10-linux.yml b/src/environment-3.10-linux.yml deleted file mode 100644 index f2667c2307e..00000000000 --- a/src/environment-3.10-linux.yml +++ /dev/null @@ -1,483 +0,0 @@ -# Generated by conda-lock. -# platform: linux-64 -# input_hash: 5dc443f6ceb3674d099e0ec613ba37acf67d72b0b26699816fc7afb3c9523b1f - -channels: - - conda-forge -dependencies: - - _libgcc_mutex=0.1=conda_forge - - _openmp_mutex=4.5=2_kmp_llvm - - _r-mutex=1.0.1=anacondar_1 - - alabaster=0.7.16=pyhd8ed1ab_0 - - alsa-lib=1.2.12=h4ab18f5_0 - - anyio=4.4.0=pyhd8ed1ab_0 - - appdirs=1.4.4=pyh9f0ad1d_0 - - appnope=0.1.4=pyhd8ed1ab_0 - - argon2-cffi=23.1.0=pyhd8ed1ab_0 - - argon2-cffi-bindings=21.2.0=py310h2372a71_4 - - arpack=3.9.1=nompi_h77f6705_101 - - arrow=1.3.0=pyhd8ed1ab_0 - - asttokens=2.4.1=pyhd8ed1ab_0 - - async-lru=2.0.4=pyhd8ed1ab_0 - - attr=2.5.1=h166bdaf_1 - - attrs=23.2.0=pyh71513ae_0 - - autoconf=2.71=pl5321h2b4cb7a_1 - - automake=1.16.5=pl5321ha770c72_0 - - babel=2.14.0=pyhd8ed1ab_0 - - bc=1.07.1=h7f98852_0 - - bdw-gc=8.0.6=h4bd325d_0 - - beautifulsoup4=4.12.3=pyha770c72_0 - - beniget=0.4.1=pyhd8ed1ab_0 - - binutils=2.40=h4852527_7 - - binutils_impl_linux-64=2.40=ha1999f0_7 - - binutils_linux-64=2.40=hb3c18ed_9 - - blas=2.120=openblas - - blas-devel=3.9.0=20_linux64_openblas - - bleach=6.1.0=pyhd8ed1ab_0 - - boost-cpp=1.85.0=h44aadfe_2 - - brial=1.2.12=pyh694c41f_3 - - brotli=1.1.0=hd590300_1 - - brotli-bin=1.1.0=hd590300_1 - - brotli-python=1.1.0=py310hc6cd4ac_1 - - bwidget=1.9.14=ha770c72_1 - - bzip2=1.0.8=hd590300_5 - - c-ares=1.28.1=hd590300_0 - - c-compiler=1.7.0=hd590300_1 - - ca-certificates=2024.6.2=hbcca054_0 - - cached-property=1.5.2=hd8ed1ab_1 - - cached_property=1.5.2=pyha770c72_1 - - cachetools=5.3.3=pyhd8ed1ab_0 - - cairo=1.18.0=hbb29018_2 - - cddlib=1!0.94m=h9202a9a_0 - - certifi=2024.6.2=pyhd8ed1ab_0 - - cffi=1.16.0=py310h2fee648_0 - - chardet=5.2.0=py310hff52083_1 - - charset-normalizer=3.3.2=pyhd8ed1ab_0 - - cliquer=1.22=hd590300_1 - - cmake=3.29.6=hcafd917_0 - - colorama=0.4.6=pyhd8ed1ab_0 - - colorlog=6.8.2=py310hff52083_0 - - comm=0.2.2=pyhd8ed1ab_0 - - compilers=1.7.0=ha770c72_1 - - contourpy=1.2.1=py310hd41b1e2_0 - - conway-polynomials=0.9=pyhd8ed1ab_0 - - cppy=1.2.1=pyhd8ed1ab_0 - - curl=8.8.0=he654da7_0 - - cvxopt=1.3.2=py310h7b0674a_2 - - cxx-compiler=1.7.0=h00ab1b0_1 - - cycler=0.12.1=pyhd8ed1ab_0 - - cypari2=2.1.5=py310h14ed79e_0 - - cysignals=1.11.2=py310h945e7c7_3 - - cython=3.0.10=py310hc6cd4ac_0 - - dbus=1.13.6=h5008d03_3 - - debugpy=1.8.1=py310hc6cd4ac_0 - - decorator=5.1.1=pyhd8ed1ab_0 - - defusedxml=0.7.1=pyhd8ed1ab_0 - - distlib=0.3.8=pyhd8ed1ab_0 - - docutils=0.21.2=pyhd8ed1ab_0 - - dsdp=5.8=hd9d9efa_1203 - - ecl=23.9.9=hed6455c_0 - - eclib=20231212=h96f522a_0 - - ecm=7.0.5=h9458935_0 - - editables=0.5=pyhd8ed1ab_0 - - entrypoints=0.4=pyhd8ed1ab_0 - - exceptiongroup=1.2.0=pyhd8ed1ab_2 - - executing=2.0.1=pyhd8ed1ab_0 - - expat=2.6.2=h59595ed_0 - - fflas-ffpack=2.5.0=h4f9960b_0 - - fftw=3.3.10=nompi_hf1063bd_110 - - filelock=3.15.4=pyhd8ed1ab_0 - - flit-core=3.9.0=pyhd8ed1ab_1 - - 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_2 - - fontconfig=2.14.2=h14ed4e7_0 - - fonts-conda-ecosystem=1=0 - - fonts-conda-forge=1=0 - - fonttools=4.53.0=py310hc51659f_0 - - fortran-compiler=1.7.0=heb67821_1 - - fplll=5.4.5=h384768b_0 - - fpylll=0.6.1=py310h7e26f94_0 - - fqdn=1.5.1=pyhd8ed1ab_0 - - freetype=2.12.1=h267a509_2 - - fribidi=1.0.10=h36c2ea0_0 - - furo=2024.5.6=pyhd8ed1ab_0 - - gap-core=4.12.2=he9a28a4_3 - - gap-defaults=4.12.2=ha770c72_3 - - gast=0.5.4=pyhd8ed1ab_0 - - gcc=12.3.0=h915e2ae_13 - - gcc_impl_linux-64=12.3.0=h58ffeeb_13 - - gcc_linux-64=12.3.0=h9528a6a_9 - - gengetopt=2.23=h9c3ff4c_0 - - gettext=0.22.5=h59595ed_2 - - gettext-tools=0.22.5=h59595ed_2 - - gf2x=1.3.0=ha476b99_2 - - gfan=0.6.2=hb86e20a_1003 - - gfortran=12.3.0=h915e2ae_13 - - gfortran_impl_linux-64=12.3.0=h8f2110c_13 - - gfortran_linux-64=12.3.0=h5877db1_9 - - giac=1.9.0.21=h673759e_1 - - giflib=5.2.2=hd590300_0 - - givaro=4.2.0=hb789bce_0 - - glib=2.80.2=h8a4344b_1 - - glib-tools=2.80.2=h73ef956_1 - - glpk=5.0=h445213a_0 - - gmp=6.3.0=hac33072_2 - - gmpy2=2.1.5=py310hc7909c9_1 - - graphite2=1.3.13=h59595ed_1003 - - gsl=2.7=he838d99_0 - - gst-plugins-base=1.24.5=hbaaba92_0 - - gstreamer=1.24.5=haf2f30d_0 - - gxx=12.3.0=h915e2ae_13 - - gxx_impl_linux-64=12.3.0=h2a574ab_13 - - gxx_linux-64=12.3.0=ha28b414_9 - - h11=0.14.0=pyhd8ed1ab_0 - - h2=4.1.0=pyhd8ed1ab_0 - - harfbuzz=8.5.0=hfac3d4d_0 - - hatchling=1.25.0=pyhd8ed1ab_0 - - hpack=4.0.0=pyh9f0ad1d_0 - - httpcore=1.0.5=pyhd8ed1ab_0 - - httpx=0.27.0=pyhd8ed1ab_0 - - hyperframe=6.0.1=pyhd8ed1ab_0 - - icu=73.2=h59595ed_0 - - idna=3.7=pyhd8ed1ab_0 - - igraph=0.10.12=hef0740d_1 - - imagesize=1.4.1=pyhd8ed1ab_0 - - iml=1.0.5=h623f65a_1004 - - importlib-metadata=8.0.0=pyha770c72_0 - - importlib-resources=6.4.0=pyhd8ed1ab_0 - - importlib_metadata=8.0.0=hd8ed1ab_0 - - importlib_resources=6.4.0=pyhd8ed1ab_0 - - ipykernel=6.29.4=pyh3099207_0 - - ipympl=0.9.4=pyhd8ed1ab_0 - - ipython=8.25.0=pyh707e725_0 - - ipython_genutils=0.2.0=pyhd8ed1ab_1 - - ipywidgets=8.1.3=pyhd8ed1ab_0 - - isoduration=20.11.0=pyhd8ed1ab_0 - - jedi=0.19.1=pyhd8ed1ab_0 - - jinja2=3.1.4=pyhd8ed1ab_0 - - jmol=14.32.10=ha770c72_0 - - json5=0.9.25=pyhd8ed1ab_0 - - jsonpointer=3.0.0=py310hff52083_0 - - jsonschema=4.22.0=pyhd8ed1ab_0 - - jsonschema-specifications=2023.12.1=pyhd8ed1ab_0 - - jsonschema-with-format-nongpl=4.22.0=pyhd8ed1ab_0 - - jupyter-jsmol=2022.1.0=pyhd8ed1ab_0 - - jupyter-lsp=2.2.5=pyhd8ed1ab_0 - - jupyter-sphinx=0.5.3=pyha770c72_4 - - jupyter_client=8.6.2=pyhd8ed1ab_0 - - jupyter_core=5.7.2=py310hff52083_0 - - jupyter_events=0.10.0=pyhd8ed1ab_0 - - jupyter_server=2.14.1=pyhd8ed1ab_0 - - jupyter_server_terminals=0.5.3=pyhd8ed1ab_0 - - jupyter_sphinx=0.5.3=hd8ed1ab_4 - - jupyterlab=4.2.2=pyhd8ed1ab_0 - - jupyterlab_pygments=0.3.0=pyhd8ed1ab_1 - - jupyterlab_server=2.27.2=pyhd8ed1ab_0 - - jupyterlab_widgets=3.0.11=pyhd8ed1ab_0 - - kernel-headers_linux-64=2.6.32=he073ed8_17 - - keyutils=1.6.1=h166bdaf_0 - - kiwisolver=1.4.5=py310hd41b1e2_1 - - krb5=1.21.2=h659d440_0 - - lame=3.100=h166bdaf_1003 - - lcalc=2.0.5=h5aac1b6_2 - - lcms2=2.16=hb7c19ff_0 - - ld_impl_linux-64=2.40=hf3520f5_7 - - lerc=4.0.0=h27087fc_0 - - libasprintf=0.22.5=h661eb56_2 - - libasprintf-devel=0.22.5=h661eb56_2 - - libatomic_ops=7.6.14=h166bdaf_0 - - libblas=3.9.0=20_linux64_openblas - - libboost=1.85.0=hba137d9_2 - - libboost-devel=1.85.0=h00ab1b0_2 - - libboost-headers=1.85.0=ha770c72_2 - - libbraiding=1.2=hcb278e6_0 - - libbrial=1.2.12=h76af697_3 - - libbrotlicommon=1.1.0=hd590300_1 - - libbrotlidec=1.1.0=hd590300_1 - - libbrotlienc=1.1.0=hd590300_1 - - libcap=2.69=h0f662aa_0 - - libcblas=3.9.0=20_linux64_openblas - - libclang-cpp15=15.0.7=default_h127d8a8_5 - - libclang13=18.1.8=default_h6ae225f_0 - - libcups=2.3.3=h4637d8d_4 - - libcurl=8.8.0=hca28451_0 - - libdeflate=1.20=hd590300_0 - - libedit=3.1.20191231=he28a2e2_2 - - libev=4.33=hd590300_2 - - libevent=2.1.12=hf998b51_1 - - libexpat=2.6.2=h59595ed_0 - - libffi=3.4.2=h7f98852_5 - - libflac=1.4.3=h59595ed_0 - - libflint=3.0.1=h5f2e117_ntl_100 - - libgcc-devel_linux-64=12.3.0=h6b66f73_113 - - libgcc-ng=13.2.0=h77fa898_13 - - libgcrypt=1.10.3=hd590300_0 - - libgd=2.3.3=h119a65a_9 - - libgettextpo=0.22.5=h59595ed_2 - - libgettextpo-devel=0.22.5=h59595ed_2 - - libgfortran-ng=13.2.0=h69a702a_13 - - libgfortran5=13.2.0=h3d2ce59_13 - - libglib=2.80.2=h8a4344b_1 - - libgomp=13.2.0=h77fa898_13 - - libgpg-error=1.49=h4f305b6_0 - - libhomfly=1.02r6=hd590300_1 - - libhwloc=2.10.0=default_h5622ce7_1001 - - libiconv=1.17=hd590300_2 - - libjpeg-turbo=3.0.0=hd590300_1 - - liblapack=3.9.0=20_linux64_openblas - - liblapacke=3.9.0=20_linux64_openblas - - libllvm15=15.0.7=hb3ce162_4 - - libllvm18=18.1.8=hc9dba70_0 - - libnghttp2=1.58.0=h47da74e_1 - - libnsl=2.0.1=hd590300_0 - - libogg=1.3.5=h4ab18f5_0 - - libopenblas=0.3.25=pthreads_h413a1c8_0 - - libopus=1.3.1=h7f98852_1 - - libpng=1.6.43=h2797004_0 - - libpq=16.3=ha72fbe1_0 - - libsanitizer=12.3.0=hb8811af_13 - - libsndfile=1.2.2=hc60ed4a_1 - - libsodium=1.0.18=h36c2ea0_1 - - libsqlite=3.46.0=hde9e2c9_0 - - libssh2=1.11.0=h0841786_0 - - libstdcxx-devel_linux-64=12.3.0=h6b66f73_113 - - libstdcxx-ng=13.2.0=hc0a3c3a_13 - - libsystemd0=255=h3516f8a_1 - - libtiff=4.6.0=h1dd3fc0_3 - - libtool=2.4.7=h27087fc_0 - - libuuid=2.38.1=h0b41bf4_0 - - libuv=1.48.0=hd590300_0 - - libvorbis=1.3.7=h9c3ff4c_0 - - libwebp=1.4.0=h2c329e2_0 - - libwebp-base=1.4.0=hd590300_0 - - libxcb=1.16=hd590300_0 - - libxcrypt=4.4.36=hd590300_1 - - libxkbcommon=1.7.0=h2c5496b_1 - - libxml2=2.12.7=hc051c1a_1 - - libzlib=1.3.1=h4ab18f5_1 - - linbox=1.7.0=ha329b40_0 - - llvm-openmp=18.1.8=hf5423f3_0 - - lrcalc=2.1=h59595ed_6 - - lz4-c=1.9.4=hcb278e6_0 - - m4=1.4.18=h516909a_1001 - - m4ri=20140914=hae5d5c5_1006 - - m4rie=20150908=h267a509_1002 - - make=4.3=hd18ef5c_1 - - markupsafe=2.1.5=py310h2372a71_0 - - mathjax=3.2.2=ha770c72_0 - - matplotlib=3.8.4=py310hff52083_2 - - matplotlib-base=3.8.4=py310hef631a5_2 - - matplotlib-inline=0.1.7=pyhd8ed1ab_0 - - maxima=5.47.0=hed6455c_2 - - memory-allocator=0.1.3=py310h2372a71_0 - - metis=5.1.0=h59595ed_1007 - - mistune=3.0.2=pyhd8ed1ab_0 - - mpc=1.3.1=hfe3b2da_0 - - mpfi=1.5.4=h9f54685_1001 - - mpfr=4.2.1=h9458935_1 - - mpg123=1.32.6=h59595ed_0 - - mpmath=1.3.0=pyhd8ed1ab_0 - - munkres=1.1.4=pyh9f0ad1d_0 - - mysql-common=8.3.0=hf1915f5_4 - - mysql-libs=8.3.0=hca2cd23_4 - - nauty=2.8.8=hd590300_1 - - nbclient=0.10.0=pyhd8ed1ab_0 - - nbconvert=7.16.4=hd8ed1ab_1 - - nbconvert-core=7.16.4=pyhd8ed1ab_1 - - nbconvert-pandoc=7.16.4=hd8ed1ab_1 - - nbformat=5.10.4=pyhd8ed1ab_0 - - ncurses=6.5=h59595ed_0 - - nest-asyncio=1.6.0=pyhd8ed1ab_0 - - networkx=3.2.1=pyhd8ed1ab_0 - - ninja=1.12.1=h297d8ca_0 - - notebook=7.2.1=pyhd8ed1ab_0 - - notebook-shim=0.2.4=pyhd8ed1ab_0 - - nspr=4.35=h27087fc_0 - - nss=3.101=h593d115_0 - - ntl=11.4.3=hef3c4d3_1 - - numpy=1.26.4=py310hb13e2d6_0 - - openblas=0.3.25=pthreads_h7a3da1a_0 - - openjdk=21.0.2=haa376d0_0 - - openjpeg=2.5.2=h488ebb8_0 - - openssl=3.3.1=h4ab18f5_0 - - overrides=7.7.0=pyhd8ed1ab_0 - - packaging=24.1=pyhd8ed1ab_0 - - palp=2.20=h36c2ea0_0 - - pandoc=3.2.1=ha770c72_0 - - pandocfilters=1.5.0=pyhd8ed1ab_0 - - pango=1.54.0=h84a9a3c_0 - - pari=2.15.5=h4d4ae9b_2_pthread - - pari-elldata=0.0.20161017=0 - - pari-galdata=0.0.20180411=0 - - pari-galpol=0.0.20180625=0 - - pari-seadata=0.0.20090618=0 - - pari-seadata-small=0.0.20090618=0 - - parso=0.8.4=pyhd8ed1ab_0 - - patch=2.7.6=h7f98852_1002 - - pathspec=0.12.1=pyhd8ed1ab_0 - - pcre2=10.44=h0f59acf_0 - - pep517=0.13.0=pyhd8ed1ab_0 - - perl=5.32.1=7_hd590300_perl5 - - pexpect=4.9.0=pyhd8ed1ab_0 - - pickleshare=0.7.5=py_1003 - - pillow=10.3.0=py310hebfe307_1 - - pip=24.0=pyhd8ed1ab_0 - - pixman=0.43.2=h59595ed_0 - - pkg-config=0.29.2=h36c2ea0_1008 - - pkgconfig=1.5.5=pyhd8ed1ab_4 - - pkgutil-resolve-name=1.3.10=pyhd8ed1ab_1 - - planarity=3.0.2.0=hd590300_0 - - platformdirs=4.2.2=pyhd8ed1ab_0 - - pluggy=1.5.0=pyhd8ed1ab_0 - - ply=3.11=pyhd8ed1ab_2 - - ppl=1.2=h6ec01c2_1006 - - pplpy=0.8.9=py310h18554fa_1 - - primecount=7.9=hcb278e6_0 - - primecountpy=0.1.0=py310hd41b1e2_4 - - primesieve=11.1=h59595ed_0 - - prometheus_client=0.20.0=pyhd8ed1ab_0 - - prompt-toolkit=3.0.47=pyha770c72_0 - - prompt_toolkit=3.0.47=hd8ed1ab_0 - - psutil=6.0.0=py310hc51659f_0 - - pthread-stubs=0.4=h36c2ea0_1001 - - ptyprocess=0.7.0=pyhd3deb0d_0 - - pulseaudio-client=17.0=hb77b528_0 - - pure_eval=0.2.2=pyhd8ed1ab_0 - - py=1.11.0=pyh6c4a22f_0 - - pybind11=2.12.0=py310hd41b1e2_0 - - pybind11-global=2.12.0=py310hd41b1e2_0 - - pycparser=2.22=pyhd8ed1ab_0 - - pygments=2.18.0=pyhd8ed1ab_0 - - pyparsing=3.1.2=pyhd8ed1ab_0 - - pyproject-api=1.7.1=pyhd8ed1ab_0 - - pyqt=5.15.9=py310h04931ad_5 - - pyqt5-sip=12.12.2=py310hc6cd4ac_5 - - pyrsistent=0.20.0=py310h2372a71_0 - - pysocks=1.7.1=pyha2e5f31_6 - - python=3.10.14=hd12c33a_0_cpython - - python-build=1.2.1=pyhd8ed1ab_0 - - python-dateutil=2.9.0=pyhd8ed1ab_0 - - python-fastjsonschema=2.20.0=pyhd8ed1ab_0 - - python-json-logger=2.0.7=pyhd8ed1ab_0 - - python-lrcalc=2.1=py310hc6cd4ac_6 - - python-tzdata=2024.1=pyhd8ed1ab_0 - - python_abi=3.10=4_cp310 - - pythran=0.15.0=py310hcb52e73_1 - - pytz=2024.1=pyhd8ed1ab_0 - - pytz-deprecation-shim=0.1.0.post0=py310hff52083_4 - - pyyaml=6.0.1=py310h2372a71_1 - - pyzmq=26.0.3=py310h6883aea_0 - - qd=2.3.22=h2cc385e_1004 - - qhull=2020.2=h4bd325d_2 - - qt-main=5.15.8=ha2b5568_22 - - r-base=4.3.3=he2d9a6e_3 - - r-lattice=0.22_6=r43h57805ef_0 - - readline=8.2=h8228510_1 - - referencing=0.35.1=pyhd8ed1ab_0 - - requests=2.32.3=pyhd8ed1ab_0 - - rfc3339-validator=0.1.4=pyhd8ed1ab_0 - - rfc3986-validator=0.1.1=pyh9f0ad1d_0 - - rhash=1.4.4=hd590300_0 - - rpds-py=0.18.1=py310he421c4c_0 - - rpy2=3.5.11=py310r43h1f7b6fc_3 - - rw=0.9=hd590300_2 - - sagemath-db-combinatorial-designs=20140630=1 - - sagemath-db-elliptic-curves=0.8.1=hecc5488_0 - - sagemath-db-graphs=20210214=hd8ed1ab_0 - - sagemath-db-polytopes=20170220=1 - - sagetex=3.6.1=pyhd8ed1ab_0 - - scipy=1.11.4=py310hb13e2d6_0 - - sed=4.8=he412f7d_0 - - send2trash=1.8.3=pyh0d859eb_0 - - setuptools=70.1.1=pyhd8ed1ab_0 - - setuptools-scm=8.1.0=pyhd8ed1ab_0 - - setuptools_scm=8.1.0=hd8ed1ab_0 - - simplegeneric=0.8.1=py_1 - - singular=4.3.2.p8=h33f5c3f_1 - - sip=6.7.12=py310hc6cd4ac_0 - - six=1.16.0=pyh6c4a22f_0 - - sniffio=1.3.1=pyhd8ed1ab_0 - - snowballstemmer=2.2.0=pyhd8ed1ab_0 - - soupsieve=2.5=pyhd8ed1ab_1 - - sphinx=7.3.7=pyhd8ed1ab_0 - - sphinx-basic-ng=1.0.0b2=pyhd8ed1ab_1 - - sphinx-copybutton=0.5.2=pyhd8ed1ab_0 - - sphinxcontrib-applehelp=1.0.8=pyhd8ed1ab_0 - - sphinxcontrib-devhelp=1.0.6=pyhd8ed1ab_0 - - sphinxcontrib-htmlhelp=2.0.5=pyhd8ed1ab_0 - - sphinxcontrib-jsmath=1.0.1=pyhd8ed1ab_0 - - sphinxcontrib-qthelp=1.0.7=pyhd8ed1ab_0 - - sphinxcontrib-serializinghtml=1.1.10=pyhd8ed1ab_0 - - sphinxcontrib-websupport=1.2.7=pyhd8ed1ab_0 - - sqlite=3.46.0=h6d4b2fc_0 - - stack_data=0.6.2=pyhd8ed1ab_0 - - suitesparse=7.7.0=hf4753ba_1 - - symmetrica=3.0.1=hcb278e6_0 - - sympow=2.023.6=hc6ab17c_3 - - sympy=1.12.1=pypyh2585a3b_103 - - sysroot_linux-64=2.12=he073ed8_17 - - tachyon=0.99b6=hba7d16a_1002 - - tar=1.34=hb2e2bae_1 - - tbb=2021.12.0=h297d8ca_1 - - terminado=0.18.1=pyh0d859eb_0 - - texinfo=7.0=pl5321h0f457ee_0 - - three.js=122=hd8ed1ab_2 - - threejs-sage=122=hd8ed1ab_2 - - tinycss2=1.3.0=pyhd8ed1ab_0 - - tk=8.6.13=noxft_h4845f30_101 - - tktable=2.10=h8bc8fbc_6 - - toml=0.10.2=pyhd8ed1ab_0 - - tomli=2.0.1=pyhd8ed1ab_0 - - tornado=6.4.1=py310hc51659f_0 - - tox=4.15.1=pyhd8ed1ab_0 - - traitlets=5.14.3=pyhd8ed1ab_0 - - trove-classifiers=2024.5.22=pyhd8ed1ab_0 - - types-python-dateutil=2.9.0.20240316=pyhd8ed1ab_0 - - typing-extensions=4.12.2=hd8ed1ab_0 - - typing_extensions=4.12.2=pyha770c72_0 - - typing_utils=0.1.0=pyhd8ed1ab_0 - - tzdata=2024a=h0c530f3_0 - - tzlocal=5.2=py310hff52083_0 - - unicodedata2=15.1.0=py310h2372a71_0 - - uri-template=1.3.0=pyhd8ed1ab_0 - - urllib3=2.2.2=pyhd8ed1ab_0 - - virtualenv=20.26.3=pyhd8ed1ab_0 - - wcwidth=0.2.13=pyhd8ed1ab_0 - - webcolors=24.6.0=pyhd8ed1ab_0 - - webencodings=0.5.1=pyhd8ed1ab_2 - - websocket-client=1.8.0=pyhd8ed1ab_0 - - wheel=0.43.0=pyhd8ed1ab_1 - - widgetsnbextension=4.0.11=pyhd8ed1ab_0 - - xcb-util=0.4.1=hb711507_2 - - 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.42=h4ab18f5_0 - - xorg-fixesproto=5.0=h7f98852_1002 - - xorg-inputproto=2.3.2=h7f98852_1002 - - xorg-kbproto=1.0.7=h7f98852_1002 - - xorg-libice=1.1.1=hd590300_0 - - xorg-libsm=1.2.4=h7391055_0 - - xorg-libx11=1.8.9=hb711507_1 - - xorg-libxau=1.0.11=hd590300_0 - - xorg-libxdmcp=1.1.3=h7f98852_0 - - xorg-libxext=1.3.4=h0b41bf4_2 - - xorg-libxfixes=5.0.3=h7f98852_1004 - - xorg-libxi=1.7.10=h7f98852_0 - - xorg-libxrender=0.9.11=hd590300_0 - - xorg-libxt=1.3.0=hd590300_1 - - xorg-libxtst=1.2.3=h7f98852_1002 - - xorg-recordproto=1.14.2=h7f98852_1002 - - xorg-renderproto=0.11.1=h7f98852_1002 - - xorg-xextproto=7.3.0=h0b41bf4_1003 - - xorg-xf86vidmodeproto=2.3.1=h7f98852_1002 - - xorg-xproto=7.0.31=h7f98852_1007 - - xz=5.2.6=h166bdaf_0 - - yaml=0.2.5=h7f98852_2 - - zeromq=4.3.5=h75354e8_4 - - zipp=3.19.2=pyhd8ed1ab_0 - - zlib=1.3.1=h4ab18f5_1 - - zstd=1.5.6=ha6fb4c9_0 diff --git a/src/environment-3.10-macos-x86_64.yml b/src/environment-3.10-macos-x86_64.yml deleted file mode 100644 index 268e619f1ff..00000000000 --- a/src/environment-3.10-macos-x86_64.yml +++ /dev/null @@ -1,423 +0,0 @@ -# Generated by conda-lock. -# platform: osx-64 -# input_hash: 831a1103cbcd8c06cbae982446953e3de30517fdd302ac5aa70454b8d19f63d9 - -channels: - - conda-forge -dependencies: - - _r-mutex=1.0.1=anacondar_1 - - alabaster=0.7.16=pyhd8ed1ab_0 - - anyio=4.4.0=pyhd8ed1ab_0 - - appdirs=1.4.4=pyh9f0ad1d_0 - - appnope=0.1.4=pyhd8ed1ab_0 - - argon2-cffi=23.1.0=pyhd8ed1ab_0 - - argon2-cffi-bindings=21.2.0=py310h6729b98_4 - - arpack=3.9.1=nompi_hf81eadf_101 - - arrow=1.3.0=pyhd8ed1ab_0 - - asttokens=2.4.1=pyhd8ed1ab_0 - - async-lru=2.0.4=pyhd8ed1ab_0 - - attrs=23.2.0=pyh71513ae_0 - - autoconf=2.71=pl5321hed12c24_1 - - automake=1.16.5=pl5321h694c41f_0 - - babel=2.14.0=pyhd8ed1ab_0 - - bc=1.07.1=h0d85af4_0 - - bdw-gc=8.0.6=h940c156_0 - - beautifulsoup4=4.12.3=pyha770c72_0 - - beniget=0.4.1=pyhd8ed1ab_0 - - blas=2.120=openblas - - blas-devel=3.9.0=20_osx64_openblas - - bleach=6.1.0=pyhd8ed1ab_0 - - boost-cpp=1.85.0=h07eb623_2 - - brial=1.2.12=pyh694c41f_3 - - brotli=1.1.0=h0dc2134_1 - - brotli-bin=1.1.0=h0dc2134_1 - - brotli-python=1.1.0=py310h9e9d8ca_1 - - bwidget=1.9.14=h694c41f_1 - - bzip2=1.0.8=h10d778d_5 - - c-ares=1.28.1=h10d778d_0 - - c-compiler=1.7.0=h282daa2_1 - - ca-certificates=2024.6.2=h8857fd0_0 - - cached-property=1.5.2=hd8ed1ab_1 - - cached_property=1.5.2=pyha770c72_1 - - cachetools=5.3.3=pyhd8ed1ab_0 - - cairo=1.18.0=h9f650ed_2 - - cctools=986=h40f6528_0 - - cctools_osx-64=986=ha1c5b94_0 - - cddlib=1!0.94m=h0f52abe_0 - - certifi=2024.6.2=pyhd8ed1ab_0 - - cffi=1.16.0=py310hdca579f_0 - - chardet=5.2.0=py310h2ec42d9_1 - - charset-normalizer=3.3.2=pyhd8ed1ab_0 - - clang=16.0.6=default_ha3b9224_8 - - clang-16=16.0.6=default_h4c8afb6_8 - - clang_impl_osx-64=16.0.6=h8787910_16 - - clang_osx-64=16.0.6=hb91bd55_16 - - clangxx=16.0.6=default_ha3b9224_8 - - clangxx_impl_osx-64=16.0.6=h6d92fbe_16 - - clangxx_osx-64=16.0.6=hb91bd55_16 - - cliquer=1.22=h10d778d_1 - - cmake=3.29.6=h749d262_0 - - colorama=0.4.6=pyhd8ed1ab_0 - - colorlog=6.8.2=py310h2ec42d9_0 - - comm=0.2.2=pyhd8ed1ab_0 - - compiler-rt=16.0.6=ha38d28d_2 - - compiler-rt_osx-64=16.0.6=ha38d28d_2 - - compilers=1.7.0=h694c41f_1 - - contourpy=1.2.1=py310hb3b189b_0 - - conway-polynomials=0.9=pyhd8ed1ab_0 - - cppy=1.2.1=pyhd8ed1ab_0 - - curl=8.8.0=hea67d85_0 - - cvxopt=1.3.2=py310h1fac3e1_2 - - cxx-compiler=1.7.0=h7728843_1 - - cycler=0.12.1=pyhd8ed1ab_0 - - cypari2=2.1.5=py310hc7df965_0 - - cysignals=1.11.2=py310h8c82e65_3 - - cython=3.0.10=py310h5daac23_0 - - debugpy=1.8.1=py310h5daac23_0 - - decorator=5.1.1=pyhd8ed1ab_0 - - defusedxml=0.7.1=pyhd8ed1ab_0 - - distlib=0.3.8=pyhd8ed1ab_0 - - docutils=0.21.2=pyhd8ed1ab_0 - - dsdp=5.8=h6e329d1_1203 - - ecl=23.9.9=h2b27fa8_0 - - eclib=20231212=h02435c3_0 - - ecm=7.0.5=h4f6b447_0 - - editables=0.5=pyhd8ed1ab_0 - - entrypoints=0.4=pyhd8ed1ab_0 - - exceptiongroup=1.2.0=pyhd8ed1ab_2 - - executing=2.0.1=pyhd8ed1ab_0 - - expat=2.6.2=h73e2aa4_0 - - fflas-ffpack=2.5.0=h5898d61_0 - - fftw=3.3.10=nompi_h292e606_110 - - filelock=3.15.4=pyhd8ed1ab_0 - - flit-core=3.9.0=pyhd8ed1ab_1 - - 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_2 - - fontconfig=2.14.2=h5bb23bf_0 - - fonts-conda-ecosystem=1=0 - - fonts-conda-forge=1=0 - - fonttools=4.53.0=py310h936d840_0 - - fortran-compiler=1.7.0=h6c2ab21_1 - - fplll=5.4.5=hb7981ad_0 - - fpylll=0.6.1=py310h65a3d7e_0 - - fqdn=1.5.1=pyhd8ed1ab_0 - - freetype=2.12.1=h60636b9_2 - - fribidi=1.0.10=hbcb3906_0 - - furo=2024.5.6=pyhd8ed1ab_0 - - gap-core=4.12.2=hc16eb5f_3 - - gap-defaults=4.12.2=h694c41f_3 - - gast=0.5.4=pyhd8ed1ab_0 - - gengetopt=2.23=he49afe7_0 - - gettext=0.22.5=h5ff76d1_2 - - gettext-tools=0.22.5=h5ff76d1_2 - - gf2x=1.3.0=hb2a7efb_2 - - gfan=0.6.2=hd793b56_1003 - - gfortran=12.3.0=h2c809b3_1 - - gfortran_impl_osx-64=12.3.0=hc328e78_3 - - gfortran_osx-64=12.3.0=h18f7dce_1 - - giac=1.9.0.21=h92f3f65_1 - - giflib=5.2.2=h10d778d_0 - - givaro=4.2.0=h1b3d6f7_0 - - glpk=5.0=h3cb5acd_0 - - gmp=6.3.0=hf036a51_2 - - gmpy2=2.1.5=py310h0310db1_1 - - graphite2=1.3.13=h73e2aa4_1003 - - gsl=2.7=h93259b0_0 - - h11=0.14.0=pyhd8ed1ab_0 - - h2=4.1.0=pyhd8ed1ab_0 - - harfbuzz=8.5.0=h053f038_0 - - hatchling=1.25.0=pyhd8ed1ab_0 - - hpack=4.0.0=pyh9f0ad1d_0 - - httpcore=1.0.5=pyhd8ed1ab_0 - - httpx=0.27.0=pyhd8ed1ab_0 - - hyperframe=6.0.1=pyhd8ed1ab_0 - - icu=73.2=hf5e326d_0 - - idna=3.7=pyhd8ed1ab_0 - - igraph=0.10.12=hde4452d_1 - - imagesize=1.4.1=pyhd8ed1ab_0 - - iml=1.0.5=h61918c1_1004 - - importlib-metadata=8.0.0=pyha770c72_0 - - importlib-resources=6.4.0=pyhd8ed1ab_0 - - importlib_metadata=8.0.0=hd8ed1ab_0 - - importlib_resources=6.4.0=pyhd8ed1ab_0 - - ipykernel=6.29.4=pyh57ce528_0 - - ipympl=0.9.4=pyhd8ed1ab_0 - - ipython=8.25.0=pyh707e725_0 - - ipython_genutils=0.2.0=pyhd8ed1ab_1 - - ipywidgets=8.1.3=pyhd8ed1ab_0 - - isl=0.26=imath32_h2e86a7b_101 - - isoduration=20.11.0=pyhd8ed1ab_0 - - jedi=0.19.1=pyhd8ed1ab_0 - - jinja2=3.1.4=pyhd8ed1ab_0 - - jmol=14.32.9=h694c41f_0 - - json5=0.9.25=pyhd8ed1ab_0 - - jsonpointer=3.0.0=py310h2ec42d9_0 - - jsonschema=4.22.0=pyhd8ed1ab_0 - - jsonschema-specifications=2023.12.1=pyhd8ed1ab_0 - - jsonschema-with-format-nongpl=4.22.0=pyhd8ed1ab_0 - - jupyter-jsmol=2022.1.0=pyhd8ed1ab_0 - - jupyter-lsp=2.2.5=pyhd8ed1ab_0 - - jupyter-sphinx=0.5.3=pyha770c72_4 - - jupyter_client=8.6.2=pyhd8ed1ab_0 - - jupyter_core=5.7.2=py310h2ec42d9_0 - - jupyter_events=0.10.0=pyhd8ed1ab_0 - - jupyter_server=2.14.1=pyhd8ed1ab_0 - - jupyter_server_terminals=0.5.3=pyhd8ed1ab_0 - - jupyter_sphinx=0.5.3=hd8ed1ab_4 - - jupyterlab=4.2.2=pyhd8ed1ab_0 - - jupyterlab_pygments=0.3.0=pyhd8ed1ab_1 - - jupyterlab_server=2.27.2=pyhd8ed1ab_0 - - jupyterlab_widgets=3.0.11=pyhd8ed1ab_0 - - kiwisolver=1.4.5=py310h88cfcbd_1 - - krb5=1.21.2=hb884880_0 - - lcalc=2.0.5=h547a6ed_2 - - lcms2=2.16=ha2f27b4_0 - - ld64=711=ha02d983_0 - - ld64_osx-64=711=ha20a434_0 - - lerc=4.0.0=hb486fe8_0 - - libasprintf=0.22.5=h5ff76d1_2 - - libasprintf-devel=0.22.5=h5ff76d1_2 - - libatomic_ops=7.6.14=hb7f2c08_0 - - libblas=3.9.0=20_osx64_openblas - - libboost=1.85.0=h739af76_2 - - libboost-devel=1.85.0=h2b186f8_2 - - libboost-headers=1.85.0=h694c41f_2 - - libbraiding=1.2=hf0c8a7f_0 - - libbrial=1.2.12=h81e9653_3 - - libbrotlicommon=1.1.0=h0dc2134_1 - - libbrotlidec=1.1.0=h0dc2134_1 - - libbrotlienc=1.1.0=h0dc2134_1 - - libcblas=3.9.0=20_osx64_openblas - - libclang-cpp16=16.0.6=default_h4c8afb6_8 - - libcurl=8.8.0=hf9fcc65_0 - - libcxx=17.0.6=h88467a6_0 - - libdeflate=1.20=h49d49c5_0 - - libedit=3.1.20191231=h0678c8f_2 - - libev=4.33=h10d778d_2 - - libexpat=2.6.2=h73e2aa4_0 - - libffi=3.4.2=h0d85af4_5 - - libflint=3.0.1=h5d15de0_ntl_100 - - libgd=2.3.3=h0dceb68_9 - - libgettextpo=0.22.5=h5ff76d1_2 - - libgettextpo-devel=0.22.5=h5ff76d1_2 - - libgfortran=5.0.0=13_2_0_h97931a8_3 - - libgfortran-devel_osx-64=12.3.0=h0b6f5ec_3 - - libgfortran5=13.2.0=h2873a65_3 - - libglib=2.80.2=h736d271_1 - - libhomfly=1.02r6=h10d778d_1 - - libhwloc=2.10.0=default_h456cccd_1001 - - libiconv=1.17=hd75f5a5_2 - - libintl=0.22.5=h5ff76d1_2 - - libintl-devel=0.22.5=h5ff76d1_2 - - libjpeg-turbo=3.0.0=h0dc2134_1 - - liblapack=3.9.0=20_osx64_openblas - - liblapacke=3.9.0=20_osx64_openblas - - libllvm16=16.0.6=hbedff68_3 - - libnghttp2=1.58.0=h64cf6d3_1 - - libopenblas=0.3.25=openmp_hfef2a42_0 - - libpng=1.6.43=h92b6c6a_0 - - libsodium=1.0.18=hbcb3906_1 - - libsqlite=3.46.0=h1b8f9f3_0 - - libssh2=1.11.0=hd019ec5_0 - - libtiff=4.6.0=h129831d_3 - - libtool=2.4.7=hf0c8a7f_0 - - libuv=1.48.0=h67532ce_0 - - libwebp=1.4.0=hc207709_0 - - libwebp-base=1.4.0=h10d778d_0 - - libxcb=1.16=h0dc2134_0 - - libxml2=2.12.7=h3e169fe_1 - - libzlib=1.3.1=h87427d6_1 - - linbox=1.7.0=h7061c92_0 - - llvm-openmp=18.1.8=h15ab845_0 - - llvm-tools=16.0.6=hbedff68_3 - - lrcalc=2.1=h73e2aa4_6 - - m4=1.4.18=haf1e3a3_1001 - - m4ri=20140914=hd82a5f3_1006 - - m4rie=20150908=hc616cfc_1002 - - make=4.3=h22f3db7_1 - - markupsafe=2.1.5=py310hb372a2b_0 - - mathjax=3.2.2=h694c41f_0 - - matplotlib=3.8.4=py310h2ec42d9_2 - - matplotlib-base=3.8.4=py310h7ea1ff3_2 - - matplotlib-inline=0.1.7=pyhd8ed1ab_0 - - maxima=5.47.0=h2b27fa8_2 - - memory-allocator=0.1.3=py310h6729b98_0 - - metis=5.1.0=he965462_1007 - - mistune=3.0.2=pyhd8ed1ab_0 - - mpc=1.3.1=h81bd1dd_0 - - mpfi=1.5.4=h52b28e3_1001 - - mpfr=4.2.1=h4f6b447_1 - - mpmath=1.3.0=pyhd8ed1ab_0 - - munkres=1.1.4=pyh9f0ad1d_0 - - nauty=2.8.8=h10d778d_1 - - nbclient=0.10.0=pyhd8ed1ab_0 - - nbconvert=7.16.4=hd8ed1ab_1 - - nbconvert-core=7.16.4=pyhd8ed1ab_1 - - nbconvert-pandoc=7.16.4=hd8ed1ab_1 - - nbformat=5.10.4=pyhd8ed1ab_0 - - ncurses=6.5=h5846eda_0 - - nest-asyncio=1.6.0=pyhd8ed1ab_0 - - networkx=3.2.1=pyhd8ed1ab_0 - - ninja=1.12.1=h3c5361c_0 - - notebook=7.2.1=pyhd8ed1ab_0 - - notebook-shim=0.2.4=pyhd8ed1ab_0 - - ntl=11.4.3=h0ab3c2f_1 - - numpy=1.26.4=py310h4bfa8fc_0 - - openblas=0.3.25=openmp_h6794695_0 - - openjdk=22.0.1=h2d185b6_0 - - openjpeg=2.5.2=h7310d3a_0 - - openssl=3.3.1=h87427d6_0 - - overrides=7.7.0=pyhd8ed1ab_0 - - packaging=24.1=pyhd8ed1ab_0 - - palp=2.20=hbcb3906_0 - - pandoc=3.2.1=h694c41f_0 - - pandocfilters=1.5.0=pyhd8ed1ab_0 - - pango=1.54.0=h880b76c_0 - - pari=2.15.5=h7ba67ff_2_pthread - - pari-elldata=0.0.20161017=0 - - pari-galdata=0.0.20180411=0 - - pari-galpol=0.0.20180625=0 - - pari-seadata=0.0.20090618=0 - - pari-seadata-small=0.0.20090618=0 - - parso=0.8.4=pyhd8ed1ab_0 - - patch=2.7.6=hbcf498f_1002 - - pathspec=0.12.1=pyhd8ed1ab_0 - - pcre2=10.44=h7634a1b_0 - - pep517=0.13.0=pyhd8ed1ab_0 - - perl=5.32.1=7_h10d778d_perl5 - - pexpect=4.9.0=pyhd8ed1ab_0 - - pickleshare=0.7.5=py_1003 - - pillow=10.3.0=py310h2fdc51f_1 - - pip=24.0=pyhd8ed1ab_0 - - pixman=0.43.4=h73e2aa4_0 - - pkg-config=0.29.2=ha3d46e9_1008 - - pkgconfig=1.5.5=pyhd8ed1ab_4 - - pkgutil-resolve-name=1.3.10=pyhd8ed1ab_1 - - planarity=3.0.2.0=h10d778d_0 - - platformdirs=4.2.2=pyhd8ed1ab_0 - - pluggy=1.5.0=pyhd8ed1ab_0 - - ply=3.11=pyhd8ed1ab_2 - - ppl=1.2=ha60d53e_1006 - - pplpy=0.8.9=py310hbe8aec3_1 - - primecount=7.6=ha894c9a_0 - - primecountpy=0.1.0=py310h88cfcbd_4 - - primesieve=11.0=hf0c8a7f_0 - - prometheus_client=0.20.0=pyhd8ed1ab_0 - - prompt-toolkit=3.0.47=pyha770c72_0 - - prompt_toolkit=3.0.47=hd8ed1ab_0 - - psutil=6.0.0=py310h936d840_0 - - pthread-stubs=0.4=hc929b4f_1001 - - ptyprocess=0.7.0=pyhd3deb0d_0 - - pure_eval=0.2.2=pyhd8ed1ab_0 - - py=1.11.0=pyh6c4a22f_0 - - pybind11=2.12.0=py310hb3b189b_0 - - pybind11-global=2.12.0=py310hb3b189b_0 - - pycparser=2.22=pyhd8ed1ab_0 - - pygments=2.18.0=pyhd8ed1ab_0 - - pyobjc-core=10.3.1=py310h445dc1f_0 - - pyobjc-framework-cocoa=10.3.1=py310h445dc1f_0 - - pyparsing=3.1.2=pyhd8ed1ab_0 - - pyproject-api=1.7.1=pyhd8ed1ab_0 - - pyrsistent=0.20.0=py310hb372a2b_0 - - pysocks=1.7.1=pyha2e5f31_6 - - python=3.10.14=h00d2728_0_cpython - - python-build=1.2.1=pyhd8ed1ab_0 - - python-dateutil=2.9.0=pyhd8ed1ab_0 - - python-fastjsonschema=2.20.0=pyhd8ed1ab_0 - - python-json-logger=2.0.7=pyhd8ed1ab_0 - - python-lrcalc=2.1=py310h5daac23_6 - - python-tzdata=2024.1=pyhd8ed1ab_0 - - python_abi=3.10=4_cp310 - - pythran=0.15.0=py310h076e4b7_1 - - pytz=2024.1=pyhd8ed1ab_0 - - pytz-deprecation-shim=0.1.0.post0=py310h2ec42d9_4 - - pyyaml=6.0.1=py310h6729b98_1 - - pyzmq=26.0.3=py310he0bbd50_0 - - qd=2.3.22=h2beb688_1004 - - qhull=2020.2=h940c156_2 - - r-base=4.3.3=h4648a1f_3 - - r-lattice=0.22_6=r43hb2c329c_0 - - readline=8.2=h9e318b2_1 - - referencing=0.35.1=pyhd8ed1ab_0 - - requests=2.32.3=pyhd8ed1ab_0 - - rfc3339-validator=0.1.4=pyhd8ed1ab_0 - - rfc3986-validator=0.1.1=pyh9f0ad1d_0 - - rhash=1.4.4=h0dc2134_0 - - rpds-py=0.18.1=py310h12a1ced_0 - - rpy2=3.5.11=py310r43hf0b6da5_3 - - rw=0.9=h10d778d_2 - - sagemath-db-combinatorial-designs=20140630=1 - - sagemath-db-elliptic-curves=0.8.1=hecc5488_0 - - sagemath-db-graphs=20210214=hd8ed1ab_0 - - sagemath-db-polytopes=20170220=1 - - sagetex=3.6.1=pyhd8ed1ab_0 - - scipy=1.11.4=py310h3f1db6d_0 - - send2trash=1.8.3=pyh31c8845_0 - - setuptools=70.1.1=pyhd8ed1ab_0 - - setuptools-scm=8.1.0=pyhd8ed1ab_0 - - setuptools_scm=8.1.0=hd8ed1ab_0 - - sigtool=0.1.3=h88f4db0_0 - - simplegeneric=0.8.1=py_1 - - singular=4.3.2.p8=h0d51a9f_1 - - six=1.16.0=pyh6c4a22f_0 - - sniffio=1.3.1=pyhd8ed1ab_0 - - snowballstemmer=2.2.0=pyhd8ed1ab_0 - - soupsieve=2.5=pyhd8ed1ab_1 - - sphinx=7.3.7=pyhd8ed1ab_0 - - sphinx-basic-ng=1.0.0b2=pyhd8ed1ab_1 - - sphinx-copybutton=0.5.2=pyhd8ed1ab_0 - - sphinxcontrib-applehelp=1.0.8=pyhd8ed1ab_0 - - sphinxcontrib-devhelp=1.0.6=pyhd8ed1ab_0 - - sphinxcontrib-htmlhelp=2.0.5=pyhd8ed1ab_0 - - sphinxcontrib-jsmath=1.0.1=pyhd8ed1ab_0 - - sphinxcontrib-qthelp=1.0.7=pyhd8ed1ab_0 - - sphinxcontrib-serializinghtml=1.1.10=pyhd8ed1ab_0 - - sphinxcontrib-websupport=1.2.7=pyhd8ed1ab_0 - - sqlite=3.46.0=h28673e1_0 - - stack_data=0.6.2=pyhd8ed1ab_0 - - suitesparse=7.7.0=hd2b2131_1 - - symmetrica=3.0.1=hf0c8a7f_0 - - sympow=2.023.6=h115ba6a_3 - - sympy=1.12.1=pypyh2585a3b_103 - - tachyon=0.99b6=h3a1d103_1002 - - tapi=1100.0.11=h9ce4665_0 - - tar=1.34=hcb2f6ea_1 - - tbb=2021.12.0=h3c5361c_1 - - terminado=0.18.1=pyh31c8845_0 - - texinfo=7.0=pl5321hc47821c_0 - - three.js=122=hd8ed1ab_2 - - threejs-sage=122=hd8ed1ab_2 - - tinycss2=1.3.0=pyhd8ed1ab_0 - - tk=8.6.13=h1abcd95_1 - - tktable=2.10=hba9d6f1_6 - - tomli=2.0.1=pyhd8ed1ab_0 - - tornado=6.4.1=py310h936d840_0 - - tox=4.15.1=pyhd8ed1ab_0 - - traitlets=5.14.3=pyhd8ed1ab_0 - - trove-classifiers=2024.5.22=pyhd8ed1ab_0 - - types-python-dateutil=2.9.0.20240316=pyhd8ed1ab_0 - - typing-extensions=4.12.2=hd8ed1ab_0 - - typing_extensions=4.12.2=pyha770c72_0 - - typing_utils=0.1.0=pyhd8ed1ab_0 - - tzdata=2024a=h0c530f3_0 - - tzlocal=5.2=py310h2ec42d9_0 - - unicodedata2=15.1.0=py310h6729b98_0 - - uri-template=1.3.0=pyhd8ed1ab_0 - - urllib3=2.2.2=pyhd8ed1ab_0 - - virtualenv=20.26.3=pyhd8ed1ab_0 - - wcwidth=0.2.13=pyhd8ed1ab_0 - - webcolors=24.6.0=pyhd8ed1ab_0 - - webencodings=0.5.1=pyhd8ed1ab_2 - - websocket-client=1.8.0=pyhd8ed1ab_0 - - wheel=0.43.0=pyhd8ed1ab_1 - - widgetsnbextension=4.0.11=pyhd8ed1ab_0 - - xorg-libxau=1.0.11=h0dc2134_0 - - xorg-libxdmcp=1.1.3=h35c211d_0 - - xz=5.2.6=h775f41a_0 - - yaml=0.2.5=h0d85af4_2 - - zeromq=4.3.5=hde137ed_4 - - zipp=3.19.2=pyhd8ed1ab_0 - - zlib=1.3.1=h87427d6_1 - - zstd=1.5.6=h915ae27_0 diff --git a/src/environment-3.10-macos.yml b/src/environment-3.10-macos.yml deleted file mode 100644 index 9110653e86c..00000000000 --- a/src/environment-3.10-macos.yml +++ /dev/null @@ -1,423 +0,0 @@ -# Generated by conda-lock. -# platform: osx-arm64 -# input_hash: fce4b9b5cdb20ebb2d93612fa27b4d6584379772c37a8cccd6c2390e2ce5f3b1 - -channels: - - conda-forge -dependencies: - - _r-mutex=1.0.1=anacondar_1 - - alabaster=0.7.16=pyhd8ed1ab_0 - - anyio=4.4.0=pyhd8ed1ab_0 - - appdirs=1.4.4=pyh9f0ad1d_0 - - appnope=0.1.4=pyhd8ed1ab_0 - - argon2-cffi=23.1.0=pyhd8ed1ab_0 - - argon2-cffi-bindings=21.2.0=py310h2aa6e3c_4 - - arpack=3.9.1=nompi_h593882a_101 - - arrow=1.3.0=pyhd8ed1ab_0 - - asttokens=2.4.1=pyhd8ed1ab_0 - - async-lru=2.0.4=pyhd8ed1ab_0 - - attrs=23.2.0=pyh71513ae_0 - - autoconf=2.71=pl5321hcd07c0c_1 - - automake=1.16.5=pl5321hce30654_0 - - babel=2.14.0=pyhd8ed1ab_0 - - bc=1.07.1=h3422bc3_0 - - bdw-gc=8.0.6=hc021e02_0 - - beautifulsoup4=4.12.3=pyha770c72_0 - - beniget=0.4.1=pyhd8ed1ab_0 - - blas=2.120=openblas - - blas-devel=3.9.0=20_osxarm64_openblas - - bleach=6.1.0=pyhd8ed1ab_0 - - boost-cpp=1.85.0=hca5e981_2 - - brial=1.2.12=pyh694c41f_3 - - brotli=1.1.0=hb547adb_1 - - brotli-bin=1.1.0=hb547adb_1 - - brotli-python=1.1.0=py310h1253130_1 - - bwidget=1.9.14=hce30654_1 - - bzip2=1.0.8=h93a5062_5 - - c-ares=1.28.1=h93a5062_0 - - c-compiler=1.7.0=h6aa9301_1 - - ca-certificates=2024.6.2=hf0a4a13_0 - - cached-property=1.5.2=hd8ed1ab_1 - - cached_property=1.5.2=pyha770c72_1 - - cachetools=5.3.3=pyhd8ed1ab_0 - - cairo=1.18.0=hc6c324b_2 - - cctools=986=h4faf515_0 - - cctools_osx-arm64=986=h62378fb_0 - - cddlib=1!0.94m=h6d7a090_0 - - certifi=2024.6.2=pyhd8ed1ab_0 - - cffi=1.16.0=py310hdcd7c05_0 - - chardet=5.2.0=py310hbe9552e_1 - - charset-normalizer=3.3.2=pyhd8ed1ab_0 - - clang=16.0.6=default_h095aff0_8 - - clang-16=16.0.6=default_hb63da90_8 - - clang_impl_osx-arm64=16.0.6=hc421ffc_16 - - clang_osx-arm64=16.0.6=h54d7cd3_16 - - clangxx=16.0.6=default_h095aff0_8 - - clangxx_impl_osx-arm64=16.0.6=hcd7bac0_16 - - clangxx_osx-arm64=16.0.6=h54d7cd3_16 - - cliquer=1.22=h93a5062_1 - - cmake=3.29.6=had79d8f_0 - - colorama=0.4.6=pyhd8ed1ab_0 - - colorlog=6.8.2=py310hbe9552e_0 - - comm=0.2.2=pyhd8ed1ab_0 - - compiler-rt=16.0.6=h3808999_2 - - compiler-rt_osx-arm64=16.0.6=h3808999_2 - - compilers=1.7.0=hce30654_1 - - contourpy=1.2.1=py310h21239e6_0 - - conway-polynomials=0.9=pyhd8ed1ab_0 - - cppy=1.2.1=pyhd8ed1ab_0 - - curl=8.8.0=h653d890_0 - - cvxopt=1.3.2=py310h7e4e7d1_2 - - cxx-compiler=1.7.0=h2ffa867_1 - - cycler=0.12.1=pyhd8ed1ab_0 - - cypari2=2.1.5=py310h5e3d6bc_0 - - cysignals=1.11.2=py310hfd3b3fe_3 - - cython=3.0.10=py310h692a8b6_0 - - debugpy=1.8.1=py310h692a8b6_0 - - decorator=5.1.1=pyhd8ed1ab_0 - - defusedxml=0.7.1=pyhd8ed1ab_0 - - distlib=0.3.8=pyhd8ed1ab_0 - - docutils=0.21.2=pyhd8ed1ab_0 - - dsdp=5.8=h9397a75_1203 - - ecl=23.9.9=h1d9728a_0 - - eclib=20231212=h7f07de4_0 - - ecm=7.0.5=h41d338b_0 - - editables=0.5=pyhd8ed1ab_0 - - entrypoints=0.4=pyhd8ed1ab_0 - - exceptiongroup=1.2.0=pyhd8ed1ab_2 - - executing=2.0.1=pyhd8ed1ab_0 - - expat=2.6.2=hebf3989_0 - - fflas-ffpack=2.5.0=h4bc3318_0 - - fftw=3.3.10=nompi_h6637ab6_110 - - filelock=3.15.4=pyhd8ed1ab_0 - - flit-core=3.9.0=pyhd8ed1ab_1 - - 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_2 - - fontconfig=2.14.2=h82840c6_0 - - fonts-conda-ecosystem=1=0 - - fonts-conda-forge=1=0 - - fonttools=4.53.0=py310ha6dd24b_0 - - fortran-compiler=1.7.0=hafb19e3_1 - - fplll=5.4.5=hb7d509d_0 - - fpylll=0.6.1=py310hd9be144_0 - - fqdn=1.5.1=pyhd8ed1ab_0 - - freetype=2.12.1=hadb7bae_2 - - fribidi=1.0.10=h27ca646_0 - - furo=2024.5.6=pyhd8ed1ab_0 - - gap-core=4.12.2=he8f4e70_3 - - gap-defaults=4.12.2=hce30654_3 - - gast=0.5.4=pyhd8ed1ab_0 - - gengetopt=2.23=hbdafb3b_0 - - gettext=0.22.5=h8fbad5d_2 - - gettext-tools=0.22.5=h8fbad5d_2 - - gf2x=1.3.0=hdaa854c_2 - - gfan=0.6.2=hec08f5c_1003 - - gfortran=12.3.0=h1ca8e4b_1 - - gfortran_impl_osx-arm64=12.3.0=h53ed385_3 - - gfortran_osx-arm64=12.3.0=h57527a5_1 - - giac=1.9.0.21=h1c96721_1 - - giflib=5.2.2=h93a5062_0 - - givaro=4.2.0=h018886a_0 - - glpk=5.0=h6d7a090_0 - - gmp=6.3.0=h7bae524_2 - - gmpy2=2.1.5=py310h3bc658a_1 - - graphite2=1.3.13=hebf3989_1003 - - gsl=2.7=h6e638da_0 - - h11=0.14.0=pyhd8ed1ab_0 - - h2=4.1.0=pyhd8ed1ab_0 - - harfbuzz=8.5.0=h1836168_0 - - hatchling=1.25.0=pyhd8ed1ab_0 - - hpack=4.0.0=pyh9f0ad1d_0 - - httpcore=1.0.5=pyhd8ed1ab_0 - - httpx=0.27.0=pyhd8ed1ab_0 - - hyperframe=6.0.1=pyhd8ed1ab_0 - - icu=73.2=hc8870d7_0 - - idna=3.7=pyhd8ed1ab_0 - - igraph=0.10.12=h762ac30_1 - - imagesize=1.4.1=pyhd8ed1ab_0 - - iml=1.0.5=hd73f12c_1004 - - importlib-metadata=8.0.0=pyha770c72_0 - - importlib-resources=6.4.0=pyhd8ed1ab_0 - - importlib_metadata=8.0.0=hd8ed1ab_0 - - importlib_resources=6.4.0=pyhd8ed1ab_0 - - ipykernel=6.29.4=pyh57ce528_0 - - ipympl=0.9.4=pyhd8ed1ab_0 - - ipython=8.25.0=pyh707e725_0 - - ipython_genutils=0.2.0=pyhd8ed1ab_1 - - ipywidgets=8.1.3=pyhd8ed1ab_0 - - isl=0.26=imath32_h347afa1_101 - - isoduration=20.11.0=pyhd8ed1ab_0 - - jedi=0.19.1=pyhd8ed1ab_0 - - jinja2=3.1.4=pyhd8ed1ab_0 - - jmol=14.32.10=hce30654_0 - - json5=0.9.25=pyhd8ed1ab_0 - - jsonpointer=3.0.0=py310hbe9552e_0 - - jsonschema=4.22.0=pyhd8ed1ab_0 - - jsonschema-specifications=2023.12.1=pyhd8ed1ab_0 - - jsonschema-with-format-nongpl=4.22.0=pyhd8ed1ab_0 - - jupyter-jsmol=2022.1.0=pyhd8ed1ab_0 - - jupyter-lsp=2.2.5=pyhd8ed1ab_0 - - jupyter-sphinx=0.5.3=pyha770c72_4 - - jupyter_client=8.6.2=pyhd8ed1ab_0 - - jupyter_core=5.7.2=py310hbe9552e_0 - - jupyter_events=0.10.0=pyhd8ed1ab_0 - - jupyter_server=2.14.1=pyhd8ed1ab_0 - - jupyter_server_terminals=0.5.3=pyhd8ed1ab_0 - - jupyter_sphinx=0.5.3=hd8ed1ab_4 - - jupyterlab=4.2.2=pyhd8ed1ab_0 - - jupyterlab_pygments=0.3.0=pyhd8ed1ab_1 - - jupyterlab_server=2.27.2=pyhd8ed1ab_0 - - jupyterlab_widgets=3.0.11=pyhd8ed1ab_0 - - kiwisolver=1.4.5=py310h38f39d4_1 - - krb5=1.21.2=h92f50d5_0 - - lcalc=2.0.5=h4a402bc_2 - - lcms2=2.16=ha0e7c42_0 - - ld64=711=h634c8be_0 - - ld64_osx-arm64=711=ha4bd21c_0 - - lerc=4.0.0=h9a09cb3_0 - - libasprintf=0.22.5=h8fbad5d_2 - - libasprintf-devel=0.22.5=h8fbad5d_2 - - libatomic_ops=7.6.14=h1a8c8d9_0 - - libblas=3.9.0=20_osxarm64_openblas - - libboost=1.85.0=h17eb2be_2 - - libboost-devel=1.85.0=hf450f58_2 - - libboost-headers=1.85.0=hce30654_2 - - libbraiding=1.2=hb7217d7_0 - - libbrial=1.2.12=h56a29cd_3 - - libbrotlicommon=1.1.0=hb547adb_1 - - libbrotlidec=1.1.0=hb547adb_1 - - libbrotlienc=1.1.0=hb547adb_1 - - libcblas=3.9.0=20_osxarm64_openblas - - libclang-cpp16=16.0.6=default_hb63da90_8 - - libcurl=8.8.0=h7b6f9a7_0 - - libcxx=17.0.6=h5f092b4_0 - - libdeflate=1.20=h93a5062_0 - - libedit=3.1.20191231=hc8eb9b7_2 - - libev=4.33=h93a5062_2 - - libexpat=2.6.2=hebf3989_0 - - libffi=3.4.2=h3422bc3_5 - - libflint=3.0.1=h28749a5_ntl_100 - - libgd=2.3.3=hfdf3952_9 - - libgettextpo=0.22.5=h8fbad5d_2 - - libgettextpo-devel=0.22.5=h8fbad5d_2 - - libgfortran=5.0.0=13_2_0_hd922786_3 - - libgfortran-devel_osx-arm64=12.3.0=hc62be1c_3 - - libgfortran5=13.2.0=hf226fd6_3 - - libglib=2.80.2=h59d46d9_1 - - libhomfly=1.02r6=h93a5062_1 - - libhwloc=2.10.0=default_h7685b71_1001 - - libiconv=1.17=h0d3ecfb_2 - - libintl=0.22.5=h8fbad5d_2 - - libintl-devel=0.22.5=h8fbad5d_2 - - libjpeg-turbo=3.0.0=hb547adb_1 - - liblapack=3.9.0=20_osxarm64_openblas - - liblapacke=3.9.0=20_osxarm64_openblas - - libllvm16=16.0.6=haab561b_3 - - libnghttp2=1.58.0=ha4dd798_1 - - libopenblas=0.3.25=openmp_h6c19121_0 - - libpng=1.6.43=h091b4b1_0 - - libsodium=1.0.18=h27ca646_1 - - libsqlite=3.46.0=hfb93653_0 - - libssh2=1.11.0=h7a5bd25_0 - - libtiff=4.6.0=h07db509_3 - - libtool=2.4.7=hb7217d7_0 - - libuv=1.48.0=h93a5062_0 - - libwebp=1.4.0=h54798ee_0 - - libwebp-base=1.4.0=h93a5062_0 - - libxcb=1.16=hf2054a2_0 - - libxml2=2.12.7=ha661575_1 - - libzlib=1.3.1=hfb2fe0b_1 - - linbox=1.7.0=h3afee3a_0 - - llvm-openmp=18.1.8=hde57baf_0 - - llvm-tools=16.0.6=haab561b_3 - - lrcalc=2.1=hebf3989_6 - - m4=1.4.18=h642e427_1001 - - m4ri=20140914=hc97c1ff_1006 - - m4rie=20150908=h22b9e9d_1002 - - make=4.3=he57ea6c_1 - - markupsafe=2.1.5=py310hd125d64_0 - - mathjax=3.2.2=hce30654_0 - - matplotlib=3.8.4=py310hb6292c7_2 - - matplotlib-base=3.8.4=py310hedb7998_2 - - matplotlib-inline=0.1.7=pyhd8ed1ab_0 - - maxima=5.47.0=h2bbcd85_2 - - memory-allocator=0.1.3=py310h2aa6e3c_0 - - metis=5.1.0=h13dd4ca_1007 - - mistune=3.0.2=pyhd8ed1ab_0 - - mpc=1.3.1=h91ba8db_0 - - mpfi=1.5.4=hbde5f5b_1001 - - mpfr=4.2.1=h41d338b_1 - - mpmath=1.3.0=pyhd8ed1ab_0 - - munkres=1.1.4=pyh9f0ad1d_0 - - nauty=2.8.8=h93a5062_1 - - nbclient=0.10.0=pyhd8ed1ab_0 - - nbconvert=7.16.4=hd8ed1ab_1 - - nbconvert-core=7.16.4=pyhd8ed1ab_1 - - nbconvert-pandoc=7.16.4=hd8ed1ab_1 - - nbformat=5.10.4=pyhd8ed1ab_0 - - ncurses=6.5=hb89a1cb_0 - - nest-asyncio=1.6.0=pyhd8ed1ab_0 - - networkx=3.2.1=pyhd8ed1ab_0 - - ninja=1.12.1=h420ef59_0 - - notebook=7.2.1=pyhd8ed1ab_0 - - notebook-shim=0.2.4=pyhd8ed1ab_0 - - ntl=11.4.3=hbb3f309_1 - - numpy=1.26.4=py310hd45542a_0 - - openblas=0.3.25=openmp_h55c453e_0 - - openjdk=22.0.1=hbeb2e11_0 - - openjpeg=2.5.2=h9f1df11_0 - - openssl=3.3.1=hfb2fe0b_0 - - overrides=7.7.0=pyhd8ed1ab_0 - - packaging=24.1=pyhd8ed1ab_0 - - palp=2.20=h27ca646_0 - - pandoc=3.2.1=hce30654_0 - - pandocfilters=1.5.0=pyhd8ed1ab_0 - - pango=1.54.0=h5cb9fbc_0 - - pari=2.15.5=h4f2304c_2_pthread - - pari-elldata=0.0.20161017=0 - - pari-galdata=0.0.20180411=0 - - pari-galpol=0.0.20180625=0 - - pari-seadata=0.0.20090618=0 - - pari-seadata-small=0.0.20090618=0 - - parso=0.8.4=pyhd8ed1ab_0 - - patch=2.7.6=h27ca646_1002 - - pathspec=0.12.1=pyhd8ed1ab_0 - - pcre2=10.44=h297a79d_0 - - pep517=0.13.0=pyhd8ed1ab_0 - - perl=5.32.1=7_h4614cfb_perl5 - - pexpect=4.9.0=pyhd8ed1ab_0 - - pickleshare=0.7.5=py_1003 - - pillow=10.3.0=py310h01af8b1_1 - - pip=24.0=pyhd8ed1ab_0 - - pixman=0.43.4=hebf3989_0 - - pkg-config=0.29.2=hab62308_1008 - - pkgconfig=1.5.5=pyhd8ed1ab_4 - - pkgutil-resolve-name=1.3.10=pyhd8ed1ab_1 - - planarity=3.0.2.0=h93a5062_0 - - platformdirs=4.2.2=pyhd8ed1ab_0 - - pluggy=1.5.0=pyhd8ed1ab_0 - - ply=3.11=pyhd8ed1ab_2 - - ppl=1.2=h8b147cf_1006 - - pplpy=0.8.9=py310hc3af9bb_1 - - primecount=7.6=hb6e4faa_0 - - primecountpy=0.1.0=py310h38f39d4_4 - - primesieve=11.0=hb7217d7_0 - - prometheus_client=0.20.0=pyhd8ed1ab_0 - - prompt-toolkit=3.0.47=pyha770c72_0 - - prompt_toolkit=3.0.47=hd8ed1ab_0 - - psutil=6.0.0=py310ha6dd24b_0 - - pthread-stubs=0.4=h27ca646_1001 - - ptyprocess=0.7.0=pyhd3deb0d_0 - - pure_eval=0.2.2=pyhd8ed1ab_0 - - py=1.11.0=pyh6c4a22f_0 - - pybind11=2.12.0=py310h21239e6_0 - - pybind11-global=2.12.0=py310h21239e6_0 - - pycparser=2.22=pyhd8ed1ab_0 - - pygments=2.18.0=pyhd8ed1ab_0 - - pyobjc-core=10.3.1=py310h4b7648a_0 - - pyobjc-framework-cocoa=10.3.1=py310h4b7648a_0 - - pyparsing=3.1.2=pyhd8ed1ab_0 - - pyproject-api=1.7.1=pyhd8ed1ab_0 - - pyrsistent=0.20.0=py310hd125d64_0 - - pysocks=1.7.1=pyha2e5f31_6 - - python=3.10.14=h2469fbe_0_cpython - - python-build=1.2.1=pyhd8ed1ab_0 - - python-dateutil=2.9.0=pyhd8ed1ab_0 - - python-fastjsonschema=2.20.0=pyhd8ed1ab_0 - - python-json-logger=2.0.7=pyhd8ed1ab_0 - - python-lrcalc=2.1=py310h692a8b6_6 - - python-tzdata=2024.1=pyhd8ed1ab_0 - - python_abi=3.10=4_cp310 - - pythran=0.15.0=py310h1359cc7_1 - - pytz=2024.1=pyhd8ed1ab_0 - - pytz-deprecation-shim=0.1.0.post0=py310hbe9552e_4 - - pyyaml=6.0.1=py310h2aa6e3c_1 - - pyzmq=26.0.3=py310h16e08c9_0 - - qd=2.3.22=hbec66e7_1004 - - qhull=2020.2=hc021e02_2 - - r-base=4.3.3=h8112bfe_3 - - r-lattice=0.22_6=r43hd2d937b_0 - - readline=8.2=h92ec313_1 - - referencing=0.35.1=pyhd8ed1ab_0 - - requests=2.32.3=pyhd8ed1ab_0 - - rfc3339-validator=0.1.4=pyhd8ed1ab_0 - - rfc3986-validator=0.1.1=pyh9f0ad1d_0 - - rhash=1.4.4=hb547adb_0 - - rpds-py=0.18.1=py310h947b723_0 - - rpy2=3.5.11=py310r43h280b8fa_3 - - rw=0.9=h93a5062_2 - - sagemath-db-combinatorial-designs=20140630=1 - - sagemath-db-elliptic-curves=0.8.1=hecc5488_0 - - sagemath-db-graphs=20210214=hd8ed1ab_0 - - sagemath-db-polytopes=20170220=1 - - sagetex=3.6.1=pyhd8ed1ab_0 - - scipy=1.11.4=py310h2b794db_0 - - send2trash=1.8.3=pyh31c8845_0 - - setuptools=70.1.1=pyhd8ed1ab_0 - - setuptools-scm=8.1.0=pyhd8ed1ab_0 - - setuptools_scm=8.1.0=hd8ed1ab_0 - - sigtool=0.1.3=h44b9a77_0 - - simplegeneric=0.8.1=py_1 - - singular=4.3.2.p8=hb460b52_1 - - six=1.16.0=pyh6c4a22f_0 - - sniffio=1.3.1=pyhd8ed1ab_0 - - snowballstemmer=2.2.0=pyhd8ed1ab_0 - - soupsieve=2.5=pyhd8ed1ab_1 - - sphinx=7.3.7=pyhd8ed1ab_0 - - sphinx-basic-ng=1.0.0b2=pyhd8ed1ab_1 - - sphinx-copybutton=0.5.2=pyhd8ed1ab_0 - - sphinxcontrib-applehelp=1.0.8=pyhd8ed1ab_0 - - sphinxcontrib-devhelp=1.0.6=pyhd8ed1ab_0 - - sphinxcontrib-htmlhelp=2.0.5=pyhd8ed1ab_0 - - sphinxcontrib-jsmath=1.0.1=pyhd8ed1ab_0 - - sphinxcontrib-qthelp=1.0.7=pyhd8ed1ab_0 - - sphinxcontrib-serializinghtml=1.1.10=pyhd8ed1ab_0 - - sphinxcontrib-websupport=1.2.7=pyhd8ed1ab_0 - - sqlite=3.46.0=h5838104_0 - - stack_data=0.6.2=pyhd8ed1ab_0 - - suitesparse=7.7.0=hf6fcff2_1 - - symmetrica=3.0.1=hb7217d7_0 - - sympow=2.023.6=hb0babe8_3 - - sympy=1.12.1=pypyh2585a3b_103 - - tachyon=0.99b6=hb8a568e_1002 - - tapi=1100.0.11=he4954df_0 - - tar=1.34=h7cb298e_1 - - tbb=2021.12.0=h420ef59_1 - - terminado=0.18.1=pyh31c8845_0 - - texinfo=7.0=pl5321h9ea1dce_0 - - three.js=122=hd8ed1ab_2 - - threejs-sage=122=hd8ed1ab_2 - - tinycss2=1.3.0=pyhd8ed1ab_0 - - tk=8.6.13=h5083fa2_1 - - tktable=2.10=h1e387b8_6 - - tomli=2.0.1=pyhd8ed1ab_0 - - tornado=6.4.1=py310ha6dd24b_0 - - tox=4.15.1=pyhd8ed1ab_0 - - traitlets=5.14.3=pyhd8ed1ab_0 - - trove-classifiers=2024.5.22=pyhd8ed1ab_0 - - types-python-dateutil=2.9.0.20240316=pyhd8ed1ab_0 - - typing-extensions=4.12.2=hd8ed1ab_0 - - typing_extensions=4.12.2=pyha770c72_0 - - typing_utils=0.1.0=pyhd8ed1ab_0 - - tzdata=2024a=h0c530f3_0 - - tzlocal=5.2=py310hbe9552e_0 - - unicodedata2=15.1.0=py310h2aa6e3c_0 - - uri-template=1.3.0=pyhd8ed1ab_0 - - urllib3=2.2.2=pyhd8ed1ab_0 - - virtualenv=20.26.3=pyhd8ed1ab_0 - - wcwidth=0.2.13=pyhd8ed1ab_0 - - webcolors=24.6.0=pyhd8ed1ab_0 - - webencodings=0.5.1=pyhd8ed1ab_2 - - websocket-client=1.8.0=pyhd8ed1ab_0 - - wheel=0.43.0=pyhd8ed1ab_1 - - widgetsnbextension=4.0.11=pyhd8ed1ab_0 - - xorg-libxau=1.0.11=hb547adb_0 - - xorg-libxdmcp=1.1.3=h27ca646_0 - - xz=5.2.6=h57fd34a_0 - - yaml=0.2.5=h3422bc3_2 - - zeromq=4.3.5=hcc0f68c_4 - - zipp=3.19.2=pyhd8ed1ab_0 - - zlib=1.3.1=hfb2fe0b_1 - - zstd=1.5.6=hb46c0d2_0 diff --git a/src/environment-3.11-linux-aarch64.yml b/src/environment-3.11-linux-aarch64.yml deleted file mode 100644 index 87cee9aad2a..00000000000 --- a/src/environment-3.11-linux-aarch64.yml +++ /dev/null @@ -1,434 +0,0 @@ -# Generated by conda-lock. -# platform: linux-aarch64 -# input_hash: 53cce21c9c8a4b11b84e96405de20cc945c84809a7997b8508761fc9ca727ee0 - -channels: - - conda-forge -dependencies: - - _openmp_mutex=4.5=2_kmp_llvm - - _r-mutex=1.0.1=anacondar_1 - - _sysroot_linux-aarch64_curr_repodata_hack=4=h57d6b7b_14 - - alabaster=0.7.16=pyhd8ed1ab_0 - - alsa-lib=1.2.11=h31becfc_1 - - anyio=4.4.0=pyhd8ed1ab_0 - - appdirs=1.4.4=pyh9f0ad1d_0 - - appnope=0.1.4=pyhd8ed1ab_0 - - argon2-cffi=23.1.0=pyhd8ed1ab_0 - - argon2-cffi-bindings=21.2.0=py311hcd402e7_4 - - arpack=3.9.1=nompi_hd363cd0_101 - - arrow=1.3.0=pyhd8ed1ab_0 - - asttokens=2.4.1=pyhd8ed1ab_0 - - async-lru=2.0.4=pyhd8ed1ab_0 - - attrs=23.2.0=pyh71513ae_0 - - autoconf=2.71=pl5321h2148fe1_1 - - automake=1.16.5=pl5321h8af1aa0_0 - - babel=2.14.0=pyhd8ed1ab_0 - - bc=1.07.1=hf897c2e_0 - - bdw-gc=8.0.6=hd62202e_0 - - beautifulsoup4=4.12.3=pyha770c72_0 - - beniget=0.4.1=pyhd8ed1ab_0 - - binutils=2.40=hf1166c9_7 - - binutils_impl_linux-aarch64=2.40=hf54a868_7 - - binutils_linux-aarch64=2.40=h1f91aba_9 - - blas=2.120=openblas - - blas-devel=3.9.0=20_linuxaarch64_openblas - - bleach=6.1.0=pyhd8ed1ab_0 - - boost-cpp=1.85.0=ha990451_2 - - brial=1.2.12=pyh694c41f_3 - - brotli=1.1.0=h31becfc_1 - - brotli-bin=1.1.0=h31becfc_1 - - brotli-python=1.1.0=py311h8715677_1 - - bwidget=1.9.14=h8af1aa0_1 - - bzip2=1.0.8=h31becfc_5 - - c-ares=1.28.1=h31becfc_0 - - c-compiler=1.7.0=h31becfc_1 - - ca-certificates=2024.6.2=hcefe29a_0 - - cached-property=1.5.2=hd8ed1ab_1 - - cached_property=1.5.2=pyha770c72_1 - - cachetools=5.3.3=pyhd8ed1ab_0 - - cairo=1.18.0=h5c54ea9_2 - - cddlib=1!0.94m=h719063d_0 - - certifi=2024.6.2=pyhd8ed1ab_0 - - cffi=1.16.0=py311h7963103_0 - - chardet=5.2.0=py311hfecb2dc_1 - - charset-normalizer=3.3.2=pyhd8ed1ab_0 - - cliquer=1.22=h31becfc_1 - - cmake=3.29.6=h7042e5d_0 - - colorama=0.4.6=pyhd8ed1ab_0 - - colorlog=6.8.2=py311hec3470c_0 - - comm=0.2.2=pyhd8ed1ab_0 - - compilers=1.7.0=h8af1aa0_1 - - contourpy=1.2.1=py311h098ece5_0 - - conway-polynomials=0.9=pyhd8ed1ab_0 - - cppy=1.2.1=pyhd8ed1ab_0 - - curl=8.8.0=h7daf2e0_0 - - cvxopt=1.3.2=py311ha095bbf_2 - - cxx-compiler=1.7.0=h2a328a1_1 - - cycler=0.12.1=pyhd8ed1ab_0 - - cypari2=2.1.5=py311h5ab95f0_0 - - cysignals=1.11.2=py311h644d908_3 - - cython=3.0.10=py311h8715677_0 - - debugpy=1.8.1=py311h8715677_0 - - decorator=5.1.1=pyhd8ed1ab_0 - - defusedxml=0.7.1=pyhd8ed1ab_0 - - distlib=0.3.8=pyhd8ed1ab_0 - - docutils=0.21.2=pyhd8ed1ab_0 - - dsdp=5.8=hb12102e_1203 - - ecl=23.9.9=h6475f26_0 - - eclib=20231212=he26bab5_0 - - ecm=7.0.5=ha2d0fc4_0 - - editables=0.5=pyhd8ed1ab_0 - - entrypoints=0.4=pyhd8ed1ab_0 - - exceptiongroup=1.2.0=pyhd8ed1ab_2 - - executing=2.0.1=pyhd8ed1ab_0 - - expat=2.6.2=h2f0025b_0 - - fflas-ffpack=2.5.0=h503e619_0 - - fftw=3.3.10=nompi_h020dacd_110 - - filelock=3.15.4=pyhd8ed1ab_0 - - flit-core=3.9.0=pyhd8ed1ab_1 - - 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_2 - - fontconfig=2.14.2=ha9a116f_0 - - fonts-conda-ecosystem=1=0 - - fonts-conda-forge=1=0 - - fonttools=4.53.0=py311hf4892ed_0 - - fortran-compiler=1.7.0=h7048d53_1 - - fplll=5.4.5=hb3a790e_0 - - fpylll=0.6.1=py311h5d3d69a_0 - - fqdn=1.5.1=pyhd8ed1ab_0 - - freetype=2.12.1=hf0a5ef3_2 - - fribidi=1.0.10=hb9de7d4_0 - - furo=2024.5.6=pyhd8ed1ab_0 - - gap-core=4.12.2=h597289e_3 - - gap-defaults=4.12.2=h8af1aa0_3 - - gast=0.5.4=pyhd8ed1ab_0 - - gcc=12.3.0=hdb0cc85_13 - - gcc_impl_linux-aarch64=12.3.0=h3d98823_13 - - gcc_linux-aarch64=12.3.0=ha52a6ea_9 - - gengetopt=2.23=h01db608_0 - - gf2x=1.3.0=h1b3b3a3_2 - - gfan=0.6.2=h5f589ec_1003 - - gfortran=12.3.0=hdb0cc85_13 - - gfortran_impl_linux-aarch64=12.3.0=h97ebfd2_13 - - gfortran_linux-aarch64=12.3.0=ha7b8e4b_9 - - giac=1.9.0.21=h04922a4_1 - - giflib=5.2.2=h31becfc_0 - - givaro=4.2.0=h364d21b_0 - - glpk=5.0=h66325d0_0 - - gmp=6.3.0=h0a1ffab_2 - - gmpy2=2.1.5=py311h3c136a7_1 - - graphite2=1.3.13=h2f0025b_1003 - - gsl=2.7=h294027d_0 - - gxx=12.3.0=hdb0cc85_13 - - gxx_impl_linux-aarch64=12.3.0=hba91e99_13 - - gxx_linux-aarch64=12.3.0=h9d1f256_9 - - h11=0.14.0=pyhd8ed1ab_0 - - h2=4.1.0=pyhd8ed1ab_0 - - harfbuzz=8.5.0=h9812418_0 - - hatchling=1.25.0=pyhd8ed1ab_0 - - hpack=4.0.0=pyh9f0ad1d_0 - - httpcore=1.0.5=pyhd8ed1ab_0 - - httpx=0.27.0=pyhd8ed1ab_0 - - hyperframe=6.0.1=pyhd8ed1ab_0 - - icu=73.2=h787c7f5_0 - - idna=3.7=pyhd8ed1ab_0 - - igraph=0.10.12=h197073e_1 - - imagesize=1.4.1=pyhd8ed1ab_0 - - iml=1.0.5=h15043fe_1004 - - importlib-metadata=8.0.0=pyha770c72_0 - - importlib-resources=6.4.0=pyhd8ed1ab_0 - - importlib_metadata=8.0.0=hd8ed1ab_0 - - importlib_resources=6.4.0=pyhd8ed1ab_0 - - ipykernel=6.29.4=pyh3099207_0 - - ipympl=0.9.4=pyhd8ed1ab_0 - - ipython=8.25.0=pyh707e725_0 - - ipython_genutils=0.2.0=pyhd8ed1ab_1 - - ipywidgets=8.1.3=pyhd8ed1ab_0 - - isoduration=20.11.0=pyhd8ed1ab_0 - - jedi=0.19.1=pyhd8ed1ab_0 - - jinja2=3.1.4=pyhd8ed1ab_0 - - jmol=14.32.10=h8af1aa0_0 - - json5=0.9.25=pyhd8ed1ab_0 - - jsonpointer=3.0.0=py311hec3470c_0 - - jsonschema=4.22.0=pyhd8ed1ab_0 - - jsonschema-specifications=2023.12.1=pyhd8ed1ab_0 - - jsonschema-with-format-nongpl=4.22.0=pyhd8ed1ab_0 - - jupyter-jsmol=2022.1.0=pyhd8ed1ab_0 - - jupyter-lsp=2.2.5=pyhd8ed1ab_0 - - jupyter-sphinx=0.5.3=pyha770c72_4 - - jupyter_client=8.6.2=pyhd8ed1ab_0 - - jupyter_core=5.7.2=py311hec3470c_0 - - jupyter_events=0.10.0=pyhd8ed1ab_0 - - jupyter_server=2.14.1=pyhd8ed1ab_0 - - jupyter_server_terminals=0.5.3=pyhd8ed1ab_0 - - jupyter_sphinx=0.5.3=hd8ed1ab_4 - - jupyterlab=4.2.2=pyhd8ed1ab_0 - - jupyterlab_pygments=0.3.0=pyhd8ed1ab_1 - - jupyterlab_server=2.27.2=pyhd8ed1ab_0 - - jupyterlab_widgets=3.0.11=pyhd8ed1ab_0 - - kernel-headers_linux-aarch64=4.18.0=h5b4a56d_14 - - keyutils=1.6.1=h4e544f5_0 - - kiwisolver=1.4.5=py311h0d5d7b0_1 - - krb5=1.21.2=hc419048_0 - - lcalc=2.0.5=he588f68_2 - - lcms2=2.16=h922389a_0 - - ld_impl_linux-aarch64=2.40=h9fc2d93_7 - - lerc=4.0.0=h4de3ea5_0 - - libatomic_ops=7.6.14=h4e544f5_0 - - libblas=3.9.0=20_linuxaarch64_openblas - - libboost=1.85.0=hb41fec8_2 - - libboost-devel=1.85.0=h37bb5a9_2 - - libboost-headers=1.85.0=h8af1aa0_2 - - libbraiding=1.2=hd600fc2_0 - - libbrial=1.2.12=h9429f74_3 - - libbrotlicommon=1.1.0=h31becfc_1 - - libbrotlidec=1.1.0=h31becfc_1 - - libbrotlienc=1.1.0=h31becfc_1 - - libcblas=3.9.0=20_linuxaarch64_openblas - - libcups=2.3.3=h405e4a8_4 - - libcurl=8.8.0=h4e8248e_0 - - libdeflate=1.20=h31becfc_0 - - libedit=3.1.20191231=he28a2e2_2 - - libev=4.33=h31becfc_2 - - libexpat=2.6.2=h2f0025b_0 - - libffi=3.4.2=h3557bc0_5 - - libflint=3.0.1=hc392af7_ntl_100 - - libgcc-devel_linux-aarch64=12.3.0=h6144e03_113 - - libgcc-ng=13.2.0=he277a41_13 - - libgd=2.3.3=hcd22fd5_9 - - libgfortran-ng=13.2.0=he9431aa_13 - - libgfortran5=13.2.0=h2af0866_13 - - libglib=2.80.2=haee52c6_1 - - libgomp=13.2.0=he277a41_13 - - libhomfly=1.02r6=h31becfc_1 - - libhwloc=2.10.0=default_h3030c0e_1001 - - libiconv=1.17=h31becfc_2 - - libjpeg-turbo=3.0.0=h31becfc_1 - - liblapack=3.9.0=20_linuxaarch64_openblas - - liblapacke=3.9.0=20_linuxaarch64_openblas - - libnghttp2=1.58.0=hb0e430d_1 - - libnsl=2.0.1=h31becfc_0 - - libopenblas=0.3.25=pthreads_h5a5ec62_0 - - libpng=1.6.43=h194ca79_0 - - libsanitizer=12.3.0=h57e2e72_13 - - libsodium=1.0.18=hb9de7d4_1 - - libsqlite=3.46.0=hf51ef55_0 - - libssh2=1.11.0=h492db2e_0 - - libstdcxx-devel_linux-aarch64=12.3.0=h6144e03_113 - - libstdcxx-ng=13.2.0=h3f4de04_13 - - libtiff=4.6.0=hf980d43_3 - - libtool=2.4.7=h4de3ea5_0 - - libuuid=2.38.1=hb4cce97_0 - - libuv=1.48.0=h31becfc_0 - - libwebp=1.4.0=h8b4e01b_0 - - libwebp-base=1.4.0=h31becfc_0 - - libxcb=1.16=h7935292_0 - - libxcrypt=4.4.36=h31becfc_1 - - libxml2=2.12.7=h49dc7a2_1 - - libzlib=1.3.1=h68df207_1 - - linbox=1.7.0=h681a5ee_0 - - llvm-openmp=18.1.8=hb063fc5_0 - - lrcalc=2.1=h2f0025b_6 - - m4=1.4.18=h516909a_1001 - - m4ri=20140914=hedfd65a_1006 - - m4rie=20150908=hf0a5ef3_1002 - - make=4.3=h309ac5b_1 - - markupsafe=2.1.5=py311hc8f2f60_0 - - mathjax=3.2.2=h8af1aa0_0 - - matplotlib=3.8.4=py311hfecb2dc_2 - - matplotlib-base=3.8.4=py311h55059f0_2 - - matplotlib-inline=0.1.7=pyhd8ed1ab_0 - - maxima=5.47.0=h6475f26_2 - - memory-allocator=0.1.3=py311hcd402e7_0 - - metis=5.1.0=h2f0025b_1007 - - mistune=3.0.2=pyhd8ed1ab_0 - - mpc=1.3.1=hf4c8f4c_0 - - mpfi=1.5.4=h846f343_1001 - - mpfr=4.2.1=ha2d0fc4_1 - - mpmath=1.3.0=pyhd8ed1ab_0 - - munkres=1.1.4=pyh9f0ad1d_0 - - nauty=2.8.8=h31becfc_1 - - nbclient=0.10.0=pyhd8ed1ab_0 - - nbconvert=7.16.4=hd8ed1ab_1 - - nbconvert-core=7.16.4=pyhd8ed1ab_1 - - nbconvert-pandoc=7.16.4=hd8ed1ab_1 - - nbformat=5.10.4=pyhd8ed1ab_0 - - ncurses=6.5=h0425590_0 - - nest-asyncio=1.6.0=pyhd8ed1ab_0 - - networkx=3.2.1=pyhd8ed1ab_0 - - ninja=1.12.1=h70be974_0 - - notebook=7.2.1=pyhd8ed1ab_0 - - notebook-shim=0.2.4=pyhd8ed1ab_0 - - ntl=11.4.3=h0d7519b_1 - - numpy=1.26.4=py311h69ead2a_0 - - openblas=0.3.25=pthreads_h339cbfa_0 - - openjdk=22.0.1=h3d4cd67_0 - - openjpeg=2.5.2=h0d9d63b_0 - - openssl=3.3.1=h68df207_0 - - overrides=7.7.0=pyhd8ed1ab_0 - - packaging=24.1=pyhd8ed1ab_0 - - palp=2.20=hb9de7d4_0 - - pandoc=3.2.1=h8af1aa0_0 - - pandocfilters=1.5.0=pyhd8ed1ab_0 - - pango=1.54.0=h399c48b_0 - - pari=2.15.5=h169c2a7_2_pthread - - pari-elldata=0.0.20161017=0 - - pari-galdata=0.0.20180411=0 - - pari-galpol=0.0.20180625=0 - - pari-seadata=0.0.20090618=0 - - pari-seadata-small=0.0.20090618=0 - - parso=0.8.4=pyhd8ed1ab_0 - - patch=2.7.6=hf897c2e_1002 - - pathspec=0.12.1=pyhd8ed1ab_0 - - pcre2=10.44=h070dd5b_0 - - pep517=0.13.0=pyhd8ed1ab_0 - - perl=5.32.1=7_h31becfc_perl5 - - pexpect=4.9.0=pyhd8ed1ab_0 - - pickleshare=0.7.5=py_1003 - - pillow=10.3.0=py311h54289d1_1 - - pip=24.0=pyhd8ed1ab_0 - - pixman=0.43.4=h2f0025b_0 - - pkg-config=0.29.2=hb9de7d4_1008 - - pkgconfig=1.5.5=pyhd8ed1ab_4 - - pkgutil-resolve-name=1.3.10=pyhd8ed1ab_1 - - planarity=3.0.2.0=h31becfc_0 - - platformdirs=4.2.2=pyhd8ed1ab_0 - - pluggy=1.5.0=pyhd8ed1ab_0 - - ply=3.11=pyhd8ed1ab_2 - - 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 - - prometheus_client=0.20.0=pyhd8ed1ab_0 - - prompt-toolkit=3.0.47=pyha770c72_0 - - prompt_toolkit=3.0.47=hd8ed1ab_0 - - psutil=6.0.0=py311hf4892ed_0 - - pthread-stubs=0.4=hb9de7d4_1001 - - ptyprocess=0.7.0=pyhd3deb0d_0 - - pure_eval=0.2.2=pyhd8ed1ab_0 - - py=1.11.0=pyh6c4a22f_0 - - pybind11=2.12.0=py311h098ece5_0 - - pybind11-global=2.12.0=py311h098ece5_0 - - pycparser=2.22=pyhd8ed1ab_0 - - pygments=2.18.0=pyhd8ed1ab_0 - - pyparsing=3.1.2=pyhd8ed1ab_0 - - pyproject-api=1.7.1=pyhd8ed1ab_0 - - pyrsistent=0.20.0=py311hc8f2f60_0 - - pysocks=1.7.1=pyha2e5f31_6 - - python=3.11.9=hddfb980_0_cpython - - python-build=1.2.1=pyhd8ed1ab_0 - - python-dateutil=2.9.0=pyhd8ed1ab_0 - - python-fastjsonschema=2.20.0=pyhd8ed1ab_0 - - python-json-logger=2.0.7=pyhd8ed1ab_0 - - python-lrcalc=2.1=py311h8715677_6 - - python-tzdata=2024.1=pyhd8ed1ab_0 - - python_abi=3.11=4_cp311 - - pythran=0.15.0=py311hec5c23b_1 - - pytz=2024.1=pyhd8ed1ab_0 - - pytz-deprecation-shim=0.1.0.post0=py311hec3470c_4 - - pyyaml=6.0.1=py311hcd402e7_1 - - pyzmq=26.0.3=py311hb8d4657_0 - - qd=2.3.22=h05efe27_1004 - - qhull=2020.2=hd62202e_2 - - r-base=4.3.3=h7f20121_3 - - r-lattice=0.22_6=r43h25e906a_0 - - readline=8.2=h8fc344f_1 - - referencing=0.35.1=pyhd8ed1ab_0 - - requests=2.32.3=pyhd8ed1ab_0 - - rfc3339-validator=0.1.4=pyhd8ed1ab_0 - - rfc3986-validator=0.1.1=pyh9f0ad1d_0 - - rhash=1.4.4=h31becfc_0 - - rpds-py=0.18.1=py311h949f54a_0 - - rpy2=3.5.11=py311r43hf13da56_3 - - rw=0.9=h31becfc_2 - - sagemath-db-combinatorial-designs=20140630=1 - - sagemath-db-elliptic-curves=0.8.1=hecc5488_0 - - sagemath-db-graphs=20210214=hd8ed1ab_0 - - sagemath-db-polytopes=20170220=1 - - sagetex=3.6.1=pyhd8ed1ab_0 - - scipy=1.11.3=py311h69ead2a_1 - - sed=4.8=ha0d5d3d_0 - - send2trash=1.8.3=pyh0d859eb_0 - - setuptools=70.1.1=pyhd8ed1ab_0 - - setuptools-scm=8.1.0=pyhd8ed1ab_0 - - setuptools_scm=8.1.0=hd8ed1ab_0 - - simplegeneric=0.8.1=py_1 - - singular=4.3.2.p8=hbe76a8a_1 - - six=1.16.0=pyh6c4a22f_0 - - sniffio=1.3.1=pyhd8ed1ab_0 - - snowballstemmer=2.2.0=pyhd8ed1ab_0 - - soupsieve=2.5=pyhd8ed1ab_1 - - sphinx=7.3.7=pyhd8ed1ab_0 - - sphinx-basic-ng=1.0.0b2=pyhd8ed1ab_1 - - sphinx-copybutton=0.5.2=pyhd8ed1ab_0 - - sphinxcontrib-applehelp=1.0.8=pyhd8ed1ab_0 - - sphinxcontrib-devhelp=1.0.6=pyhd8ed1ab_0 - - sphinxcontrib-htmlhelp=2.0.5=pyhd8ed1ab_0 - - sphinxcontrib-jsmath=1.0.1=pyhd8ed1ab_0 - - sphinxcontrib-qthelp=1.0.7=pyhd8ed1ab_0 - - sphinxcontrib-serializinghtml=1.1.10=pyhd8ed1ab_0 - - sphinxcontrib-websupport=1.2.7=pyhd8ed1ab_0 - - sqlite=3.46.0=hdc7ab3c_0 - - stack_data=0.6.2=pyhd8ed1ab_0 - - suitesparse=7.7.0=h3944111_1 - - symmetrica=3.0.1=hd600fc2_0 - - sympow=2.023.6=h157afb5_3 - - sympy=1.12.1=pypyh2585a3b_103 - - sysroot_linux-aarch64=2.17=h5b4a56d_14 - - tachyon=0.99b6=ha0bfc61_1002 - - tar=1.34=h048efde_0 - - tbb=2021.12.0=h70be974_1 - - terminado=0.18.1=pyh0d859eb_0 - - texinfo=7.0=pl5321h17f021e_0 - - three.js=122=hd8ed1ab_2 - - threejs-sage=122=hd8ed1ab_2 - - tinycss2=1.3.0=pyhd8ed1ab_0 - - tk=8.6.13=h194ca79_0 - - tktable=2.10=h52f7bd3_6 - - tomli=2.0.1=pyhd8ed1ab_0 - - tornado=6.4.1=py311h323e239_0 - - tox=4.15.1=pyhd8ed1ab_0 - - traitlets=5.14.3=pyhd8ed1ab_0 - - trove-classifiers=2024.5.22=pyhd8ed1ab_0 - - types-python-dateutil=2.9.0.20240316=pyhd8ed1ab_0 - - typing-extensions=4.12.2=hd8ed1ab_0 - - typing_extensions=4.12.2=pyha770c72_0 - - typing_utils=0.1.0=pyhd8ed1ab_0 - - tzdata=2024a=h0c530f3_0 - - tzlocal=5.2=py311hec3470c_0 - - uri-template=1.3.0=pyhd8ed1ab_0 - - urllib3=2.2.2=pyhd8ed1ab_0 - - virtualenv=20.26.3=pyhd8ed1ab_0 - - wcwidth=0.2.13=pyhd8ed1ab_0 - - webcolors=24.6.0=pyhd8ed1ab_0 - - webencodings=0.5.1=pyhd8ed1ab_2 - - websocket-client=1.8.0=pyhd8ed1ab_0 - - wheel=0.43.0=pyhd8ed1ab_1 - - widgetsnbextension=4.0.11=pyhd8ed1ab_0 - - xorg-fixesproto=5.0=h3557bc0_1002 - - xorg-inputproto=2.3.2=h3557bc0_1002 - - xorg-kbproto=1.0.7=h3557bc0_1002 - - xorg-libice=1.1.1=h7935292_0 - - xorg-libsm=1.2.4=h5a01bc2_0 - - xorg-libx11=1.8.9=h08be655_1 - - xorg-libxau=1.0.11=h31becfc_0 - - xorg-libxdmcp=1.1.3=h3557bc0_0 - - xorg-libxext=1.3.4=h2a766a3_2 - - xorg-libxfixes=5.0.3=h3557bc0_1004 - - xorg-libxi=1.7.10=h3557bc0_0 - - xorg-libxrender=0.9.11=h7935292_0 - - xorg-libxt=1.3.0=h7935292_1 - - xorg-libxtst=1.2.3=hf897c2e_1002 - - xorg-recordproto=1.14.2=hf897c2e_1002 - - xorg-renderproto=0.11.1=h3557bc0_1002 - - xorg-xextproto=7.3.0=h2a766a3_1003 - - xorg-xproto=7.0.31=h3557bc0_1007 - - xz=5.2.6=h9cdd2b7_0 - - yaml=0.2.5=hf897c2e_2 - - zeromq=4.3.5=h28faeed_4 - - zipp=3.19.2=pyhd8ed1ab_0 - - zlib=1.3.1=h68df207_1 - - zstd=1.5.6=h02f22dd_0 diff --git a/src/environment-3.11-linux.yml b/src/environment-3.11-linux.yml deleted file mode 100644 index 6716e043193..00000000000 --- a/src/environment-3.11-linux.yml +++ /dev/null @@ -1,482 +0,0 @@ -# Generated by conda-lock. -# platform: linux-64 -# input_hash: 042b3b9a5ce5e44ed6334284078d156e424e41f02852c8c6a155cb9b4e620e60 - -channels: - - conda-forge -dependencies: - - _libgcc_mutex=0.1=conda_forge - - _openmp_mutex=4.5=2_kmp_llvm - - _r-mutex=1.0.1=anacondar_1 - - alabaster=0.7.16=pyhd8ed1ab_0 - - alsa-lib=1.2.12=h4ab18f5_0 - - anyio=4.4.0=pyhd8ed1ab_0 - - appdirs=1.4.4=pyh9f0ad1d_0 - - appnope=0.1.4=pyhd8ed1ab_0 - - argon2-cffi=23.1.0=pyhd8ed1ab_0 - - argon2-cffi-bindings=21.2.0=py311h459d7ec_4 - - arpack=3.9.1=nompi_h77f6705_101 - - arrow=1.3.0=pyhd8ed1ab_0 - - asttokens=2.4.1=pyhd8ed1ab_0 - - async-lru=2.0.4=pyhd8ed1ab_0 - - attr=2.5.1=h166bdaf_1 - - attrs=23.2.0=pyh71513ae_0 - - autoconf=2.71=pl5321h2b4cb7a_1 - - automake=1.16.5=pl5321ha770c72_0 - - babel=2.14.0=pyhd8ed1ab_0 - - bc=1.07.1=h7f98852_0 - - bdw-gc=8.0.6=h4bd325d_0 - - beautifulsoup4=4.12.3=pyha770c72_0 - - beniget=0.4.1=pyhd8ed1ab_0 - - binutils=2.40=h4852527_7 - - binutils_impl_linux-64=2.40=ha1999f0_7 - - binutils_linux-64=2.40=hb3c18ed_9 - - blas=2.120=openblas - - blas-devel=3.9.0=20_linux64_openblas - - bleach=6.1.0=pyhd8ed1ab_0 - - boost-cpp=1.85.0=h44aadfe_2 - - brial=1.2.12=pyh694c41f_3 - - brotli=1.1.0=hd590300_1 - - brotli-bin=1.1.0=hd590300_1 - - brotli-python=1.1.0=py311hb755f60_1 - - bwidget=1.9.14=ha770c72_1 - - bzip2=1.0.8=hd590300_5 - - c-ares=1.28.1=hd590300_0 - - c-compiler=1.7.0=hd590300_1 - - ca-certificates=2024.6.2=hbcca054_0 - - cached-property=1.5.2=hd8ed1ab_1 - - cached_property=1.5.2=pyha770c72_1 - - cachetools=5.3.3=pyhd8ed1ab_0 - - cairo=1.18.0=hbb29018_2 - - cddlib=1!0.94m=h9202a9a_0 - - certifi=2024.6.2=pyhd8ed1ab_0 - - cffi=1.16.0=py311hb3a22ac_0 - - chardet=5.2.0=py311h38be061_1 - - charset-normalizer=3.3.2=pyhd8ed1ab_0 - - cliquer=1.22=hd590300_1 - - cmake=3.29.6=hcafd917_0 - - colorama=0.4.6=pyhd8ed1ab_0 - - colorlog=6.8.2=py311h38be061_0 - - comm=0.2.2=pyhd8ed1ab_0 - - compilers=1.7.0=ha770c72_1 - - contourpy=1.2.1=py311h9547e67_0 - - conway-polynomials=0.9=pyhd8ed1ab_0 - - cppy=1.2.1=pyhd8ed1ab_0 - - curl=8.8.0=he654da7_0 - - cvxopt=1.3.2=py311hec6cc1f_2 - - cxx-compiler=1.7.0=h00ab1b0_1 - - cycler=0.12.1=pyhd8ed1ab_0 - - cypari2=2.1.5=py311hd2352ae_0 - - cysignals=1.11.2=py311h82528dc_3 - - cython=3.0.10=py311hb755f60_0 - - dbus=1.13.6=h5008d03_3 - - debugpy=1.8.1=py311hb755f60_0 - - decorator=5.1.1=pyhd8ed1ab_0 - - defusedxml=0.7.1=pyhd8ed1ab_0 - - distlib=0.3.8=pyhd8ed1ab_0 - - docutils=0.21.2=pyhd8ed1ab_0 - - dsdp=5.8=hd9d9efa_1203 - - ecl=23.9.9=hed6455c_0 - - eclib=20231212=h96f522a_0 - - ecm=7.0.5=h9458935_0 - - editables=0.5=pyhd8ed1ab_0 - - entrypoints=0.4=pyhd8ed1ab_0 - - exceptiongroup=1.2.0=pyhd8ed1ab_2 - - executing=2.0.1=pyhd8ed1ab_0 - - expat=2.6.2=h59595ed_0 - - fflas-ffpack=2.5.0=h4f9960b_0 - - fftw=3.3.10=nompi_hf1063bd_110 - - filelock=3.15.4=pyhd8ed1ab_0 - - flit-core=3.9.0=pyhd8ed1ab_1 - - 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_2 - - fontconfig=2.14.2=h14ed4e7_0 - - fonts-conda-ecosystem=1=0 - - fonts-conda-forge=1=0 - - fonttools=4.53.0=py311h331c9d8_0 - - fortran-compiler=1.7.0=heb67821_1 - - fplll=5.4.5=h384768b_0 - - fpylll=0.6.1=py311hcfae7cf_0 - - fqdn=1.5.1=pyhd8ed1ab_0 - - freetype=2.12.1=h267a509_2 - - fribidi=1.0.10=h36c2ea0_0 - - furo=2024.5.6=pyhd8ed1ab_0 - - gap-core=4.12.2=he9a28a4_3 - - gap-defaults=4.12.2=ha770c72_3 - - gast=0.5.4=pyhd8ed1ab_0 - - gcc=12.3.0=h915e2ae_13 - - gcc_impl_linux-64=12.3.0=h58ffeeb_13 - - gcc_linux-64=12.3.0=h9528a6a_9 - - gengetopt=2.23=h9c3ff4c_0 - - gettext=0.22.5=h59595ed_2 - - gettext-tools=0.22.5=h59595ed_2 - - gf2x=1.3.0=ha476b99_2 - - gfan=0.6.2=hb86e20a_1003 - - gfortran=12.3.0=h915e2ae_13 - - gfortran_impl_linux-64=12.3.0=h8f2110c_13 - - gfortran_linux-64=12.3.0=h5877db1_9 - - giac=1.9.0.21=h673759e_1 - - giflib=5.2.2=hd590300_0 - - givaro=4.2.0=hb789bce_0 - - glib=2.80.2=h8a4344b_1 - - glib-tools=2.80.2=h73ef956_1 - - glpk=5.0=h445213a_0 - - gmp=6.3.0=hac33072_2 - - gmpy2=2.1.5=py311hc4f1f91_1 - - graphite2=1.3.13=h59595ed_1003 - - gsl=2.7=he838d99_0 - - gst-plugins-base=1.24.5=hbaaba92_0 - - gstreamer=1.24.5=haf2f30d_0 - - gxx=12.3.0=h915e2ae_13 - - gxx_impl_linux-64=12.3.0=h2a574ab_13 - - gxx_linux-64=12.3.0=ha28b414_9 - - h11=0.14.0=pyhd8ed1ab_0 - - h2=4.1.0=pyhd8ed1ab_0 - - harfbuzz=8.5.0=hfac3d4d_0 - - hatchling=1.25.0=pyhd8ed1ab_0 - - hpack=4.0.0=pyh9f0ad1d_0 - - httpcore=1.0.5=pyhd8ed1ab_0 - - httpx=0.27.0=pyhd8ed1ab_0 - - hyperframe=6.0.1=pyhd8ed1ab_0 - - icu=73.2=h59595ed_0 - - idna=3.7=pyhd8ed1ab_0 - - igraph=0.10.12=hef0740d_1 - - imagesize=1.4.1=pyhd8ed1ab_0 - - iml=1.0.5=h623f65a_1004 - - importlib-metadata=8.0.0=pyha770c72_0 - - importlib-resources=6.4.0=pyhd8ed1ab_0 - - importlib_metadata=8.0.0=hd8ed1ab_0 - - importlib_resources=6.4.0=pyhd8ed1ab_0 - - ipykernel=6.29.4=pyh3099207_0 - - ipympl=0.9.4=pyhd8ed1ab_0 - - ipython=8.25.0=pyh707e725_0 - - ipython_genutils=0.2.0=pyhd8ed1ab_1 - - ipywidgets=8.1.3=pyhd8ed1ab_0 - - isoduration=20.11.0=pyhd8ed1ab_0 - - jedi=0.19.1=pyhd8ed1ab_0 - - jinja2=3.1.4=pyhd8ed1ab_0 - - jmol=14.32.10=ha770c72_0 - - json5=0.9.25=pyhd8ed1ab_0 - - jsonpointer=3.0.0=py311h38be061_0 - - jsonschema=4.22.0=pyhd8ed1ab_0 - - jsonschema-specifications=2023.12.1=pyhd8ed1ab_0 - - jsonschema-with-format-nongpl=4.22.0=pyhd8ed1ab_0 - - jupyter-jsmol=2022.1.0=pyhd8ed1ab_0 - - jupyter-lsp=2.2.5=pyhd8ed1ab_0 - - jupyter-sphinx=0.5.3=pyha770c72_4 - - jupyter_client=8.6.2=pyhd8ed1ab_0 - - jupyter_core=5.7.2=py311h38be061_0 - - jupyter_events=0.10.0=pyhd8ed1ab_0 - - jupyter_server=2.14.1=pyhd8ed1ab_0 - - jupyter_server_terminals=0.5.3=pyhd8ed1ab_0 - - jupyter_sphinx=0.5.3=hd8ed1ab_4 - - jupyterlab=4.2.2=pyhd8ed1ab_0 - - jupyterlab_pygments=0.3.0=pyhd8ed1ab_1 - - jupyterlab_server=2.27.2=pyhd8ed1ab_0 - - jupyterlab_widgets=3.0.11=pyhd8ed1ab_0 - - kernel-headers_linux-64=2.6.32=he073ed8_17 - - keyutils=1.6.1=h166bdaf_0 - - kiwisolver=1.4.5=py311h9547e67_1 - - krb5=1.21.2=h659d440_0 - - lame=3.100=h166bdaf_1003 - - lcalc=2.0.5=h5aac1b6_2 - - lcms2=2.16=hb7c19ff_0 - - ld_impl_linux-64=2.40=hf3520f5_7 - - lerc=4.0.0=h27087fc_0 - - libasprintf=0.22.5=h661eb56_2 - - libasprintf-devel=0.22.5=h661eb56_2 - - libatomic_ops=7.6.14=h166bdaf_0 - - libblas=3.9.0=20_linux64_openblas - - libboost=1.85.0=hba137d9_2 - - libboost-devel=1.85.0=h00ab1b0_2 - - libboost-headers=1.85.0=ha770c72_2 - - libbraiding=1.2=hcb278e6_0 - - libbrial=1.2.12=h76af697_3 - - libbrotlicommon=1.1.0=hd590300_1 - - libbrotlidec=1.1.0=hd590300_1 - - libbrotlienc=1.1.0=hd590300_1 - - libcap=2.69=h0f662aa_0 - - libcblas=3.9.0=20_linux64_openblas - - libclang-cpp15=15.0.7=default_h127d8a8_5 - - libclang13=18.1.8=default_h6ae225f_0 - - libcups=2.3.3=h4637d8d_4 - - libcurl=8.8.0=hca28451_0 - - libdeflate=1.20=hd590300_0 - - libedit=3.1.20191231=he28a2e2_2 - - libev=4.33=hd590300_2 - - libevent=2.1.12=hf998b51_1 - - libexpat=2.6.2=h59595ed_0 - - libffi=3.4.2=h7f98852_5 - - libflac=1.4.3=h59595ed_0 - - libflint=3.0.1=h5f2e117_ntl_100 - - libgcc-devel_linux-64=12.3.0=h6b66f73_113 - - libgcc-ng=13.2.0=h77fa898_13 - - libgcrypt=1.10.3=hd590300_0 - - libgd=2.3.3=h119a65a_9 - - libgettextpo=0.22.5=h59595ed_2 - - libgettextpo-devel=0.22.5=h59595ed_2 - - libgfortran-ng=13.2.0=h69a702a_13 - - libgfortran5=13.2.0=h3d2ce59_13 - - libglib=2.80.2=h8a4344b_1 - - libgomp=13.2.0=h77fa898_13 - - libgpg-error=1.49=h4f305b6_0 - - libhomfly=1.02r6=hd590300_1 - - libhwloc=2.10.0=default_h5622ce7_1001 - - libiconv=1.17=hd590300_2 - - libjpeg-turbo=3.0.0=hd590300_1 - - liblapack=3.9.0=20_linux64_openblas - - liblapacke=3.9.0=20_linux64_openblas - - libllvm15=15.0.7=hb3ce162_4 - - libllvm18=18.1.8=hc9dba70_0 - - libnghttp2=1.58.0=h47da74e_1 - - libnsl=2.0.1=hd590300_0 - - libogg=1.3.5=h4ab18f5_0 - - libopenblas=0.3.25=pthreads_h413a1c8_0 - - libopus=1.3.1=h7f98852_1 - - libpng=1.6.43=h2797004_0 - - libpq=16.3=ha72fbe1_0 - - libsanitizer=12.3.0=hb8811af_13 - - libsndfile=1.2.2=hc60ed4a_1 - - libsodium=1.0.18=h36c2ea0_1 - - libsqlite=3.46.0=hde9e2c9_0 - - libssh2=1.11.0=h0841786_0 - - libstdcxx-devel_linux-64=12.3.0=h6b66f73_113 - - libstdcxx-ng=13.2.0=hc0a3c3a_13 - - libsystemd0=255=h3516f8a_1 - - libtiff=4.6.0=h1dd3fc0_3 - - libtool=2.4.7=h27087fc_0 - - libuuid=2.38.1=h0b41bf4_0 - - libuv=1.48.0=hd590300_0 - - libvorbis=1.3.7=h9c3ff4c_0 - - libwebp=1.4.0=h2c329e2_0 - - libwebp-base=1.4.0=hd590300_0 - - libxcb=1.16=hd590300_0 - - libxcrypt=4.4.36=hd590300_1 - - libxkbcommon=1.7.0=h2c5496b_1 - - libxml2=2.12.7=hc051c1a_1 - - libzlib=1.3.1=h4ab18f5_1 - - linbox=1.7.0=ha329b40_0 - - llvm-openmp=18.1.8=hf5423f3_0 - - lrcalc=2.1=h59595ed_6 - - lz4-c=1.9.4=hcb278e6_0 - - m4=1.4.18=h516909a_1001 - - m4ri=20140914=hae5d5c5_1006 - - m4rie=20150908=h267a509_1002 - - make=4.3=hd18ef5c_1 - - markupsafe=2.1.5=py311h459d7ec_0 - - mathjax=3.2.2=ha770c72_0 - - matplotlib=3.8.4=py311h38be061_2 - - matplotlib-base=3.8.4=py311ha4ca890_2 - - matplotlib-inline=0.1.7=pyhd8ed1ab_0 - - maxima=5.47.0=hed6455c_2 - - memory-allocator=0.1.3=py311h459d7ec_0 - - metis=5.1.0=h59595ed_1007 - - mistune=3.0.2=pyhd8ed1ab_0 - - mpc=1.3.1=hfe3b2da_0 - - mpfi=1.5.4=h9f54685_1001 - - mpfr=4.2.1=h9458935_1 - - mpg123=1.32.6=h59595ed_0 - - mpmath=1.3.0=pyhd8ed1ab_0 - - munkres=1.1.4=pyh9f0ad1d_0 - - mysql-common=8.3.0=hf1915f5_4 - - mysql-libs=8.3.0=hca2cd23_4 - - nauty=2.8.8=hd590300_1 - - nbclient=0.10.0=pyhd8ed1ab_0 - - nbconvert=7.16.4=hd8ed1ab_1 - - nbconvert-core=7.16.4=pyhd8ed1ab_1 - - nbconvert-pandoc=7.16.4=hd8ed1ab_1 - - nbformat=5.10.4=pyhd8ed1ab_0 - - ncurses=6.5=h59595ed_0 - - nest-asyncio=1.6.0=pyhd8ed1ab_0 - - networkx=3.2.1=pyhd8ed1ab_0 - - ninja=1.12.1=h297d8ca_0 - - notebook=7.2.1=pyhd8ed1ab_0 - - notebook-shim=0.2.4=pyhd8ed1ab_0 - - nspr=4.35=h27087fc_0 - - nss=3.101=h593d115_0 - - ntl=11.4.3=hef3c4d3_1 - - numpy=1.26.4=py311h64a7726_0 - - openblas=0.3.25=pthreads_h7a3da1a_0 - - openjdk=21.0.2=haa376d0_0 - - openjpeg=2.5.2=h488ebb8_0 - - openssl=3.3.1=h4ab18f5_0 - - overrides=7.7.0=pyhd8ed1ab_0 - - packaging=24.1=pyhd8ed1ab_0 - - palp=2.20=h36c2ea0_0 - - pandoc=3.2.1=ha770c72_0 - - pandocfilters=1.5.0=pyhd8ed1ab_0 - - pango=1.54.0=h84a9a3c_0 - - pari=2.15.5=h4d4ae9b_2_pthread - - pari-elldata=0.0.20161017=0 - - pari-galdata=0.0.20180411=0 - - pari-galpol=0.0.20180625=0 - - pari-seadata=0.0.20090618=0 - - pari-seadata-small=0.0.20090618=0 - - parso=0.8.4=pyhd8ed1ab_0 - - patch=2.7.6=h7f98852_1002 - - pathspec=0.12.1=pyhd8ed1ab_0 - - pcre2=10.44=h0f59acf_0 - - pep517=0.13.0=pyhd8ed1ab_0 - - perl=5.32.1=7_hd590300_perl5 - - pexpect=4.9.0=pyhd8ed1ab_0 - - pickleshare=0.7.5=py_1003 - - pillow=10.3.0=py311h82a398c_1 - - pip=24.0=pyhd8ed1ab_0 - - pixman=0.43.2=h59595ed_0 - - pkg-config=0.29.2=h36c2ea0_1008 - - pkgconfig=1.5.5=pyhd8ed1ab_4 - - pkgutil-resolve-name=1.3.10=pyhd8ed1ab_1 - - planarity=3.0.2.0=hd590300_0 - - platformdirs=4.2.2=pyhd8ed1ab_0 - - pluggy=1.5.0=pyhd8ed1ab_0 - - ply=3.11=pyhd8ed1ab_2 - - 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 - - prometheus_client=0.20.0=pyhd8ed1ab_0 - - prompt-toolkit=3.0.47=pyha770c72_0 - - prompt_toolkit=3.0.47=hd8ed1ab_0 - - psutil=6.0.0=py311h331c9d8_0 - - pthread-stubs=0.4=h36c2ea0_1001 - - ptyprocess=0.7.0=pyhd3deb0d_0 - - pulseaudio-client=17.0=hb77b528_0 - - pure_eval=0.2.2=pyhd8ed1ab_0 - - py=1.11.0=pyh6c4a22f_0 - - pybind11=2.12.0=py311h9547e67_0 - - pybind11-global=2.12.0=py311h9547e67_0 - - pycparser=2.22=pyhd8ed1ab_0 - - pygments=2.18.0=pyhd8ed1ab_0 - - pyparsing=3.1.2=pyhd8ed1ab_0 - - pyproject-api=1.7.1=pyhd8ed1ab_0 - - pyqt=5.15.9=py311hf0fb5b6_5 - - pyqt5-sip=12.12.2=py311hb755f60_5 - - pyrsistent=0.20.0=py311h459d7ec_0 - - pysocks=1.7.1=pyha2e5f31_6 - - python=3.11.9=hb806964_0_cpython - - python-build=1.2.1=pyhd8ed1ab_0 - - python-dateutil=2.9.0=pyhd8ed1ab_0 - - python-fastjsonschema=2.20.0=pyhd8ed1ab_0 - - python-json-logger=2.0.7=pyhd8ed1ab_0 - - python-lrcalc=2.1=py311hb755f60_6 - - python-tzdata=2024.1=pyhd8ed1ab_0 - - python_abi=3.11=4_cp311 - - pythran=0.15.0=py311h92ebd52_1 - - pytz=2024.1=pyhd8ed1ab_0 - - pytz-deprecation-shim=0.1.0.post0=py311h38be061_4 - - pyyaml=6.0.1=py311h459d7ec_1 - - pyzmq=26.0.3=py311h08a0b41_0 - - qd=2.3.22=h2cc385e_1004 - - qhull=2020.2=h4bd325d_2 - - qt-main=5.15.8=ha2b5568_22 - - r-base=4.3.3=he2d9a6e_3 - - r-lattice=0.22_6=r43h57805ef_0 - - readline=8.2=h8228510_1 - - referencing=0.35.1=pyhd8ed1ab_0 - - requests=2.32.3=pyhd8ed1ab_0 - - rfc3339-validator=0.1.4=pyhd8ed1ab_0 - - rfc3986-validator=0.1.1=pyh9f0ad1d_0 - - rhash=1.4.4=hd590300_0 - - rpds-py=0.18.1=py311h5ecf98a_0 - - rpy2=3.5.11=py311r43h1f0f07a_3 - - rw=0.9=hd590300_2 - - sagemath-db-combinatorial-designs=20140630=1 - - sagemath-db-elliptic-curves=0.8.1=hecc5488_0 - - sagemath-db-graphs=20210214=hd8ed1ab_0 - - sagemath-db-polytopes=20170220=1 - - sagetex=3.6.1=pyhd8ed1ab_0 - - scipy=1.11.4=py311h64a7726_0 - - sed=4.8=he412f7d_0 - - send2trash=1.8.3=pyh0d859eb_0 - - setuptools=70.1.1=pyhd8ed1ab_0 - - setuptools-scm=8.1.0=pyhd8ed1ab_0 - - setuptools_scm=8.1.0=hd8ed1ab_0 - - simplegeneric=0.8.1=py_1 - - singular=4.3.2.p8=h33f5c3f_1 - - sip=6.7.12=py311hb755f60_0 - - six=1.16.0=pyh6c4a22f_0 - - sniffio=1.3.1=pyhd8ed1ab_0 - - snowballstemmer=2.2.0=pyhd8ed1ab_0 - - soupsieve=2.5=pyhd8ed1ab_1 - - sphinx=7.3.7=pyhd8ed1ab_0 - - sphinx-basic-ng=1.0.0b2=pyhd8ed1ab_1 - - sphinx-copybutton=0.5.2=pyhd8ed1ab_0 - - sphinxcontrib-applehelp=1.0.8=pyhd8ed1ab_0 - - sphinxcontrib-devhelp=1.0.6=pyhd8ed1ab_0 - - sphinxcontrib-htmlhelp=2.0.5=pyhd8ed1ab_0 - - sphinxcontrib-jsmath=1.0.1=pyhd8ed1ab_0 - - sphinxcontrib-qthelp=1.0.7=pyhd8ed1ab_0 - - sphinxcontrib-serializinghtml=1.1.10=pyhd8ed1ab_0 - - sphinxcontrib-websupport=1.2.7=pyhd8ed1ab_0 - - sqlite=3.46.0=h6d4b2fc_0 - - stack_data=0.6.2=pyhd8ed1ab_0 - - suitesparse=7.7.0=hf4753ba_1 - - symmetrica=3.0.1=hcb278e6_0 - - sympow=2.023.6=hc6ab17c_3 - - sympy=1.12.1=pypyh2585a3b_103 - - sysroot_linux-64=2.12=he073ed8_17 - - tachyon=0.99b6=hba7d16a_1002 - - tar=1.34=hb2e2bae_1 - - tbb=2021.12.0=h297d8ca_1 - - terminado=0.18.1=pyh0d859eb_0 - - texinfo=7.0=pl5321h0f457ee_0 - - three.js=122=hd8ed1ab_2 - - threejs-sage=122=hd8ed1ab_2 - - tinycss2=1.3.0=pyhd8ed1ab_0 - - tk=8.6.13=noxft_h4845f30_101 - - tktable=2.10=h8bc8fbc_6 - - toml=0.10.2=pyhd8ed1ab_0 - - tomli=2.0.1=pyhd8ed1ab_0 - - tornado=6.4.1=py311h331c9d8_0 - - tox=4.15.1=pyhd8ed1ab_0 - - traitlets=5.14.3=pyhd8ed1ab_0 - - trove-classifiers=2024.5.22=pyhd8ed1ab_0 - - types-python-dateutil=2.9.0.20240316=pyhd8ed1ab_0 - - typing-extensions=4.12.2=hd8ed1ab_0 - - typing_extensions=4.12.2=pyha770c72_0 - - typing_utils=0.1.0=pyhd8ed1ab_0 - - tzdata=2024a=h0c530f3_0 - - tzlocal=5.2=py311h38be061_0 - - uri-template=1.3.0=pyhd8ed1ab_0 - - urllib3=2.2.2=pyhd8ed1ab_0 - - virtualenv=20.26.3=pyhd8ed1ab_0 - - wcwidth=0.2.13=pyhd8ed1ab_0 - - webcolors=24.6.0=pyhd8ed1ab_0 - - webencodings=0.5.1=pyhd8ed1ab_2 - - websocket-client=1.8.0=pyhd8ed1ab_0 - - wheel=0.43.0=pyhd8ed1ab_1 - - widgetsnbextension=4.0.11=pyhd8ed1ab_0 - - xcb-util=0.4.1=hb711507_2 - - 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.42=h4ab18f5_0 - - xorg-fixesproto=5.0=h7f98852_1002 - - xorg-inputproto=2.3.2=h7f98852_1002 - - xorg-kbproto=1.0.7=h7f98852_1002 - - xorg-libice=1.1.1=hd590300_0 - - xorg-libsm=1.2.4=h7391055_0 - - xorg-libx11=1.8.9=hb711507_1 - - xorg-libxau=1.0.11=hd590300_0 - - xorg-libxdmcp=1.1.3=h7f98852_0 - - xorg-libxext=1.3.4=h0b41bf4_2 - - xorg-libxfixes=5.0.3=h7f98852_1004 - - xorg-libxi=1.7.10=h7f98852_0 - - xorg-libxrender=0.9.11=hd590300_0 - - xorg-libxt=1.3.0=hd590300_1 - - xorg-libxtst=1.2.3=h7f98852_1002 - - xorg-recordproto=1.14.2=h7f98852_1002 - - xorg-renderproto=0.11.1=h7f98852_1002 - - xorg-xextproto=7.3.0=h0b41bf4_1003 - - xorg-xf86vidmodeproto=2.3.1=h7f98852_1002 - - xorg-xproto=7.0.31=h7f98852_1007 - - xz=5.2.6=h166bdaf_0 - - yaml=0.2.5=h7f98852_2 - - zeromq=4.3.5=h75354e8_4 - - zipp=3.19.2=pyhd8ed1ab_0 - - zlib=1.3.1=h4ab18f5_1 - - zstd=1.5.6=ha6fb4c9_0 diff --git a/src/environment-3.11-macos-x86_64.yml b/src/environment-3.11-macos-x86_64.yml deleted file mode 100644 index d0fc9f07c5c..00000000000 --- a/src/environment-3.11-macos-x86_64.yml +++ /dev/null @@ -1,422 +0,0 @@ -# Generated by conda-lock. -# platform: osx-64 -# input_hash: 2d3e06919a9241aca6e25ca728e3013423030e7220d74f404ad621f0ad0ff5bd - -channels: - - conda-forge -dependencies: - - _r-mutex=1.0.1=anacondar_1 - - alabaster=0.7.16=pyhd8ed1ab_0 - - anyio=4.4.0=pyhd8ed1ab_0 - - appdirs=1.4.4=pyh9f0ad1d_0 - - appnope=0.1.4=pyhd8ed1ab_0 - - argon2-cffi=23.1.0=pyhd8ed1ab_0 - - argon2-cffi-bindings=21.2.0=py311h2725bcf_4 - - arpack=3.9.1=nompi_hf81eadf_101 - - arrow=1.3.0=pyhd8ed1ab_0 - - asttokens=2.4.1=pyhd8ed1ab_0 - - async-lru=2.0.4=pyhd8ed1ab_0 - - attrs=23.2.0=pyh71513ae_0 - - autoconf=2.71=pl5321hed12c24_1 - - automake=1.16.5=pl5321h694c41f_0 - - babel=2.14.0=pyhd8ed1ab_0 - - bc=1.07.1=h0d85af4_0 - - bdw-gc=8.0.6=h940c156_0 - - beautifulsoup4=4.12.3=pyha770c72_0 - - beniget=0.4.1=pyhd8ed1ab_0 - - blas=2.120=openblas - - blas-devel=3.9.0=20_osx64_openblas - - bleach=6.1.0=pyhd8ed1ab_0 - - boost-cpp=1.85.0=h07eb623_2 - - brial=1.2.12=pyh694c41f_3 - - brotli=1.1.0=h0dc2134_1 - - brotli-bin=1.1.0=h0dc2134_1 - - brotli-python=1.1.0=py311hdf8f085_1 - - bwidget=1.9.14=h694c41f_1 - - bzip2=1.0.8=h10d778d_5 - - c-ares=1.28.1=h10d778d_0 - - c-compiler=1.7.0=h282daa2_1 - - ca-certificates=2024.6.2=h8857fd0_0 - - cached-property=1.5.2=hd8ed1ab_1 - - cached_property=1.5.2=pyha770c72_1 - - cachetools=5.3.3=pyhd8ed1ab_0 - - cairo=1.18.0=h9f650ed_2 - - cctools=986=h40f6528_0 - - cctools_osx-64=986=ha1c5b94_0 - - cddlib=1!0.94m=h0f52abe_0 - - certifi=2024.6.2=pyhd8ed1ab_0 - - cffi=1.16.0=py311hc0b63fd_0 - - chardet=5.2.0=py311h6eed73b_1 - - charset-normalizer=3.3.2=pyhd8ed1ab_0 - - clang=16.0.6=default_ha3b9224_8 - - clang-16=16.0.6=default_h4c8afb6_8 - - clang_impl_osx-64=16.0.6=h8787910_16 - - clang_osx-64=16.0.6=hb91bd55_16 - - clangxx=16.0.6=default_ha3b9224_8 - - clangxx_impl_osx-64=16.0.6=h6d92fbe_16 - - clangxx_osx-64=16.0.6=hb91bd55_16 - - cliquer=1.22=h10d778d_1 - - cmake=3.29.6=h749d262_0 - - colorama=0.4.6=pyhd8ed1ab_0 - - colorlog=6.8.2=py311h6eed73b_0 - - comm=0.2.2=pyhd8ed1ab_0 - - compiler-rt=16.0.6=ha38d28d_2 - - compiler-rt_osx-64=16.0.6=ha38d28d_2 - - compilers=1.7.0=h694c41f_1 - - contourpy=1.2.1=py311h1d816ee_0 - - conway-polynomials=0.9=pyhd8ed1ab_0 - - cppy=1.2.1=pyhd8ed1ab_0 - - curl=8.8.0=hea67d85_0 - - cvxopt=1.3.2=py311he94735a_2 - - cxx-compiler=1.7.0=h7728843_1 - - cycler=0.12.1=pyhd8ed1ab_0 - - cypari2=2.1.5=py311h4fde0ae_0 - - cysignals=1.11.2=py311h8a58447_3 - - cython=3.0.10=py311hdd0406b_0 - - debugpy=1.8.1=py311hdd0406b_0 - - decorator=5.1.1=pyhd8ed1ab_0 - - defusedxml=0.7.1=pyhd8ed1ab_0 - - distlib=0.3.8=pyhd8ed1ab_0 - - docutils=0.21.2=pyhd8ed1ab_0 - - dsdp=5.8=h6e329d1_1203 - - ecl=23.9.9=h2b27fa8_0 - - eclib=20231212=h02435c3_0 - - ecm=7.0.5=h4f6b447_0 - - editables=0.5=pyhd8ed1ab_0 - - entrypoints=0.4=pyhd8ed1ab_0 - - exceptiongroup=1.2.0=pyhd8ed1ab_2 - - executing=2.0.1=pyhd8ed1ab_0 - - expat=2.6.2=h73e2aa4_0 - - fflas-ffpack=2.5.0=h5898d61_0 - - fftw=3.3.10=nompi_h292e606_110 - - filelock=3.15.4=pyhd8ed1ab_0 - - flit-core=3.9.0=pyhd8ed1ab_1 - - 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_2 - - fontconfig=2.14.2=h5bb23bf_0 - - fonts-conda-ecosystem=1=0 - - fonts-conda-forge=1=0 - - fonttools=4.53.0=py311h72ae277_0 - - fortran-compiler=1.7.0=h6c2ab21_1 - - fplll=5.4.5=hb7981ad_0 - - fpylll=0.6.1=py311h85fbf69_0 - - fqdn=1.5.1=pyhd8ed1ab_0 - - freetype=2.12.1=h60636b9_2 - - fribidi=1.0.10=hbcb3906_0 - - furo=2024.5.6=pyhd8ed1ab_0 - - gap-core=4.12.2=hc16eb5f_3 - - gap-defaults=4.12.2=h694c41f_3 - - gast=0.5.4=pyhd8ed1ab_0 - - gengetopt=2.23=he49afe7_0 - - gettext=0.22.5=h5ff76d1_2 - - gettext-tools=0.22.5=h5ff76d1_2 - - gf2x=1.3.0=hb2a7efb_2 - - gfan=0.6.2=hd793b56_1003 - - gfortran=12.3.0=h2c809b3_1 - - gfortran_impl_osx-64=12.3.0=hc328e78_3 - - gfortran_osx-64=12.3.0=h18f7dce_1 - - giac=1.9.0.21=h92f3f65_1 - - giflib=5.2.2=h10d778d_0 - - givaro=4.2.0=h1b3d6f7_0 - - glpk=5.0=h3cb5acd_0 - - gmp=6.3.0=hf036a51_2 - - gmpy2=2.1.5=py311hab17429_1 - - graphite2=1.3.13=h73e2aa4_1003 - - gsl=2.7=h93259b0_0 - - h11=0.14.0=pyhd8ed1ab_0 - - h2=4.1.0=pyhd8ed1ab_0 - - harfbuzz=8.5.0=h053f038_0 - - hatchling=1.25.0=pyhd8ed1ab_0 - - hpack=4.0.0=pyh9f0ad1d_0 - - httpcore=1.0.5=pyhd8ed1ab_0 - - httpx=0.27.0=pyhd8ed1ab_0 - - hyperframe=6.0.1=pyhd8ed1ab_0 - - icu=73.2=hf5e326d_0 - - idna=3.7=pyhd8ed1ab_0 - - igraph=0.10.12=hde4452d_1 - - imagesize=1.4.1=pyhd8ed1ab_0 - - iml=1.0.5=h61918c1_1004 - - importlib-metadata=8.0.0=pyha770c72_0 - - importlib-resources=6.4.0=pyhd8ed1ab_0 - - importlib_metadata=8.0.0=hd8ed1ab_0 - - importlib_resources=6.4.0=pyhd8ed1ab_0 - - ipykernel=6.29.4=pyh57ce528_0 - - ipympl=0.9.4=pyhd8ed1ab_0 - - ipython=8.25.0=pyh707e725_0 - - ipython_genutils=0.2.0=pyhd8ed1ab_1 - - ipywidgets=8.1.3=pyhd8ed1ab_0 - - isl=0.26=imath32_h2e86a7b_101 - - isoduration=20.11.0=pyhd8ed1ab_0 - - jedi=0.19.1=pyhd8ed1ab_0 - - jinja2=3.1.4=pyhd8ed1ab_0 - - jmol=14.32.9=h694c41f_0 - - json5=0.9.25=pyhd8ed1ab_0 - - jsonpointer=3.0.0=py311h6eed73b_0 - - jsonschema=4.22.0=pyhd8ed1ab_0 - - jsonschema-specifications=2023.12.1=pyhd8ed1ab_0 - - jsonschema-with-format-nongpl=4.22.0=pyhd8ed1ab_0 - - jupyter-jsmol=2022.1.0=pyhd8ed1ab_0 - - jupyter-lsp=2.2.5=pyhd8ed1ab_0 - - jupyter-sphinx=0.5.3=pyha770c72_4 - - jupyter_client=8.6.2=pyhd8ed1ab_0 - - jupyter_core=5.7.2=py311h6eed73b_0 - - jupyter_events=0.10.0=pyhd8ed1ab_0 - - jupyter_server=2.14.1=pyhd8ed1ab_0 - - jupyter_server_terminals=0.5.3=pyhd8ed1ab_0 - - jupyter_sphinx=0.5.3=hd8ed1ab_4 - - jupyterlab=4.2.2=pyhd8ed1ab_0 - - jupyterlab_pygments=0.3.0=pyhd8ed1ab_1 - - jupyterlab_server=2.27.2=pyhd8ed1ab_0 - - jupyterlab_widgets=3.0.11=pyhd8ed1ab_0 - - kiwisolver=1.4.5=py311h5fe6e05_1 - - krb5=1.21.2=hb884880_0 - - lcalc=2.0.5=h547a6ed_2 - - lcms2=2.16=ha2f27b4_0 - - ld64=711=ha02d983_0 - - ld64_osx-64=711=ha20a434_0 - - lerc=4.0.0=hb486fe8_0 - - libasprintf=0.22.5=h5ff76d1_2 - - libasprintf-devel=0.22.5=h5ff76d1_2 - - libatomic_ops=7.6.14=hb7f2c08_0 - - libblas=3.9.0=20_osx64_openblas - - libboost=1.85.0=h739af76_2 - - libboost-devel=1.85.0=h2b186f8_2 - - libboost-headers=1.85.0=h694c41f_2 - - libbraiding=1.2=hf0c8a7f_0 - - libbrial=1.2.12=h81e9653_3 - - libbrotlicommon=1.1.0=h0dc2134_1 - - libbrotlidec=1.1.0=h0dc2134_1 - - libbrotlienc=1.1.0=h0dc2134_1 - - libcblas=3.9.0=20_osx64_openblas - - libclang-cpp16=16.0.6=default_h4c8afb6_8 - - libcurl=8.8.0=hf9fcc65_0 - - libcxx=17.0.6=h88467a6_0 - - libdeflate=1.20=h49d49c5_0 - - libedit=3.1.20191231=h0678c8f_2 - - libev=4.33=h10d778d_2 - - libexpat=2.6.2=h73e2aa4_0 - - libffi=3.4.2=h0d85af4_5 - - libflint=3.0.1=h5d15de0_ntl_100 - - libgd=2.3.3=h0dceb68_9 - - libgettextpo=0.22.5=h5ff76d1_2 - - libgettextpo-devel=0.22.5=h5ff76d1_2 - - libgfortran=5.0.0=13_2_0_h97931a8_3 - - libgfortran-devel_osx-64=12.3.0=h0b6f5ec_3 - - libgfortran5=13.2.0=h2873a65_3 - - libglib=2.80.2=h736d271_1 - - libhomfly=1.02r6=h10d778d_1 - - libhwloc=2.10.0=default_h456cccd_1001 - - libiconv=1.17=hd75f5a5_2 - - libintl=0.22.5=h5ff76d1_2 - - libintl-devel=0.22.5=h5ff76d1_2 - - libjpeg-turbo=3.0.0=h0dc2134_1 - - liblapack=3.9.0=20_osx64_openblas - - liblapacke=3.9.0=20_osx64_openblas - - libllvm16=16.0.6=hbedff68_3 - - libnghttp2=1.58.0=h64cf6d3_1 - - libopenblas=0.3.25=openmp_hfef2a42_0 - - libpng=1.6.43=h92b6c6a_0 - - libsodium=1.0.18=hbcb3906_1 - - libsqlite=3.46.0=h1b8f9f3_0 - - libssh2=1.11.0=hd019ec5_0 - - libtiff=4.6.0=h129831d_3 - - libtool=2.4.7=hf0c8a7f_0 - - libuv=1.48.0=h67532ce_0 - - libwebp=1.4.0=hc207709_0 - - libwebp-base=1.4.0=h10d778d_0 - - libxcb=1.16=h0dc2134_0 - - libxml2=2.12.7=h3e169fe_1 - - libzlib=1.3.1=h87427d6_1 - - linbox=1.7.0=h7061c92_0 - - llvm-openmp=18.1.8=h15ab845_0 - - llvm-tools=16.0.6=hbedff68_3 - - lrcalc=2.1=h73e2aa4_6 - - m4=1.4.18=haf1e3a3_1001 - - m4ri=20140914=hd82a5f3_1006 - - m4rie=20150908=hc616cfc_1002 - - make=4.3=h22f3db7_1 - - markupsafe=2.1.5=py311he705e18_0 - - mathjax=3.2.2=h694c41f_0 - - matplotlib=3.8.4=py311h6eed73b_2 - - matplotlib-base=3.8.4=py311hff79762_2 - - matplotlib-inline=0.1.7=pyhd8ed1ab_0 - - maxima=5.47.0=h2b27fa8_2 - - memory-allocator=0.1.3=py311h2725bcf_0 - - metis=5.1.0=he965462_1007 - - mistune=3.0.2=pyhd8ed1ab_0 - - mpc=1.3.1=h81bd1dd_0 - - mpfi=1.5.4=h52b28e3_1001 - - mpfr=4.2.1=h4f6b447_1 - - mpmath=1.3.0=pyhd8ed1ab_0 - - munkres=1.1.4=pyh9f0ad1d_0 - - nauty=2.8.8=h10d778d_1 - - nbclient=0.10.0=pyhd8ed1ab_0 - - nbconvert=7.16.4=hd8ed1ab_1 - - nbconvert-core=7.16.4=pyhd8ed1ab_1 - - nbconvert-pandoc=7.16.4=hd8ed1ab_1 - - nbformat=5.10.4=pyhd8ed1ab_0 - - ncurses=6.5=h5846eda_0 - - nest-asyncio=1.6.0=pyhd8ed1ab_0 - - networkx=3.2.1=pyhd8ed1ab_0 - - ninja=1.12.1=h3c5361c_0 - - notebook=7.2.1=pyhd8ed1ab_0 - - notebook-shim=0.2.4=pyhd8ed1ab_0 - - ntl=11.4.3=h0ab3c2f_1 - - numpy=1.26.4=py311hc43a94b_0 - - openblas=0.3.25=openmp_h6794695_0 - - openjdk=22.0.1=h2d185b6_0 - - openjpeg=2.5.2=h7310d3a_0 - - openssl=3.3.1=h87427d6_0 - - overrides=7.7.0=pyhd8ed1ab_0 - - packaging=24.1=pyhd8ed1ab_0 - - palp=2.20=hbcb3906_0 - - pandoc=3.2.1=h694c41f_0 - - pandocfilters=1.5.0=pyhd8ed1ab_0 - - pango=1.54.0=h880b76c_0 - - pari=2.15.5=h7ba67ff_2_pthread - - pari-elldata=0.0.20161017=0 - - pari-galdata=0.0.20180411=0 - - pari-galpol=0.0.20180625=0 - - pari-seadata=0.0.20090618=0 - - pari-seadata-small=0.0.20090618=0 - - parso=0.8.4=pyhd8ed1ab_0 - - patch=2.7.6=hbcf498f_1002 - - pathspec=0.12.1=pyhd8ed1ab_0 - - pcre2=10.44=h7634a1b_0 - - pep517=0.13.0=pyhd8ed1ab_0 - - perl=5.32.1=7_h10d778d_perl5 - - pexpect=4.9.0=pyhd8ed1ab_0 - - pickleshare=0.7.5=py_1003 - - pillow=10.3.0=py311h2755ac0_1 - - pip=24.0=pyhd8ed1ab_0 - - pixman=0.43.4=h73e2aa4_0 - - pkg-config=0.29.2=ha3d46e9_1008 - - pkgconfig=1.5.5=pyhd8ed1ab_4 - - pkgutil-resolve-name=1.3.10=pyhd8ed1ab_1 - - planarity=3.0.2.0=h10d778d_0 - - platformdirs=4.2.2=pyhd8ed1ab_0 - - pluggy=1.5.0=pyhd8ed1ab_0 - - ply=3.11=pyhd8ed1ab_2 - - 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 - - prometheus_client=0.20.0=pyhd8ed1ab_0 - - prompt-toolkit=3.0.47=pyha770c72_0 - - prompt_toolkit=3.0.47=hd8ed1ab_0 - - psutil=6.0.0=py311h72ae277_0 - - pthread-stubs=0.4=hc929b4f_1001 - - ptyprocess=0.7.0=pyhd3deb0d_0 - - pure_eval=0.2.2=pyhd8ed1ab_0 - - py=1.11.0=pyh6c4a22f_0 - - pybind11=2.12.0=py311h1d816ee_0 - - pybind11-global=2.12.0=py311h1d816ee_0 - - pycparser=2.22=pyhd8ed1ab_0 - - pygments=2.18.0=pyhd8ed1ab_0 - - pyobjc-core=10.3.1=py311h9d23797_0 - - pyobjc-framework-cocoa=10.3.1=py311h9d23797_0 - - pyparsing=3.1.2=pyhd8ed1ab_0 - - pyproject-api=1.7.1=pyhd8ed1ab_0 - - pyrsistent=0.20.0=py311he705e18_0 - - pysocks=1.7.1=pyha2e5f31_6 - - python=3.11.9=h657bba9_0_cpython - - python-build=1.2.1=pyhd8ed1ab_0 - - python-dateutil=2.9.0=pyhd8ed1ab_0 - - python-fastjsonschema=2.20.0=pyhd8ed1ab_0 - - python-json-logger=2.0.7=pyhd8ed1ab_0 - - python-lrcalc=2.1=py311hdd0406b_6 - - python-tzdata=2024.1=pyhd8ed1ab_0 - - python_abi=3.11=4_cp311 - - pythran=0.15.0=py311ha853786_1 - - pytz=2024.1=pyhd8ed1ab_0 - - pytz-deprecation-shim=0.1.0.post0=py311h6eed73b_4 - - pyyaml=6.0.1=py311h2725bcf_1 - - pyzmq=26.0.3=py311h89e2aaa_0 - - qd=2.3.22=h2beb688_1004 - - qhull=2020.2=h940c156_2 - - r-base=4.3.3=h4648a1f_3 - - r-lattice=0.22_6=r43hb2c329c_0 - - readline=8.2=h9e318b2_1 - - referencing=0.35.1=pyhd8ed1ab_0 - - requests=2.32.3=pyhd8ed1ab_0 - - rfc3339-validator=0.1.4=pyhd8ed1ab_0 - - rfc3986-validator=0.1.1=pyh9f0ad1d_0 - - rhash=1.4.4=h0dc2134_0 - - rpds-py=0.18.1=py311h295b1db_0 - - rpy2=3.5.11=py311r43h4a70a88_3 - - rw=0.9=h10d778d_2 - - sagemath-db-combinatorial-designs=20140630=1 - - sagemath-db-elliptic-curves=0.8.1=hecc5488_0 - - sagemath-db-graphs=20210214=hd8ed1ab_0 - - sagemath-db-polytopes=20170220=1 - - sagetex=3.6.1=pyhd8ed1ab_0 - - scipy=1.11.4=py311he0bea55_0 - - send2trash=1.8.3=pyh31c8845_0 - - setuptools=70.1.1=pyhd8ed1ab_0 - - setuptools-scm=8.1.0=pyhd8ed1ab_0 - - setuptools_scm=8.1.0=hd8ed1ab_0 - - sigtool=0.1.3=h88f4db0_0 - - simplegeneric=0.8.1=py_1 - - singular=4.3.2.p8=h0d51a9f_1 - - six=1.16.0=pyh6c4a22f_0 - - sniffio=1.3.1=pyhd8ed1ab_0 - - snowballstemmer=2.2.0=pyhd8ed1ab_0 - - soupsieve=2.5=pyhd8ed1ab_1 - - sphinx=7.3.7=pyhd8ed1ab_0 - - sphinx-basic-ng=1.0.0b2=pyhd8ed1ab_1 - - sphinx-copybutton=0.5.2=pyhd8ed1ab_0 - - sphinxcontrib-applehelp=1.0.8=pyhd8ed1ab_0 - - sphinxcontrib-devhelp=1.0.6=pyhd8ed1ab_0 - - sphinxcontrib-htmlhelp=2.0.5=pyhd8ed1ab_0 - - sphinxcontrib-jsmath=1.0.1=pyhd8ed1ab_0 - - sphinxcontrib-qthelp=1.0.7=pyhd8ed1ab_0 - - sphinxcontrib-serializinghtml=1.1.10=pyhd8ed1ab_0 - - sphinxcontrib-websupport=1.2.7=pyhd8ed1ab_0 - - sqlite=3.46.0=h28673e1_0 - - stack_data=0.6.2=pyhd8ed1ab_0 - - suitesparse=7.7.0=hd2b2131_1 - - symmetrica=3.0.1=hf0c8a7f_0 - - sympow=2.023.6=h115ba6a_3 - - sympy=1.12.1=pypyh2585a3b_103 - - tachyon=0.99b6=h3a1d103_1002 - - tapi=1100.0.11=h9ce4665_0 - - tar=1.34=hcb2f6ea_1 - - tbb=2021.12.0=h3c5361c_1 - - terminado=0.18.1=pyh31c8845_0 - - texinfo=7.0=pl5321hc47821c_0 - - three.js=122=hd8ed1ab_2 - - threejs-sage=122=hd8ed1ab_2 - - tinycss2=1.3.0=pyhd8ed1ab_0 - - tk=8.6.13=h1abcd95_1 - - tktable=2.10=hba9d6f1_6 - - tomli=2.0.1=pyhd8ed1ab_0 - - tornado=6.4.1=py311h72ae277_0 - - tox=4.15.1=pyhd8ed1ab_0 - - traitlets=5.14.3=pyhd8ed1ab_0 - - trove-classifiers=2024.5.22=pyhd8ed1ab_0 - - types-python-dateutil=2.9.0.20240316=pyhd8ed1ab_0 - - typing-extensions=4.12.2=hd8ed1ab_0 - - typing_extensions=4.12.2=pyha770c72_0 - - typing_utils=0.1.0=pyhd8ed1ab_0 - - tzdata=2024a=h0c530f3_0 - - tzlocal=5.2=py311h6eed73b_0 - - uri-template=1.3.0=pyhd8ed1ab_0 - - urllib3=2.2.2=pyhd8ed1ab_0 - - virtualenv=20.26.3=pyhd8ed1ab_0 - - wcwidth=0.2.13=pyhd8ed1ab_0 - - webcolors=24.6.0=pyhd8ed1ab_0 - - webencodings=0.5.1=pyhd8ed1ab_2 - - websocket-client=1.8.0=pyhd8ed1ab_0 - - wheel=0.43.0=pyhd8ed1ab_1 - - widgetsnbextension=4.0.11=pyhd8ed1ab_0 - - xorg-libxau=1.0.11=h0dc2134_0 - - xorg-libxdmcp=1.1.3=h35c211d_0 - - xz=5.2.6=h775f41a_0 - - yaml=0.2.5=h0d85af4_2 - - zeromq=4.3.5=hde137ed_4 - - zipp=3.19.2=pyhd8ed1ab_0 - - zlib=1.3.1=h87427d6_1 - - zstd=1.5.6=h915ae27_0 diff --git a/src/environment-3.11-macos.yml b/src/environment-3.11-macos.yml deleted file mode 100644 index 192cc3a5f33..00000000000 --- a/src/environment-3.11-macos.yml +++ /dev/null @@ -1,422 +0,0 @@ -# Generated by conda-lock. -# platform: osx-arm64 -# input_hash: fd2f5edaba32b4c1f22d499071de74bde7eb804a27ac64e89ee82df0d733a829 - -channels: - - conda-forge -dependencies: - - _r-mutex=1.0.1=anacondar_1 - - alabaster=0.7.16=pyhd8ed1ab_0 - - anyio=4.4.0=pyhd8ed1ab_0 - - appdirs=1.4.4=pyh9f0ad1d_0 - - appnope=0.1.4=pyhd8ed1ab_0 - - argon2-cffi=23.1.0=pyhd8ed1ab_0 - - argon2-cffi-bindings=21.2.0=py311heffc1b2_4 - - arpack=3.9.1=nompi_h593882a_101 - - arrow=1.3.0=pyhd8ed1ab_0 - - asttokens=2.4.1=pyhd8ed1ab_0 - - async-lru=2.0.4=pyhd8ed1ab_0 - - attrs=23.2.0=pyh71513ae_0 - - autoconf=2.71=pl5321hcd07c0c_1 - - automake=1.16.5=pl5321hce30654_0 - - babel=2.14.0=pyhd8ed1ab_0 - - bc=1.07.1=h3422bc3_0 - - bdw-gc=8.0.6=hc021e02_0 - - beautifulsoup4=4.12.3=pyha770c72_0 - - beniget=0.4.1=pyhd8ed1ab_0 - - blas=2.120=openblas - - blas-devel=3.9.0=20_osxarm64_openblas - - bleach=6.1.0=pyhd8ed1ab_0 - - boost-cpp=1.85.0=hca5e981_2 - - brial=1.2.12=pyh694c41f_3 - - brotli=1.1.0=hb547adb_1 - - brotli-bin=1.1.0=hb547adb_1 - - brotli-python=1.1.0=py311ha891d26_1 - - bwidget=1.9.14=hce30654_1 - - bzip2=1.0.8=h93a5062_5 - - c-ares=1.28.1=h93a5062_0 - - c-compiler=1.7.0=h6aa9301_1 - - ca-certificates=2024.6.2=hf0a4a13_0 - - cached-property=1.5.2=hd8ed1ab_1 - - cached_property=1.5.2=pyha770c72_1 - - cachetools=5.3.3=pyhd8ed1ab_0 - - cairo=1.18.0=hc6c324b_2 - - cctools=986=h4faf515_0 - - cctools_osx-arm64=986=h62378fb_0 - - cddlib=1!0.94m=h6d7a090_0 - - certifi=2024.6.2=pyhd8ed1ab_0 - - cffi=1.16.0=py311h4a08483_0 - - chardet=5.2.0=py311h267d04e_1 - - charset-normalizer=3.3.2=pyhd8ed1ab_0 - - clang=16.0.6=default_h095aff0_8 - - clang-16=16.0.6=default_hb63da90_8 - - clang_impl_osx-arm64=16.0.6=hc421ffc_16 - - clang_osx-arm64=16.0.6=h54d7cd3_16 - - clangxx=16.0.6=default_h095aff0_8 - - clangxx_impl_osx-arm64=16.0.6=hcd7bac0_16 - - clangxx_osx-arm64=16.0.6=h54d7cd3_16 - - cliquer=1.22=h93a5062_1 - - cmake=3.29.6=had79d8f_0 - - colorama=0.4.6=pyhd8ed1ab_0 - - colorlog=6.8.2=py311h267d04e_0 - - comm=0.2.2=pyhd8ed1ab_0 - - compiler-rt=16.0.6=h3808999_2 - - compiler-rt_osx-arm64=16.0.6=h3808999_2 - - compilers=1.7.0=hce30654_1 - - contourpy=1.2.1=py311hcc98501_0 - - conway-polynomials=0.9=pyhd8ed1ab_0 - - cppy=1.2.1=pyhd8ed1ab_0 - - curl=8.8.0=h653d890_0 - - cvxopt=1.3.2=py311h77cf4c7_2 - - cxx-compiler=1.7.0=h2ffa867_1 - - cycler=0.12.1=pyhd8ed1ab_0 - - cypari2=2.1.5=py311h2c49a9d_0 - - cysignals=1.11.2=py311he42fc87_3 - - cython=3.0.10=py311h92babd0_0 - - debugpy=1.8.1=py311h92babd0_0 - - decorator=5.1.1=pyhd8ed1ab_0 - - defusedxml=0.7.1=pyhd8ed1ab_0 - - distlib=0.3.8=pyhd8ed1ab_0 - - docutils=0.21.2=pyhd8ed1ab_0 - - dsdp=5.8=h9397a75_1203 - - ecl=23.9.9=h1d9728a_0 - - eclib=20231212=h7f07de4_0 - - ecm=7.0.5=h41d338b_0 - - editables=0.5=pyhd8ed1ab_0 - - entrypoints=0.4=pyhd8ed1ab_0 - - exceptiongroup=1.2.0=pyhd8ed1ab_2 - - executing=2.0.1=pyhd8ed1ab_0 - - expat=2.6.2=hebf3989_0 - - fflas-ffpack=2.5.0=h4bc3318_0 - - fftw=3.3.10=nompi_h6637ab6_110 - - filelock=3.15.4=pyhd8ed1ab_0 - - flit-core=3.9.0=pyhd8ed1ab_1 - - 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_2 - - fontconfig=2.14.2=h82840c6_0 - - fonts-conda-ecosystem=1=0 - - fonts-conda-forge=1=0 - - fonttools=4.53.0=py311hd3f4193_0 - - fortran-compiler=1.7.0=hafb19e3_1 - - fplll=5.4.5=hb7d509d_0 - - fpylll=0.6.1=py311h341b96b_0 - - fqdn=1.5.1=pyhd8ed1ab_0 - - freetype=2.12.1=hadb7bae_2 - - fribidi=1.0.10=h27ca646_0 - - furo=2024.5.6=pyhd8ed1ab_0 - - gap-core=4.12.2=he8f4e70_3 - - gap-defaults=4.12.2=hce30654_3 - - gast=0.5.4=pyhd8ed1ab_0 - - gengetopt=2.23=hbdafb3b_0 - - gettext=0.22.5=h8fbad5d_2 - - gettext-tools=0.22.5=h8fbad5d_2 - - gf2x=1.3.0=hdaa854c_2 - - gfan=0.6.2=hec08f5c_1003 - - gfortran=12.3.0=h1ca8e4b_1 - - gfortran_impl_osx-arm64=12.3.0=h53ed385_3 - - gfortran_osx-arm64=12.3.0=h57527a5_1 - - giac=1.9.0.21=h1c96721_1 - - giflib=5.2.2=h93a5062_0 - - givaro=4.2.0=h018886a_0 - - glpk=5.0=h6d7a090_0 - - gmp=6.3.0=h7bae524_2 - - gmpy2=2.1.5=py311h1e33d93_1 - - graphite2=1.3.13=hebf3989_1003 - - gsl=2.7=h6e638da_0 - - h11=0.14.0=pyhd8ed1ab_0 - - h2=4.1.0=pyhd8ed1ab_0 - - harfbuzz=8.5.0=h1836168_0 - - hatchling=1.25.0=pyhd8ed1ab_0 - - hpack=4.0.0=pyh9f0ad1d_0 - - httpcore=1.0.5=pyhd8ed1ab_0 - - httpx=0.27.0=pyhd8ed1ab_0 - - hyperframe=6.0.1=pyhd8ed1ab_0 - - icu=73.2=hc8870d7_0 - - idna=3.7=pyhd8ed1ab_0 - - igraph=0.10.12=h762ac30_1 - - imagesize=1.4.1=pyhd8ed1ab_0 - - iml=1.0.5=hd73f12c_1004 - - importlib-metadata=8.0.0=pyha770c72_0 - - importlib-resources=6.4.0=pyhd8ed1ab_0 - - importlib_metadata=8.0.0=hd8ed1ab_0 - - importlib_resources=6.4.0=pyhd8ed1ab_0 - - ipykernel=6.29.4=pyh57ce528_0 - - ipympl=0.9.4=pyhd8ed1ab_0 - - ipython=8.25.0=pyh707e725_0 - - ipython_genutils=0.2.0=pyhd8ed1ab_1 - - ipywidgets=8.1.3=pyhd8ed1ab_0 - - isl=0.26=imath32_h347afa1_101 - - isoduration=20.11.0=pyhd8ed1ab_0 - - jedi=0.19.1=pyhd8ed1ab_0 - - jinja2=3.1.4=pyhd8ed1ab_0 - - jmol=14.32.10=hce30654_0 - - json5=0.9.25=pyhd8ed1ab_0 - - jsonpointer=3.0.0=py311h267d04e_0 - - jsonschema=4.22.0=pyhd8ed1ab_0 - - jsonschema-specifications=2023.12.1=pyhd8ed1ab_0 - - jsonschema-with-format-nongpl=4.22.0=pyhd8ed1ab_0 - - jupyter-jsmol=2022.1.0=pyhd8ed1ab_0 - - jupyter-lsp=2.2.5=pyhd8ed1ab_0 - - jupyter-sphinx=0.5.3=pyha770c72_4 - - jupyter_client=8.6.2=pyhd8ed1ab_0 - - jupyter_core=5.7.2=py311h267d04e_0 - - jupyter_events=0.10.0=pyhd8ed1ab_0 - - jupyter_server=2.14.1=pyhd8ed1ab_0 - - jupyter_server_terminals=0.5.3=pyhd8ed1ab_0 - - jupyter_sphinx=0.5.3=hd8ed1ab_4 - - jupyterlab=4.2.2=pyhd8ed1ab_0 - - jupyterlab_pygments=0.3.0=pyhd8ed1ab_1 - - jupyterlab_server=2.27.2=pyhd8ed1ab_0 - - jupyterlab_widgets=3.0.11=pyhd8ed1ab_0 - - kiwisolver=1.4.5=py311he4fd1f5_1 - - krb5=1.21.2=h92f50d5_0 - - lcalc=2.0.5=h4a402bc_2 - - lcms2=2.16=ha0e7c42_0 - - ld64=711=h634c8be_0 - - ld64_osx-arm64=711=ha4bd21c_0 - - lerc=4.0.0=h9a09cb3_0 - - libasprintf=0.22.5=h8fbad5d_2 - - libasprintf-devel=0.22.5=h8fbad5d_2 - - libatomic_ops=7.6.14=h1a8c8d9_0 - - libblas=3.9.0=20_osxarm64_openblas - - libboost=1.85.0=h17eb2be_2 - - libboost-devel=1.85.0=hf450f58_2 - - libboost-headers=1.85.0=hce30654_2 - - libbraiding=1.2=hb7217d7_0 - - libbrial=1.2.12=h56a29cd_3 - - libbrotlicommon=1.1.0=hb547adb_1 - - libbrotlidec=1.1.0=hb547adb_1 - - libbrotlienc=1.1.0=hb547adb_1 - - libcblas=3.9.0=20_osxarm64_openblas - - libclang-cpp16=16.0.6=default_hb63da90_8 - - libcurl=8.8.0=h7b6f9a7_0 - - libcxx=17.0.6=h5f092b4_0 - - libdeflate=1.20=h93a5062_0 - - libedit=3.1.20191231=hc8eb9b7_2 - - libev=4.33=h93a5062_2 - - libexpat=2.6.2=hebf3989_0 - - libffi=3.4.2=h3422bc3_5 - - libflint=3.0.1=h28749a5_ntl_100 - - libgd=2.3.3=hfdf3952_9 - - libgettextpo=0.22.5=h8fbad5d_2 - - libgettextpo-devel=0.22.5=h8fbad5d_2 - - libgfortran=5.0.0=13_2_0_hd922786_3 - - libgfortran-devel_osx-arm64=12.3.0=hc62be1c_3 - - libgfortran5=13.2.0=hf226fd6_3 - - libglib=2.80.2=h59d46d9_1 - - libhomfly=1.02r6=h93a5062_1 - - libhwloc=2.10.0=default_h7685b71_1001 - - libiconv=1.17=h0d3ecfb_2 - - libintl=0.22.5=h8fbad5d_2 - - libintl-devel=0.22.5=h8fbad5d_2 - - libjpeg-turbo=3.0.0=hb547adb_1 - - liblapack=3.9.0=20_osxarm64_openblas - - liblapacke=3.9.0=20_osxarm64_openblas - - libllvm16=16.0.6=haab561b_3 - - libnghttp2=1.58.0=ha4dd798_1 - - libopenblas=0.3.25=openmp_h6c19121_0 - - libpng=1.6.43=h091b4b1_0 - - libsodium=1.0.18=h27ca646_1 - - libsqlite=3.46.0=hfb93653_0 - - libssh2=1.11.0=h7a5bd25_0 - - libtiff=4.6.0=h07db509_3 - - libtool=2.4.7=hb7217d7_0 - - libuv=1.48.0=h93a5062_0 - - libwebp=1.4.0=h54798ee_0 - - libwebp-base=1.4.0=h93a5062_0 - - libxcb=1.16=hf2054a2_0 - - libxml2=2.12.7=ha661575_1 - - libzlib=1.3.1=hfb2fe0b_1 - - linbox=1.7.0=h3afee3a_0 - - llvm-openmp=18.1.8=hde57baf_0 - - llvm-tools=16.0.6=haab561b_3 - - lrcalc=2.1=hebf3989_6 - - m4=1.4.18=h642e427_1001 - - m4ri=20140914=hc97c1ff_1006 - - m4rie=20150908=h22b9e9d_1002 - - make=4.3=he57ea6c_1 - - markupsafe=2.1.5=py311h05b510d_0 - - mathjax=3.2.2=hce30654_0 - - matplotlib=3.8.4=py311ha1ab1f8_2 - - matplotlib-base=3.8.4=py311h000fb6e_2 - - matplotlib-inline=0.1.7=pyhd8ed1ab_0 - - maxima=5.47.0=h2bbcd85_2 - - memory-allocator=0.1.3=py311heffc1b2_0 - - metis=5.1.0=h13dd4ca_1007 - - mistune=3.0.2=pyhd8ed1ab_0 - - mpc=1.3.1=h91ba8db_0 - - mpfi=1.5.4=hbde5f5b_1001 - - mpfr=4.2.1=h41d338b_1 - - mpmath=1.3.0=pyhd8ed1ab_0 - - munkres=1.1.4=pyh9f0ad1d_0 - - nauty=2.8.8=h93a5062_1 - - nbclient=0.10.0=pyhd8ed1ab_0 - - nbconvert=7.16.4=hd8ed1ab_1 - - nbconvert-core=7.16.4=pyhd8ed1ab_1 - - nbconvert-pandoc=7.16.4=hd8ed1ab_1 - - nbformat=5.10.4=pyhd8ed1ab_0 - - ncurses=6.5=hb89a1cb_0 - - nest-asyncio=1.6.0=pyhd8ed1ab_0 - - networkx=3.2.1=pyhd8ed1ab_0 - - ninja=1.12.1=h420ef59_0 - - notebook=7.2.1=pyhd8ed1ab_0 - - notebook-shim=0.2.4=pyhd8ed1ab_0 - - ntl=11.4.3=hbb3f309_1 - - numpy=1.26.4=py311h7125741_0 - - openblas=0.3.25=openmp_h55c453e_0 - - openjdk=22.0.1=hbeb2e11_0 - - openjpeg=2.5.2=h9f1df11_0 - - openssl=3.3.1=hfb2fe0b_0 - - overrides=7.7.0=pyhd8ed1ab_0 - - packaging=24.1=pyhd8ed1ab_0 - - palp=2.20=h27ca646_0 - - pandoc=3.2.1=hce30654_0 - - pandocfilters=1.5.0=pyhd8ed1ab_0 - - pango=1.54.0=h5cb9fbc_0 - - pari=2.15.5=h4f2304c_2_pthread - - pari-elldata=0.0.20161017=0 - - pari-galdata=0.0.20180411=0 - - pari-galpol=0.0.20180625=0 - - pari-seadata=0.0.20090618=0 - - pari-seadata-small=0.0.20090618=0 - - parso=0.8.4=pyhd8ed1ab_0 - - patch=2.7.6=h27ca646_1002 - - pathspec=0.12.1=pyhd8ed1ab_0 - - pcre2=10.44=h297a79d_0 - - pep517=0.13.0=pyhd8ed1ab_0 - - perl=5.32.1=7_h4614cfb_perl5 - - pexpect=4.9.0=pyhd8ed1ab_0 - - pickleshare=0.7.5=py_1003 - - pillow=10.3.0=py311hd7951ec_1 - - pip=24.0=pyhd8ed1ab_0 - - pixman=0.43.4=hebf3989_0 - - pkg-config=0.29.2=hab62308_1008 - - pkgconfig=1.5.5=pyhd8ed1ab_4 - - pkgutil-resolve-name=1.3.10=pyhd8ed1ab_1 - - planarity=3.0.2.0=h93a5062_0 - - platformdirs=4.2.2=pyhd8ed1ab_0 - - pluggy=1.5.0=pyhd8ed1ab_0 - - ply=3.11=pyhd8ed1ab_2 - - 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 - - prometheus_client=0.20.0=pyhd8ed1ab_0 - - prompt-toolkit=3.0.47=pyha770c72_0 - - prompt_toolkit=3.0.47=hd8ed1ab_0 - - psutil=6.0.0=py311hd3f4193_0 - - pthread-stubs=0.4=h27ca646_1001 - - ptyprocess=0.7.0=pyhd3deb0d_0 - - pure_eval=0.2.2=pyhd8ed1ab_0 - - py=1.11.0=pyh6c4a22f_0 - - pybind11=2.12.0=py311hcc98501_0 - - pybind11-global=2.12.0=py311hcc98501_0 - - pycparser=2.22=pyhd8ed1ab_0 - - pygments=2.18.0=pyhd8ed1ab_0 - - pyobjc-core=10.3.1=py311h5f135c3_0 - - pyobjc-framework-cocoa=10.3.1=py311h5f135c3_0 - - pyparsing=3.1.2=pyhd8ed1ab_0 - - pyproject-api=1.7.1=pyhd8ed1ab_0 - - pyrsistent=0.20.0=py311h05b510d_0 - - pysocks=1.7.1=pyha2e5f31_6 - - python=3.11.9=h932a869_0_cpython - - python-build=1.2.1=pyhd8ed1ab_0 - - python-dateutil=2.9.0=pyhd8ed1ab_0 - - python-fastjsonschema=2.20.0=pyhd8ed1ab_0 - - python-json-logger=2.0.7=pyhd8ed1ab_0 - - python-lrcalc=2.1=py311h92babd0_6 - - python-tzdata=2024.1=pyhd8ed1ab_0 - - python_abi=3.11=4_cp311 - - pythran=0.15.0=py311hceb3b21_1 - - pytz=2024.1=pyhd8ed1ab_0 - - pytz-deprecation-shim=0.1.0.post0=py311h267d04e_4 - - pyyaml=6.0.1=py311heffc1b2_1 - - pyzmq=26.0.3=py311h9bed540_0 - - qd=2.3.22=hbec66e7_1004 - - qhull=2020.2=hc021e02_2 - - r-base=4.3.3=h8112bfe_3 - - r-lattice=0.22_6=r43hd2d937b_0 - - readline=8.2=h92ec313_1 - - referencing=0.35.1=pyhd8ed1ab_0 - - requests=2.32.3=pyhd8ed1ab_0 - - rfc3339-validator=0.1.4=pyhd8ed1ab_0 - - rfc3986-validator=0.1.1=pyh9f0ad1d_0 - - rhash=1.4.4=hb547adb_0 - - rpds-py=0.18.1=py311h98c6a39_0 - - rpy2=3.5.11=py311r43hb49d859_3 - - rw=0.9=h93a5062_2 - - sagemath-db-combinatorial-designs=20140630=1 - - sagemath-db-elliptic-curves=0.8.1=hecc5488_0 - - sagemath-db-graphs=20210214=hd8ed1ab_0 - - sagemath-db-polytopes=20170220=1 - - sagetex=3.6.1=pyhd8ed1ab_0 - - scipy=1.11.4=py311h2b215a9_0 - - send2trash=1.8.3=pyh31c8845_0 - - setuptools=70.1.1=pyhd8ed1ab_0 - - setuptools-scm=8.1.0=pyhd8ed1ab_0 - - setuptools_scm=8.1.0=hd8ed1ab_0 - - sigtool=0.1.3=h44b9a77_0 - - simplegeneric=0.8.1=py_1 - - singular=4.3.2.p8=hb460b52_1 - - six=1.16.0=pyh6c4a22f_0 - - sniffio=1.3.1=pyhd8ed1ab_0 - - snowballstemmer=2.2.0=pyhd8ed1ab_0 - - soupsieve=2.5=pyhd8ed1ab_1 - - sphinx=7.3.7=pyhd8ed1ab_0 - - sphinx-basic-ng=1.0.0b2=pyhd8ed1ab_1 - - sphinx-copybutton=0.5.2=pyhd8ed1ab_0 - - sphinxcontrib-applehelp=1.0.8=pyhd8ed1ab_0 - - sphinxcontrib-devhelp=1.0.6=pyhd8ed1ab_0 - - sphinxcontrib-htmlhelp=2.0.5=pyhd8ed1ab_0 - - sphinxcontrib-jsmath=1.0.1=pyhd8ed1ab_0 - - sphinxcontrib-qthelp=1.0.7=pyhd8ed1ab_0 - - sphinxcontrib-serializinghtml=1.1.10=pyhd8ed1ab_0 - - sphinxcontrib-websupport=1.2.7=pyhd8ed1ab_0 - - sqlite=3.46.0=h5838104_0 - - stack_data=0.6.2=pyhd8ed1ab_0 - - suitesparse=7.7.0=hf6fcff2_1 - - symmetrica=3.0.1=hb7217d7_0 - - sympow=2.023.6=hb0babe8_3 - - sympy=1.12.1=pypyh2585a3b_103 - - tachyon=0.99b6=hb8a568e_1002 - - tapi=1100.0.11=he4954df_0 - - tar=1.34=h7cb298e_1 - - tbb=2021.12.0=h420ef59_1 - - terminado=0.18.1=pyh31c8845_0 - - texinfo=7.0=pl5321h9ea1dce_0 - - three.js=122=hd8ed1ab_2 - - threejs-sage=122=hd8ed1ab_2 - - tinycss2=1.3.0=pyhd8ed1ab_0 - - tk=8.6.13=h5083fa2_1 - - tktable=2.10=h1e387b8_6 - - tomli=2.0.1=pyhd8ed1ab_0 - - tornado=6.4.1=py311hd3f4193_0 - - tox=4.15.1=pyhd8ed1ab_0 - - traitlets=5.14.3=pyhd8ed1ab_0 - - trove-classifiers=2024.5.22=pyhd8ed1ab_0 - - types-python-dateutil=2.9.0.20240316=pyhd8ed1ab_0 - - typing-extensions=4.12.2=hd8ed1ab_0 - - typing_extensions=4.12.2=pyha770c72_0 - - typing_utils=0.1.0=pyhd8ed1ab_0 - - tzdata=2024a=h0c530f3_0 - - tzlocal=5.2=py311h267d04e_0 - - uri-template=1.3.0=pyhd8ed1ab_0 - - urllib3=2.2.2=pyhd8ed1ab_0 - - virtualenv=20.26.3=pyhd8ed1ab_0 - - wcwidth=0.2.13=pyhd8ed1ab_0 - - webcolors=24.6.0=pyhd8ed1ab_0 - - webencodings=0.5.1=pyhd8ed1ab_2 - - websocket-client=1.8.0=pyhd8ed1ab_0 - - wheel=0.43.0=pyhd8ed1ab_1 - - widgetsnbextension=4.0.11=pyhd8ed1ab_0 - - xorg-libxau=1.0.11=hb547adb_0 - - xorg-libxdmcp=1.1.3=h27ca646_0 - - xz=5.2.6=h57fd34a_0 - - yaml=0.2.5=h3422bc3_2 - - zeromq=4.3.5=hcc0f68c_4 - - zipp=3.19.2=pyhd8ed1ab_0 - - zlib=1.3.1=hfb2fe0b_1 - - zstd=1.5.6=hb46c0d2_0 diff --git a/src/environment-3.9-linux-aarch64.yml b/src/environment-3.9-linux-aarch64.yml deleted file mode 100644 index 43382444aae..00000000000 --- a/src/environment-3.9-linux-aarch64.yml +++ /dev/null @@ -1,435 +0,0 @@ -# Generated by conda-lock. -# platform: linux-aarch64 -# input_hash: ff1dc47da14265a884b6d8aae2cde457456f547babfa735ad39ad330bb83aa6a - -channels: - - conda-forge -dependencies: - - _openmp_mutex=4.5=2_kmp_llvm - - _r-mutex=1.0.1=anacondar_1 - - _sysroot_linux-aarch64_curr_repodata_hack=4=h57d6b7b_14 - - alabaster=0.7.16=pyhd8ed1ab_0 - - alsa-lib=1.2.11=h31becfc_1 - - anyio=4.4.0=pyhd8ed1ab_0 - - appdirs=1.4.4=pyh9f0ad1d_0 - - appnope=0.1.4=pyhd8ed1ab_0 - - argon2-cffi=23.1.0=pyhd8ed1ab_0 - - argon2-cffi-bindings=21.2.0=py39h898b7ef_4 - - arpack=3.9.1=nompi_hd363cd0_101 - - arrow=1.3.0=pyhd8ed1ab_0 - - asttokens=2.4.1=pyhd8ed1ab_0 - - async-lru=2.0.4=pyhd8ed1ab_0 - - attrs=23.2.0=pyh71513ae_0 - - autoconf=2.71=pl5321h2148fe1_1 - - automake=1.16.5=pl5321h8af1aa0_0 - - babel=2.14.0=pyhd8ed1ab_0 - - bc=1.07.1=hf897c2e_0 - - bdw-gc=8.0.6=hd62202e_0 - - beautifulsoup4=4.12.3=pyha770c72_0 - - beniget=0.4.1=pyhd8ed1ab_0 - - binutils=2.40=hf1166c9_7 - - binutils_impl_linux-aarch64=2.40=hf54a868_7 - - binutils_linux-aarch64=2.40=h1f91aba_9 - - blas=2.120=openblas - - blas-devel=3.9.0=20_linuxaarch64_openblas - - bleach=6.1.0=pyhd8ed1ab_0 - - boost-cpp=1.85.0=ha990451_2 - - brial=1.2.12=pyh694c41f_3 - - brotli=1.1.0=h31becfc_1 - - brotli-bin=1.1.0=h31becfc_1 - - brotli-python=1.1.0=py39h387a81e_1 - - bwidget=1.9.14=h8af1aa0_1 - - bzip2=1.0.8=h31becfc_5 - - c-ares=1.28.1=h31becfc_0 - - c-compiler=1.7.0=h31becfc_1 - - ca-certificates=2024.6.2=hcefe29a_0 - - cached-property=1.5.2=hd8ed1ab_1 - - cached_property=1.5.2=pyha770c72_1 - - cachetools=5.3.3=pyhd8ed1ab_0 - - cairo=1.18.0=h5c54ea9_2 - - cddlib=1!0.94m=h719063d_0 - - certifi=2024.6.2=pyhd8ed1ab_0 - - cffi=1.16.0=py39hdf53b9e_0 - - chardet=5.2.0=py39ha65689a_1 - - charset-normalizer=3.3.2=pyhd8ed1ab_0 - - cliquer=1.22=h31becfc_1 - - cmake=3.29.6=h7042e5d_0 - - colorama=0.4.6=pyhd8ed1ab_0 - - colorlog=6.8.2=py39h4420490_0 - - comm=0.2.2=pyhd8ed1ab_0 - - compilers=1.7.0=h8af1aa0_1 - - contourpy=1.2.1=py39hd16970a_0 - - conway-polynomials=0.9=pyhd8ed1ab_0 - - cppy=1.2.1=pyhd8ed1ab_0 - - curl=8.8.0=h7daf2e0_0 - - cvxopt=1.3.2=py39h093dae0_2 - - cxx-compiler=1.7.0=h2a328a1_1 - - cycler=0.12.1=pyhd8ed1ab_0 - - cypari2=2.1.5=py39h532d932_0 - - cysignals=1.11.2=py39hfa81392_3 - - cython=3.0.10=py39h387a81e_0 - - debugpy=1.8.1=py39h387a81e_0 - - decorator=5.1.1=pyhd8ed1ab_0 - - defusedxml=0.7.1=pyhd8ed1ab_0 - - distlib=0.3.8=pyhd8ed1ab_0 - - docutils=0.21.2=pyhd8ed1ab_0 - - dsdp=5.8=hb12102e_1203 - - ecl=23.9.9=h6475f26_0 - - eclib=20231212=he26bab5_0 - - ecm=7.0.5=ha2d0fc4_0 - - editables=0.5=pyhd8ed1ab_0 - - entrypoints=0.4=pyhd8ed1ab_0 - - exceptiongroup=1.2.0=pyhd8ed1ab_2 - - executing=2.0.1=pyhd8ed1ab_0 - - expat=2.6.2=h2f0025b_0 - - fflas-ffpack=2.5.0=h503e619_0 - - fftw=3.3.10=nompi_h020dacd_110 - - filelock=3.15.4=pyhd8ed1ab_0 - - flit-core=3.9.0=pyhd8ed1ab_1 - - 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_2 - - fontconfig=2.14.2=ha9a116f_0 - - fonts-conda-ecosystem=1=0 - - fonts-conda-forge=1=0 - - fonttools=4.53.0=py39he257ee7_0 - - fortran-compiler=1.7.0=h7048d53_1 - - fplll=5.4.5=hb3a790e_0 - - fpylll=0.6.1=py39h97065f7_0 - - fqdn=1.5.1=pyhd8ed1ab_0 - - freetype=2.12.1=hf0a5ef3_2 - - fribidi=1.0.10=hb9de7d4_0 - - furo=2024.5.6=pyhd8ed1ab_0 - - gap-core=4.12.2=h597289e_3 - - gap-defaults=4.12.2=h8af1aa0_3 - - gast=0.5.4=pyhd8ed1ab_0 - - gcc=12.3.0=hdb0cc85_13 - - gcc_impl_linux-aarch64=12.3.0=h3d98823_13 - - gcc_linux-aarch64=12.3.0=ha52a6ea_9 - - gengetopt=2.23=h01db608_0 - - gf2x=1.3.0=h1b3b3a3_2 - - gfan=0.6.2=h5f589ec_1003 - - gfortran=12.3.0=hdb0cc85_13 - - gfortran_impl_linux-aarch64=12.3.0=h97ebfd2_13 - - gfortran_linux-aarch64=12.3.0=ha7b8e4b_9 - - giac=1.9.0.21=h04922a4_1 - - giflib=5.2.2=h31becfc_0 - - givaro=4.2.0=h364d21b_0 - - glpk=5.0=h66325d0_0 - - gmp=6.3.0=h0a1ffab_2 - - gmpy2=2.1.5=py39hcc1b389_1 - - graphite2=1.3.13=h2f0025b_1003 - - gsl=2.7=h294027d_0 - - gxx=12.3.0=hdb0cc85_13 - - gxx_impl_linux-aarch64=12.3.0=hba91e99_13 - - gxx_linux-aarch64=12.3.0=h9d1f256_9 - - h11=0.14.0=pyhd8ed1ab_0 - - h2=4.1.0=pyhd8ed1ab_0 - - harfbuzz=8.5.0=h9812418_0 - - hatchling=1.25.0=pyhd8ed1ab_0 - - hpack=4.0.0=pyh9f0ad1d_0 - - httpcore=1.0.5=pyhd8ed1ab_0 - - httpx=0.27.0=pyhd8ed1ab_0 - - hyperframe=6.0.1=pyhd8ed1ab_0 - - icu=73.2=h787c7f5_0 - - idna=3.7=pyhd8ed1ab_0 - - igraph=0.10.12=h197073e_1 - - imagesize=1.4.1=pyhd8ed1ab_0 - - iml=1.0.5=h15043fe_1004 - - importlib-metadata=8.0.0=pyha770c72_0 - - importlib-resources=6.4.0=pyhd8ed1ab_0 - - importlib_metadata=8.0.0=hd8ed1ab_0 - - importlib_resources=6.4.0=pyhd8ed1ab_0 - - ipykernel=6.29.4=pyh3099207_0 - - ipympl=0.9.4=pyhd8ed1ab_0 - - ipython=8.18.1=pyh707e725_3 - - ipython_genutils=0.2.0=pyhd8ed1ab_1 - - ipywidgets=8.1.3=pyhd8ed1ab_0 - - isoduration=20.11.0=pyhd8ed1ab_0 - - jedi=0.19.1=pyhd8ed1ab_0 - - jinja2=3.1.4=pyhd8ed1ab_0 - - jmol=14.32.10=h8af1aa0_0 - - json5=0.9.25=pyhd8ed1ab_0 - - jsonpointer=3.0.0=py39h4420490_0 - - jsonschema=4.22.0=pyhd8ed1ab_0 - - jsonschema-specifications=2023.12.1=pyhd8ed1ab_0 - - jsonschema-with-format-nongpl=4.22.0=pyhd8ed1ab_0 - - jupyter-jsmol=2022.1.0=pyhd8ed1ab_0 - - jupyter-lsp=2.2.5=pyhd8ed1ab_0 - - jupyter-sphinx=0.5.3=pyha770c72_4 - - jupyter_client=8.6.2=pyhd8ed1ab_0 - - jupyter_core=5.7.2=py39h4420490_0 - - jupyter_events=0.10.0=pyhd8ed1ab_0 - - jupyter_server=2.14.1=pyhd8ed1ab_0 - - jupyter_server_terminals=0.5.3=pyhd8ed1ab_0 - - jupyter_sphinx=0.5.3=hd8ed1ab_4 - - jupyterlab=4.2.2=pyhd8ed1ab_0 - - jupyterlab_pygments=0.3.0=pyhd8ed1ab_1 - - jupyterlab_server=2.27.2=pyhd8ed1ab_0 - - jupyterlab_widgets=3.0.11=pyhd8ed1ab_0 - - kernel-headers_linux-aarch64=4.18.0=h5b4a56d_14 - - keyutils=1.6.1=h4e544f5_0 - - kiwisolver=1.4.5=py39had2cf8c_1 - - krb5=1.21.2=hc419048_0 - - lcalc=2.0.5=he588f68_2 - - lcms2=2.16=h922389a_0 - - ld_impl_linux-aarch64=2.40=h9fc2d93_7 - - lerc=4.0.0=h4de3ea5_0 - - libatomic_ops=7.6.14=h4e544f5_0 - - libblas=3.9.0=20_linuxaarch64_openblas - - libboost=1.85.0=hb41fec8_2 - - libboost-devel=1.85.0=h37bb5a9_2 - - libboost-headers=1.85.0=h8af1aa0_2 - - libbraiding=1.2=hd600fc2_0 - - libbrial=1.2.12=h9429f74_3 - - libbrotlicommon=1.1.0=h31becfc_1 - - libbrotlidec=1.1.0=h31becfc_1 - - libbrotlienc=1.1.0=h31becfc_1 - - libcblas=3.9.0=20_linuxaarch64_openblas - - libcups=2.3.3=h405e4a8_4 - - libcurl=8.8.0=h4e8248e_0 - - libdeflate=1.20=h31becfc_0 - - libedit=3.1.20191231=he28a2e2_2 - - libev=4.33=h31becfc_2 - - libexpat=2.6.2=h2f0025b_0 - - libffi=3.4.2=h3557bc0_5 - - libflint=3.0.1=hc392af7_ntl_100 - - libgcc-devel_linux-aarch64=12.3.0=h6144e03_113 - - libgcc-ng=13.2.0=he277a41_13 - - libgd=2.3.3=hcd22fd5_9 - - libgfortran-ng=13.2.0=he9431aa_13 - - libgfortran5=13.2.0=h2af0866_13 - - libglib=2.80.2=haee52c6_1 - - libgomp=13.2.0=he277a41_13 - - libhomfly=1.02r6=h31becfc_1 - - libhwloc=2.10.0=default_h3030c0e_1001 - - libiconv=1.17=h31becfc_2 - - libjpeg-turbo=3.0.0=h31becfc_1 - - liblapack=3.9.0=20_linuxaarch64_openblas - - liblapacke=3.9.0=20_linuxaarch64_openblas - - libnghttp2=1.58.0=hb0e430d_1 - - libnsl=2.0.1=h31becfc_0 - - libopenblas=0.3.25=pthreads_h5a5ec62_0 - - libpng=1.6.43=h194ca79_0 - - libsanitizer=12.3.0=h57e2e72_13 - - libsodium=1.0.18=hb9de7d4_1 - - libsqlite=3.46.0=hf51ef55_0 - - libssh2=1.11.0=h492db2e_0 - - libstdcxx-devel_linux-aarch64=12.3.0=h6144e03_113 - - libstdcxx-ng=13.2.0=h3f4de04_13 - - libtiff=4.6.0=hf980d43_3 - - libtool=2.4.7=h4de3ea5_0 - - libuuid=2.38.1=hb4cce97_0 - - libuv=1.48.0=h31becfc_0 - - libwebp=1.4.0=h8b4e01b_0 - - libwebp-base=1.4.0=h31becfc_0 - - libxcb=1.16=h7935292_0 - - libxcrypt=4.4.36=h31becfc_1 - - libxml2=2.12.7=h49dc7a2_1 - - libzlib=1.3.1=h68df207_1 - - linbox=1.7.0=h681a5ee_0 - - llvm-openmp=18.1.8=hb063fc5_0 - - lrcalc=2.1=h2f0025b_6 - - m4=1.4.18=h516909a_1001 - - m4ri=20140914=hedfd65a_1006 - - m4rie=20150908=hf0a5ef3_1002 - - make=4.3=h309ac5b_1 - - markupsafe=2.1.5=py39h7cc1d5f_0 - - mathjax=3.2.2=h8af1aa0_0 - - matplotlib=3.8.4=py39ha65689a_2 - - matplotlib-base=3.8.4=py39hf44f4b6_2 - - matplotlib-inline=0.1.7=pyhd8ed1ab_0 - - maxima=5.47.0=h6475f26_2 - - memory-allocator=0.1.3=py39h898b7ef_0 - - metis=5.1.0=h2f0025b_1007 - - mistune=3.0.2=pyhd8ed1ab_0 - - mpc=1.3.1=hf4c8f4c_0 - - mpfi=1.5.4=h846f343_1001 - - mpfr=4.2.1=ha2d0fc4_1 - - mpmath=1.3.0=pyhd8ed1ab_0 - - munkres=1.1.4=pyh9f0ad1d_0 - - nauty=2.8.8=h31becfc_1 - - nbclient=0.10.0=pyhd8ed1ab_0 - - nbconvert=7.16.4=hd8ed1ab_1 - - nbconvert-core=7.16.4=pyhd8ed1ab_1 - - nbconvert-pandoc=7.16.4=hd8ed1ab_1 - - nbformat=5.10.4=pyhd8ed1ab_0 - - ncurses=6.5=h0425590_0 - - nest-asyncio=1.6.0=pyhd8ed1ab_0 - - networkx=3.2.1=pyhd8ed1ab_0 - - ninja=1.12.1=h70be974_0 - - notebook=7.2.1=pyhd8ed1ab_0 - - notebook-shim=0.2.4=pyhd8ed1ab_0 - - ntl=11.4.3=h0d7519b_1 - - numpy=1.26.4=py39h91c28bb_0 - - openblas=0.3.25=pthreads_h339cbfa_0 - - openjdk=22.0.1=h3d4cd67_0 - - openjpeg=2.5.2=h0d9d63b_0 - - openssl=3.3.1=h68df207_0 - - overrides=7.7.0=pyhd8ed1ab_0 - - packaging=24.1=pyhd8ed1ab_0 - - palp=2.20=hb9de7d4_0 - - pandoc=3.2.1=h8af1aa0_0 - - pandocfilters=1.5.0=pyhd8ed1ab_0 - - pango=1.54.0=h399c48b_0 - - pari=2.15.5=h169c2a7_2_pthread - - pari-elldata=0.0.20161017=0 - - pari-galdata=0.0.20180411=0 - - pari-galpol=0.0.20180625=0 - - pari-seadata=0.0.20090618=0 - - pari-seadata-small=0.0.20090618=0 - - parso=0.8.4=pyhd8ed1ab_0 - - patch=2.7.6=hf897c2e_1002 - - pathspec=0.12.1=pyhd8ed1ab_0 - - pcre2=10.44=h070dd5b_0 - - pep517=0.13.0=pyhd8ed1ab_0 - - perl=5.32.1=7_h31becfc_perl5 - - pexpect=4.9.0=pyhd8ed1ab_0 - - pickleshare=0.7.5=py_1003 - - pillow=10.3.0=py39h4a8821f_1 - - pip=24.0=pyhd8ed1ab_0 - - pixman=0.43.4=h2f0025b_0 - - pkg-config=0.29.2=hb9de7d4_1008 - - pkgconfig=1.5.5=pyhd8ed1ab_4 - - pkgutil-resolve-name=1.3.10=pyhd8ed1ab_1 - - planarity=3.0.2.0=h31becfc_0 - - platformdirs=4.2.2=pyhd8ed1ab_0 - - pluggy=1.5.0=pyhd8ed1ab_0 - - ply=3.11=pyhd8ed1ab_2 - - 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 - - prometheus_client=0.20.0=pyhd8ed1ab_0 - - prompt-toolkit=3.0.47=pyha770c72_0 - - prompt_toolkit=3.0.47=hd8ed1ab_0 - - psutil=6.0.0=py39he257ee7_0 - - pthread-stubs=0.4=hb9de7d4_1001 - - ptyprocess=0.7.0=pyhd3deb0d_0 - - pure_eval=0.2.2=pyhd8ed1ab_0 - - py=1.11.0=pyh6c4a22f_0 - - pybind11=2.12.0=py39hd16970a_0 - - pybind11-global=2.12.0=py39hd16970a_0 - - pycparser=2.22=pyhd8ed1ab_0 - - pygments=2.18.0=pyhd8ed1ab_0 - - pyparsing=3.1.2=pyhd8ed1ab_0 - - pyproject-api=1.7.1=pyhd8ed1ab_0 - - pyrsistent=0.20.0=py39h7cc1d5f_0 - - pysocks=1.7.1=pyha2e5f31_6 - - python=3.9.19=h4ac3b42_0_cpython - - python-build=1.2.1=pyhd8ed1ab_0 - - python-dateutil=2.9.0=pyhd8ed1ab_0 - - python-fastjsonschema=2.20.0=pyhd8ed1ab_0 - - python-json-logger=2.0.7=pyhd8ed1ab_0 - - python-lrcalc=2.1=py39h387a81e_6 - - python-tzdata=2024.1=pyhd8ed1ab_0 - - python_abi=3.9=4_cp39 - - pythran=0.15.0=py39hc2250db_1 - - pytz=2024.1=pyhd8ed1ab_0 - - pytz-deprecation-shim=0.1.0.post0=py39h4420490_4 - - pyyaml=6.0.1=py39h898b7ef_1 - - pyzmq=26.0.3=py39h866fef3_0 - - qd=2.3.22=h05efe27_1004 - - qhull=2020.2=hd62202e_2 - - r-base=4.3.3=h7f20121_3 - - r-lattice=0.22_6=r43h25e906a_0 - - readline=8.2=h8fc344f_1 - - referencing=0.35.1=pyhd8ed1ab_0 - - requests=2.32.3=pyhd8ed1ab_0 - - rfc3339-validator=0.1.4=pyhd8ed1ab_0 - - rfc3986-validator=0.1.1=pyh9f0ad1d_0 - - rhash=1.4.4=h31becfc_0 - - rpds-py=0.18.1=py39hb8f4057_0 - - rpy2=3.5.11=py39r43h1ae4408_3 - - rw=0.9=h31becfc_2 - - sagemath-db-combinatorial-designs=20140630=1 - - sagemath-db-elliptic-curves=0.8.1=hecc5488_0 - - sagemath-db-graphs=20210214=hd8ed1ab_0 - - sagemath-db-polytopes=20170220=1 - - sagetex=3.6.1=pyhd8ed1ab_0 - - scipy=1.11.3=py39h91c28bb_1 - - sed=4.8=ha0d5d3d_0 - - send2trash=1.8.3=pyh0d859eb_0 - - setuptools=70.1.1=pyhd8ed1ab_0 - - setuptools-scm=8.1.0=pyhd8ed1ab_0 - - setuptools_scm=8.1.0=hd8ed1ab_0 - - simplegeneric=0.8.1=py_1 - - singular=4.3.2.p8=hbe76a8a_1 - - six=1.16.0=pyh6c4a22f_0 - - sniffio=1.3.1=pyhd8ed1ab_0 - - snowballstemmer=2.2.0=pyhd8ed1ab_0 - - soupsieve=2.5=pyhd8ed1ab_1 - - sphinx=7.3.7=pyhd8ed1ab_0 - - sphinx-basic-ng=1.0.0b2=pyhd8ed1ab_1 - - sphinx-copybutton=0.5.2=pyhd8ed1ab_0 - - sphinxcontrib-applehelp=1.0.8=pyhd8ed1ab_0 - - sphinxcontrib-devhelp=1.0.6=pyhd8ed1ab_0 - - sphinxcontrib-htmlhelp=2.0.5=pyhd8ed1ab_0 - - sphinxcontrib-jsmath=1.0.1=pyhd8ed1ab_0 - - sphinxcontrib-qthelp=1.0.7=pyhd8ed1ab_0 - - sphinxcontrib-serializinghtml=1.1.10=pyhd8ed1ab_0 - - sphinxcontrib-websupport=1.2.7=pyhd8ed1ab_0 - - sqlite=3.46.0=hdc7ab3c_0 - - stack_data=0.6.2=pyhd8ed1ab_0 - - suitesparse=7.7.0=h3944111_1 - - symmetrica=3.0.1=hd600fc2_0 - - sympow=2.023.6=h157afb5_3 - - sympy=1.12.1=pypyh2585a3b_103 - - sysroot_linux-aarch64=2.17=h5b4a56d_14 - - tachyon=0.99b6=ha0bfc61_1002 - - tar=1.34=h048efde_0 - - tbb=2021.12.0=h70be974_1 - - terminado=0.18.1=pyh0d859eb_0 - - texinfo=7.0=pl5321h17f021e_0 - - three.js=122=hd8ed1ab_2 - - threejs-sage=122=hd8ed1ab_2 - - tinycss2=1.3.0=pyhd8ed1ab_0 - - tk=8.6.13=h194ca79_0 - - tktable=2.10=h52f7bd3_6 - - tomli=2.0.1=pyhd8ed1ab_0 - - tornado=6.4.1=py39ha3e8b56_0 - - tox=4.15.1=pyhd8ed1ab_0 - - traitlets=5.14.3=pyhd8ed1ab_0 - - trove-classifiers=2024.5.22=pyhd8ed1ab_0 - - types-python-dateutil=2.9.0.20240316=pyhd8ed1ab_0 - - typing-extensions=4.12.2=hd8ed1ab_0 - - typing_extensions=4.12.2=pyha770c72_0 - - typing_utils=0.1.0=pyhd8ed1ab_0 - - tzdata=2024a=h0c530f3_0 - - tzlocal=5.2=py39h4420490_0 - - unicodedata2=15.1.0=py39h898b7ef_0 - - uri-template=1.3.0=pyhd8ed1ab_0 - - urllib3=2.2.2=pyhd8ed1ab_0 - - virtualenv=20.26.3=pyhd8ed1ab_0 - - wcwidth=0.2.13=pyhd8ed1ab_0 - - webcolors=24.6.0=pyhd8ed1ab_0 - - webencodings=0.5.1=pyhd8ed1ab_2 - - websocket-client=1.8.0=pyhd8ed1ab_0 - - wheel=0.43.0=pyhd8ed1ab_1 - - widgetsnbextension=4.0.11=pyhd8ed1ab_0 - - xorg-fixesproto=5.0=h3557bc0_1002 - - xorg-inputproto=2.3.2=h3557bc0_1002 - - xorg-kbproto=1.0.7=h3557bc0_1002 - - xorg-libice=1.1.1=h7935292_0 - - xorg-libsm=1.2.4=h5a01bc2_0 - - xorg-libx11=1.8.9=h08be655_1 - - xorg-libxau=1.0.11=h31becfc_0 - - xorg-libxdmcp=1.1.3=h3557bc0_0 - - xorg-libxext=1.3.4=h2a766a3_2 - - xorg-libxfixes=5.0.3=h3557bc0_1004 - - xorg-libxi=1.7.10=h3557bc0_0 - - xorg-libxrender=0.9.11=h7935292_0 - - xorg-libxt=1.3.0=h7935292_1 - - xorg-libxtst=1.2.3=hf897c2e_1002 - - xorg-recordproto=1.14.2=hf897c2e_1002 - - xorg-renderproto=0.11.1=h3557bc0_1002 - - xorg-xextproto=7.3.0=h2a766a3_1003 - - xorg-xproto=7.0.31=h3557bc0_1007 - - xz=5.2.6=h9cdd2b7_0 - - yaml=0.2.5=hf897c2e_2 - - zeromq=4.3.5=h28faeed_4 - - zipp=3.19.2=pyhd8ed1ab_0 - - zlib=1.3.1=h68df207_1 - - zstd=1.5.6=h02f22dd_0 diff --git a/src/environment-3.9-linux.yml b/src/environment-3.9-linux.yml deleted file mode 100644 index c1cae4f27db..00000000000 --- a/src/environment-3.9-linux.yml +++ /dev/null @@ -1,483 +0,0 @@ -# Generated by conda-lock. -# platform: linux-64 -# input_hash: e864996ba609c3a06f1c78376812e9f6180653730f5c2e60df67268b3e2fb7d6 - -channels: - - conda-forge -dependencies: - - _libgcc_mutex=0.1=conda_forge - - _openmp_mutex=4.5=2_kmp_llvm - - _r-mutex=1.0.1=anacondar_1 - - alabaster=0.7.16=pyhd8ed1ab_0 - - alsa-lib=1.2.12=h4ab18f5_0 - - anyio=4.4.0=pyhd8ed1ab_0 - - appdirs=1.4.4=pyh9f0ad1d_0 - - appnope=0.1.4=pyhd8ed1ab_0 - - argon2-cffi=23.1.0=pyhd8ed1ab_0 - - argon2-cffi-bindings=21.2.0=py39hd1e30aa_4 - - arpack=3.9.1=nompi_h77f6705_101 - - arrow=1.3.0=pyhd8ed1ab_0 - - asttokens=2.4.1=pyhd8ed1ab_0 - - async-lru=2.0.4=pyhd8ed1ab_0 - - attr=2.5.1=h166bdaf_1 - - attrs=23.2.0=pyh71513ae_0 - - autoconf=2.71=pl5321h2b4cb7a_1 - - automake=1.16.5=pl5321ha770c72_0 - - babel=2.14.0=pyhd8ed1ab_0 - - bc=1.07.1=h7f98852_0 - - bdw-gc=8.0.6=h4bd325d_0 - - beautifulsoup4=4.12.3=pyha770c72_0 - - beniget=0.4.1=pyhd8ed1ab_0 - - binutils=2.40=h4852527_7 - - binutils_impl_linux-64=2.40=ha1999f0_7 - - binutils_linux-64=2.40=hb3c18ed_9 - - blas=2.120=openblas - - blas-devel=3.9.0=20_linux64_openblas - - bleach=6.1.0=pyhd8ed1ab_0 - - boost-cpp=1.85.0=h44aadfe_2 - - brial=1.2.12=pyh694c41f_3 - - brotli=1.1.0=hd590300_1 - - brotli-bin=1.1.0=hd590300_1 - - brotli-python=1.1.0=py39h3d6467e_1 - - bwidget=1.9.14=ha770c72_1 - - bzip2=1.0.8=hd590300_5 - - c-ares=1.28.1=hd590300_0 - - c-compiler=1.7.0=hd590300_1 - - ca-certificates=2024.6.2=hbcca054_0 - - cached-property=1.5.2=hd8ed1ab_1 - - cached_property=1.5.2=pyha770c72_1 - - cachetools=5.3.3=pyhd8ed1ab_0 - - cairo=1.18.0=hbb29018_2 - - cddlib=1!0.94m=h9202a9a_0 - - certifi=2024.6.2=pyhd8ed1ab_0 - - cffi=1.16.0=py39h7a31438_0 - - chardet=5.2.0=py39hf3d152e_1 - - charset-normalizer=3.3.2=pyhd8ed1ab_0 - - cliquer=1.22=hd590300_1 - - cmake=3.29.6=hcafd917_0 - - colorama=0.4.6=pyhd8ed1ab_0 - - colorlog=6.8.2=py39hf3d152e_0 - - comm=0.2.2=pyhd8ed1ab_0 - - compilers=1.7.0=ha770c72_1 - - contourpy=1.2.1=py39h7633fee_0 - - conway-polynomials=0.9=pyhd8ed1ab_0 - - cppy=1.2.1=pyhd8ed1ab_0 - - curl=8.8.0=he654da7_0 - - cvxopt=1.3.2=py39h640215f_2 - - cxx-compiler=1.7.0=h00ab1b0_1 - - cycler=0.12.1=pyhd8ed1ab_0 - - cypari2=2.1.5=py39h1698a45_0 - - cysignals=1.11.2=py39h1ce0973_3 - - cython=3.0.10=py39h3d6467e_0 - - dbus=1.13.6=h5008d03_3 - - debugpy=1.8.1=py39h3d6467e_0 - - decorator=5.1.1=pyhd8ed1ab_0 - - defusedxml=0.7.1=pyhd8ed1ab_0 - - distlib=0.3.8=pyhd8ed1ab_0 - - docutils=0.21.2=pyhd8ed1ab_0 - - dsdp=5.8=hd9d9efa_1203 - - ecl=23.9.9=hed6455c_0 - - eclib=20231212=h96f522a_0 - - ecm=7.0.5=h9458935_0 - - editables=0.5=pyhd8ed1ab_0 - - entrypoints=0.4=pyhd8ed1ab_0 - - exceptiongroup=1.2.0=pyhd8ed1ab_2 - - executing=2.0.1=pyhd8ed1ab_0 - - expat=2.6.2=h59595ed_0 - - fflas-ffpack=2.5.0=h4f9960b_0 - - fftw=3.3.10=nompi_hf1063bd_110 - - filelock=3.15.4=pyhd8ed1ab_0 - - flit-core=3.9.0=pyhd8ed1ab_1 - - 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_2 - - fontconfig=2.14.2=h14ed4e7_0 - - fonts-conda-ecosystem=1=0 - - fonts-conda-forge=1=0 - - fonttools=4.53.0=py39hd3abc70_0 - - fortran-compiler=1.7.0=heb67821_1 - - fplll=5.4.5=h384768b_0 - - fpylll=0.6.1=py39h2525e16_0 - - fqdn=1.5.1=pyhd8ed1ab_0 - - freetype=2.12.1=h267a509_2 - - fribidi=1.0.10=h36c2ea0_0 - - furo=2024.5.6=pyhd8ed1ab_0 - - gap-core=4.12.2=he9a28a4_3 - - gap-defaults=4.12.2=ha770c72_3 - - gast=0.5.4=pyhd8ed1ab_0 - - gcc=12.3.0=h915e2ae_13 - - gcc_impl_linux-64=12.3.0=h58ffeeb_13 - - gcc_linux-64=12.3.0=h9528a6a_9 - - gengetopt=2.23=h9c3ff4c_0 - - gettext=0.22.5=h59595ed_2 - - gettext-tools=0.22.5=h59595ed_2 - - gf2x=1.3.0=ha476b99_2 - - gfan=0.6.2=hb86e20a_1003 - - gfortran=12.3.0=h915e2ae_13 - - gfortran_impl_linux-64=12.3.0=h8f2110c_13 - - gfortran_linux-64=12.3.0=h5877db1_9 - - giac=1.9.0.21=h673759e_1 - - giflib=5.2.2=hd590300_0 - - givaro=4.2.0=hb789bce_0 - - glib=2.80.2=h8a4344b_1 - - glib-tools=2.80.2=h73ef956_1 - - glpk=5.0=h445213a_0 - - gmp=6.3.0=hac33072_2 - - gmpy2=2.1.5=py39h048c657_1 - - graphite2=1.3.13=h59595ed_1003 - - gsl=2.7=he838d99_0 - - gst-plugins-base=1.24.5=hbaaba92_0 - - gstreamer=1.24.5=haf2f30d_0 - - gxx=12.3.0=h915e2ae_13 - - gxx_impl_linux-64=12.3.0=h2a574ab_13 - - gxx_linux-64=12.3.0=ha28b414_9 - - h11=0.14.0=pyhd8ed1ab_0 - - h2=4.1.0=pyhd8ed1ab_0 - - harfbuzz=8.5.0=hfac3d4d_0 - - hatchling=1.25.0=pyhd8ed1ab_0 - - hpack=4.0.0=pyh9f0ad1d_0 - - httpcore=1.0.5=pyhd8ed1ab_0 - - httpx=0.27.0=pyhd8ed1ab_0 - - hyperframe=6.0.1=pyhd8ed1ab_0 - - icu=73.2=h59595ed_0 - - idna=3.7=pyhd8ed1ab_0 - - igraph=0.10.12=hef0740d_1 - - imagesize=1.4.1=pyhd8ed1ab_0 - - iml=1.0.5=h623f65a_1004 - - importlib-metadata=8.0.0=pyha770c72_0 - - importlib-resources=6.4.0=pyhd8ed1ab_0 - - importlib_metadata=8.0.0=hd8ed1ab_0 - - importlib_resources=6.4.0=pyhd8ed1ab_0 - - ipykernel=6.29.4=pyh3099207_0 - - ipympl=0.9.4=pyhd8ed1ab_0 - - ipython=8.18.1=pyh707e725_3 - - ipython_genutils=0.2.0=pyhd8ed1ab_1 - - ipywidgets=8.1.3=pyhd8ed1ab_0 - - isoduration=20.11.0=pyhd8ed1ab_0 - - jedi=0.19.1=pyhd8ed1ab_0 - - jinja2=3.1.4=pyhd8ed1ab_0 - - jmol=14.32.10=ha770c72_0 - - json5=0.9.25=pyhd8ed1ab_0 - - jsonpointer=3.0.0=py39hf3d152e_0 - - jsonschema=4.22.0=pyhd8ed1ab_0 - - jsonschema-specifications=2023.12.1=pyhd8ed1ab_0 - - jsonschema-with-format-nongpl=4.22.0=pyhd8ed1ab_0 - - jupyter-jsmol=2022.1.0=pyhd8ed1ab_0 - - jupyter-lsp=2.2.5=pyhd8ed1ab_0 - - jupyter-sphinx=0.5.3=pyha770c72_4 - - jupyter_client=8.6.2=pyhd8ed1ab_0 - - jupyter_core=5.7.2=py39hf3d152e_0 - - jupyter_events=0.10.0=pyhd8ed1ab_0 - - jupyter_server=2.14.1=pyhd8ed1ab_0 - - jupyter_server_terminals=0.5.3=pyhd8ed1ab_0 - - jupyter_sphinx=0.5.3=hd8ed1ab_4 - - jupyterlab=4.2.2=pyhd8ed1ab_0 - - jupyterlab_pygments=0.3.0=pyhd8ed1ab_1 - - jupyterlab_server=2.27.2=pyhd8ed1ab_0 - - jupyterlab_widgets=3.0.11=pyhd8ed1ab_0 - - kernel-headers_linux-64=2.6.32=he073ed8_17 - - keyutils=1.6.1=h166bdaf_0 - - kiwisolver=1.4.5=py39h7633fee_1 - - krb5=1.21.2=h659d440_0 - - lame=3.100=h166bdaf_1003 - - lcalc=2.0.5=h5aac1b6_2 - - lcms2=2.16=hb7c19ff_0 - - ld_impl_linux-64=2.40=hf3520f5_7 - - lerc=4.0.0=h27087fc_0 - - libasprintf=0.22.5=h661eb56_2 - - libasprintf-devel=0.22.5=h661eb56_2 - - libatomic_ops=7.6.14=h166bdaf_0 - - libblas=3.9.0=20_linux64_openblas - - libboost=1.85.0=hba137d9_2 - - libboost-devel=1.85.0=h00ab1b0_2 - - libboost-headers=1.85.0=ha770c72_2 - - libbraiding=1.2=hcb278e6_0 - - libbrial=1.2.12=h76af697_3 - - libbrotlicommon=1.1.0=hd590300_1 - - libbrotlidec=1.1.0=hd590300_1 - - libbrotlienc=1.1.0=hd590300_1 - - libcap=2.69=h0f662aa_0 - - libcblas=3.9.0=20_linux64_openblas - - libclang-cpp15=15.0.7=default_h127d8a8_5 - - libclang13=18.1.8=default_h6ae225f_0 - - libcups=2.3.3=h4637d8d_4 - - libcurl=8.8.0=hca28451_0 - - libdeflate=1.20=hd590300_0 - - libedit=3.1.20191231=he28a2e2_2 - - libev=4.33=hd590300_2 - - libevent=2.1.12=hf998b51_1 - - libexpat=2.6.2=h59595ed_0 - - libffi=3.4.2=h7f98852_5 - - libflac=1.4.3=h59595ed_0 - - libflint=3.0.1=h5f2e117_ntl_100 - - libgcc-devel_linux-64=12.3.0=h6b66f73_113 - - libgcc-ng=13.2.0=h77fa898_13 - - libgcrypt=1.10.3=hd590300_0 - - libgd=2.3.3=h119a65a_9 - - libgettextpo=0.22.5=h59595ed_2 - - libgettextpo-devel=0.22.5=h59595ed_2 - - libgfortran-ng=13.2.0=h69a702a_13 - - libgfortran5=13.2.0=h3d2ce59_13 - - libglib=2.80.2=h8a4344b_1 - - libgomp=13.2.0=h77fa898_13 - - libgpg-error=1.49=h4f305b6_0 - - libhomfly=1.02r6=hd590300_1 - - libhwloc=2.10.0=default_h5622ce7_1001 - - libiconv=1.17=hd590300_2 - - libjpeg-turbo=3.0.0=hd590300_1 - - liblapack=3.9.0=20_linux64_openblas - - liblapacke=3.9.0=20_linux64_openblas - - libllvm15=15.0.7=hb3ce162_4 - - libllvm18=18.1.8=hc9dba70_0 - - libnghttp2=1.58.0=h47da74e_1 - - libnsl=2.0.1=hd590300_0 - - libogg=1.3.5=h4ab18f5_0 - - libopenblas=0.3.25=pthreads_h413a1c8_0 - - libopus=1.3.1=h7f98852_1 - - libpng=1.6.43=h2797004_0 - - libpq=16.3=ha72fbe1_0 - - libsanitizer=12.3.0=hb8811af_13 - - libsndfile=1.2.2=hc60ed4a_1 - - libsodium=1.0.18=h36c2ea0_1 - - libsqlite=3.46.0=hde9e2c9_0 - - libssh2=1.11.0=h0841786_0 - - libstdcxx-devel_linux-64=12.3.0=h6b66f73_113 - - libstdcxx-ng=13.2.0=hc0a3c3a_13 - - libsystemd0=255=h3516f8a_1 - - libtiff=4.6.0=h1dd3fc0_3 - - libtool=2.4.7=h27087fc_0 - - libuuid=2.38.1=h0b41bf4_0 - - libuv=1.48.0=hd590300_0 - - libvorbis=1.3.7=h9c3ff4c_0 - - libwebp=1.4.0=h2c329e2_0 - - libwebp-base=1.4.0=hd590300_0 - - libxcb=1.16=hd590300_0 - - libxcrypt=4.4.36=hd590300_1 - - libxkbcommon=1.7.0=h2c5496b_1 - - libxml2=2.12.7=hc051c1a_1 - - libzlib=1.3.1=h4ab18f5_1 - - linbox=1.7.0=ha329b40_0 - - llvm-openmp=18.1.8=hf5423f3_0 - - lrcalc=2.1=h59595ed_6 - - lz4-c=1.9.4=hcb278e6_0 - - m4=1.4.18=h516909a_1001 - - m4ri=20140914=hae5d5c5_1006 - - m4rie=20150908=h267a509_1002 - - make=4.3=hd18ef5c_1 - - markupsafe=2.1.5=py39hd1e30aa_0 - - mathjax=3.2.2=ha770c72_0 - - matplotlib=3.8.4=py39hf3d152e_2 - - matplotlib-base=3.8.4=py39h10d1fc8_2 - - matplotlib-inline=0.1.7=pyhd8ed1ab_0 - - maxima=5.47.0=hed6455c_2 - - memory-allocator=0.1.3=py39hd1e30aa_0 - - metis=5.1.0=h59595ed_1007 - - mistune=3.0.2=pyhd8ed1ab_0 - - mpc=1.3.1=hfe3b2da_0 - - mpfi=1.5.4=h9f54685_1001 - - mpfr=4.2.1=h9458935_1 - - mpg123=1.32.6=h59595ed_0 - - mpmath=1.3.0=pyhd8ed1ab_0 - - munkres=1.1.4=pyh9f0ad1d_0 - - mysql-common=8.3.0=hf1915f5_4 - - mysql-libs=8.3.0=hca2cd23_4 - - nauty=2.8.8=hd590300_1 - - nbclient=0.10.0=pyhd8ed1ab_0 - - nbconvert=7.16.4=hd8ed1ab_1 - - nbconvert-core=7.16.4=pyhd8ed1ab_1 - - nbconvert-pandoc=7.16.4=hd8ed1ab_1 - - nbformat=5.10.4=pyhd8ed1ab_0 - - ncurses=6.5=h59595ed_0 - - nest-asyncio=1.6.0=pyhd8ed1ab_0 - - networkx=3.2.1=pyhd8ed1ab_0 - - ninja=1.12.1=h297d8ca_0 - - notebook=7.2.1=pyhd8ed1ab_0 - - notebook-shim=0.2.4=pyhd8ed1ab_0 - - nspr=4.35=h27087fc_0 - - nss=3.101=h593d115_0 - - ntl=11.4.3=hef3c4d3_1 - - numpy=1.26.4=py39h474f0d3_0 - - openblas=0.3.25=pthreads_h7a3da1a_0 - - openjdk=21.0.2=haa376d0_0 - - openjpeg=2.5.2=h488ebb8_0 - - openssl=3.3.1=h4ab18f5_0 - - overrides=7.7.0=pyhd8ed1ab_0 - - packaging=24.1=pyhd8ed1ab_0 - - palp=2.20=h36c2ea0_0 - - pandoc=3.2.1=ha770c72_0 - - pandocfilters=1.5.0=pyhd8ed1ab_0 - - pango=1.54.0=h84a9a3c_0 - - pari=2.15.5=h4d4ae9b_2_pthread - - pari-elldata=0.0.20161017=0 - - pari-galdata=0.0.20180411=0 - - pari-galpol=0.0.20180625=0 - - pari-seadata=0.0.20090618=0 - - pari-seadata-small=0.0.20090618=0 - - parso=0.8.4=pyhd8ed1ab_0 - - patch=2.7.6=h7f98852_1002 - - pathspec=0.12.1=pyhd8ed1ab_0 - - pcre2=10.44=h0f59acf_0 - - pep517=0.13.0=pyhd8ed1ab_0 - - perl=5.32.1=7_hd590300_perl5 - - pexpect=4.9.0=pyhd8ed1ab_0 - - pickleshare=0.7.5=py_1003 - - pillow=10.3.0=py39h16a7006_1 - - pip=24.0=pyhd8ed1ab_0 - - pixman=0.43.2=h59595ed_0 - - pkg-config=0.29.2=h36c2ea0_1008 - - pkgconfig=1.5.5=pyhd8ed1ab_4 - - pkgutil-resolve-name=1.3.10=pyhd8ed1ab_1 - - planarity=3.0.2.0=hd590300_0 - - platformdirs=4.2.2=pyhd8ed1ab_0 - - pluggy=1.5.0=pyhd8ed1ab_0 - - ply=3.11=pyhd8ed1ab_2 - - 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 - - prometheus_client=0.20.0=pyhd8ed1ab_0 - - prompt-toolkit=3.0.47=pyha770c72_0 - - prompt_toolkit=3.0.47=hd8ed1ab_0 - - psutil=6.0.0=py39hd3abc70_0 - - pthread-stubs=0.4=h36c2ea0_1001 - - ptyprocess=0.7.0=pyhd3deb0d_0 - - pulseaudio-client=17.0=hb77b528_0 - - pure_eval=0.2.2=pyhd8ed1ab_0 - - py=1.11.0=pyh6c4a22f_0 - - pybind11=2.12.0=py39h7633fee_0 - - pybind11-global=2.12.0=py39h7633fee_0 - - pycparser=2.22=pyhd8ed1ab_0 - - pygments=2.18.0=pyhd8ed1ab_0 - - pyparsing=3.1.2=pyhd8ed1ab_0 - - pyproject-api=1.7.1=pyhd8ed1ab_0 - - pyqt=5.15.9=py39h52134e7_5 - - pyqt5-sip=12.12.2=py39h3d6467e_5 - - pyrsistent=0.20.0=py39hd1e30aa_0 - - pysocks=1.7.1=pyha2e5f31_6 - - python=3.9.19=h0755675_0_cpython - - python-build=1.2.1=pyhd8ed1ab_0 - - python-dateutil=2.9.0=pyhd8ed1ab_0 - - python-fastjsonschema=2.20.0=pyhd8ed1ab_0 - - python-json-logger=2.0.7=pyhd8ed1ab_0 - - python-lrcalc=2.1=py39h3d6467e_6 - - python-tzdata=2024.1=pyhd8ed1ab_0 - - python_abi=3.9=4_cp39 - - pythran=0.15.0=py39hda80f44_1 - - pytz=2024.1=pyhd8ed1ab_0 - - pytz-deprecation-shim=0.1.0.post0=py39hf3d152e_4 - - pyyaml=6.0.1=py39hd1e30aa_1 - - pyzmq=26.0.3=py39ha1047a2_0 - - qd=2.3.22=h2cc385e_1004 - - qhull=2020.2=h4bd325d_2 - - qt-main=5.15.8=ha2b5568_22 - - r-base=4.3.3=he2d9a6e_3 - - r-lattice=0.22_6=r43h57805ef_0 - - readline=8.2=h8228510_1 - - referencing=0.35.1=pyhd8ed1ab_0 - - requests=2.32.3=pyhd8ed1ab_0 - - rfc3339-validator=0.1.4=pyhd8ed1ab_0 - - rfc3986-validator=0.1.1=pyh9f0ad1d_0 - - rhash=1.4.4=hd590300_0 - - rpds-py=0.18.1=py39ha68c5e3_0 - - rpy2=3.5.11=py39r43h44dd56e_3 - - rw=0.9=hd590300_2 - - sagemath-db-combinatorial-designs=20140630=1 - - sagemath-db-elliptic-curves=0.8.1=hecc5488_0 - - sagemath-db-graphs=20210214=hd8ed1ab_0 - - sagemath-db-polytopes=20170220=1 - - sagetex=3.6.1=pyhd8ed1ab_0 - - scipy=1.11.4=py39h474f0d3_0 - - sed=4.8=he412f7d_0 - - send2trash=1.8.3=pyh0d859eb_0 - - setuptools=70.1.1=pyhd8ed1ab_0 - - setuptools-scm=8.1.0=pyhd8ed1ab_0 - - setuptools_scm=8.1.0=hd8ed1ab_0 - - simplegeneric=0.8.1=py_1 - - singular=4.3.2.p8=h33f5c3f_1 - - sip=6.7.12=py39h3d6467e_0 - - six=1.16.0=pyh6c4a22f_0 - - sniffio=1.3.1=pyhd8ed1ab_0 - - snowballstemmer=2.2.0=pyhd8ed1ab_0 - - soupsieve=2.5=pyhd8ed1ab_1 - - sphinx=7.3.7=pyhd8ed1ab_0 - - sphinx-basic-ng=1.0.0b2=pyhd8ed1ab_1 - - sphinx-copybutton=0.5.2=pyhd8ed1ab_0 - - sphinxcontrib-applehelp=1.0.8=pyhd8ed1ab_0 - - sphinxcontrib-devhelp=1.0.6=pyhd8ed1ab_0 - - sphinxcontrib-htmlhelp=2.0.5=pyhd8ed1ab_0 - - sphinxcontrib-jsmath=1.0.1=pyhd8ed1ab_0 - - sphinxcontrib-qthelp=1.0.7=pyhd8ed1ab_0 - - sphinxcontrib-serializinghtml=1.1.10=pyhd8ed1ab_0 - - sphinxcontrib-websupport=1.2.7=pyhd8ed1ab_0 - - sqlite=3.46.0=h6d4b2fc_0 - - stack_data=0.6.2=pyhd8ed1ab_0 - - suitesparse=7.7.0=hf4753ba_1 - - symmetrica=3.0.1=hcb278e6_0 - - sympow=2.023.6=hc6ab17c_3 - - sympy=1.12.1=pypyh2585a3b_103 - - sysroot_linux-64=2.12=he073ed8_17 - - tachyon=0.99b6=hba7d16a_1002 - - tar=1.34=hb2e2bae_1 - - tbb=2021.12.0=h297d8ca_1 - - terminado=0.18.1=pyh0d859eb_0 - - texinfo=7.0=pl5321h0f457ee_0 - - three.js=122=hd8ed1ab_2 - - threejs-sage=122=hd8ed1ab_2 - - tinycss2=1.3.0=pyhd8ed1ab_0 - - tk=8.6.13=noxft_h4845f30_101 - - tktable=2.10=h8bc8fbc_6 - - toml=0.10.2=pyhd8ed1ab_0 - - tomli=2.0.1=pyhd8ed1ab_0 - - tornado=6.4.1=py39hd3abc70_0 - - tox=4.15.1=pyhd8ed1ab_0 - - traitlets=5.14.3=pyhd8ed1ab_0 - - trove-classifiers=2024.5.22=pyhd8ed1ab_0 - - types-python-dateutil=2.9.0.20240316=pyhd8ed1ab_0 - - typing-extensions=4.12.2=hd8ed1ab_0 - - typing_extensions=4.12.2=pyha770c72_0 - - typing_utils=0.1.0=pyhd8ed1ab_0 - - tzdata=2024a=h0c530f3_0 - - tzlocal=5.2=py39hf3d152e_0 - - unicodedata2=15.1.0=py39hd1e30aa_0 - - uri-template=1.3.0=pyhd8ed1ab_0 - - urllib3=2.2.2=pyhd8ed1ab_0 - - virtualenv=20.26.3=pyhd8ed1ab_0 - - wcwidth=0.2.13=pyhd8ed1ab_0 - - webcolors=24.6.0=pyhd8ed1ab_0 - - webencodings=0.5.1=pyhd8ed1ab_2 - - websocket-client=1.8.0=pyhd8ed1ab_0 - - wheel=0.43.0=pyhd8ed1ab_1 - - widgetsnbextension=4.0.11=pyhd8ed1ab_0 - - xcb-util=0.4.1=hb711507_2 - - 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.42=h4ab18f5_0 - - xorg-fixesproto=5.0=h7f98852_1002 - - xorg-inputproto=2.3.2=h7f98852_1002 - - xorg-kbproto=1.0.7=h7f98852_1002 - - xorg-libice=1.1.1=hd590300_0 - - xorg-libsm=1.2.4=h7391055_0 - - xorg-libx11=1.8.9=hb711507_1 - - xorg-libxau=1.0.11=hd590300_0 - - xorg-libxdmcp=1.1.3=h7f98852_0 - - xorg-libxext=1.3.4=h0b41bf4_2 - - xorg-libxfixes=5.0.3=h7f98852_1004 - - xorg-libxi=1.7.10=h7f98852_0 - - xorg-libxrender=0.9.11=hd590300_0 - - xorg-libxt=1.3.0=hd590300_1 - - xorg-libxtst=1.2.3=h7f98852_1002 - - xorg-recordproto=1.14.2=h7f98852_1002 - - xorg-renderproto=0.11.1=h7f98852_1002 - - xorg-xextproto=7.3.0=h0b41bf4_1003 - - xorg-xf86vidmodeproto=2.3.1=h7f98852_1002 - - xorg-xproto=7.0.31=h7f98852_1007 - - xz=5.2.6=h166bdaf_0 - - yaml=0.2.5=h7f98852_2 - - zeromq=4.3.5=h75354e8_4 - - zipp=3.19.2=pyhd8ed1ab_0 - - zlib=1.3.1=h4ab18f5_1 - - zstd=1.5.6=ha6fb4c9_0 diff --git a/src/environment-3.9-macos-x86_64.yml b/src/environment-3.9-macos-x86_64.yml deleted file mode 100644 index c3026a8fbc0..00000000000 --- a/src/environment-3.9-macos-x86_64.yml +++ /dev/null @@ -1,423 +0,0 @@ -# Generated by conda-lock. -# platform: osx-64 -# input_hash: 7b973134e4e44170c953a71c99253450b079227c08993b2a49ae3ddd14d93fdb - -channels: - - conda-forge -dependencies: - - _r-mutex=1.0.1=anacondar_1 - - alabaster=0.7.16=pyhd8ed1ab_0 - - anyio=4.4.0=pyhd8ed1ab_0 - - appdirs=1.4.4=pyh9f0ad1d_0 - - appnope=0.1.4=pyhd8ed1ab_0 - - argon2-cffi=23.1.0=pyhd8ed1ab_0 - - argon2-cffi-bindings=21.2.0=py39hdc70f33_4 - - arpack=3.9.1=nompi_hf81eadf_101 - - arrow=1.3.0=pyhd8ed1ab_0 - - asttokens=2.4.1=pyhd8ed1ab_0 - - async-lru=2.0.4=pyhd8ed1ab_0 - - attrs=23.2.0=pyh71513ae_0 - - autoconf=2.71=pl5321hed12c24_1 - - automake=1.16.5=pl5321h694c41f_0 - - babel=2.14.0=pyhd8ed1ab_0 - - bc=1.07.1=h0d85af4_0 - - bdw-gc=8.0.6=h940c156_0 - - beautifulsoup4=4.12.3=pyha770c72_0 - - beniget=0.4.1=pyhd8ed1ab_0 - - blas=2.120=openblas - - blas-devel=3.9.0=20_osx64_openblas - - bleach=6.1.0=pyhd8ed1ab_0 - - boost-cpp=1.85.0=h07eb623_2 - - brial=1.2.12=pyh694c41f_3 - - brotli=1.1.0=h0dc2134_1 - - brotli-bin=1.1.0=h0dc2134_1 - - brotli-python=1.1.0=py39h840bb9f_1 - - bwidget=1.9.14=h694c41f_1 - - bzip2=1.0.8=h10d778d_5 - - c-ares=1.28.1=h10d778d_0 - - c-compiler=1.7.0=h282daa2_1 - - ca-certificates=2024.6.2=h8857fd0_0 - - cached-property=1.5.2=hd8ed1ab_1 - - cached_property=1.5.2=pyha770c72_1 - - cachetools=5.3.3=pyhd8ed1ab_0 - - cairo=1.18.0=h9f650ed_2 - - cctools=986=h40f6528_0 - - cctools_osx-64=986=ha1c5b94_0 - - cddlib=1!0.94m=h0f52abe_0 - - certifi=2024.6.2=pyhd8ed1ab_0 - - cffi=1.16.0=py39h18ef598_0 - - chardet=5.2.0=py39h6e9494a_1 - - charset-normalizer=3.3.2=pyhd8ed1ab_0 - - clang=16.0.6=default_ha3b9224_8 - - clang-16=16.0.6=default_h4c8afb6_8 - - clang_impl_osx-64=16.0.6=h8787910_16 - - clang_osx-64=16.0.6=hb91bd55_16 - - clangxx=16.0.6=default_ha3b9224_8 - - clangxx_impl_osx-64=16.0.6=h6d92fbe_16 - - clangxx_osx-64=16.0.6=hb91bd55_16 - - cliquer=1.22=h10d778d_1 - - cmake=3.29.6=h749d262_0 - - colorama=0.4.6=pyhd8ed1ab_0 - - colorlog=6.8.2=py39h6e9494a_0 - - comm=0.2.2=pyhd8ed1ab_0 - - compiler-rt=16.0.6=ha38d28d_2 - - compiler-rt_osx-64=16.0.6=ha38d28d_2 - - compilers=1.7.0=h694c41f_1 - - contourpy=1.2.1=py39h0ca7971_0 - - conway-polynomials=0.9=pyhd8ed1ab_0 - - cppy=1.2.1=pyhd8ed1ab_0 - - curl=8.8.0=hea67d85_0 - - cvxopt=1.3.2=py39hd66cc7a_2 - - cxx-compiler=1.7.0=h7728843_1 - - cycler=0.12.1=pyhd8ed1ab_0 - - cypari2=2.1.5=py39hc0d7317_0 - - cysignals=1.11.2=py39hf6ae30e_3 - - cython=3.0.10=py39hd253f6c_0 - - debugpy=1.8.1=py39hd253f6c_0 - - decorator=5.1.1=pyhd8ed1ab_0 - - defusedxml=0.7.1=pyhd8ed1ab_0 - - distlib=0.3.8=pyhd8ed1ab_0 - - docutils=0.21.2=pyhd8ed1ab_0 - - dsdp=5.8=h6e329d1_1203 - - ecl=23.9.9=h2b27fa8_0 - - eclib=20231212=h02435c3_0 - - ecm=7.0.5=h4f6b447_0 - - editables=0.5=pyhd8ed1ab_0 - - entrypoints=0.4=pyhd8ed1ab_0 - - exceptiongroup=1.2.0=pyhd8ed1ab_2 - - executing=2.0.1=pyhd8ed1ab_0 - - expat=2.6.2=h73e2aa4_0 - - fflas-ffpack=2.5.0=h5898d61_0 - - fftw=3.3.10=nompi_h292e606_110 - - filelock=3.15.4=pyhd8ed1ab_0 - - flit-core=3.9.0=pyhd8ed1ab_1 - - 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_2 - - fontconfig=2.14.2=h5bb23bf_0 - - fonts-conda-ecosystem=1=0 - - fonts-conda-forge=1=0 - - fonttools=4.53.0=py39hded5825_0 - - fortran-compiler=1.7.0=h6c2ab21_1 - - fplll=5.4.5=hb7981ad_0 - - fpylll=0.6.1=py39h3b3ffec_0 - - fqdn=1.5.1=pyhd8ed1ab_0 - - freetype=2.12.1=h60636b9_2 - - fribidi=1.0.10=hbcb3906_0 - - furo=2024.5.6=pyhd8ed1ab_0 - - gap-core=4.12.2=hc16eb5f_3 - - gap-defaults=4.12.2=h694c41f_3 - - gast=0.5.4=pyhd8ed1ab_0 - - gengetopt=2.23=he49afe7_0 - - gettext=0.22.5=h5ff76d1_2 - - gettext-tools=0.22.5=h5ff76d1_2 - - gf2x=1.3.0=hb2a7efb_2 - - gfan=0.6.2=hd793b56_1003 - - gfortran=12.3.0=h2c809b3_1 - - gfortran_impl_osx-64=12.3.0=hc328e78_3 - - gfortran_osx-64=12.3.0=h18f7dce_1 - - giac=1.9.0.21=h92f3f65_1 - - giflib=5.2.2=h10d778d_0 - - givaro=4.2.0=h1b3d6f7_0 - - glpk=5.0=h3cb5acd_0 - - gmp=6.3.0=hf036a51_2 - - gmpy2=2.1.5=py39h87b48b1_1 - - graphite2=1.3.13=h73e2aa4_1003 - - gsl=2.7=h93259b0_0 - - h11=0.14.0=pyhd8ed1ab_0 - - h2=4.1.0=pyhd8ed1ab_0 - - harfbuzz=8.5.0=h053f038_0 - - hatchling=1.25.0=pyhd8ed1ab_0 - - hpack=4.0.0=pyh9f0ad1d_0 - - httpcore=1.0.5=pyhd8ed1ab_0 - - httpx=0.27.0=pyhd8ed1ab_0 - - hyperframe=6.0.1=pyhd8ed1ab_0 - - icu=73.2=hf5e326d_0 - - idna=3.7=pyhd8ed1ab_0 - - igraph=0.10.12=hde4452d_1 - - imagesize=1.4.1=pyhd8ed1ab_0 - - iml=1.0.5=h61918c1_1004 - - importlib-metadata=8.0.0=pyha770c72_0 - - importlib-resources=6.4.0=pyhd8ed1ab_0 - - importlib_metadata=8.0.0=hd8ed1ab_0 - - importlib_resources=6.4.0=pyhd8ed1ab_0 - - ipykernel=6.29.4=pyh57ce528_0 - - ipympl=0.9.4=pyhd8ed1ab_0 - - ipython=8.18.1=pyh707e725_3 - - ipython_genutils=0.2.0=pyhd8ed1ab_1 - - ipywidgets=8.1.3=pyhd8ed1ab_0 - - isl=0.26=imath32_h2e86a7b_101 - - isoduration=20.11.0=pyhd8ed1ab_0 - - jedi=0.19.1=pyhd8ed1ab_0 - - jinja2=3.1.4=pyhd8ed1ab_0 - - jmol=14.32.9=h694c41f_0 - - json5=0.9.25=pyhd8ed1ab_0 - - jsonpointer=3.0.0=py39h6e9494a_0 - - jsonschema=4.22.0=pyhd8ed1ab_0 - - jsonschema-specifications=2023.12.1=pyhd8ed1ab_0 - - jsonschema-with-format-nongpl=4.22.0=pyhd8ed1ab_0 - - jupyter-jsmol=2022.1.0=pyhd8ed1ab_0 - - jupyter-lsp=2.2.5=pyhd8ed1ab_0 - - jupyter-sphinx=0.5.3=pyha770c72_4 - - jupyter_client=8.6.2=pyhd8ed1ab_0 - - jupyter_core=5.7.1=py39h6e9494a_0 - - jupyter_events=0.10.0=pyhd8ed1ab_0 - - jupyter_server=2.14.1=pyhd8ed1ab_0 - - jupyter_server_terminals=0.5.3=pyhd8ed1ab_0 - - jupyter_sphinx=0.5.3=hd8ed1ab_4 - - jupyterlab=4.2.2=pyhd8ed1ab_0 - - jupyterlab_pygments=0.3.0=pyhd8ed1ab_1 - - jupyterlab_server=2.27.2=pyhd8ed1ab_0 - - jupyterlab_widgets=3.0.11=pyhd8ed1ab_0 - - kiwisolver=1.4.5=py39h8ee36c8_1 - - krb5=1.21.2=hb884880_0 - - lcalc=2.0.5=h547a6ed_2 - - lcms2=2.16=ha2f27b4_0 - - ld64=711=ha02d983_0 - - ld64_osx-64=711=ha20a434_0 - - lerc=4.0.0=hb486fe8_0 - - libasprintf=0.22.5=h5ff76d1_2 - - libasprintf-devel=0.22.5=h5ff76d1_2 - - libatomic_ops=7.6.14=hb7f2c08_0 - - libblas=3.9.0=20_osx64_openblas - - libboost=1.85.0=h739af76_2 - - libboost-devel=1.85.0=h2b186f8_2 - - libboost-headers=1.85.0=h694c41f_2 - - libbraiding=1.2=hf0c8a7f_0 - - libbrial=1.2.12=h81e9653_3 - - libbrotlicommon=1.1.0=h0dc2134_1 - - libbrotlidec=1.1.0=h0dc2134_1 - - libbrotlienc=1.1.0=h0dc2134_1 - - libcblas=3.9.0=20_osx64_openblas - - libclang-cpp16=16.0.6=default_h4c8afb6_8 - - libcurl=8.8.0=hf9fcc65_0 - - libcxx=17.0.6=h88467a6_0 - - libdeflate=1.20=h49d49c5_0 - - libedit=3.1.20191231=h0678c8f_2 - - libev=4.33=h10d778d_2 - - libexpat=2.6.2=h73e2aa4_0 - - libffi=3.4.2=h0d85af4_5 - - libflint=3.0.1=h5d15de0_ntl_100 - - libgd=2.3.3=h0dceb68_9 - - libgettextpo=0.22.5=h5ff76d1_2 - - libgettextpo-devel=0.22.5=h5ff76d1_2 - - libgfortran=5.0.0=13_2_0_h97931a8_3 - - libgfortran-devel_osx-64=12.3.0=h0b6f5ec_3 - - libgfortran5=13.2.0=h2873a65_3 - - libglib=2.80.2=h736d271_1 - - libhomfly=1.02r6=h10d778d_1 - - libhwloc=2.10.0=default_h456cccd_1001 - - libiconv=1.17=hd75f5a5_2 - - libintl=0.22.5=h5ff76d1_2 - - libintl-devel=0.22.5=h5ff76d1_2 - - libjpeg-turbo=3.0.0=h0dc2134_1 - - liblapack=3.9.0=20_osx64_openblas - - liblapacke=3.9.0=20_osx64_openblas - - libllvm16=16.0.6=hbedff68_3 - - libnghttp2=1.58.0=h64cf6d3_1 - - libopenblas=0.3.25=openmp_hfef2a42_0 - - libpng=1.6.43=h92b6c6a_0 - - libsodium=1.0.18=hbcb3906_1 - - libsqlite=3.46.0=h1b8f9f3_0 - - libssh2=1.11.0=hd019ec5_0 - - libtiff=4.6.0=h129831d_3 - - libtool=2.4.7=hf0c8a7f_0 - - libuv=1.48.0=h67532ce_0 - - libwebp=1.4.0=hc207709_0 - - libwebp-base=1.4.0=h10d778d_0 - - libxcb=1.16=h0dc2134_0 - - libxml2=2.12.7=h3e169fe_1 - - libzlib=1.3.1=h87427d6_1 - - linbox=1.7.0=h7061c92_0 - - llvm-openmp=18.1.8=h15ab845_0 - - llvm-tools=16.0.6=hbedff68_3 - - lrcalc=2.1=h73e2aa4_6 - - m4=1.4.18=haf1e3a3_1001 - - m4ri=20140914=hd82a5f3_1006 - - m4rie=20150908=hc616cfc_1002 - - make=4.3=h22f3db7_1 - - markupsafe=2.1.5=py39ha09f3b3_0 - - mathjax=3.2.2=h694c41f_0 - - matplotlib=3.8.4=py39h6e9494a_2 - - matplotlib-base=3.8.4=py39hfca4cae_2 - - matplotlib-inline=0.1.7=pyhd8ed1ab_0 - - maxima=5.47.0=h2b27fa8_2 - - memory-allocator=0.1.3=py39hdc70f33_0 - - metis=5.1.0=he965462_1007 - - mistune=3.0.2=pyhd8ed1ab_0 - - mpc=1.3.1=h81bd1dd_0 - - mpfi=1.5.4=h52b28e3_1001 - - mpfr=4.2.1=h4f6b447_1 - - mpmath=1.3.0=pyhd8ed1ab_0 - - munkres=1.1.4=pyh9f0ad1d_0 - - nauty=2.8.8=h10d778d_1 - - nbclient=0.10.0=pyhd8ed1ab_0 - - nbconvert=7.16.4=hd8ed1ab_1 - - nbconvert-core=7.16.4=pyhd8ed1ab_1 - - nbconvert-pandoc=7.16.4=hd8ed1ab_1 - - nbformat=5.10.4=pyhd8ed1ab_0 - - ncurses=6.5=h5846eda_0 - - nest-asyncio=1.6.0=pyhd8ed1ab_0 - - networkx=3.2.1=pyhd8ed1ab_0 - - ninja=1.12.1=h3c5361c_0 - - notebook=7.2.1=pyhd8ed1ab_0 - - notebook-shim=0.2.4=pyhd8ed1ab_0 - - ntl=11.4.3=h0ab3c2f_1 - - numpy=1.26.4=py39h28c39a1_0 - - openblas=0.3.25=openmp_h6794695_0 - - openjdk=22.0.1=h2d185b6_0 - - openjpeg=2.5.2=h7310d3a_0 - - openssl=3.3.1=h87427d6_0 - - overrides=7.7.0=pyhd8ed1ab_0 - - packaging=24.1=pyhd8ed1ab_0 - - palp=2.20=hbcb3906_0 - - pandoc=3.2.1=h694c41f_0 - - pandocfilters=1.5.0=pyhd8ed1ab_0 - - pango=1.54.0=h880b76c_0 - - pari=2.15.5=h7ba67ff_2_pthread - - pari-elldata=0.0.20161017=0 - - pari-galdata=0.0.20180411=0 - - pari-galpol=0.0.20180625=0 - - pari-seadata=0.0.20090618=0 - - pari-seadata-small=0.0.20090618=0 - - parso=0.8.4=pyhd8ed1ab_0 - - patch=2.7.6=hbcf498f_1002 - - pathspec=0.12.1=pyhd8ed1ab_0 - - pcre2=10.44=h7634a1b_0 - - pep517=0.13.0=pyhd8ed1ab_0 - - perl=5.32.1=7_h10d778d_perl5 - - pexpect=4.9.0=pyhd8ed1ab_0 - - pickleshare=0.7.5=py_1003 - - pillow=10.3.0=py39hc3a33ae_1 - - pip=24.0=pyhd8ed1ab_0 - - pixman=0.43.4=h73e2aa4_0 - - pkg-config=0.29.2=ha3d46e9_1008 - - pkgconfig=1.5.5=pyhd8ed1ab_4 - - pkgutil-resolve-name=1.3.10=pyhd8ed1ab_1 - - planarity=3.0.2.0=h10d778d_0 - - platformdirs=4.2.2=pyhd8ed1ab_0 - - pluggy=1.5.0=pyhd8ed1ab_0 - - ply=3.11=pyhd8ed1ab_2 - - 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 - - prometheus_client=0.20.0=pyhd8ed1ab_0 - - prompt-toolkit=3.0.47=pyha770c72_0 - - prompt_toolkit=3.0.47=hd8ed1ab_0 - - psutil=6.0.0=py39hded5825_0 - - pthread-stubs=0.4=hc929b4f_1001 - - ptyprocess=0.7.0=pyhd3deb0d_0 - - pure_eval=0.2.2=pyhd8ed1ab_0 - - py=1.11.0=pyh6c4a22f_0 - - pybind11=2.12.0=py39h0ca7971_0 - - pybind11-global=2.12.0=py39h0ca7971_0 - - pycparser=2.22=pyhd8ed1ab_0 - - pygments=2.18.0=pyhd8ed1ab_0 - - pyobjc-core=10.3.1=py39hf8f43b1_0 - - pyobjc-framework-cocoa=10.3.1=py39hf8f43b1_0 - - pyparsing=3.1.2=pyhd8ed1ab_0 - - pyproject-api=1.7.1=pyhd8ed1ab_0 - - pyrsistent=0.20.0=py39ha09f3b3_0 - - pysocks=1.7.1=pyha2e5f31_6 - - python=3.9.19=h7a9c478_0_cpython - - python-build=1.2.1=pyhd8ed1ab_0 - - python-dateutil=2.9.0=pyhd8ed1ab_0 - - python-fastjsonschema=2.20.0=pyhd8ed1ab_0 - - python-json-logger=2.0.7=pyhd8ed1ab_0 - - python-lrcalc=2.1=py39hd253f6c_6 - - python-tzdata=2024.1=pyhd8ed1ab_0 - - python_abi=3.9=4_cp39 - - pythran=0.15.0=py39h5d0c61a_1 - - pytz=2024.1=pyhd8ed1ab_0 - - pytz-deprecation-shim=0.1.0.post0=py39h6e9494a_4 - - pyyaml=6.0.1=py39hdc70f33_1 - - pyzmq=26.0.3=py39h304b177_0 - - qd=2.3.22=h2beb688_1004 - - qhull=2020.2=h940c156_2 - - r-base=4.3.3=h4648a1f_3 - - r-lattice=0.22_6=r43hb2c329c_0 - - readline=8.2=h9e318b2_1 - - referencing=0.35.1=pyhd8ed1ab_0 - - requests=2.32.3=pyhd8ed1ab_0 - - rfc3339-validator=0.1.4=pyhd8ed1ab_0 - - rfc3986-validator=0.1.1=pyh9f0ad1d_0 - - rhash=1.4.4=h0dc2134_0 - - rpds-py=0.18.1=py39hf59063a_0 - - rpy2=3.5.11=py39r43hd01001f_3 - - rw=0.9=h10d778d_2 - - sagemath-db-combinatorial-designs=20140630=1 - - sagemath-db-elliptic-curves=0.8.1=hecc5488_0 - - sagemath-db-graphs=20210214=hd8ed1ab_0 - - sagemath-db-polytopes=20170220=1 - - sagetex=3.6.1=pyhd8ed1ab_0 - - scipy=1.11.4=py39ha321857_0 - - send2trash=1.8.3=pyh31c8845_0 - - setuptools=70.1.1=pyhd8ed1ab_0 - - setuptools-scm=8.1.0=pyhd8ed1ab_0 - - setuptools_scm=8.1.0=hd8ed1ab_0 - - sigtool=0.1.3=h88f4db0_0 - - simplegeneric=0.8.1=py_1 - - singular=4.3.2.p8=h0d51a9f_1 - - six=1.16.0=pyh6c4a22f_0 - - sniffio=1.3.1=pyhd8ed1ab_0 - - snowballstemmer=2.2.0=pyhd8ed1ab_0 - - soupsieve=2.5=pyhd8ed1ab_1 - - sphinx=7.3.7=pyhd8ed1ab_0 - - sphinx-basic-ng=1.0.0b2=pyhd8ed1ab_1 - - sphinx-copybutton=0.5.2=pyhd8ed1ab_0 - - sphinxcontrib-applehelp=1.0.8=pyhd8ed1ab_0 - - sphinxcontrib-devhelp=1.0.6=pyhd8ed1ab_0 - - sphinxcontrib-htmlhelp=2.0.5=pyhd8ed1ab_0 - - sphinxcontrib-jsmath=1.0.1=pyhd8ed1ab_0 - - sphinxcontrib-qthelp=1.0.7=pyhd8ed1ab_0 - - sphinxcontrib-serializinghtml=1.1.10=pyhd8ed1ab_0 - - sphinxcontrib-websupport=1.2.7=pyhd8ed1ab_0 - - sqlite=3.46.0=h28673e1_0 - - stack_data=0.6.2=pyhd8ed1ab_0 - - suitesparse=7.7.0=hd2b2131_1 - - symmetrica=3.0.1=hf0c8a7f_0 - - sympow=2.023.6=h115ba6a_3 - - sympy=1.12.1=pypyh2585a3b_103 - - tachyon=0.99b6=h3a1d103_1002 - - tapi=1100.0.11=h9ce4665_0 - - tar=1.34=hcb2f6ea_1 - - tbb=2021.12.0=h3c5361c_1 - - terminado=0.18.1=pyh31c8845_0 - - texinfo=7.0=pl5321hc47821c_0 - - three.js=122=hd8ed1ab_2 - - threejs-sage=122=hd8ed1ab_2 - - tinycss2=1.3.0=pyhd8ed1ab_0 - - tk=8.6.13=h1abcd95_1 - - tktable=2.10=hba9d6f1_6 - - tomli=2.0.1=pyhd8ed1ab_0 - - tornado=6.4.1=py39hded5825_0 - - tox=4.15.1=pyhd8ed1ab_0 - - traitlets=5.14.3=pyhd8ed1ab_0 - - trove-classifiers=2024.5.22=pyhd8ed1ab_0 - - types-python-dateutil=2.9.0.20240316=pyhd8ed1ab_0 - - typing-extensions=4.12.2=hd8ed1ab_0 - - typing_extensions=4.12.2=pyha770c72_0 - - typing_utils=0.1.0=pyhd8ed1ab_0 - - tzdata=2024a=h0c530f3_0 - - tzlocal=5.2=py39h6e9494a_0 - - unicodedata2=15.1.0=py39hdc70f33_0 - - uri-template=1.3.0=pyhd8ed1ab_0 - - urllib3=2.2.2=pyhd8ed1ab_0 - - virtualenv=20.26.3=pyhd8ed1ab_0 - - wcwidth=0.2.13=pyhd8ed1ab_0 - - webcolors=24.6.0=pyhd8ed1ab_0 - - webencodings=0.5.1=pyhd8ed1ab_2 - - websocket-client=1.8.0=pyhd8ed1ab_0 - - wheel=0.43.0=pyhd8ed1ab_1 - - widgetsnbextension=4.0.11=pyhd8ed1ab_0 - - xorg-libxau=1.0.11=h0dc2134_0 - - xorg-libxdmcp=1.1.3=h35c211d_0 - - xz=5.2.6=h775f41a_0 - - yaml=0.2.5=h0d85af4_2 - - zeromq=4.3.5=hde137ed_4 - - zipp=3.19.2=pyhd8ed1ab_0 - - zlib=1.3.1=h87427d6_1 - - zstd=1.5.6=h915ae27_0 diff --git a/src/environment-3.9-macos.yml b/src/environment-3.9-macos.yml deleted file mode 100644 index 5137c9298af..00000000000 --- a/src/environment-3.9-macos.yml +++ /dev/null @@ -1,423 +0,0 @@ -# Generated by conda-lock. -# platform: osx-arm64 -# input_hash: c72df9df3a2c7c120e9ff1ca936ae3527692a0de782793536087f2041f57d700 - -channels: - - conda-forge -dependencies: - - _r-mutex=1.0.1=anacondar_1 - - alabaster=0.7.16=pyhd8ed1ab_0 - - anyio=4.4.0=pyhd8ed1ab_0 - - appdirs=1.4.4=pyh9f0ad1d_0 - - appnope=0.1.4=pyhd8ed1ab_0 - - argon2-cffi=23.1.0=pyhd8ed1ab_0 - - argon2-cffi-bindings=21.2.0=py39h0f82c59_4 - - arpack=3.9.1=nompi_h593882a_101 - - arrow=1.3.0=pyhd8ed1ab_0 - - asttokens=2.4.1=pyhd8ed1ab_0 - - async-lru=2.0.4=pyhd8ed1ab_0 - - attrs=23.2.0=pyh71513ae_0 - - autoconf=2.71=pl5321hcd07c0c_1 - - automake=1.16.5=pl5321hce30654_0 - - babel=2.14.0=pyhd8ed1ab_0 - - bc=1.07.1=h3422bc3_0 - - bdw-gc=8.0.6=hc021e02_0 - - beautifulsoup4=4.12.3=pyha770c72_0 - - beniget=0.4.1=pyhd8ed1ab_0 - - blas=2.120=openblas - - blas-devel=3.9.0=20_osxarm64_openblas - - bleach=6.1.0=pyhd8ed1ab_0 - - boost-cpp=1.85.0=hca5e981_2 - - brial=1.2.12=pyh694c41f_3 - - brotli=1.1.0=hb547adb_1 - - brotli-bin=1.1.0=hb547adb_1 - - brotli-python=1.1.0=py39hb198ff7_1 - - bwidget=1.9.14=hce30654_1 - - bzip2=1.0.8=h93a5062_5 - - c-ares=1.28.1=h93a5062_0 - - c-compiler=1.7.0=h6aa9301_1 - - ca-certificates=2024.6.2=hf0a4a13_0 - - cached-property=1.5.2=hd8ed1ab_1 - - cached_property=1.5.2=pyha770c72_1 - - cachetools=5.3.3=pyhd8ed1ab_0 - - cairo=1.18.0=hc6c324b_2 - - cctools=986=h4faf515_0 - - cctools_osx-arm64=986=h62378fb_0 - - cddlib=1!0.94m=h6d7a090_0 - - certifi=2024.6.2=pyhd8ed1ab_0 - - cffi=1.16.0=py39he153c15_0 - - chardet=5.2.0=py39h2804cbe_1 - - charset-normalizer=3.3.2=pyhd8ed1ab_0 - - clang=16.0.6=default_h095aff0_8 - - clang-16=16.0.6=default_hb63da90_8 - - clang_impl_osx-arm64=16.0.6=hc421ffc_16 - - clang_osx-arm64=16.0.6=h54d7cd3_16 - - clangxx=16.0.6=default_h095aff0_8 - - clangxx_impl_osx-arm64=16.0.6=hcd7bac0_16 - - clangxx_osx-arm64=16.0.6=h54d7cd3_16 - - cliquer=1.22=h93a5062_1 - - cmake=3.29.6=had79d8f_0 - - colorama=0.4.6=pyhd8ed1ab_0 - - colorlog=6.8.2=py39h2804cbe_0 - - comm=0.2.2=pyhd8ed1ab_0 - - compiler-rt=16.0.6=h3808999_2 - - compiler-rt_osx-arm64=16.0.6=h3808999_2 - - compilers=1.7.0=hce30654_1 - - contourpy=1.2.1=py39h48c5dd5_0 - - conway-polynomials=0.9=pyhd8ed1ab_0 - - cppy=1.2.1=pyhd8ed1ab_0 - - curl=8.8.0=h653d890_0 - - cvxopt=1.3.2=py39hf9e8641_2 - - cxx-compiler=1.7.0=h2ffa867_1 - - cycler=0.12.1=pyhd8ed1ab_0 - - cypari2=2.1.5=py39h070b2a8_0 - - cysignals=1.11.2=py39h65fc70a_3 - - cython=3.0.10=py39hf3050f2_0 - - debugpy=1.8.1=py39hf3050f2_0 - - decorator=5.1.1=pyhd8ed1ab_0 - - defusedxml=0.7.1=pyhd8ed1ab_0 - - distlib=0.3.8=pyhd8ed1ab_0 - - docutils=0.21.2=pyhd8ed1ab_0 - - dsdp=5.8=h9397a75_1203 - - ecl=23.9.9=h1d9728a_0 - - eclib=20231212=h7f07de4_0 - - ecm=7.0.5=h41d338b_0 - - editables=0.5=pyhd8ed1ab_0 - - entrypoints=0.4=pyhd8ed1ab_0 - - exceptiongroup=1.2.0=pyhd8ed1ab_2 - - executing=2.0.1=pyhd8ed1ab_0 - - expat=2.6.2=hebf3989_0 - - fflas-ffpack=2.5.0=h4bc3318_0 - - fftw=3.3.10=nompi_h6637ab6_110 - - filelock=3.15.4=pyhd8ed1ab_0 - - flit-core=3.9.0=pyhd8ed1ab_1 - - 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_2 - - fontconfig=2.14.2=h82840c6_0 - - fonts-conda-ecosystem=1=0 - - fonts-conda-forge=1=0 - - fonttools=4.53.0=py39hfea33bf_0 - - fortran-compiler=1.7.0=hafb19e3_1 - - fplll=5.4.5=hb7d509d_0 - - fpylll=0.6.1=py39h2eadeda_0 - - fqdn=1.5.1=pyhd8ed1ab_0 - - freetype=2.12.1=hadb7bae_2 - - fribidi=1.0.10=h27ca646_0 - - furo=2024.5.6=pyhd8ed1ab_0 - - gap-core=4.12.2=he8f4e70_3 - - gap-defaults=4.12.2=hce30654_3 - - gast=0.5.4=pyhd8ed1ab_0 - - gengetopt=2.23=hbdafb3b_0 - - gettext=0.22.5=h8fbad5d_2 - - gettext-tools=0.22.5=h8fbad5d_2 - - gf2x=1.3.0=hdaa854c_2 - - gfan=0.6.2=hec08f5c_1003 - - gfortran=12.3.0=h1ca8e4b_1 - - gfortran_impl_osx-arm64=12.3.0=h53ed385_3 - - gfortran_osx-arm64=12.3.0=h57527a5_1 - - giac=1.9.0.21=h1c96721_1 - - giflib=5.2.2=h93a5062_0 - - givaro=4.2.0=h018886a_0 - - glpk=5.0=h6d7a090_0 - - gmp=6.3.0=h7bae524_2 - - gmpy2=2.1.5=py39h9bb7c0c_1 - - graphite2=1.3.13=hebf3989_1003 - - gsl=2.7=h6e638da_0 - - h11=0.14.0=pyhd8ed1ab_0 - - h2=4.1.0=pyhd8ed1ab_0 - - harfbuzz=8.5.0=h1836168_0 - - hatchling=1.25.0=pyhd8ed1ab_0 - - hpack=4.0.0=pyh9f0ad1d_0 - - httpcore=1.0.5=pyhd8ed1ab_0 - - httpx=0.27.0=pyhd8ed1ab_0 - - hyperframe=6.0.1=pyhd8ed1ab_0 - - icu=73.2=hc8870d7_0 - - idna=3.7=pyhd8ed1ab_0 - - igraph=0.10.12=h762ac30_1 - - imagesize=1.4.1=pyhd8ed1ab_0 - - iml=1.0.5=hd73f12c_1004 - - importlib-metadata=8.0.0=pyha770c72_0 - - importlib-resources=6.4.0=pyhd8ed1ab_0 - - importlib_metadata=8.0.0=hd8ed1ab_0 - - importlib_resources=6.4.0=pyhd8ed1ab_0 - - ipykernel=6.29.4=pyh57ce528_0 - - ipympl=0.9.4=pyhd8ed1ab_0 - - ipython=8.18.1=pyh707e725_3 - - ipython_genutils=0.2.0=pyhd8ed1ab_1 - - ipywidgets=8.1.3=pyhd8ed1ab_0 - - isl=0.26=imath32_h347afa1_101 - - isoduration=20.11.0=pyhd8ed1ab_0 - - jedi=0.19.1=pyhd8ed1ab_0 - - jinja2=3.1.4=pyhd8ed1ab_0 - - jmol=14.32.10=hce30654_0 - - json5=0.9.25=pyhd8ed1ab_0 - - jsonpointer=3.0.0=py39h2804cbe_0 - - jsonschema=4.22.0=pyhd8ed1ab_0 - - jsonschema-specifications=2023.12.1=pyhd8ed1ab_0 - - jsonschema-with-format-nongpl=4.22.0=pyhd8ed1ab_0 - - jupyter-jsmol=2022.1.0=pyhd8ed1ab_0 - - jupyter-lsp=2.2.5=pyhd8ed1ab_0 - - jupyter-sphinx=0.5.3=pyha770c72_4 - - jupyter_client=8.6.2=pyhd8ed1ab_0 - - jupyter_core=5.7.2=py39h2804cbe_0 - - jupyter_events=0.10.0=pyhd8ed1ab_0 - - jupyter_server=2.14.1=pyhd8ed1ab_0 - - jupyter_server_terminals=0.5.3=pyhd8ed1ab_0 - - jupyter_sphinx=0.5.3=hd8ed1ab_4 - - jupyterlab=4.2.2=pyhd8ed1ab_0 - - jupyterlab_pygments=0.3.0=pyhd8ed1ab_1 - - jupyterlab_server=2.27.2=pyhd8ed1ab_0 - - jupyterlab_widgets=3.0.11=pyhd8ed1ab_0 - - kiwisolver=1.4.5=py39hbd775c9_1 - - krb5=1.21.2=h92f50d5_0 - - lcalc=2.0.5=h4a402bc_2 - - lcms2=2.16=ha0e7c42_0 - - ld64=711=h634c8be_0 - - ld64_osx-arm64=711=ha4bd21c_0 - - lerc=4.0.0=h9a09cb3_0 - - libasprintf=0.22.5=h8fbad5d_2 - - libasprintf-devel=0.22.5=h8fbad5d_2 - - libatomic_ops=7.6.14=h1a8c8d9_0 - - libblas=3.9.0=20_osxarm64_openblas - - libboost=1.85.0=h17eb2be_2 - - libboost-devel=1.85.0=hf450f58_2 - - libboost-headers=1.85.0=hce30654_2 - - libbraiding=1.2=hb7217d7_0 - - libbrial=1.2.12=h56a29cd_3 - - libbrotlicommon=1.1.0=hb547adb_1 - - libbrotlidec=1.1.0=hb547adb_1 - - libbrotlienc=1.1.0=hb547adb_1 - - libcblas=3.9.0=20_osxarm64_openblas - - libclang-cpp16=16.0.6=default_hb63da90_8 - - libcurl=8.8.0=h7b6f9a7_0 - - libcxx=17.0.6=h5f092b4_0 - - libdeflate=1.20=h93a5062_0 - - libedit=3.1.20191231=hc8eb9b7_2 - - libev=4.33=h93a5062_2 - - libexpat=2.6.2=hebf3989_0 - - libffi=3.4.2=h3422bc3_5 - - libflint=3.0.1=h28749a5_ntl_100 - - libgd=2.3.3=hfdf3952_9 - - libgettextpo=0.22.5=h8fbad5d_2 - - libgettextpo-devel=0.22.5=h8fbad5d_2 - - libgfortran=5.0.0=13_2_0_hd922786_3 - - libgfortran-devel_osx-arm64=12.3.0=hc62be1c_3 - - libgfortran5=13.2.0=hf226fd6_3 - - libglib=2.80.2=h59d46d9_1 - - libhomfly=1.02r6=h93a5062_1 - - libhwloc=2.10.0=default_h7685b71_1001 - - libiconv=1.17=h0d3ecfb_2 - - libintl=0.22.5=h8fbad5d_2 - - libintl-devel=0.22.5=h8fbad5d_2 - - libjpeg-turbo=3.0.0=hb547adb_1 - - liblapack=3.9.0=20_osxarm64_openblas - - liblapacke=3.9.0=20_osxarm64_openblas - - libllvm16=16.0.6=haab561b_3 - - libnghttp2=1.58.0=ha4dd798_1 - - libopenblas=0.3.25=openmp_h6c19121_0 - - libpng=1.6.43=h091b4b1_0 - - libsodium=1.0.18=h27ca646_1 - - libsqlite=3.46.0=hfb93653_0 - - libssh2=1.11.0=h7a5bd25_0 - - libtiff=4.6.0=h07db509_3 - - libtool=2.4.7=hb7217d7_0 - - libuv=1.48.0=h93a5062_0 - - libwebp=1.4.0=h54798ee_0 - - libwebp-base=1.4.0=h93a5062_0 - - libxcb=1.16=hf2054a2_0 - - libxml2=2.12.7=ha661575_1 - - libzlib=1.3.1=hfb2fe0b_1 - - linbox=1.7.0=h3afee3a_0 - - llvm-openmp=18.1.8=hde57baf_0 - - llvm-tools=16.0.6=haab561b_3 - - lrcalc=2.1=hebf3989_6 - - m4=1.4.18=h642e427_1001 - - m4ri=20140914=hc97c1ff_1006 - - m4rie=20150908=h22b9e9d_1002 - - make=4.3=he57ea6c_1 - - markupsafe=2.1.5=py39h17cfd9d_0 - - mathjax=3.2.2=hce30654_0 - - matplotlib=3.8.4=py39hdf13c20_2 - - matplotlib-base=3.8.4=py39h15359f4_2 - - matplotlib-inline=0.1.7=pyhd8ed1ab_0 - - maxima=5.47.0=h2bbcd85_2 - - memory-allocator=0.1.3=py39h0f82c59_0 - - metis=5.1.0=h13dd4ca_1007 - - mistune=3.0.2=pyhd8ed1ab_0 - - mpc=1.3.1=h91ba8db_0 - - mpfi=1.5.4=hbde5f5b_1001 - - mpfr=4.2.1=h41d338b_1 - - mpmath=1.3.0=pyhd8ed1ab_0 - - munkres=1.1.4=pyh9f0ad1d_0 - - nauty=2.8.8=h93a5062_1 - - nbclient=0.10.0=pyhd8ed1ab_0 - - nbconvert=7.16.4=hd8ed1ab_1 - - nbconvert-core=7.16.4=pyhd8ed1ab_1 - - nbconvert-pandoc=7.16.4=hd8ed1ab_1 - - nbformat=5.10.4=pyhd8ed1ab_0 - - ncurses=6.5=hb89a1cb_0 - - nest-asyncio=1.6.0=pyhd8ed1ab_0 - - networkx=3.2.1=pyhd8ed1ab_0 - - ninja=1.12.1=h420ef59_0 - - notebook=7.2.1=pyhd8ed1ab_0 - - notebook-shim=0.2.4=pyhd8ed1ab_0 - - ntl=11.4.3=hbb3f309_1 - - numpy=1.26.4=py39h7aa2656_0 - - openblas=0.3.25=openmp_h55c453e_0 - - openjdk=22.0.1=hbeb2e11_0 - - openjpeg=2.5.2=h9f1df11_0 - - openssl=3.3.1=hfb2fe0b_0 - - overrides=7.7.0=pyhd8ed1ab_0 - - packaging=24.1=pyhd8ed1ab_0 - - palp=2.20=h27ca646_0 - - pandoc=3.2.1=hce30654_0 - - pandocfilters=1.5.0=pyhd8ed1ab_0 - - pango=1.54.0=h5cb9fbc_0 - - pari=2.15.5=h4f2304c_2_pthread - - pari-elldata=0.0.20161017=0 - - pari-galdata=0.0.20180411=0 - - pari-galpol=0.0.20180625=0 - - pari-seadata=0.0.20090618=0 - - pari-seadata-small=0.0.20090618=0 - - parso=0.8.4=pyhd8ed1ab_0 - - patch=2.7.6=h27ca646_1002 - - pathspec=0.12.1=pyhd8ed1ab_0 - - pcre2=10.44=h297a79d_0 - - pep517=0.13.0=pyhd8ed1ab_0 - - perl=5.32.1=7_h4614cfb_perl5 - - pexpect=4.9.0=pyhd8ed1ab_0 - - pickleshare=0.7.5=py_1003 - - pillow=10.3.0=py39h3baf582_1 - - pip=24.0=pyhd8ed1ab_0 - - pixman=0.43.4=hebf3989_0 - - pkg-config=0.29.2=hab62308_1008 - - pkgconfig=1.5.5=pyhd8ed1ab_4 - - pkgutil-resolve-name=1.3.10=pyhd8ed1ab_1 - - planarity=3.0.2.0=h93a5062_0 - - platformdirs=4.2.2=pyhd8ed1ab_0 - - pluggy=1.5.0=pyhd8ed1ab_0 - - ply=3.11=pyhd8ed1ab_2 - - 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 - - prometheus_client=0.20.0=pyhd8ed1ab_0 - - prompt-toolkit=3.0.47=pyha770c72_0 - - prompt_toolkit=3.0.47=hd8ed1ab_0 - - psutil=6.0.0=py39hfea33bf_0 - - pthread-stubs=0.4=h27ca646_1001 - - ptyprocess=0.7.0=pyhd3deb0d_0 - - pure_eval=0.2.2=pyhd8ed1ab_0 - - py=1.11.0=pyh6c4a22f_0 - - pybind11=2.12.0=py39h48c5dd5_0 - - pybind11-global=2.12.0=py39h48c5dd5_0 - - pycparser=2.22=pyhd8ed1ab_0 - - pygments=2.18.0=pyhd8ed1ab_0 - - pyobjc-core=10.3.1=py39h336d860_0 - - pyobjc-framework-cocoa=10.3.1=py39h336d860_0 - - pyparsing=3.1.2=pyhd8ed1ab_0 - - pyproject-api=1.7.1=pyhd8ed1ab_0 - - pyrsistent=0.20.0=py39h17cfd9d_0 - - pysocks=1.7.1=pyha2e5f31_6 - - python=3.9.19=hd7ebdb9_0_cpython - - python-build=1.2.1=pyhd8ed1ab_0 - - python-dateutil=2.9.0=pyhd8ed1ab_0 - - python-fastjsonschema=2.20.0=pyhd8ed1ab_0 - - python-json-logger=2.0.7=pyhd8ed1ab_0 - - python-lrcalc=2.1=py39hf3050f2_6 - - python-tzdata=2024.1=pyhd8ed1ab_0 - - python_abi=3.9=4_cp39 - - pythran=0.15.0=py39h1261dcd_1 - - pytz=2024.1=pyhd8ed1ab_0 - - pytz-deprecation-shim=0.1.0.post0=py39h2804cbe_4 - - pyyaml=6.0.1=py39h0f82c59_1 - - pyzmq=26.0.3=py39he7f0319_0 - - qd=2.3.22=hbec66e7_1004 - - qhull=2020.2=hc021e02_2 - - r-base=4.3.3=h8112bfe_3 - - r-lattice=0.22_6=r43hd2d937b_0 - - readline=8.2=h92ec313_1 - - referencing=0.35.1=pyhd8ed1ab_0 - - requests=2.32.3=pyhd8ed1ab_0 - - rfc3339-validator=0.1.4=pyhd8ed1ab_0 - - rfc3986-validator=0.1.1=pyh9f0ad1d_0 - - rhash=1.4.4=hb547adb_0 - - rpds-py=0.18.1=py39h0019b8a_0 - - rpy2=3.5.11=py39r43hf4a74a7_3 - - rw=0.9=h93a5062_2 - - sagemath-db-combinatorial-designs=20140630=1 - - sagemath-db-elliptic-curves=0.8.1=hecc5488_0 - - sagemath-db-graphs=20210214=hd8ed1ab_0 - - sagemath-db-polytopes=20170220=1 - - sagetex=3.6.1=pyhd8ed1ab_0 - - scipy=1.11.4=py39h36c428d_0 - - send2trash=1.8.3=pyh31c8845_0 - - setuptools=70.1.1=pyhd8ed1ab_0 - - setuptools-scm=8.1.0=pyhd8ed1ab_0 - - setuptools_scm=8.1.0=hd8ed1ab_0 - - sigtool=0.1.3=h44b9a77_0 - - simplegeneric=0.8.1=py_1 - - singular=4.3.2.p8=hb460b52_1 - - six=1.16.0=pyh6c4a22f_0 - - sniffio=1.3.1=pyhd8ed1ab_0 - - snowballstemmer=2.2.0=pyhd8ed1ab_0 - - soupsieve=2.5=pyhd8ed1ab_1 - - sphinx=7.3.7=pyhd8ed1ab_0 - - sphinx-basic-ng=1.0.0b2=pyhd8ed1ab_1 - - sphinx-copybutton=0.5.2=pyhd8ed1ab_0 - - sphinxcontrib-applehelp=1.0.8=pyhd8ed1ab_0 - - sphinxcontrib-devhelp=1.0.6=pyhd8ed1ab_0 - - sphinxcontrib-htmlhelp=2.0.5=pyhd8ed1ab_0 - - sphinxcontrib-jsmath=1.0.1=pyhd8ed1ab_0 - - sphinxcontrib-qthelp=1.0.7=pyhd8ed1ab_0 - - sphinxcontrib-serializinghtml=1.1.10=pyhd8ed1ab_0 - - sphinxcontrib-websupport=1.2.7=pyhd8ed1ab_0 - - sqlite=3.46.0=h5838104_0 - - stack_data=0.6.2=pyhd8ed1ab_0 - - suitesparse=7.7.0=hf6fcff2_1 - - symmetrica=3.0.1=hb7217d7_0 - - sympow=2.023.6=hb0babe8_3 - - sympy=1.12.1=pypyh2585a3b_103 - - tachyon=0.99b6=hb8a568e_1002 - - tapi=1100.0.11=he4954df_0 - - tar=1.34=h7cb298e_1 - - tbb=2021.12.0=h420ef59_1 - - terminado=0.18.1=pyh31c8845_0 - - texinfo=7.0=pl5321h9ea1dce_0 - - three.js=122=hd8ed1ab_2 - - threejs-sage=122=hd8ed1ab_2 - - tinycss2=1.3.0=pyhd8ed1ab_0 - - tk=8.6.13=h5083fa2_1 - - tktable=2.10=h1e387b8_6 - - tomli=2.0.1=pyhd8ed1ab_0 - - tornado=6.4.1=py39hfea33bf_0 - - tox=4.15.1=pyhd8ed1ab_0 - - traitlets=5.14.3=pyhd8ed1ab_0 - - trove-classifiers=2024.5.22=pyhd8ed1ab_0 - - types-python-dateutil=2.9.0.20240316=pyhd8ed1ab_0 - - typing-extensions=4.12.2=hd8ed1ab_0 - - typing_extensions=4.12.2=pyha770c72_0 - - typing_utils=0.1.0=pyhd8ed1ab_0 - - tzdata=2024a=h0c530f3_0 - - tzlocal=5.2=py39h2804cbe_0 - - unicodedata2=15.1.0=py39h0f82c59_0 - - uri-template=1.3.0=pyhd8ed1ab_0 - - urllib3=2.2.2=pyhd8ed1ab_0 - - virtualenv=20.26.3=pyhd8ed1ab_0 - - wcwidth=0.2.13=pyhd8ed1ab_0 - - webcolors=24.6.0=pyhd8ed1ab_0 - - webencodings=0.5.1=pyhd8ed1ab_2 - - websocket-client=1.8.0=pyhd8ed1ab_0 - - wheel=0.43.0=pyhd8ed1ab_1 - - widgetsnbextension=4.0.11=pyhd8ed1ab_0 - - xorg-libxau=1.0.11=hb547adb_0 - - xorg-libxdmcp=1.1.3=h27ca646_0 - - xz=5.2.6=h57fd34a_0 - - yaml=0.2.5=h3422bc3_2 - - zeromq=4.3.5=hcc0f68c_4 - - zipp=3.19.2=pyhd8ed1ab_0 - - zlib=1.3.1=hfb2fe0b_1 - - zstd=1.5.6=hb46c0d2_0 From 16eb3227c2353401136cc986154feb1586d56cfb Mon Sep 17 00:00:00 2001 From: janmenjayap Date: Sun, 29 Sep 2024 17:24:29 +0530 Subject: [PATCH 227/537] Introduced graphs/matching_covered_graph.py --- src/doc/en/reference/graphs/index.rst | 1 + src/sage/graphs/all.py | 1 + src/sage/graphs/matching.py | 2 +- src/sage/graphs/matching_covered_graph.py | 464 ++++++++++++++++++++++ 4 files changed, 467 insertions(+), 1 deletion(-) create mode 100644 src/sage/graphs/matching_covered_graph.py diff --git a/src/doc/en/reference/graphs/index.rst b/src/doc/en/reference/graphs/index.rst index 34c5f134839..bb8594634b1 100644 --- a/src/doc/en/reference/graphs/index.rst +++ b/src/doc/en/reference/graphs/index.rst @@ -85,6 +85,7 @@ Libraries of algorithms sage/graphs/pq_trees sage/graphs/trees sage/graphs/matching + sage/graphs/matching_covered_graph sage/graphs/matchpoly sage/graphs/genus sage/graphs/lovasz_theta diff --git a/src/sage/graphs/all.py b/src/sage/graphs/all.py index 14f4eb9204b..a42a1d7210f 100644 --- a/src/sage/graphs/all.py +++ b/src/sage/graphs/all.py @@ -9,6 +9,7 @@ from sage.graphs.graph import Graph from sage.graphs.digraph import DiGraph from sage.graphs.bipartite_graph import BipartiteGraph +from sage.graphs.matching_covered_graph import MatchingCoveredGraph import sage.graphs.weakly_chordal import sage.graphs.lovasz_theta import sage.graphs.partial_cube diff --git a/src/sage/graphs/matching.py b/src/sage/graphs/matching.py index 457ccc16a75..d76317dc8e0 100644 --- a/src/sage/graphs/matching.py +++ b/src/sage/graphs/matching.py @@ -695,7 +695,7 @@ def is_factor_critical(G, matching=None, algorithm='Edmonds', solver=None, verbo def is_matching_covered(G, matching=None, algorithm='Edmonds', coNP_certificate=False, - solver=None, verbose=0, *, integrality_tolerance=0.001): + solver=None, verbose=0, integrality_tolerance=0.001): r""" Check if the graph is matching covered. diff --git a/src/sage/graphs/matching_covered_graph.py b/src/sage/graphs/matching_covered_graph.py new file mode 100644 index 00000000000..ad0f722a368 --- /dev/null +++ b/src/sage/graphs/matching_covered_graph.py @@ -0,0 +1,464 @@ +r""" +Matching covered graphs + +This module implements functions and operations pertaining to matching covered graphs. + +A *matching* in a graph is a set of pairwise nonadjacent links +(nonloop edges). In other words, a matching in a graph is the edge set of an +1-regular subgraph. A matching is called a *perfect* *matching* if it the +subgraph generated by a set of matching edges spans the graph, i.e. it's the +edge set of an 1-regular spanning subgraph. A connected nontrivial graph is +called *matching* *covered* if each edge participates in some perfect matching. + +AUTHORS: + +- Janmenjaya Panda (2024-06-14): initial version +""" +# **************************************************************************** +# Copyright (C) 2024 Janmenjaya Panda +# +# 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 .graph import Graph + +class MatchingCoveredGraph(Graph): + r""" + Matching covered graph + + INPUT: + + - ``data`` -- can be any of the following: + + - Empty or ``None`` (throws a :class:`ValueError` as the graph must be nontrival). + + - An arbitrary graph. + + - ``matching`` -- (default: ``None``); a perfect matching of the + graph, that can be given using any valid input format of + :class:`~sage.graphs.graph.Graph`. + + If set to ``None``, a matching is computed using the other parameters. + + - ``algorithm`` -- string (default: ``'Edmonds'``); the algorithm to be + used to compute a maximum matching of the graph among + + - ``'Edmonds'`` selects Edmonds' algorithm as implemented in NetworkX, + + - ``'LP'`` uses a Linear Program formulation of the matching problem. + + - ``solver`` -- string (default: ``None``); specify 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 (only useful when ``algorithm + == 'LP'``). + + - ``integrality_tolerance`` -- float; parameter for use with MILP + solvers over an inexact base ring; see + :meth:`MixedIntegerLinearProgram.get_values`. + + .. NOTE:: + + All remaining arguments are passed to the ``Graph`` constructor + + EXAMPLES: + + Generating an object of the class ``MatchingCoveredGraph`` from the + provided instance of ``Graph`` without providing any other information:: + + sage: G = MatchingCoveredGraph(graphs.PetersenGraph()) + SAGE: G + Matching covered Petersen graph: Graph on 10 vertices + sage: G = graphs.StaircaseGraph(4) + sage: H = MatchingCoveredGraph(G) + sage: H + Matching covered staircase graph: Graph on 8 vertices + sage: H == G + True + sage: G = Graph({0: [1, 2, 3, 4], 1: [2, 5], 2: [5], 3: [4, 5], 4: [5]}) + sage: H = MatchingCoveredGraph(G) + sage: H + Matching covered graph: Graph on 6 vertices + sage: H == G + True + sage: # needs networkx + sage: import networkx + sage: G = Graph(networkx.complete_bipartite_graph(12, 12)) + sage: H = MatchingCoveredGraph(G) + sage: H + Matching covered graph: Graph on 12 vertices + sage: H == G + True + sage: G = Graph('E|fG', sparse=True) + sage: H = MatchingCoveredGraph(G) + sage: H + Matching covered graph: Graph on 6 vertices + sage: H == G + True + sage: # needs sage.modules + sage: M = Matrix([(0,1,0,0,1,1,0,0,0,0), + ....: (1,0,1,0,0,0,1,0,0,0), + ....: (0,1,0,1,0,0,0,1,0,0), + ....: (0,0,1,0,1,0,0,0,1,0), + ....: (1,0,0,1,0,0,0,0,0,1), + ....: (1,0,0,0,0,0,0,1,1,0), + ....: (0,1,0,0,0,0,0,0,1,1), + ....: (0,0,1,0,0,1,0,0,0,1), + ....: (0,0,0,1,0,1,1,0,0,0), + ....: (0,0,0,0,1,0,1,1,0,0)]) + sage: M + [0 1 0 0 1 1 0 0 0 0] + [1 0 1 0 0 0 1 0 0 0] + [0 1 0 1 0 0 0 1 0 0] + [0 0 1 0 1 0 0 0 1 0] + [1 0 0 1 0 0 0 0 0 1] + [1 0 0 0 0 0 0 1 1 0] + [0 1 0 0 0 0 0 0 1 1] + [0 0 1 0 0 1 0 0 0 1] + [0 0 0 1 0 1 1 0 0 0] + [0 0 0 0 1 0 1 1 0 0] + sage: G = Graph(M) + sage: H = MatchingCoveredGraph(G) + sage: H == G + True + sage: # needs sage.modules + sage: M = Matrix([(-1, 0, 0, 0, 1, 0, 0, 0, 0, 0,-1, 0, 0, 0, 0), + ....: ( 1,-1, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1, 0, 0, 0), + ....: ( 0, 1,-1, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1, 0, 0), + ....: ( 0, 0, 1,-1, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1, 0), + ....: ( 0, 0, 0, 1,-1, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1), + ....: ( 0, 0, 0, 0, 0,-1, 0, 0, 0, 1, 1, 0, 0, 0, 0), + ....: ( 0, 0, 0, 0, 0, 0, 0, 1,-1, 0, 0, 1, 0, 0, 0), + ....: ( 0, 0, 0, 0, 0, 1,-1, 0, 0, 0, 0, 0, 1, 0, 0), + ....: ( 0, 0, 0, 0, 0, 0, 0, 0, 1,-1, 0, 0, 0, 1, 0), + ....: ( 0, 0, 0, 0, 0, 0, 1,-1, 0, 0, 0, 0, 0, 0, 1)]) + sage: M + [-1 0 0 0 1 0 0 0 0 0 -1 0 0 0 0] + [ 1 -1 0 0 0 0 0 0 0 0 0 -1 0 0 0] + [ 0 1 -1 0 0 0 0 0 0 0 0 0 -1 0 0] + [ 0 0 1 -1 0 0 0 0 0 0 0 0 0 -1 0] + [ 0 0 0 1 -1 0 0 0 0 0 0 0 0 0 -1] + [ 0 0 0 0 0 -1 0 0 0 1 1 0 0 0 0] + [ 0 0 0 0 0 0 0 1 -1 0 0 1 0 0 0] + [ 0 0 0 0 0 1 -1 0 0 0 0 0 1 0 0] + [ 0 0 0 0 0 0 0 0 1 -1 0 0 0 1 0] + [ 0 0 0 0 0 0 1 -1 0 0 0 0 0 0 1] + sage: G = Graph(M) + sage: H = MatchingCoveredGraph(G) + sage: H == G + True + sage: G = Graph([(0, 1), (0, 3), (0, 4), (1, 2), (1, 5), (2, 3), (2, 6), (3, 7), (4, 5), (4, 7), (5, 6), (6, 7)]) + sage: H = MatchingCoveredGraph(G) + sage: H == G + True + sage: import igraph # optional - python_igraph + sage: G = Graph(igraph.Graph([(0, 1), (0, 3), (1, 2), (2, 3)])) # optional - python_igraph + sage: H = MatchingCoveredGraph(G) + sage: H + Matching covered graph on 4 vertices + + One may specify a matching:: + + sage: P = graphs.PetersenGraph() + sage: M = P.matching() + sage: G = MatchingCoveredGraph(P, matching=M) + sage: G + Matching covered Petersen graph: Graph on 10 vertices + sage: P == G + True + sage: G = graphs.TruncatedBiwheelGraph() + sage: M = G.matching() + sage: H = MatchingCoveredGraph(G, M) + sage: H + Matching covered Truncated biwheel graph: Graph on 28 vertices + sage: H == G + True + + TESTS: + + An empty graph is not matching covered:: + + sage: G = Graph() + sage: H = MatchingCoveredGraph(G) + Traceback (most recent call last): + ... + ValueError: the graph is trivial + sage: G = Graph(None) + sage: H = MatchingCoveredGraph(G) + Traceback (most recent call last): + ... + ValueError: the graph is trivial + sage: G = MatchingCoveredGraph() + Traceback (most recent call last): + ... + ValueError: the graph is trivial + sage: G = MatchingCoveredGraph(None) + Traceback (most recent call last): + ... + ValueError: the graph is trivial + + Providing with a graph that is not connected:: + + sage: + + Make sure that self-loops are not allowed for a matching covered graph:: + + sage: P = graphs.PetersenGraph() + sage: G = MatchingCoveredGraph(P) + sage: G.allows_loops() + False + sage: G.allow_loops(True) + Traceback (most recent call last): + ... + ValueError: + sage: G.add_edge(0, 0) + Traceback (most recent call last): + ... + ValueError: cannot add edge from 0 to 0 in graph without loops + sage: H = MatchingCoveredGraph(P, loops=True) + Traceback (most recent call last): + ... + ValueError: loops are not allowed in matching covered graphs + + Make sure that multiple edges are allowed for a matching covered graph by + default and can be modified for this not to be allowed:: + + sage: P = graphs.PetersenGraph() + sage: G = MatchingCoveredGraph(P) + sage: G.allows_multiple_edges() + True + sage: G.add_edge(next(P.edge_iterator())) + sage: G.allow_multiple_edges(False) + sage: G.allows_multple_edges() + False + sage: G.add_edge(next(P.edge_iterator())) + Traceback (most recent call last): + ... + ValueError: + sage: H = MatchingCoveredGraph(P, multiedges=False) + sage: G.allows_multple_edges() + False + sage: H.add_edge(next(P.edge_iterator())) + Traceback (most recent call last): + ... + ValueError: + + Providing with a connected nontrivial graph free of self-loops that is + not matching covered:: + + sage: G = graphs.CompleteGraph(11) + sage: H = MatchingCoveredGraph(G) + Traceback (most recent call last): + ... + ValueError: input graph is not matching covered + sage: G = Graph({0: [1, 6, 11], 1: [2, 4], 2: [3, 5], 3: [4, 5], + ....: 4: [5], 6: [7, 9], 7: [8, 10], 8: [9, 10], 9: [10], + ....: 11: [12, 14], 12: [13, 15], 13: [14, 15], 14: [15]}) + sage: H = MatchingCoveredGraph(G) + Traceback (most recent call last): + ... + ValueError: input graph is not matching covered + sage: # needs networkx + sage: import networkx + sage: G = Graph(networkx.complete_bipartite_graph(2, 12)) + sage: H = MatchingCoveredGraph(G) + Traceback (most recent call last): + ... + ValueError: input graph is not matching covered + sage: G = Graph('F~~~w') + sage: H = MatchingCoveredGraph(G) + Traceback (most recent call last): + ... + ValueError: input graph is not matching covered + sage: # needs sage.modules + sage: M = Matrix([(0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0), + ....: (1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), + ....: (0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), + ....: (0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), + ....: (0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), + ....: (0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), + ....: (1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0), + ....: (0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0), + ....: (0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0), + ....: (0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0), + ....: (0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0), + ....: (1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0), + ....: (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1), + ....: (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1), + ....: (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1), + ....: (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0)]) + sage: M + [0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0] + [1 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0] + [0 1 0 1 0 1 0 0 0 0 0 0 0 0 0 0] + [0 0 1 0 1 1 0 0 0 0 0 0 0 0 0 0] + [0 1 0 1 0 1 0 0 0 0 0 0 0 0 0 0] + [0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0] + [1 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0] + [0 0 0 0 0 0 1 0 1 0 1 0 0 0 0 0] + [0 0 0 0 0 0 0 1 0 1 1 0 0 0 0 0] + [0 0 0 0 0 0 1 0 1 0 1 0 0 0 0 0] + [0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0] + [1 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0] + [0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 1] + [0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 1] + [0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 1] + [0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0] + sage: G = Graph(M) + sage: H = MatchingCoveredGraph(G) + Traceback (most recent call last): + ... + ValueError: input graph is not matching covered + sage: # needs sage.modules + sage: M = Matrix([(1, 1, 0, 0, 0, 0), + (0, 0, 1, 1, 0, 0), + (0, 0, 1, 0, 1, 0), + (1, 0, 0, 0, 0, 1), + (0, 1, 0, 1, 1, 1)]) + sage: G = Graph(M) + sage: H = MatchingCoveredGraph(G) + Traceback (most recent call last): + ... + ValueError: input graph is not matching covered + sage: G = Graph([(11, 12), (11, 14), (0, 1), (0, 11), (0, 6), (1, 2), + ....: (1, 4), (2, 3), (2, 5), (3, 4), (3, 5), (4, 5), + ....: (6, 7), (6, 9), (7, 8), (7, 10), (8, 9), (8, 10), + ....: (9, 10), (12, 13), (12, 15), (13, 14), (13, 15), + ....: (14, 15)]) + sage: H = MatchingCoveredGraph(G) + Traceback (most recent call last): + ... + ValueError: input graph is not matching covered + sage: import igraph # optional - python_igraph + sage: G = Graph(igraph.Graph([(0, 1), (0, 2), (0, 3), (1, 2), (2, 3)])) # optional - python_igraph + sage: H = MatchingCoveredGraph(G) + Traceback (most recent call last): + ... + ValueError: input graph is not matching covered + + Providing with a wrong matching:: + + sage: G = graphs.CompleteGraph(6) + sage: M = Graph(G.matching()) + sage: M.add_edges([(0, 1), (0, 2)]) + sage: H = MatchingCoveredGraph(G, matching=M) + Traceback (most recent call last): + ... + ValueError: the input is not a matching + sage: N = Graph(G.matching()) + sage: N.add_edge(6, 7) + sage: H = MatchingCoveredGraph(G, matching=N) + Traceback (most recent call last): + ... + ValueError: the input is not a matching of the graph + sage: J = Graph() + sage: J.add_edges([(0, 1), (2, 3)]) + sage: H = MatchingCoveredGraph(G, matching=J) + Traceback (most recent call last): + ... + ValueError: the input is not a perfect matching of the graph + """ + + def __init__(self, data=None, matching=None, algorithm='Edmonds', + solver=None, verbose=0, integrality_tolerance=0.001, + *args, **kwds): + r""" + Create a matching covered graph, that is a connected nontrivial graph + wherein each edge participates in some perfect matching + + See documentation ``MatchingCoveredGraph?`` for detailed information. + """ + if kwds is None: + kwds = {'loops': False} + else: + if 'loops' in kwds and kwds['loops']: + raise ValueError('loops are not allowed in a matching \ + covered graph') + kwds['loops'] = False + + # Note that self-loops are now allowed in a matching covered graph. + # Hence, such method shall be turned off + from types import MethodType + self.allow_loops = MethodType(Graph.allow_loops, self) + + if data is None: + raise ValueError('the graph is trivial') + + elif isinstance(data, MatchingCoveredGraph): + Graph.__init__(self, data, *args, **kwds) + + else: + self._upgrade_from_graph(matching, algorithm, solver, verbose, + integrality_tolerance) + + del self.allow_loops + self.allow_multiple_edges(True) + + def _upgrade_from_graph(self, matching=None, algorithm='Edmonds', + solver=None, verbose=0, + integrality_tolerance=0.001): + """ + Upgrade the given graph to an object of matching covered graph if eligible + + See documentation ``MatchingCoveredGraph?`` for detailed information. + """ + try: + coNP_certificate = False + check, _ = self.is_matching_covered(matching, algorithm, + coNP_certificate, solver, + verbose, integrality_tolerance) + + if not check: + raise ValueError("input graph is not matching covered") + + except ValueError as error: + raise error + + def __repr__(self): + r""" + Return a short string representation of the matching covered graph + + EXAMPLES: + + If the string representation of the (matching covered) graph does not + contain the term 'matching covered', it's used as the prefix:: + + sage: G = graphs.CompleteGraph(10) + sage: H = MatchingCoveredGraph(G) + sage: H + Matching covered complete graph: Graph on 10 vertices + sage: G = MatchingCoveredGraph(BipartiteGraph(graphs.HexahedralGraph())) + sage: G + Matching covered bipartite hexahedron: graph on 8 vertices + + In case the string representation of the (matching covered) graph + contains the term 'matching covered', the representation remains as it + is:: + + sage: G = graphs.CompleteGraph(10) + sage: H = MatchingCoveredGraph(G) + sage: H + Matching covered complete graph: Graph on 10 vertices + sage: J = MatchingCoveredGraph(H) + sage: J + Matching covered complete graph: Graph on 10 vertices + sage: G = BipartiteGraph(MatchingCoveredGraph(graphs.HexahedralGraph())) + sage: G + Bipartite matching covered hexahedron: graph on 8 vertices + sage: H = MatchingCoveredGraph(G) + sage: H + Bipartite matching covered hexahedron: graph on 8 vertices + """ + s = Graph._repr_(self).lower() + if "matching covered" in s: + return s.capitalize() + return "".join(["Matching covered ", s]) \ No newline at end of file From bd95f4d64f1078ed94a63cefe125ba1ceb2028da Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Sun, 29 Sep 2024 16:20:58 +0200 Subject: [PATCH 228/537] enable user friendly P. = PolynomialSpecies(R), without implementing gens --- src/sage/rings/species.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/sage/rings/species.py b/src/sage/rings/species.py index 2952d2f44f8..3ad7b0fac72 100644 --- a/src/sage/rings/species.py +++ b/src/sage/rings/species.py @@ -1681,6 +1681,25 @@ def _element_constructor_(self, G, pi=None): Hs = _stabilizer_subgroups(S, X, a) return self._from_dict({self._indices(H, pi): ZZ.one() for H in Hs}) + def _first_ngens(self, n): + """ + Used by the preparser for ``F. = ...``. + + We do not use the generic implementation of + :class:`sage.combinat.CombinatorialFreeModule`, because we do + not want to implement `gens`. + + EXAMPLES:: + + sage: from sage.rings.species import PolynomialSpecies + sage: P. = PolynomialSpecies(QQ) # indirect doctest + sage: X + 2*Y + X + 2*Y + """ + B = self.basis() + return tuple(B[i] for grade in IntegerVectors(1, length=self._arity) + for i in self._indices.graded_component(grade)) + def change_ring(self, R): r""" Return the base change of ``self`` to `R`. From b51a8b05d81b5deb8534df0b14b3e6277e3d4430 Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Sun, 29 Sep 2024 17:45:55 +0200 Subject: [PATCH 229/537] mark some doctests as random, run TestSuite also for element classes, explain why we are skipping parts of the testsuite --- src/sage/rings/species.py | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/src/sage/rings/species.py b/src/sage/rings/species.py index 3ad7b0fac72..adc08d7a055 100644 --- a/src/sage/rings/species.py +++ b/src/sage/rings/species.py @@ -106,7 +106,6 @@ def __init__(self, parent, C): sage: C = ConjugacyClassesOfDirectlyIndecomposableSubgroups() sage: G = C(PermutationGroup([[(1,2),(3,4)],[(1,2),(5,6)]])) sage: TestSuite(G).run() - """ Element.__init__(self, parent) self._C = C @@ -263,7 +262,7 @@ def __classcall__(cls, parent, dis, domain_partition): Check that the domain is irrelevant:: sage: G = PermutationGroup([[("a", "b", "c", "d"), ("e", "f")]]) - sage: a = A(G, {0: "abcd", 1: "ef"}); a + sage: a = A(G, {0: "abcd", 1: "ef"}); a # random {((1,2,3,4)(5,6),): ({1, 2, 3, 4}, {5, 6})} sage: H = PermutationGroup([[(1,2,3,4), (5,6)]]) sage: a is A(H, {0: [1,2,3,4], 1: [5,6]}) @@ -422,7 +421,11 @@ def __init__(self, names): - ``names`` -- an iterable of ``k`` strings for the sorts of the species - TESTS:: + TESTS: + + We have to exclude `_test_graded_components`, because + :meth:`~sage.combinat.integer_vector.IntegerVectors.some_elements` + yields degrees that are too large:: sage: from sage.rings.species import AtomicSpecies sage: A1 = AtomicSpecies(["X"]) @@ -473,10 +476,10 @@ def _element_constructor_(self, G, pi=None): P_5(X) sage: G = PermutationGroup([[(1,2),(3,4,5,6)]]) - sage: A(G, {0: [1,2], 1: [3,4,5,6]}) + sage: A(G, {0: [1,2], 1: [3,4,5,6]}) # random {((1,2,3,4)(5,6),): ({5, 6}, {1, 2, 3, 4})} - sage: A(G, ([1,2], [3,4,5,6])) + sage: A(G, ([1,2], [3,4,5,6])) # random {((1,2,3,4)(5,6),): ({5, 6}, {1, 2, 3, 4})} TESTS:: @@ -761,7 +764,11 @@ def __init__(self, *args, **kwds): sage: M(G, {0: [5,6], 1: [1,2,3,4]}) {((1,2)(3,4),): ({}, {1, 2, 3, 4})}*E_2(X) - TESTS:: + TESTS: + + We have to exclude `_test_graded_components`, because + :meth:`~sage.combinat.integer_vector.IntegerVectors.some_elements` + yields degrees that are too large:: sage: M1 = MolecularSpecies("X") sage: TestSuite(M1).run(skip="_test_graded_components") @@ -949,6 +956,12 @@ def __init__(self, parent, x): sage: M = MolecularSpecies("X") sage: M(CyclicPermutationGroup(3)) # indirect doctest C_3 + + TESTS:: + + sage: X = M(CyclicPermutationGroup(3)) + sage: C3 = M(CyclicPermutationGroup(3)) + sage: TestSuite(X*C3).run() """ super().__init__(parent, x) @@ -1217,6 +1230,8 @@ class PolynomialSpeciesElement(CombinatorialFreeModule.Element): sage: E2 = P(SymmetricGroup(2)) sage: (E2*X + C3).homogeneous_degree() 3 + + sage: TestSuite(E2*X + C3).run() """ def is_constant(self): """ From ffd3fefa2d7e09e9d998120b422b4e1d5cf7c416 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Mon, 30 Sep 2024 12:22:21 +0530 Subject: [PATCH 230/537] Edited basis() method for all 3 cases --- src/sage/matroids/chow_ring.py | 83 +++++++++++++++++++--------------- 1 file changed, 47 insertions(+), 36 deletions(-) diff --git a/src/sage/matroids/chow_ring.py b/src/sage/matroids/chow_ring.py index 46edaacdf95..d907301ac6c 100644 --- a/src/sage/matroids/chow_ring.py +++ b/src/sage/matroids/chow_ring.py @@ -106,9 +106,9 @@ def _repr_(self): """ if self._augmented is True: if self._presentation == 'fy': - return "Augmented Chow ring of {} of Feitchner-Yuzvinsky presentation".format(self._matroid) + return "Augmented Chow ring of {} in Feitchner-Yuzvinsky presentation".format(self._matroid) elif self._presentation == 'atom-free': - return "Augmented Chow ring of {} of atom-free presentation".format(self._matroid) + return "Augmented Chow ring of {} in atom-free presentation".format(self._matroid) return "Chow ring of {}".format(self._matroid) def _latex_(self): @@ -190,18 +190,21 @@ def basis(self): for i in range(1, k): max_powers.append(ranks[subset[i]] - ranks[subset[i-1]]) for p in max_powers: - for combination in product(*(range(1, p))): #Generating combinations for all powers up to max_powers - expression = R.one() - for i in range(k): - expression *= flats_gen[subset[i]]**combination[i] - monomial_basis.append(expression) - if max_powers.index(p) == 0: #Generating combinations for all powers including first max_powers - expression *= flats_gen[subset[0]]**max_powers[0] + if p != 1 & p != 0: + for combination in product(*(range(1, p))): + #Generating combinations for all powers up to max_powers + expression = R.one() + for i in range(k): + expression *= flats_gen[subset[i]]**combination[i] monomial_basis.append(expression) + if max_powers.index(p) == 0: + #Generating combinations for all powers including first max_powers + expression *= flats_gen[subset[0]]**max_powers[0] + monomial_basis.append(expression) elif self._presentation == 'atom-free': subsets = [] - # Generate all subsets of the frozenset using combinations + # Generate all subsets of the frozenset using combinations for r in range(len(flats) + 1): # r is the size of the subset subsets.extend(list(subset) for subset in combinations(flats, r)) for subset in subsets: @@ -225,31 +228,37 @@ def basis(self): max_powers.append(ranks[subset[k-1]]) first_rank = ranks[subset[0]] + 1 last_rank = ranks[subset[k-1]] - for combination in product(*(range(1, p) for p in max_powers)): #Generating combinations for all powers from 1 to max_powers - expression = R.one() - if sum(combination) == first_rank: - for i in range(k): - expression *= flats_gen[subset[i]]**combination[i] - monomial_basis.append(expression) + for p in max_powers: + if p != 1 & p != 0: + for combination in product(*(range(1, p))): + #Generating combinations for all powers from 1 to max_powers + expression = R.one() + if sum(combination) == first_rank: + for i in range(k): + expression *= flats_gen[subset[i]]**combination[i] + monomial_basis.append(expression) max_powers.remove(last_rank) - for combination in product(*(range(1, p) for p in max_powers)): #Generating all combinations including 0 power and max_power for first flat - expression = R.one() - if sum(combination) == first_rank: - for i in range(len(combination)): - expression *= flats_gen[subset[i]]**combination[i] - monomial_basis.append(expression) - else: - expression *= flats_gen[subset[k-1]]**last_rank - if sum(combination) + last_rank == first_rank: - for i in range(k): - expression *= flats_gen[subset[i]]**combination[i] - monomial_basis.append(expression) + for p in max_powers: + if p != 1 & p != 0: + for combination in product(*(range(1, p))): + #Generating all combinations including 0 power and max_power for first flat + expression = R.one() + if sum(combination) == first_rank: + for i in range(len(combination)): + expression *= flats_gen[subset[i]]**combination[i] + monomial_basis.append(expression) + else: + expression *= flats_gen[subset[k-1]]**last_rank + if sum(combination) + last_rank == first_rank: + for i in range(k): + expression *= flats_gen[subset[i]]**combination[i] + monomial_basis.append(expression) else: if frozenset() in flats: flats.remove(frozenset()) #Non empty proper flats subsets = [] - # Generate all subsets of the frozenset using combinations + # Generate all subsets of the frozenset using combinations for r in range(len(flats) + 1): # r is the size of the subset subsets.extend(list(subset) for subset in combinations(flats, r)) for subset in subsets: @@ -273,11 +282,13 @@ def basis(self): max_powers.append(ranks[subset[i]]) else: max_powers.append(ranks[subset[i]] - ranks[subset[i-1]]) - for combination in product(*(range(1, p) for p in max_powers)): - expression = R.one() - for i in range(k): - expression *= flats_gen[subset[i]]**combination[i] - monomial_basis.append(expression) + for p in max_powers: + if p != 1 & p != 0: + for combination in product(*(range(1, p))): + expression = R.one() + for i in range(k): + expression *= flats_gen[subset[i]]**combination[i] + monomial_basis.append(expression) from sage.sets.family import Family @@ -349,7 +360,7 @@ def homogeneous_degree(self): Ba^2 2 sage: v = sum(ch.basis()); v Ba^2 + Ba*Babf - sage: v.homogeneous_degree() #error - basis() type is wrong! + sage: v.homogeneous_degree() Traceback (most recent call last): ... ValueError: element is not homogeneous @@ -357,7 +368,7 @@ def homogeneous_degree(self): TESTS:: sage: ch = matroids.Wheel(3).chow_ring(QQ, False) - sage: ch.zero().homogeneous_degree() #error! + sage: ch.zero().homogeneous_degree() Traceback (most recent call last): ... ValueError: the zero element does not have a well-defined degree From e2faf65ad572cb065b09607ca3c5089d23d423ca Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Mon, 30 Sep 2024 12:32:09 +0530 Subject: [PATCH 231/537] Added hyperlinks to ideals definitions in chow_ring.py --- src/sage/matroids/chow_ring.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/sage/matroids/chow_ring.py b/src/sage/matroids/chow_ring.py index d907301ac6c..7a69f289c7b 100644 --- a/src/sage/matroids/chow_ring.py +++ b/src/sage/matroids/chow_ring.py @@ -22,7 +22,8 @@ class ChowRing(QuotientRing_generic): A^*(M)_R := R[x_{F_1}, \ldots, x_{F_k}] / (Q_M + L_M), - where `(Q_M + L_M)` is the Chow ring ideal of matroid `M`. + where `(Q_M + L_M)` is the :class:`Chow ring ideal + ` of matroid `M`. The *augmented Chow ring of matroid* `M` in the Feitchner-Yuzvinsky presentation is the quotient ring @@ -31,8 +32,9 @@ class ChowRing(QuotientRing_generic): A(M)_R := R[y_{e_1}, \ldots, y_{e_n}, x_{F_1}, \ldots, x_{F_k}] / (I_M + J_M), - where `(I_M + J_M)` is the augmented Chow ring ideal of matroid `M` - of Feitchner-Yuzvinsky presentation. + where `(I_M + J_M)` is the :class:`augmented Chow ring ideal + ` of matroid `M` + in Feitchner-Yuzvinsky presentation. The *augmented Chow ring of atom-free presentation* is the quotient ring @@ -40,8 +42,9 @@ class ChowRing(QuotientRing_generic): A(M)_R := R[x_{F_1}, \ldots, x_{F_k}] / I_M^{af}, - where `I_M^{af}` is the augmented Chow ring ideal of matroid `M` in the - atom-free presentation. + where `I_M^{af}` is the :class:`augmented Chow ring ideal + ` + of matroid `M` in the atom-free presentation. .. SEEALSO:: From 8505fa7997e741b660a3e7a5e7ba2a25ec4e62ad Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Mon, 30 Sep 2024 13:09:43 +0530 Subject: [PATCH 232/537] Changed ChowRingIdeal_nonaug._gens_constructor() --- src/sage/matroids/chow_ring_ideal.py | 41 +++++++++++++++++++++------- 1 file changed, 31 insertions(+), 10 deletions(-) diff --git a/src/sage/matroids/chow_ring_ideal.py b/src/sage/matroids/chow_ring_ideal.py index 8785360f3b0..a8605323e17 100644 --- a/src/sage/matroids/chow_ring_ideal.py +++ b/src/sage/matroids/chow_ring_ideal.py @@ -76,8 +76,8 @@ class ChowRingIdeal_nonaug(ChowRingIdeal): INPUT: - - `M` -- matroid - - `R` -- commutative ring + - ``M`` -- matroid + - ``R`` -- commutative ring REFERENCES: @@ -162,18 +162,39 @@ def _gens_constructor(self, poly_ring): Aa - Af + Aace + Aadg - Acfg - Adf - Aef] """ E = list(self._matroid.groundset()) - flats = list(self._flats_generator.keys()) + R = self.ring() + flats = list(self._flats_generator) + flats.append(E) flats_containing = {x: [] for x in E} for i,F in enumerate(flats): for x in F: flats_containing[x].append(i) - gens = poly_ring.gens() - Q = [gens[i] * gens[i+j+1] for i,F in enumerate(flats) - for j,G in enumerate(flats[i+1:]) if not (F < G or G < F)] #Quadratic Generators - L = [sum(gens[i] for i in flats_containing[x]) - - sum(gens[i] for i in flats_containing[y]) - for j,x in enumerate(E) for y in E[j+1:]] #Linear Generators - return Q + L + lattice_flats = self._matroid.lattice_of_flats() + subsets = [] + I = [] + # Generate all subsets of flats using combinations + for r in range(len(flats) + 1): # r is the size of the subset + subsets.extend(list(subset) for subset in combinations(flats, r)) + for subset in subsets: + flag = True + sorted_list = sorted(subset, key=len) + for i in range (len(sorted_list)): #Checking whether the subset is a chain + if (i != 0) & (len(sorted_list[i]) == len(sorted_list[i-1])): + flag = False + break + if not flag: + term = R.one() + for el in subset: + self._flats_generator[el] + I.append(term) #Stanley-Reisner Ideal + atoms = lattice_flats.atoms() + J = [] + for a in atoms: + term = R.zero() + for F in flats_containing[a]: + term += self._flats_generator[F] + J.append(term) #Linear Generators + return I + J def _repr_(self): r""" From 9c928e2ce54262611194b06ffb6a6fa8ca0672fc Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Mon, 30 Sep 2024 13:19:34 +0530 Subject: [PATCH 233/537] Changed definition of the non aug ideal --- src/sage/matroids/chow_ring_ideal.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/sage/matroids/chow_ring_ideal.py b/src/sage/matroids/chow_ring_ideal.py index a8605323e17..957d27047c5 100644 --- a/src/sage/matroids/chow_ring_ideal.py +++ b/src/sage/matroids/chow_ring_ideal.py @@ -54,7 +54,7 @@ class ChowRingIdeal_nonaug(ChowRingIdeal): The Chow ring ideal of a matroid `M`. The *Chow ring ideal* for a matroid `M` is defined as the ideal - `(Q_M + L_M)` of the polynomial ring + `(I_M + J_M)` of the polynomial ring .. MATH:: @@ -63,16 +63,16 @@ class ChowRingIdeal_nonaug(ChowRingIdeal): where - `F_1, \ldots, F_k` are the non-empty flats of `M`, - - `Q_M` is the ideal generated by all `x_{F_i} x_{F_j}`, where - `F_i` and `F_j` are incomparable elements in the lattice of - flats, and - - `L_M` is the ideal generated by all linear forms + - `I_M` is the Stanley-Reisner ideal, i.e., it is generated + by products `x_{F_1}, \ldots, x_{F_t}` for subsets `{F_1}, \ldots, {F_t}` + of flats that are not chains, and + - `J_M` is the ideal generated by all linear forms .. MATH:: - \sum_{i_1 \in F} x_F - \sum_{i_2 \in F} x_F + \sum_{a \in F} x_F - for all `i_1 \neq i_2 \in E`. + for all atoms `a` in the lattice of flats. INPUT: @@ -117,14 +117,14 @@ def __init__(self, M, R): self._flats_generator = dict(zip(flats, gens)) MPolynomialIdeal.__init__(self, poly_ring, self._gens_constructor(poly_ring)) - def _gens_constructor(self, poly_ring): + def _gens_constructor(self): r""" Return the generators of ``self``. EXAMPLES:: sage: ch = matroids.catalog.NonFano().chow_ring(QQ, False) - sage: ch.defining_ideal()._gens_constructor(ch.defining_ideal().ring()) + sage: ch.defining_ideal()._gens_constructor() [Aa*Ab, Aa*Ac, Aa*Ad, Aa*Ae, Aa*Af, Aa*Ag, Aa*Abcd, Aa*Abeg, Aa*Acfg, Aa*Ade, Aa*Adf, Aa*Aef, Ab*Ac, Ab*Ad, Ab*Ae, Ab*Af, Ab*Ag, Ab*Aace, Ab*Aadg, Ab*Acfg, Ab*Ade, Ab*Adf, Ab*Aef, Ac*Ad, Ac*Ae, @@ -178,7 +178,7 @@ def _gens_constructor(self, poly_ring): for subset in subsets: flag = True sorted_list = sorted(subset, key=len) - for i in range (len(sorted_list)): #Checking whether the subset is a chain + for i in range (len(sorted_list)): #Checking whether the subset is not a chain if (i != 0) & (len(sorted_list[i]) == len(sorted_list[i-1])): flag = False break From 03355c9b7e30124d7c5a59e201b945330eafb859 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Mon, 30 Sep 2024 13:27:06 +0530 Subject: [PATCH 234/537] Edited documentation of ideals file --- src/sage/matroids/chow_ring_ideal.py | 52 +++++++++++----------------- 1 file changed, 21 insertions(+), 31 deletions(-) diff --git a/src/sage/matroids/chow_ring_ideal.py b/src/sage/matroids/chow_ring_ideal.py index 957d27047c5..6478a2f6fad 100644 --- a/src/sage/matroids/chow_ring_ideal.py +++ b/src/sage/matroids/chow_ring_ideal.py @@ -117,14 +117,14 @@ def __init__(self, M, R): self._flats_generator = dict(zip(flats, gens)) MPolynomialIdeal.__init__(self, poly_ring, self._gens_constructor(poly_ring)) - def _gens_constructor(self): + def _gens_constructor(self, poly_ring): r""" Return the generators of ``self``. EXAMPLES:: sage: ch = matroids.catalog.NonFano().chow_ring(QQ, False) - sage: ch.defining_ideal()._gens_constructor() + sage: ch.defining_ideal()._gens_constructor(ch.defining_ideal().ring()) [Aa*Ab, Aa*Ac, Aa*Ad, Aa*Ae, Aa*Af, Aa*Ag, Aa*Abcd, Aa*Abeg, Aa*Acfg, Aa*Ade, Aa*Adf, Aa*Aef, Ab*Ac, Ab*Ad, Ab*Ae, Ab*Af, Ab*Ag, Ab*Aace, Ab*Aadg, Ab*Acfg, Ab*Ade, Ab*Adf, Ab*Aef, Ac*Ad, Ac*Ae, @@ -162,7 +162,6 @@ def _gens_constructor(self): Aa - Af + Aace + Aadg - Acfg - Adf - Aef] """ E = list(self._matroid.groundset()) - R = self.ring() flats = list(self._flats_generator) flats.append(E) flats_containing = {x: [] for x in E} @@ -183,14 +182,14 @@ def _gens_constructor(self): flag = False break if not flag: - term = R.one() + term = poly_ring.one() for el in subset: self._flats_generator[el] I.append(term) #Stanley-Reisner Ideal atoms = lattice_flats.atoms() J = [] for a in atoms: - term = R.zero() + term = poly_ring.zero() for F in flats_containing[a]: term += self._flats_generator[F] J.append(term) #Linear Generators @@ -213,10 +212,8 @@ def _latex_(self): Return a LaTeX representation of ``self``. EXAMPLES:: - - sage: from sage.matroids.basis_matroid import BasisMatroid - sage: M1 = BasisMatroid(groundset='abcd', bases=['ab','ad', 'bc']) + sage: M1 = Matroid(groundset='abcd', bases=['ab','ad', 'bc']) sage: ch = M1.chow_ring(QQ, False) sage: ch.defining_ideal()._latex_() '\\left(\\mathit{Aac} \\mathit{Abd}, 0, @@ -533,30 +530,30 @@ class AugmentedChowRingIdeal_atom_free(ChowRingIdeal): The augmented Chow ring ideal in the atom-free presentation for a matroid `M` is defined as the ideal - `I_{af}(M)` of the polynomial ring: + `I_{af}(M)` of the polynomial ring: - ..MATH:: + .. MATH:: R[x_{F_1}, \ldots, x_{F_k}] - as + where - `F_1, \ldots, F_k` are the non-empty flats of `M`, - `I_{af}M` is the ideal generated by all quadratic forms `x_{F_i} x_{F_j}` where `F_i` and `F_j` are incomparable elements in the lattice of - flats, + flats, - ..MATH:: + .. MATH:: - x_F \sum_{i \in F'} x_{F'} + x_F \sum_{i \in F'} x_{F'} - for all `i \in E` and `i \notin F`, and + for all `i \in E` and `i \notin F`, and - ..MATH:: + ..MATH:: - \sum_{i \in F'} (x_{F'})^2 + \sum_{i \in F'} (x_{F'})^2 - for all `i \in E`. + for all `i \in E`. REFERENCES: @@ -564,8 +561,8 @@ class AugmentedChowRingIdeal_atom_free(ChowRingIdeal): INPUT: - - ``M`` -- a matroid - - ``R`` -- a commutative ring + - ``M`` -- matroid + - ``R`` -- commutative ring EXAMPLES: @@ -609,14 +606,11 @@ def __init__(self, M, R): def _gens_constructor(self, poly_ring): r""" - Return the generators of `self`. Takes in the ring of the augmented - Chow ring ideal as input. + Return the generators of ``self``. EXAMPLES:: - sage: from sage.matroids.graphic_matroid import GraphicMatroid - - sage: M1 = GraphicMatroid(graphs.CycleGraph(3)) + sage: M1 = Matroid(graphs.CycleGraph(3)) sage: ch = M1.chow_ring(QQ, True, 'atom-free') sage: ch.defining_ideal()._gens_constructor(ch.defining_ideal().ring()) [A0^2, A0^2, A1^2, A0*A1, A2^2, A0*A2, A0*A1, A0^2, A1^2, A0*A1, @@ -668,9 +662,7 @@ def _latex_(self): EXAMPLES:: - sage: from sage.matroids.basis_matroid import BasisMatroid - - sage: M1 = BasisMatroid(groundset='abcd', bases=['ab','ad', 'bc']) + sage: M1 = BMatroid(groundset='abcd', bases=['ab','ad', 'bc']) sage: ch = M1.chow_ring(QQ, True, 'atom-free') sage: ch.defining_ideal()._latex_() '\\left(\\mathit{Aac}^{2}, \\mathit{Abd}^{2}, @@ -697,9 +689,7 @@ def groebner_basis(self, algorithm='constructed', *args, **kwargs): EXAMPLES:: - sage: from sage.matroids.graphic_matroid import GraphicMatroid - - sage: M1 = GraphicMatroid(graphs.CycleGraph(3)) + sage: M1 = Matroid(graphs.CycleGraph(3)) sage: ch = M1.chow_ring(QQ, True, 'atom-free') sage: ch.defining_ideal().groebner_basis(algorithm='') [A0^2, A0*A1, A0*A2, A0*A1, A1^2, A1*A2, A0*A2, A1*A2, A2^2] From 81bed220deaae50603e701a886a7fbeb90fbb94d Mon Sep 17 00:00:00 2001 From: janmenjayap Date: Mon, 30 Sep 2024 22:33:07 +0530 Subject: [PATCH 235/537] updated the doc --- src/sage/graphs/matching_covered_graph.py | 82 ++++++++++++----------- 1 file changed, 43 insertions(+), 39 deletions(-) diff --git a/src/sage/graphs/matching_covered_graph.py b/src/sage/graphs/matching_covered_graph.py index ad0f722a368..44b9dab6550 100644 --- a/src/sage/graphs/matching_covered_graph.py +++ b/src/sage/graphs/matching_covered_graph.py @@ -76,18 +76,18 @@ class MatchingCoveredGraph(Graph): provided instance of ``Graph`` without providing any other information:: sage: G = MatchingCoveredGraph(graphs.PetersenGraph()) - SAGE: G - Matching covered Petersen graph: Graph on 10 vertices + sage: G + Matching covered petersen graph: graph on 10 vertices sage: G = graphs.StaircaseGraph(4) sage: H = MatchingCoveredGraph(G) sage: H - Matching covered staircase graph: Graph on 8 vertices + Matching covered staircase graph: graph on 8 vertices sage: H == G True sage: G = Graph({0: [1, 2, 3, 4], 1: [2, 5], 2: [5], 3: [4, 5], 4: [5]}) sage: H = MatchingCoveredGraph(G) sage: H - Matching covered graph: Graph on 6 vertices + Matching covered graph on 6 vertices sage: H == G True sage: # needs networkx @@ -95,13 +95,13 @@ class MatchingCoveredGraph(Graph): sage: G = Graph(networkx.complete_bipartite_graph(12, 12)) sage: H = MatchingCoveredGraph(G) sage: H - Matching covered graph: Graph on 12 vertices + Matching covered graph on 24 vertices sage: H == G True sage: G = Graph('E|fG', sparse=True) sage: H = MatchingCoveredGraph(G) sage: H - Matching covered graph: Graph on 6 vertices + Matching covered graph on 6 vertices sage: H == G True sage: # needs sage.modules @@ -172,14 +172,14 @@ class MatchingCoveredGraph(Graph): sage: M = P.matching() sage: G = MatchingCoveredGraph(P, matching=M) sage: G - Matching covered Petersen graph: Graph on 10 vertices + Matching covered petersen graph: graph on 10 vertices sage: P == G True - sage: G = graphs.TruncatedBiwheelGraph() + sage: G = graphs.TruncatedBiwheelGraph(14) sage: M = G.matching() sage: H = MatchingCoveredGraph(G, M) sage: H - Matching covered Truncated biwheel graph: Graph on 28 vertices + Matching covered truncated biwheel graph: graph on 28 vertices sage: H == G True @@ -219,7 +219,7 @@ class MatchingCoveredGraph(Graph): sage: G.allow_loops(True) Traceback (most recent call last): ... - ValueError: + ValueError: loops are not allowed in matching covered graphs sage: G.add_edge(0, 0) Traceback (most recent call last): ... @@ -229,28 +229,33 @@ class MatchingCoveredGraph(Graph): ... ValueError: loops are not allowed in matching covered graphs - Make sure that multiple edges are allowed for a matching covered graph by - default and can be modified for this not to be allowed:: + Make sure that multiple edges are allowed for a matching covered graph (by + default it is off and can be modified to be allowed):: sage: P = graphs.PetersenGraph() sage: G = MatchingCoveredGraph(P) + sage: G + Matching covered petersen graph: graph on 10 vertices sage: G.allows_multiple_edges() - True - sage: G.add_edge(next(P.edge_iterator())) - sage: G.allow_multiple_edges(False) - sage: G.allows_multple_edges() False + sage: G.size() + 15 + sage: G.allow_multiple_edges(True) + sage: G.allows_multiple_edges() + True sage: G.add_edge(next(P.edge_iterator())) - Traceback (most recent call last): - ... - ValueError: - sage: H = MatchingCoveredGraph(P, multiedges=False) - sage: G.allows_multple_edges() - False + sage: G.size() + 16 + sage: G + Matching covered petersen graph: multi-graph on 10 vertices + sage: H = MatchingCoveredGraph(P, multiedges=True) + sage: H.allows_multiple_edges() + True sage: H.add_edge(next(P.edge_iterator())) - Traceback (most recent call last): - ... - ValueError: + sage: H.size() + 16 + sage: H + Matching covered petersen graph: multi-graph on 10 vertices Providing with a connected nontrivial graph free of self-loops that is not matching covered:: @@ -320,10 +325,10 @@ class MatchingCoveredGraph(Graph): ValueError: input graph is not matching covered sage: # needs sage.modules sage: M = Matrix([(1, 1, 0, 0, 0, 0), - (0, 0, 1, 1, 0, 0), - (0, 0, 1, 0, 1, 0), - (1, 0, 0, 0, 0, 1), - (0, 1, 0, 1, 1, 1)]) + ....: (0, 0, 1, 1, 0, 0), + ....: (0, 0, 1, 0, 1, 0), + ....: (1, 0, 0, 0, 0, 1), + ....: (0, 1, 0, 1, 1, 1)]) sage: G = Graph(M) sage: H = MatchingCoveredGraph(G) Traceback (most recent call last): @@ -389,7 +394,6 @@ def __init__(self, data=None, matching=None, algorithm='Edmonds', # Hence, such method shall be turned off from types import MethodType self.allow_loops = MethodType(Graph.allow_loops, self) - if data is None: raise ValueError('the graph is trivial') @@ -435,10 +439,10 @@ def __repr__(self): sage: G = graphs.CompleteGraph(10) sage: H = MatchingCoveredGraph(G) sage: H - Matching covered complete graph: Graph on 10 vertices + Matching covered complete graph: graph on 10 vertices sage: G = MatchingCoveredGraph(BipartiteGraph(graphs.HexahedralGraph())) - sage: G - Matching covered bipartite hexahedron: graph on 8 vertices + sage: G # An object of the class MatchingCoveredGraph + Matching covered hexahedron: graph on 8 vertices In case the string representation of the (matching covered) graph contains the term 'matching covered', the representation remains as it @@ -447,16 +451,16 @@ def __repr__(self): sage: G = graphs.CompleteGraph(10) sage: H = MatchingCoveredGraph(G) sage: H - Matching covered complete graph: Graph on 10 vertices + Matching covered complete graph: graph on 10 vertices sage: J = MatchingCoveredGraph(H) sage: J - Matching covered complete graph: Graph on 10 vertices + Matching covered complete graph: graph on 10 vertices sage: G = BipartiteGraph(MatchingCoveredGraph(graphs.HexahedralGraph())) - sage: G - Bipartite matching covered hexahedron: graph on 8 vertices + sage: G # An object of the class BipartiteGraph + Bipartite hexahedron: graph on 8 vertices sage: H = MatchingCoveredGraph(G) - sage: H - Bipartite matching covered hexahedron: graph on 8 vertices + sage: H # An object of the class MatchingCoveredGraph + Matching covered hexahedron: graph on 8 vertices """ s = Graph._repr_(self).lower() if "matching covered" in s: From 5189a41e0af3a8891eeccf86b07d889ddd79b201 Mon Sep 17 00:00:00 2001 From: janmenjayap Date: Mon, 30 Sep 2024 22:36:23 +0530 Subject: [PATCH 236/537] rectified _upgrade_from_graph() --- src/sage/graphs/matching_covered_graph.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/sage/graphs/matching_covered_graph.py b/src/sage/graphs/matching_covered_graph.py index 44b9dab6550..0e41beb9ce9 100644 --- a/src/sage/graphs/matching_covered_graph.py +++ b/src/sage/graphs/matching_covered_graph.py @@ -400,9 +400,12 @@ def __init__(self, data=None, matching=None, algorithm='Edmonds', elif isinstance(data, MatchingCoveredGraph): Graph.__init__(self, data, *args, **kwds) - else: + elif isinstance(data, Graph): + Graph.__init__(self, data, *args, **kwds) self._upgrade_from_graph(matching, algorithm, solver, verbose, integrality_tolerance) + else: + raise ValueError('input data is of unknown type') del self.allow_loops self.allow_multiple_edges(True) @@ -417,9 +420,9 @@ def _upgrade_from_graph(self, matching=None, algorithm='Edmonds', """ try: coNP_certificate = False - check, _ = self.is_matching_covered(matching, algorithm, - coNP_certificate, solver, - verbose, integrality_tolerance) + check = Graph.is_matching_covered(self, matching, algorithm, + coNP_certificate, solver, + verbose, integrality_tolerance) if not check: raise ValueError("input graph is not matching covered") From 71ac39a17ebc17391d2f375bf6288feb09c5c4fc Mon Sep 17 00:00:00 2001 From: janmenjayap Date: Mon, 30 Sep 2024 22:38:21 +0530 Subject: [PATCH 237/537] overwrote allow_loops() --- src/sage/graphs/matching_covered_graph.py | 49 ++++++++++++++++++----- 1 file changed, 39 insertions(+), 10 deletions(-) diff --git a/src/sage/graphs/matching_covered_graph.py b/src/sage/graphs/matching_covered_graph.py index 0e41beb9ce9..a6229a6d093 100644 --- a/src/sage/graphs/matching_covered_graph.py +++ b/src/sage/graphs/matching_covered_graph.py @@ -386,14 +386,10 @@ def __init__(self, data=None, matching=None, algorithm='Edmonds', kwds = {'loops': False} else: if 'loops' in kwds and kwds['loops']: - raise ValueError('loops are not allowed in a matching \ - covered graph') + raise ValueError('loops are not allowed in matching ' + 'covered graphs') kwds['loops'] = False - # Note that self-loops are now allowed in a matching covered graph. - # Hence, such method shall be turned off - from types import MethodType - self.allow_loops = MethodType(Graph.allow_loops, self) if data is None: raise ValueError('the graph is trivial') @@ -407,9 +403,6 @@ def __init__(self, data=None, matching=None, algorithm='Edmonds', else: raise ValueError('input data is of unknown type') - del self.allow_loops - self.allow_multiple_edges(True) - def _upgrade_from_graph(self, matching=None, algorithm='Edmonds', solver=None, verbose=0, integrality_tolerance=0.001): @@ -468,4 +461,40 @@ def __repr__(self): s = Graph._repr_(self).lower() if "matching covered" in s: return s.capitalize() - return "".join(["Matching covered ", s]) \ No newline at end of file + return "".join(["Matching covered ", s]) + + def allow_loops(self, new, check=True): + """ + Change whether loops are allowed in (matching covered) graphs + + .. NOTE:: + + This method overwrites the + :meth:`~sage.graphs.generic_graph.GenericGraph.allow_loops` method + to ensure that loops are forbidden in :class:`~BipartiteGraph`. + + INPUT: + + - ``new`` -- boolean + + - ``check`` -- boolean (default: ``True``); whether to remove existing + loops from the graph when the new status is ``False``. It is an + argument in + :meth:`~sage.graphs.generic_graph.GenericGraph.allow_loops` method + and is not used in this overwritten one. + + EXAMPLES: + + Petersen graph is matching covered:: + + sage: P = graphs.PetersenGraph() + sage: P.is_matching_covered() + True + sage: G = MatchingCoveredGraph(P) + sage: G.allow_loops(True) + Traceback (most recent call last): + ... + ValueError: loops are not allowed in matching covered graphs + """ + if new is True: + raise ValueError('loops are not allowed in matching covered graphs') \ No newline at end of file From 82d918c31f391b78ff8355909a32a30781ad9d92 Mon Sep 17 00:00:00 2001 From: janmenjayap Date: Mon, 30 Sep 2024 22:40:54 +0530 Subject: [PATCH 238/537] updated a method description --- src/sage/graphs/matching_covered_graph.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/graphs/matching_covered_graph.py b/src/sage/graphs/matching_covered_graph.py index a6229a6d093..4ce588be3bc 100644 --- a/src/sage/graphs/matching_covered_graph.py +++ b/src/sage/graphs/matching_covered_graph.py @@ -407,7 +407,7 @@ def _upgrade_from_graph(self, matching=None, algorithm='Edmonds', solver=None, verbose=0, integrality_tolerance=0.001): """ - Upgrade the given graph to an object of matching covered graph if eligible + Upgrade the given graph to a matching covered graph if eligible See documentation ``MatchingCoveredGraph?`` for detailed information. """ From b164e17a81f42b1d8a90be23dd478b7203bc0ca2 Mon Sep 17 00:00:00 2001 From: janmenjayap Date: Mon, 30 Sep 2024 22:51:15 +0530 Subject: [PATCH 239/537] added a test case for disconnected graphs --- src/sage/graphs/matching_covered_graph.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/sage/graphs/matching_covered_graph.py b/src/sage/graphs/matching_covered_graph.py index 4ce588be3bc..703323750e7 100644 --- a/src/sage/graphs/matching_covered_graph.py +++ b/src/sage/graphs/matching_covered_graph.py @@ -208,7 +208,17 @@ class MatchingCoveredGraph(Graph): Providing with a graph that is not connected:: - sage: + sage: cycle1 = graphs.CycleGraph(4) + sage: cycle2 = graphs.CycleGraph(6) + sage: cycle2.relabel(lambda v: v + 4) + sage: G = Graph() + sage: G.add_edges(cycle1.edges() + cycle2.edges()) + sage: len(G.connected_components(sort=False)) + 2 + sage: H = MatchingCoveredGraph(G) + Traceback (most recent call last): + ... + ValueError: the graph is not connected Make sure that self-loops are not allowed for a matching covered graph:: From 2efb6868fcc1b022b1e1c00ca4506f067e0e1049 Mon Sep 17 00:00:00 2001 From: janmenjayap Date: Mon, 30 Sep 2024 22:52:50 +0530 Subject: [PATCH 240/537] added a test case for unknown data type --- src/sage/graphs/matching_covered_graph.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/sage/graphs/matching_covered_graph.py b/src/sage/graphs/matching_covered_graph.py index 703323750e7..a340f0b0500 100644 --- a/src/sage/graphs/matching_covered_graph.py +++ b/src/sage/graphs/matching_covered_graph.py @@ -381,6 +381,18 @@ class MatchingCoveredGraph(Graph): Traceback (most recent call last): ... ValueError: the input is not a perfect matching of the graph + + Note that data shall be one of empty or ``None`` or an instance of + ``Graph`` or an instance of ``MatchingCoveredGraph``. Otherwise a + :class:`ValueError` is returned:: + + sage: D = digraphs.Complete(10) + sage: D + Complete digraph: Digraph on 10 vertices + sage: G = MatchingCoveredGraph(D) + Traceback (most recent call last): + ... + ValueError: input data is of unknown type """ def __init__(self, data=None, matching=None, algorithm='Edmonds', From c6db6fcec4b171880a8c13b957bf56a10491712f Mon Sep 17 00:00:00 2001 From: janmenjayap Date: Mon, 30 Sep 2024 22:55:29 +0530 Subject: [PATCH 241/537] restored matching.py --- src/sage/graphs/matching.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/graphs/matching.py b/src/sage/graphs/matching.py index d76317dc8e0..457ccc16a75 100644 --- a/src/sage/graphs/matching.py +++ b/src/sage/graphs/matching.py @@ -695,7 +695,7 @@ def is_factor_critical(G, matching=None, algorithm='Edmonds', solver=None, verbo def is_matching_covered(G, matching=None, algorithm='Edmonds', coNP_certificate=False, - solver=None, verbose=0, integrality_tolerance=0.001): + solver=None, verbose=0, *, integrality_tolerance=0.001): r""" Check if the graph is matching covered. From d65de1ec26e9b7a21833d564df706d4531a49d2b Mon Sep 17 00:00:00 2001 From: janmenjayap Date: Tue, 1 Oct 2024 08:32:02 +0530 Subject: [PATCH 242/537] removed * as functional argument in matching.py --- src/sage/graphs/matching.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/sage/graphs/matching.py b/src/sage/graphs/matching.py index 457ccc16a75..ff8a5ab3be0 100644 --- a/src/sage/graphs/matching.py +++ b/src/sage/graphs/matching.py @@ -53,7 +53,7 @@ def has_perfect_matching(G, algorithm='Edmonds', solver=None, verbose=0, - *, integrality_tolerance=1e-3): + integrality_tolerance=1e-3): r""" Return whether the graph has a perfect matching @@ -160,7 +160,7 @@ def has_perfect_matching(G, algorithm='Edmonds', solver=None, verbose=0, def is_bicritical(G, matching=None, algorithm='Edmonds', coNP_certificate=False, - solver=None, verbose=0, *, integrality_tolerance=0.001): + solver=None, verbose=0, integrality_tolerance=0.001): r""" Check if the graph is bicritical @@ -490,7 +490,7 @@ def is_bicritical(G, matching=None, algorithm='Edmonds', coNP_certificate=False, def is_factor_critical(G, matching=None, algorithm='Edmonds', solver=None, verbose=0, - *, integrality_tolerance=0.001): + integrality_tolerance=0.001): r""" Check whether the graph is factor-critical. @@ -695,7 +695,7 @@ def is_factor_critical(G, matching=None, algorithm='Edmonds', solver=None, verbo def is_matching_covered(G, matching=None, algorithm='Edmonds', coNP_certificate=False, - solver=None, verbose=0, *, integrality_tolerance=0.001): + solver=None, verbose=0, integrality_tolerance=0.001): r""" Check if the graph is matching covered. @@ -1089,7 +1089,7 @@ def dfs(J, v, visited, orientation): def matching(G, value_only=False, algorithm='Edmonds', use_edge_labels=False, solver=None, verbose=0, - *, integrality_tolerance=1e-3): + integrality_tolerance=1e-3): r""" Return a maximum weighted matching of the graph represented by the list of its edges From 4c0583e31d60361d89537317648ea36e42ee9699 Mon Sep 17 00:00:00 2001 From: janmenjayap Date: Wed, 2 Oct 2024 08:18:06 +0530 Subject: [PATCH 243/537] corrected the problem due to * --- src/sage/graphs/matching.py | 10 +++++----- src/sage/graphs/matching_covered_graph.py | 14 ++++++++++---- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/src/sage/graphs/matching.py b/src/sage/graphs/matching.py index ff8a5ab3be0..457ccc16a75 100644 --- a/src/sage/graphs/matching.py +++ b/src/sage/graphs/matching.py @@ -53,7 +53,7 @@ def has_perfect_matching(G, algorithm='Edmonds', solver=None, verbose=0, - integrality_tolerance=1e-3): + *, integrality_tolerance=1e-3): r""" Return whether the graph has a perfect matching @@ -160,7 +160,7 @@ def has_perfect_matching(G, algorithm='Edmonds', solver=None, verbose=0, def is_bicritical(G, matching=None, algorithm='Edmonds', coNP_certificate=False, - solver=None, verbose=0, integrality_tolerance=0.001): + solver=None, verbose=0, *, integrality_tolerance=0.001): r""" Check if the graph is bicritical @@ -490,7 +490,7 @@ def is_bicritical(G, matching=None, algorithm='Edmonds', coNP_certificate=False, def is_factor_critical(G, matching=None, algorithm='Edmonds', solver=None, verbose=0, - integrality_tolerance=0.001): + *, integrality_tolerance=0.001): r""" Check whether the graph is factor-critical. @@ -695,7 +695,7 @@ def is_factor_critical(G, matching=None, algorithm='Edmonds', solver=None, verbo def is_matching_covered(G, matching=None, algorithm='Edmonds', coNP_certificate=False, - solver=None, verbose=0, integrality_tolerance=0.001): + solver=None, verbose=0, *, integrality_tolerance=0.001): r""" Check if the graph is matching covered. @@ -1089,7 +1089,7 @@ def dfs(J, v, visited, orientation): def matching(G, value_only=False, algorithm='Edmonds', use_edge_labels=False, solver=None, verbose=0, - integrality_tolerance=1e-3): + *, integrality_tolerance=1e-3): r""" Return a maximum weighted matching of the graph represented by the list of its edges diff --git a/src/sage/graphs/matching_covered_graph.py b/src/sage/graphs/matching_covered_graph.py index a340f0b0500..30f848121bb 100644 --- a/src/sage/graphs/matching_covered_graph.py +++ b/src/sage/graphs/matching_covered_graph.py @@ -420,7 +420,9 @@ def __init__(self, data=None, matching=None, algorithm='Edmonds', elif isinstance(data, Graph): Graph.__init__(self, data, *args, **kwds) - self._upgrade_from_graph(matching, algorithm, solver, verbose, + self._upgrade_from_graph(matching=matching, algorithm=algorithm, + solver=solver, verbose=verbose, + integrality_tolerance= integrality_tolerance) else: raise ValueError('input data is of unknown type') @@ -435,9 +437,13 @@ def _upgrade_from_graph(self, matching=None, algorithm='Edmonds', """ try: coNP_certificate = False - check = Graph.is_matching_covered(self, matching, algorithm, - coNP_certificate, solver, - verbose, integrality_tolerance) + check = Graph.is_matching_covered(G=self, matching=matching, + algorithm=algorithm, + coNP_certificate= + coNP_certificate, + solver=solver, verbose=verbose, + integrality_tolerance= + integrality_tolerance) if not check: raise ValueError("input graph is not matching covered") From cc18b20866c06bdffdf6ddbcb34cd2a3f9a4dc84 Mon Sep 17 00:00:00 2001 From: janmenjayap Date: Wed, 2 Oct 2024 08:56:45 +0530 Subject: [PATCH 244/537] removed spaces around keyword / parameter equals --- src/sage/graphs/matching_covered_graph.py | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/sage/graphs/matching_covered_graph.py b/src/sage/graphs/matching_covered_graph.py index 30f848121bb..02005af24eb 100644 --- a/src/sage/graphs/matching_covered_graph.py +++ b/src/sage/graphs/matching_covered_graph.py @@ -422,8 +422,7 @@ def __init__(self, data=None, matching=None, algorithm='Edmonds', Graph.__init__(self, data, *args, **kwds) self._upgrade_from_graph(matching=matching, algorithm=algorithm, solver=solver, verbose=verbose, - integrality_tolerance= - integrality_tolerance) + integrality_tolerance=integrality_tolerance) else: raise ValueError('input data is of unknown type') @@ -439,11 +438,9 @@ def _upgrade_from_graph(self, matching=None, algorithm='Edmonds', coNP_certificate = False check = Graph.is_matching_covered(G=self, matching=matching, algorithm=algorithm, - coNP_certificate= - coNP_certificate, + coNP_certificate=coNP_certificate, solver=solver, verbose=verbose, - integrality_tolerance= - integrality_tolerance) + integrality_tolerance=integrality_tolerance) if not check: raise ValueError("input graph is not matching covered") From 3c51d8a6e216f4df00d0a4147bdf5d847ff1a498 Mon Sep 17 00:00:00 2001 From: janmenjayap Date: Wed, 2 Oct 2024 09:22:34 +0530 Subject: [PATCH 245/537] corrected the test with igraph --- src/sage/graphs/matching_covered_graph.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/sage/graphs/matching_covered_graph.py b/src/sage/graphs/matching_covered_graph.py index 02005af24eb..3955b8dba72 100644 --- a/src/sage/graphs/matching_covered_graph.py +++ b/src/sage/graphs/matching_covered_graph.py @@ -160,8 +160,9 @@ class MatchingCoveredGraph(Graph): sage: H = MatchingCoveredGraph(G) sage: H == G True - sage: import igraph # optional - python_igraph - sage: G = Graph(igraph.Graph([(0, 1), (0, 3), (1, 2), (2, 3)])) # optional - python_igraph + sage: # optional - python_igraph + sage: import igraph + sage: G = Graph(igraph.Graph([(0, 1), (0, 3), (1, 2), (2, 3)])) sage: H = MatchingCoveredGraph(G) sage: H Matching covered graph on 4 vertices @@ -353,8 +354,9 @@ class MatchingCoveredGraph(Graph): Traceback (most recent call last): ... ValueError: input graph is not matching covered - sage: import igraph # optional - python_igraph - sage: G = Graph(igraph.Graph([(0, 1), (0, 2), (0, 3), (1, 2), (2, 3)])) # optional - python_igraph + sage: # optional - python_igraph + sage: import igraph + sage: G = Graph(igraph.Graph([(0, 1), (0, 2), (0, 3), (1, 2), (2, 3)])) sage: H = MatchingCoveredGraph(G) Traceback (most recent call last): ... From dfe569a3a74f106d953e5e0f75dbdb6e731f2fa3 Mon Sep 17 00:00:00 2001 From: janmenjayap Date: Wed, 2 Oct 2024 10:56:46 +0530 Subject: [PATCH 246/537] moved matching_covered_graph to Graph objects and methods --- src/doc/en/reference/graphs/index.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/en/reference/graphs/index.rst b/src/doc/en/reference/graphs/index.rst index bb8594634b1..91b0f2d3cd7 100644 --- a/src/doc/en/reference/graphs/index.rst +++ b/src/doc/en/reference/graphs/index.rst @@ -14,6 +14,7 @@ Graph objects and methods sage/graphs/graph sage/graphs/digraph sage/graphs/bipartite_graph + sage/graphs/matching_covered_graph sage/graphs/views Constructors and databases @@ -85,7 +86,6 @@ Libraries of algorithms sage/graphs/pq_trees sage/graphs/trees sage/graphs/matching - sage/graphs/matching_covered_graph sage/graphs/matchpoly sage/graphs/genus sage/graphs/lovasz_theta From 5ecd5002c50e293631860ef2b6ef23bfdc088c78 Mon Sep 17 00:00:00 2001 From: janmenjayap Date: Wed, 2 Oct 2024 11:25:51 +0530 Subject: [PATCH 247/537] updated the doc --- src/sage/graphs/matching_covered_graph.py | 33 ++++++++++++++--------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/src/sage/graphs/matching_covered_graph.py b/src/sage/graphs/matching_covered_graph.py index 3955b8dba72..6115a367233 100644 --- a/src/sage/graphs/matching_covered_graph.py +++ b/src/sage/graphs/matching_covered_graph.py @@ -1,7 +1,8 @@ r""" Matching covered graphs -This module implements functions and operations pertaining to matching covered graphs. +This module implements functions and operations pertaining to matching covered +graphs. A *matching* in a graph is a set of pairwise nonadjacent links (nonloop edges). In other words, a matching in a graph is the edge set of an @@ -33,7 +34,8 @@ class MatchingCoveredGraph(Graph): - ``data`` -- can be any of the following: - - Empty or ``None`` (throws a :class:`ValueError` as the graph must be nontrival). + - Empty or ``None`` (throws a :class:`ValueError` as the graph must be + nontrival). - An arbitrary graph. @@ -84,7 +86,8 @@ class MatchingCoveredGraph(Graph): Matching covered staircase graph: graph on 8 vertices sage: H == G True - sage: G = Graph({0: [1, 2, 3, 4], 1: [2, 5], 2: [5], 3: [4, 5], 4: [5]}) + sage: G = Graph({0: [1, 2, 3, 4], 1: [2, 5], + ....: 2: [5], 3: [4, 5], 4: [5]}) sage: H = MatchingCoveredGraph(G) sage: H Matching covered graph on 6 vertices @@ -156,7 +159,8 @@ class MatchingCoveredGraph(Graph): sage: H = MatchingCoveredGraph(G) sage: H == G True - sage: G = Graph([(0, 1), (0, 3), (0, 4), (1, 2), (1, 5), (2, 3), (2, 6), (3, 7), (4, 5), (4, 7), (5, 6), (6, 7)]) + sage: G = Graph([(0, 1), (0, 3), (0, 4), (1, 2), (1, 5), (2, 3), + ....: (2, 6), (3, 7), (4, 5), (4, 7), (5, 6), (6, 7)]) sage: H = MatchingCoveredGraph(G) sage: H == G True @@ -410,8 +414,8 @@ def __init__(self, data=None, matching=None, algorithm='Edmonds', kwds = {'loops': False} else: if 'loops' in kwds and kwds['loops']: - raise ValueError('loops are not allowed in matching ' - 'covered graphs') + raise ValueError('loops are not allowed in ' + 'matching covered graphs') kwds['loops'] = False if data is None: @@ -463,8 +467,9 @@ def __repr__(self): sage: H = MatchingCoveredGraph(G) sage: H Matching covered complete graph: graph on 10 vertices - sage: G = MatchingCoveredGraph(BipartiteGraph(graphs.HexahedralGraph())) - sage: G # An object of the class MatchingCoveredGraph + sage: G = graphs.HexahedralGraph() + sage: H = MatchingCoveredGraph(BipartiteGraph(G)) + sage: H # An object of the class MatchingCoveredGraph Matching covered hexahedron: graph on 8 vertices In case the string representation of the (matching covered) graph @@ -478,11 +483,12 @@ def __repr__(self): sage: J = MatchingCoveredGraph(H) sage: J Matching covered complete graph: graph on 10 vertices - sage: G = BipartiteGraph(MatchingCoveredGraph(graphs.HexahedralGraph())) - sage: G # An object of the class BipartiteGraph + sage: G = graphs.HexahedralGraph() + sage: H = BipartiteGraph(MatchingCoveredGraph(G)) + sage: H # An object of the class BipartiteGraph Bipartite hexahedron: graph on 8 vertices - sage: H = MatchingCoveredGraph(G) - sage: H # An object of the class MatchingCoveredGraph + sage: J = MatchingCoveredGraph(H) + sage: J # An object of the class MatchingCoveredGraph Matching covered hexahedron: graph on 8 vertices """ s = Graph._repr_(self).lower() @@ -524,4 +530,5 @@ def allow_loops(self, new, check=True): ValueError: loops are not allowed in matching covered graphs """ if new is True: - raise ValueError('loops are not allowed in matching covered graphs') \ No newline at end of file + raise ValueError('loops are not allowed in ' + 'matching covered graphs') \ No newline at end of file From 9220a9d74e0b22feefe02fa54822c28d2223ba2b Mon Sep 17 00:00:00 2001 From: janmenjayap Date: Wed, 2 Oct 2024 21:51:13 +0530 Subject: [PATCH 248/537] updated the documentation --- src/sage/graphs/matching.py | 19 +++++------- src/sage/graphs/matching_covered_graph.py | 38 ++++++++++------------- 2 files changed, 25 insertions(+), 32 deletions(-) diff --git a/src/sage/graphs/matching.py b/src/sage/graphs/matching.py index 457ccc16a75..2c129dbdde2 100644 --- a/src/sage/graphs/matching.py +++ b/src/sage/graphs/matching.py @@ -55,7 +55,7 @@ def has_perfect_matching(G, algorithm='Edmonds', solver=None, verbose=0, *, integrality_tolerance=1e-3): r""" - Return whether the graph has a perfect matching + Return whether the graph has a perfect matching. INPUT: @@ -162,7 +162,7 @@ def has_perfect_matching(G, algorithm='Edmonds', solver=None, verbose=0, def is_bicritical(G, matching=None, algorithm='Edmonds', coNP_certificate=False, solver=None, verbose=0, *, integrality_tolerance=0.001): r""" - Check if the graph is bicritical + Check if the graph is bicritical. A nontrivial graph `G` is *bicritical* if `G - u - v` has a perfect matching for any two distinct vertices `u` and `v` of `G`. Bicritical @@ -270,12 +270,9 @@ def is_bicritical(G, matching=None, algorithm='Edmonds', coNP_certificate=False, A graph (of order more than two) with more that one component is not bicritical:: - sage: cycle1 = graphs.CycleGraph(4) - sage: cycle2 = graphs.CycleGraph(6) - sage: cycle2.relabel(lambda v: v + 4) - sage: G = Graph() - sage: G.add_edges(cycle1.edges() + cycle2.edges()) - sage: len(G.connected_components(sort=False)) + sage: G = graphs.CycleGraph(4) + sage: G += graphs.CycleGraph(6) + sage: G.connected_components_number() 2 sage: G.is_bicritical() False @@ -1092,7 +1089,7 @@ def matching(G, value_only=False, algorithm='Edmonds', *, integrality_tolerance=1e-3): r""" Return a maximum weighted matching of the graph represented by the list - of its edges + of its edges. For more information, see the :wikipedia:`Matching_(graph_theory)`. @@ -1291,7 +1288,7 @@ def weight(x): def perfect_matchings(G, labels=False): r""" - Return an iterator over all perfect matchings of the graph + Return an iterator over all perfect matchings of the graph. ALGORITHM: @@ -1404,7 +1401,7 @@ def rec(G): def M_alternating_even_mark(G, vertex, matching): r""" Return the vertices reachable from ``vertex`` via an even alternating path - starting with a non-matching edge + starting with a non-matching edge. This method implements the algorithm proposed in [LR2004]_. Note that the complexity of the algorithm is linear in number of edges. diff --git a/src/sage/graphs/matching_covered_graph.py b/src/sage/graphs/matching_covered_graph.py index 6115a367233..945db28d494 100644 --- a/src/sage/graphs/matching_covered_graph.py +++ b/src/sage/graphs/matching_covered_graph.py @@ -93,6 +93,7 @@ class MatchingCoveredGraph(Graph): Matching covered graph on 6 vertices sage: H == G True + sage: # needs networkx sage: import networkx sage: G = Graph(networkx.complete_bipartite_graph(12, 12)) @@ -107,6 +108,7 @@ class MatchingCoveredGraph(Graph): Matching covered graph on 6 vertices sage: H == G True + sage: # needs sage.modules sage: M = Matrix([(0,1,0,0,1,1,0,0,0,0), ....: (1,0,1,0,0,0,1,0,0,0), @@ -133,6 +135,7 @@ class MatchingCoveredGraph(Graph): sage: H = MatchingCoveredGraph(G) sage: H == G True + sage: # needs sage.modules sage: M = Matrix([(-1, 0, 0, 0, 1, 0, 0, 0, 0, 0,-1, 0, 0, 0, 0), ....: ( 1,-1, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1, 0, 0, 0), @@ -164,6 +167,7 @@ class MatchingCoveredGraph(Graph): sage: H = MatchingCoveredGraph(G) sage: H == G True + sage: # optional - python_igraph sage: import igraph sage: G = Graph(igraph.Graph([(0, 1), (0, 3), (1, 2), (2, 3)])) @@ -197,28 +201,16 @@ class MatchingCoveredGraph(Graph): Traceback (most recent call last): ... ValueError: the graph is trivial - sage: G = Graph(None) - sage: H = MatchingCoveredGraph(G) - Traceback (most recent call last): - ... - ValueError: the graph is trivial sage: G = MatchingCoveredGraph() Traceback (most recent call last): ... ValueError: the graph is trivial - sage: G = MatchingCoveredGraph(None) - Traceback (most recent call last): - ... - ValueError: the graph is trivial Providing with a graph that is not connected:: - sage: cycle1 = graphs.CycleGraph(4) - sage: cycle2 = graphs.CycleGraph(6) - sage: cycle2.relabel(lambda v: v + 4) - sage: G = Graph() - sage: G.add_edges(cycle1.edges() + cycle2.edges()) - sage: len(G.connected_components(sort=False)) + sage: G = graphs.CycleGraph(4) + sage: G += graphs.CycleGraph(6) + sage: G.connected_components_number() 2 sage: H = MatchingCoveredGraph(G) Traceback (most recent call last): @@ -287,6 +279,7 @@ class MatchingCoveredGraph(Graph): Traceback (most recent call last): ... ValueError: input graph is not matching covered + sage: # needs networkx sage: import networkx sage: G = Graph(networkx.complete_bipartite_graph(2, 12)) @@ -299,6 +292,7 @@ class MatchingCoveredGraph(Graph): Traceback (most recent call last): ... ValueError: input graph is not matching covered + sage: # needs sage.modules sage: M = Matrix([(0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0), ....: (1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), @@ -338,6 +332,7 @@ class MatchingCoveredGraph(Graph): Traceback (most recent call last): ... ValueError: input graph is not matching covered + sage: # needs sage.modules sage: M = Matrix([(1, 1, 0, 0, 0, 0), ....: (0, 0, 1, 1, 0, 0), @@ -358,6 +353,7 @@ class MatchingCoveredGraph(Graph): Traceback (most recent call last): ... ValueError: input graph is not matching covered + sage: # optional - python_igraph sage: import igraph sage: G = Graph(igraph.Graph([(0, 1), (0, 2), (0, 3), (1, 2), (2, 3)])) @@ -406,7 +402,7 @@ def __init__(self, data=None, matching=None, algorithm='Edmonds', *args, **kwds): r""" Create a matching covered graph, that is a connected nontrivial graph - wherein each edge participates in some perfect matching + wherein each edge participates in some perfect matching. See documentation ``MatchingCoveredGraph?`` for detailed information. """ @@ -435,8 +431,8 @@ def __init__(self, data=None, matching=None, algorithm='Edmonds', def _upgrade_from_graph(self, matching=None, algorithm='Edmonds', solver=None, verbose=0, integrality_tolerance=0.001): - """ - Upgrade the given graph to a matching covered graph if eligible + r""" + Upgrade the given graph to a matching covered graph if eligible. See documentation ``MatchingCoveredGraph?`` for detailed information. """ @@ -456,7 +452,7 @@ def _upgrade_from_graph(self, matching=None, algorithm='Edmonds', def __repr__(self): r""" - Return a short string representation of the matching covered graph + Return a short string representation of the matching covered graph. EXAMPLES: @@ -497,8 +493,8 @@ def __repr__(self): return "".join(["Matching covered ", s]) def allow_loops(self, new, check=True): - """ - Change whether loops are allowed in (matching covered) graphs + r""" + Check whether loops are allowed in (matching covered) graphs. .. NOTE:: From 9b8ab7889a6e969463af366c470ea656f9febf67 Mon Sep 17 00:00:00 2001 From: janmenjayap Date: Wed, 2 Oct 2024 21:54:09 +0530 Subject: [PATCH 249/537] updated the code --- src/sage/graphs/matching_covered_graph.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/sage/graphs/matching_covered_graph.py b/src/sage/graphs/matching_covered_graph.py index 945db28d494..98de449b77b 100644 --- a/src/sage/graphs/matching_covered_graph.py +++ b/src/sage/graphs/matching_covered_graph.py @@ -425,8 +425,7 @@ def __init__(self, data=None, matching=None, algorithm='Edmonds', self._upgrade_from_graph(matching=matching, algorithm=algorithm, solver=solver, verbose=verbose, integrality_tolerance=integrality_tolerance) - else: - raise ValueError('input data is of unknown type') + raise ValueError('input data is of unknown type') def _upgrade_from_graph(self, matching=None, algorithm='Edmonds', solver=None, verbose=0, @@ -437,7 +436,6 @@ def _upgrade_from_graph(self, matching=None, algorithm='Edmonds', See documentation ``MatchingCoveredGraph?`` for detailed information. """ try: - coNP_certificate = False check = Graph.is_matching_covered(G=self, matching=matching, algorithm=algorithm, coNP_certificate=coNP_certificate, @@ -525,6 +523,6 @@ def allow_loops(self, new, check=True): ... ValueError: loops are not allowed in matching covered graphs """ - if new is True: + if new: raise ValueError('loops are not allowed in ' 'matching covered graphs') \ No newline at end of file From e283d1e22ffbdc7108ddadd94d8a5b98d0c3ec1c Mon Sep 17 00:00:00 2001 From: janmenjayap Date: Thu, 3 Oct 2024 00:31:03 +0530 Subject: [PATCH 250/537] updated the code --- src/sage/graphs/matching_covered_graph.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/sage/graphs/matching_covered_graph.py b/src/sage/graphs/matching_covered_graph.py index 98de449b77b..fb22608c30c 100644 --- a/src/sage/graphs/matching_covered_graph.py +++ b/src/sage/graphs/matching_covered_graph.py @@ -425,7 +425,8 @@ def __init__(self, data=None, matching=None, algorithm='Edmonds', self._upgrade_from_graph(matching=matching, algorithm=algorithm, solver=solver, verbose=verbose, integrality_tolerance=integrality_tolerance) - raise ValueError('input data is of unknown type') + else: + raise ValueError('input data is of unknown type') def _upgrade_from_graph(self, matching=None, algorithm='Edmonds', solver=None, verbose=0, @@ -438,7 +439,7 @@ def _upgrade_from_graph(self, matching=None, algorithm='Edmonds', try: check = Graph.is_matching_covered(G=self, matching=matching, algorithm=algorithm, - coNP_certificate=coNP_certificate, + coNP_certificate=False, solver=solver, verbose=verbose, integrality_tolerance=integrality_tolerance) From 629baa2558284ca12d21f745800e20e1bbf44cba Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Thu, 3 Oct 2024 10:24:35 +0530 Subject: [PATCH 251/537] Formatted doctests in chow_ring.py --- 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 7a69f289c7b..250fd427334 100644 --- a/src/sage/matroids/chow_ring.py +++ b/src/sage/matroids/chow_ring.py @@ -59,7 +59,7 @@ class ChowRing(QuotientRing_generic): - ``presentation`` -- string (default: ``None``); one of the following: * ``"fy"`` - the Feitchner-Yuzvinsky presentation - * ``"atom-free" - the atom-free presentation + * ``"atom-free"`` - the atom-free presentation REFERENCES: From cd3a3fcb17cf9045991a6a47783d8f90e2e4a600 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Thu, 3 Oct 2024 10:24:50 +0530 Subject: [PATCH 252/537] Formatted doctests in the ideals file --- src/sage/matroids/chow_ring_ideal.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/sage/matroids/chow_ring_ideal.py b/src/sage/matroids/chow_ring_ideal.py index 6478a2f6fad..bbba88b1261 100644 --- a/src/sage/matroids/chow_ring_ideal.py +++ b/src/sage/matroids/chow_ring_ideal.py @@ -351,7 +351,7 @@ class AugmentedChowRingIdeal_fy(ChowRingIdeal): - ``M`` -- matroid - ``R`` -- commutative ring - EXAMPLES:: + EXAMPLES: Augmented Chow ring ideal of Wheel matroid of rank 3:: @@ -488,7 +488,7 @@ def groebner_basis(self, algorithm='constructed', *args, **kwargs): True """ if algorithm == '': - gb = [] + gb = [] #Don't use flats. Get lattice of flats and use order_filter() E = list(self._matroid.groundset()) poly_ring = self.ring() for F in self._flats: @@ -498,10 +498,10 @@ def groebner_basis(self, algorithm='constructed', *args, **kwargs): for i in E: term = poly_ring.zero() term1 = poly_ring.zero() - for H in self._flats: - if i in H: + for H in self._flats: #Remove it somehow + if i in H: #WASTEFUL term += self._flats_generator[H] - if H > G: + if H > G: #WASTEFUL term1 += self._flats_generator[H] if term != poly_ring.zero(): gb.append(self._flats_generator[i] + term) #5.7 @@ -683,7 +683,7 @@ def _latex_(self): for g in self.gens()), latex(self.ring())) - def groebner_basis(self, algorithm='constructed', *args, **kwargs): + def groebner_basis(self, algorithm='constructed', *args, **kwargs): #Copy from fy presentation """ Returns the Groebner basis of `self`. From bdfded838582644600ed80a8dd9fb1110148f672 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Fri, 4 Oct 2024 13:22:21 +0530 Subject: [PATCH 253/537] Corrected doctest outputs --- src/sage/matroids/chow_ring_ideal.py | 337 +++++++++++++-------------- 1 file changed, 163 insertions(+), 174 deletions(-) diff --git a/src/sage/matroids/chow_ring_ideal.py b/src/sage/matroids/chow_ring_ideal.py index bbba88b1261..17945640495 100644 --- a/src/sage/matroids/chow_ring_ideal.py +++ b/src/sage/matroids/chow_ring_ideal.py @@ -10,12 +10,9 @@ from sage.matroids.utilities import cmp_elements_key from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing from sage.rings.polynomial.multi_polynomial_sequence import PolynomialSequence -from sage.misc.abstract_method import abstract_method -from itertools import combinations -from functools import reduce +from sage.combinat.posets.posets import Poset class ChowRingIdeal(MPolynomialIdeal): - @abstract_method def matroid(self): r""" Return the matroid of the given Chow ring ideal. @@ -40,11 +37,15 @@ def flats_generator(self): sage: ch = matroids.catalog.Fano().chow_ring(QQ, False) sage: ch.defining_ideal().flats_generator() {frozenset({'a'}): Aa, frozenset({'b'}): Ab, frozenset({'c'}): Ac, - frozenset({'d'}): Ad, frozenset({'e'}): Ae, frozenset({'f'}): Af, - frozenset({'g'}): Ag, frozenset({'b', 'a', 'f'}): Aabf, - frozenset({'c', 'e', 'a'}): Aace, frozenset({'d', 'g', 'a'}): Aadg, - frozenset({'c', 'b', 'd'}): Abcd, frozenset({'b', 'g', 'e'}): Abeg, - frozenset({'c', 'g', 'f'}): Acfg, frozenset({'d', 'e', 'f'}): Adef} + 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', 'f'}): Adef, + frozenset({'a', 'b', 'c', 'd', 'e', 'f', 'g'}): Aabcdefg} """ return dict(self._flats_generator) @@ -90,11 +91,11 @@ class ChowRingIdeal_nonaug(ChowRingIdeal): 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}}} + circuit-closures {3: {{0, 1, 2, 3, 4, 5}}} - non augmented sage: ch = matroids.catalog.Fano().chow_ring(QQ, False) sage: ch.defining_ideal() Chow ring ideal of Fano: Binary matroid of rank 3 on 7 elements, - type (3, 0) + type (3, 0) - non augmented """ def __init__(self, M, R): r""" @@ -106,7 +107,7 @@ def __init__(self, M, R): sage: TestSuite(I).run(skip="_test_category") """ self._matroid = M - flats = [X for i in range(1, self._matroid.rank()) + flats = [X for i in range(1, self._matroid.rank() + 1) 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: @@ -125,74 +126,127 @@ def _gens_constructor(self, poly_ring): sage: ch = matroids.catalog.NonFano().chow_ring(QQ, False) sage: ch.defining_ideal()._gens_constructor(ch.defining_ideal().ring()) - [Aa*Ab, Aa*Ac, Aa*Ad, Aa*Ae, Aa*Af, Aa*Ag, Aa*Abcd, Aa*Abeg, - Aa*Acfg, Aa*Ade, Aa*Adf, Aa*Aef, Ab*Ac, Ab*Ad, Ab*Ae, Ab*Af, Ab*Ag, - Ab*Aace, Ab*Aadg, Ab*Acfg, Ab*Ade, Ab*Adf, Ab*Aef, Ac*Ad, Ac*Ae, - Ac*Af, Ac*Ag, Ac*Aabf, Ac*Aadg, Ac*Abeg, Ac*Ade, Ac*Adf, Ac*Aef, - Ad*Ae, Ad*Af, Ad*Ag, Ad*Aabf, Ad*Aace, Ad*Abeg, Ad*Acfg, Ad*Aef, - Ae*Af, Ae*Ag, Ae*Aabf, Ae*Aadg, Ae*Abcd, Ae*Acfg, Ae*Adf, Af*Ag, - Af*Aace, Af*Aadg, Af*Abcd, Af*Abeg, Af*Ade, Ag*Aabf, Ag*Aace, - Ag*Abcd, Ag*Ade, Ag*Adf, Ag*Aef, Aabf*Aace, Aabf*Aadg, Aabf*Abcd, - Aabf*Abeg, Aabf*Acfg, Aabf*Ade, Aabf*Adf, Aabf*Aef, Aace*Aadg, - Aace*Abcd, Aace*Abeg, Aace*Acfg, Aace*Ade, Aace*Adf, Aace*Aef, - Aadg*Abcd, Aadg*Abeg, Aadg*Acfg, Aadg*Ade, Aadg*Adf, Aadg*Aef, - Abcd*Abeg, Abcd*Acfg, Abcd*Ade, Abcd*Adf, Abcd*Aef, Abeg*Acfg, - Abeg*Ade, Abeg*Adf, Abeg*Aef, Acfg*Ade, Acfg*Adf, Acfg*Aef, - Ade*Adf, Ade*Aef, Adf*Aef, - -Ab + Ae - Aabf + Aace - Abcd + Ade + Aef, - -Ac + Ae - Abcd + Abeg - Acfg + Ade + Aef, - Ae - Ag + Aace - Aadg - Acfg + Ade + Aef, - -Ad + Ae + Aace - Aadg - Abcd + Abeg - Adf + Aef, - -Aa + Ae - Aabf - Aadg + Abeg + Ade + Aef, - Ae - Af - Aabf + Aace + Abeg - Acfg + Ade - Adf, - Ab - Ac + Aabf - Aace + Abeg - Acfg, - Ab - Ag + Aabf - Aadg + Abcd - Acfg, - Ab - Ad + Aabf - Aadg + Abeg - Ade - Adf, - -Aa + Ab - Aace - Aadg + Abcd + Abeg, - Ab - Af + Abcd + Abeg - Acfg - Adf - Aef, - Ac - Ag + Aace - Aadg + Abcd - Abeg, - Ac - Ad + Aace - Aadg + Acfg - Ade - Adf, - -Aa + Ac - Aabf - Aadg + Abcd + Acfg, - Ac - Af - Aabf + Aace + Abcd - Adf - Aef, - -Ad + Ag - Abcd + Abeg + Acfg - Ade - Adf, - -Aa + Ag - Aabf - Aace + Abeg + Acfg, - -Af + Ag - Aabf + Aadg + Abeg - Adf - Aef, - -Aa + Ad - Aabf - Aace + Abcd + Ade + Adf, - Ad - Af - Aabf + Aadg + Abcd - Acfg + Ade - Aef, - Aa - Af + Aace + Aadg - Acfg - Adf - Aef] + [Aa*Ab, + Aa*Ac, + Aa*Ae, + Aa*Ad, + Aa*Ade, + Aa*Abcd, + Aa*Af, + Aa*Adf, + Aa*Aef, + Aa*Ag, + Aa*Abeg, + Aa*Acfg, + Ab*Ac, + Ab*Ae, + Ab*Aace, + Ab*Ad, + Ab*Ade, + Ab*Af, + Ab*Adf, + Ab*Aef, + Ab*Ag, + Ab*Aadg, + Ab*Acfg, + Ac*Ae, + Ac*Ad, + Ac*Ade, + Ac*Af, + Ac*Aabf, + Ac*Adf, + Ac*Aef, + Ac*Ag, + Ac*Aadg, + Ac*Abeg, + Ad*Ae, + Ae*Abcd, + Ae*Af, + Ae*Aabf, + Ae*Adf, + Ae*Ag, + Ae*Aadg, + Ae*Acfg, + Ad*Aace, + Aace*Ade, + Aace*Abcd, + Af*Aace, + Aabf*Aace, + Aace*Adf, + Aace*Aef, + Ag*Aace, + Aace*Aadg, + Aace*Abeg, + Aace*Acfg, + Ad*Af, + Ad*Aabf, + Ad*Aef, + Ad*Ag, + Ad*Abeg, + Ad*Acfg, + Abcd*Ade, + Af*Ade, + Aabf*Ade, + Ade*Adf, + Ade*Aef, + Ag*Ade, + Aadg*Ade, + Abeg*Ade, + Acfg*Ade, + Af*Abcd, + Aabf*Abcd, + Abcd*Adf, + Abcd*Aef, + Ag*Abcd, + Aadg*Abcd, + Abcd*Abeg, + Abcd*Acfg, + Af*Ag, + Af*Aadg, + Af*Abeg, + Aabf*Adf, + Aabf*Aef, + Ag*Aabf, + Aabf*Aadg, + Aabf*Abeg, + Aabf*Acfg, + Adf*Aef, + Ag*Adf, + Aadg*Adf, + Abeg*Adf, + Acfg*Adf, + Ag*Aef, + Aadg*Aef, + Abeg*Aef, + Acfg*Aef, + Aadg*Abeg, + Aadg*Acfg, + Abeg*Acfg, + Aa + Aabf + Aace + Aadg + Aabcdefg, + Ab + Aabf + Abcd + Abeg + Aabcdefg, + Ac + Aace + Abcd + Acfg + Aabcdefg, + Ad + Aadg + Abcd + Ade + Adf + Aabcdefg, + Ae + Aace + Abeg + Ade + Aef + Aabcdefg, + Af + Aabf + Acfg + Adf + Aef + Aabcdefg, + Ag + Aadg + Abeg + Acfg + Aabcdefg] """ - E = list(self._matroid.groundset()) flats = list(self._flats_generator) - flats.append(E) - flats_containing = {x: [] for x in E} - for i,F in enumerate(flats): - for x in F: - flats_containing[x].append(i) - lattice_flats = self._matroid.lattice_of_flats() - subsets = [] + reln = lambda x,y: x <= y + lattice_flats = Poset((flats, reln)) I = [] - # Generate all subsets of flats using combinations - for r in range(len(flats) + 1): # r is the size of the subset - subsets.extend(list(subset) for subset in combinations(flats, r)) + subsets = lattice_flats.antichains().elements_of_depth_iterator(2) for subset in subsets: - flag = True - sorted_list = sorted(subset, key=len) - for i in range (len(sorted_list)): #Checking whether the subset is not a chain - if (i != 0) & (len(sorted_list[i]) == len(sorted_list[i-1])): - flag = False - break - if not flag: - term = poly_ring.one() - for el in subset: - self._flats_generator[el] - I.append(term) #Stanley-Reisner Ideal - atoms = lattice_flats.atoms() - J = [] - for a in atoms: - term = poly_ring.zero() - for F in flats_containing[a]: - term += self._flats_generator[F] - J.append(term) #Linear Generators + term = poly_ring.one() + for el in subset: + term *= self._flats_generator[el] + I.append(term) #Stanley-Reisner Ideal + atoms = self._matroid.lattice_of_flats().atoms() + atoms_gen = {a:poly_ring.zero() for a in atoms} + for F in flats: + for a in atoms: + if a.issubset(F): + atoms_gen[a] += self._flats_generator[F] + J = list(atoms_gen.values()) #Linear Generators return I + J def _repr_(self): @@ -203,9 +257,9 @@ def _repr_(self): sage: ch = matroids.catalog.Fano().chow_ring(QQ, False) sage: ch.defining_ideal() - Chow ring ideal of Fano: Binary matroid of rank 3 on 7 elements, type (3, 0) + Chow ring ideal of Fano: Binary matroid of rank 3 on 7 elements, type (3, 0) - non augmented """ - return "Chow ring ideal of {}- non augmented".format(self._matroid) + return "Chow ring ideal of {} - non augmented".format(self._matroid) def _latex_(self): r""" @@ -216,17 +270,14 @@ def _latex_(self): sage: M1 = Matroid(groundset='abcd', bases=['ab','ad', 'bc']) sage: ch = M1.chow_ring(QQ, False) sage: ch.defining_ideal()._latex_() - '\\left(\\mathit{Aac} \\mathit{Abd}, 0, - \\mathit{Aac} - \\mathit{Abd}, \\mathit{Aac} - \\mathit{Abd}, - \\mathit{Aac} - \\mathit{Abd}, \\mathit{Aac} - \\mathit{Abd}, - 0\\right)\\Bold{Q}[\\mathit{Aac}, \\mathit{Abd}]' + '\\left(\\mathit{Aac} \\mathit{Abd}, \\mathit{Aac} + \\mathit{Aabcd}, \\mathit{Abd} + \\mathit{Aabcd}\\right)\\Bold{Q}[\\mathit{Aac}, \\mathit{Abd}, \\mathit{Aabcd}]' """ from sage.misc.latex import latex return '\\left(%s\\right)%s' % (", ".join(latex(g) for g in self.gens()), latex(self.ring())) - def groebner_basis(self, algorithm='', *args, **kwargs): #can you reduce it? - consider every antichain of size 2, and chains? + def groebner_basis(self, algorithm='', *args, **kwargs): r""" Return a Groebner basis of ``self``. @@ -234,7 +285,7 @@ def groebner_basis(self, algorithm='', *args, **kwargs): #can you reduce it? - c sage: ch = Matroid(groundset='abc', bases=['ab', 'ac']).chow_ring(QQ, False) sage: ch.defining_ideal().groebner_basis() - [Aa, Abc] + [Aa*Abc, Aa*Aabc] sage: ch.defining_ideal().groebner_basis().is_groebner() True @@ -243,7 +294,7 @@ def groebner_basis(self, algorithm='', *args, **kwargs): #can you reduce it? - c sage: ch = Matroid(graphs.CycleGraph(3)).chow_ring(QQ, False) sage: ch.defining_ideal().groebner_basis() - [A0, A1, A2, A0*A1, A0*A2, A1*A2, A0*A1*A2] + [A0*A1, A0*A2, A1*A2, A0*A2 + A0*A3, A0*A3, A1*A3] sage: ch.defining_ideal().groebner_basis().is_groebner() True """ @@ -251,65 +302,25 @@ def groebner_basis(self, algorithm='', *args, **kwargs): #can you reduce it? - c algorithm = 'constructed' if algorithm != 'constructed': return super().groebner_basis(algorithm=algorithm, *args, **kwargs) - flats = list(self._flats_generator) + flats = sorted(list(self._flats_generator), key=len) gb = list() - R = self.ring() - if frozenset() in flats: - flats.remove(frozenset()) #Non-empty proper flats needed - - ranks = {F:self._matroid.rank(F) for F in flats} - + R = self.ring() + reln = lambda x,y: x<=y flats_gen = self._flats_generator - subsets = [] - # Generate all subsets of flats using combinations - for r in range(len(flats) + 1): # r is the size of the subset - subsets.extend(list(subset) for subset in combinations(flats, r)) - - for subset in subsets: - k = len(subset) - flag = True - sorted_list = sorted(subset, key=len) - for i in range (len(sorted_list)): #Checking whether the subset is a chain - if (i != 0) & (len(sorted_list[i]) == len(sorted_list[i-1])): - flag = False - break - - if not flag: - if k == 2: #Taking only antichains of length 2 - term = R.one() - for x in subset: - term *= flats_gen[x] - gb.append(term) - - else: - if k == 0: - for F in flats: - term = R.zero() - for G in flats: - if G >= F: - term += flats_gen[G] - gb.append((term)**(ranks[F])) - - else: - for i in range(len(subset)): - for j in range(i+1, len(subset)): #Checking if every element in the chain is maximal - if (sorted_list[i] != sorted_list[j]) & (sorted_list[i].issubset(sorted_list[j])): - flag = False - break - - if flag: - for F in flats: - if F > reduce(lambda a, b: a.union(b), sorted_list): - term = R.one() - for x in subset: - term *= flats_gen[x] - term1 = R.zero() - for G in flats: - if G >= F: - term1 += flats_gen[G] - if term1 != R.zero(): - gb.append(term*(term1**(ranks[F] - ranks[sorted_list[len(subset) - 1]]))) - + lattice_flats = Poset((flats, reln)) + antichains = lattice_flats.antichains().elements_of_depth_iterator(2) + for subset in antichains: #Taking antichains of size 2 + term = R.one() + for x in subset: + term *= flats_gen[x] + gb.append(term) + for i in range(len(flats)): #Reduced groebner basis by computing the sum first and then the product + term = R.zero() + for j in range(i+1, len(flats)): + term += flats_gen[flats[j]] + for j in range(i): + if term != R.zero(): + gb.append(flats_gen[flats[j]]*term) g_basis = PolynomialSequence(R, [gb]) return g_basis @@ -357,8 +368,7 @@ class AugmentedChowRingIdeal_fy(ChowRingIdeal): sage: ch = matroids.Wheel(3).chow_ring(QQ, True, 'fy') sage: ch.defining_ideal() - Augmented Chow ring ideal of Wheel(3): Regular matroid of rank 3 on - 6 elements with 16 bases of Feitchner-Yuzvinsky presentation + Augmented Chow ring ideal of Wheel(3): Regular matroid of rank 3 on 6 elements with 16 bases of Feitchner-Yuzvinsky presentation """ def __init__(self, M, R): r""" @@ -447,8 +457,7 @@ def _repr_(self): sage: ch = matroids.Wheel(3).chow_ring(QQ, True, 'fy') sage: ch.defining_ideal() - Augmented Chow ring ideal of Wheel(3): Regular matroid of rank 3 on - 6 elements with 16 bases of Feitchner-Yuzvinsky presentation + Augmented Chow ring ideal of Wheel(3): Regular matroid of rank 3 on 6 elements with 16 bases of Feitchner-Yuzvinsky presentation """ return "Augmented Chow ring ideal of {} of Feitchner-Yuzvinsky presentation".format(self._matroid) @@ -457,19 +466,12 @@ def _latex_(self): Return a LaTeX representation`self`. EXAMPLES:: - - sage: from sage.matroids.basis_matroid import BasisMatroid - sage: M1 = BasisMatroid(groundset='abcd', bases=['ab','ad', 'bc']) + sage: M1 = Matroid(groundset='abcd', bases=['ab','ad', 'bc']) sage: ch = M1.chow_ring(QQ, True, 'fy') sage: ch.defining_ideal()._latex_() - '\\left(\\mathit{Bac}^{2}, \\mathit{Bac} \\mathit{Bbd}, - \\mathit{Bac} \\mathit{Bbd}, \\mathit{Bbd}^{2}, - \\mathit{Ad} - \\mathit{Bac}, \\mathit{Ab} - \\mathit{Bac}, - \\mathit{Aa} - \\mathit{Bbd}, \\mathit{Ac} - \\mathit{Bbd}\\right) - \\Bold{Q}[\\mathit{Ad}, \\mathit{Ab}, \\mathit{Aa}, \\mathit{Ac}, - \\mathit{Bac}, \\mathit{Bbd}]' - """ + '\\left(\\mathit{Bac}^{2}, \\mathit{Bac} \\mathit{Bbd}, \\mathit{Bac} \\mathit{Bbd}, \\mathit{Bbd}^{2}, \\mathit{Aa} - \\mathit{Bbd}, \\mathit{Ab} - \\mathit{Bac}, \\mathit{Ac} - \\mathit{Bbd}, \\mathit{Ad} - \\mathit{Bac}\\right)\\Bold{Q}[\\mathit{Aa}, \\mathit{Ab}, \\mathit{Ac}, \\mathit{Ad}, \\mathit{Bac}, \\mathit{Bbd}]' + """ from sage.misc.latex import latex return '\\left(%s\\right)%s' % (", ".join(latex(g) for g in self.gens()), @@ -570,8 +572,7 @@ class AugmentedChowRingIdeal_atom_free(ChowRingIdeal): sage: ch = matroids.Wheel(3).chow_ring(QQ, True, 'atom-free') sage: ch.defining_ideal() - Augmented Chow ring ideal of Wheel(3): Regular matroid of rank 3 on - 6 elements with 16 bases of atom-free presentation + Augmented Chow ring ideal of Wheel(3): Regular matroid of rank 3 on 6 elements with 16 bases in the atom-free presentation """ def __init__(self, M, R): r""" @@ -651,8 +652,7 @@ def _repr_(self): sage: ch = matroids.Wheel(3).chow_ring(QQ, True, 'atom-free') sage: ch.defining_ideal() - Augmented Chow ring ideal of Wheel(3): Regular matroid of rank 3 on - 6 elements with 16 bases of atom-free presentation + Augmented Chow ring ideal of Wheel(3): Regular matroid of rank 3 on 6 elements with 16 bases in the atom-free presentation """ return "Augmented Chow ring ideal of {} in the atom-free presentation".format(self._matroid) @@ -662,22 +662,11 @@ def _latex_(self): EXAMPLES:: - sage: M1 = BMatroid(groundset='abcd', bases=['ab','ad', 'bc']) + sage: M1 = Matroid(groundset='abcd', bases=['ab','ad', 'bc']) sage: ch = M1.chow_ring(QQ, True, 'atom-free') sage: ch.defining_ideal()._latex_() - '\\left(\\mathit{Aac}^{2}, \\mathit{Abd}^{2}, - \\mathit{Aac} \\mathit{Abd}, \\mathit{Abd}^{2}, - \\mathit{Aac} \\mathit{Abd}, \\mathit{Aac}^{2}, \\mathit{Aac}^{2}, - \\mathit{Aac} \\mathit{Abd}, \\mathit{Abd}^{2}, - \\mathit{Aac} \\mathit{Abd}, \\mathit{Abd}^{2}, - \\mathit{Aac} \\mathit{Abd}, \\mathit{Aac}^{2}, \\mathit{Aac}^{2}, - \\mathit{Aac} \\mathit{Abd}, \\mathit{Abd}^{2}, \\mathit{Abd}^{2}, - \\mathit{Aac}^{2}, \\mathit{Aac} \\mathit{Abd}, \\mathit{Aac}^{2}, - \\mathit{Aac} \\mathit{Abd}, \\mathit{Abd}^{2}, \\mathit{Abd}^{2}, - \\mathit{Abd}^{2}, \\mathit{Aac}^{2}, \\mathit{Aac} \\mathit{Abd}, - \\mathit{Aac}^{2}, \\mathit{Aac} \\mathit{Abd}\\right) - \\Bold{Q}[\\mathit{Aac}, \\mathit{Abd}]' - """ + '\\left(\\mathit{Aac}^{2}, \\mathit{Aac}^{2}, \\mathit{Abd}^{2}, \\mathit{Aac} \\mathit{Abd}, \\mathit{Aac}^{2}, \\mathit{Abd}^{2}, \\mathit{Aac} \\mathit{Abd}, \\mathit{Aac} \\mathit{Abd}, \\mathit{Aac}^{2}, \\mathit{Abd}^{2}, \\mathit{Aac} \\mathit{Abd}, \\mathit{Aac}^{2}, \\mathit{Abd}^{2}, \\mathit{Aac} \\mathit{Abd}, \\mathit{Aac} \\mathit{Abd}, \\mathit{Aac}^{2}, \\mathit{Aac} \\mathit{Abd}, \\mathit{Abd}^{2}, \\mathit{Aac}^{2}, \\mathit{Aac} \\mathit{Abd}, \\mathit{Abd}^{2}, \\mathit{Abd}^{2}, \\mathit{Aac}^{2}, \\mathit{Aac} \\mathit{Abd}, \\mathit{Abd}^{2}, \\mathit{Aac}^{2}, \\mathit{Aac} \\mathit{Abd}, \\mathit{Abd}^{2}\\right)\\Bold{Q}[\\mathit{Aac}, \\mathit{Abd}]' + """ from sage.misc.latex import latex return '\\left(%s\\right)%s' % (", ".join(latex(g) for g in self.gens()), From a5484ce6016be8a2ca20724b1a339d918742fd19 Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Fri, 4 Oct 2024 23:01:58 +0200 Subject: [PATCH 254/537] partially fix bug --- src/sage/rings/species.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/sage/rings/species.py b/src/sage/rings/species.py index adc08d7a055..720c5d2a87f 100644 --- a/src/sage/rings/species.py +++ b/src/sage/rings/species.py @@ -1689,12 +1689,11 @@ def _element_constructor_(self, G, pi=None): pi = {i: v for i, v in enumerate(pi)} return self._from_dict({self._indices(G, pi): ZZ.one()}) - X, a = G X, a = G L = [len(pi.get(i, [])) for i in range(self._arity)] S = SymmetricGroup(sum(L)).young_subgroup(L) Hs = _stabilizer_subgroups(S, X, a) - return self._from_dict({self._indices(H, pi): ZZ.one() for H in Hs}) + return self.sum_of_terms((self._indices(H, pi), ZZ.one()) for H in Hs) def _first_ngens(self, n): """ From 67b12b6a667c14e545163ac1bd5097537f6d3fb8 Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Fri, 4 Oct 2024 23:42:48 +0200 Subject: [PATCH 255/537] fix bug when specifying species via a group action --- src/sage/rings/species.py | 33 ++++++++++++++++++++++++--------- 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/src/sage/rings/species.py b/src/sage/rings/species.py index 720c5d2a87f..082403e0875 100644 --- a/src/sage/rings/species.py +++ b/src/sage/rings/species.py @@ -699,6 +699,10 @@ def _stabilizer_subgroups(G, X, a): sage: _stabilizer_subgroups(S, X, a) [Permutation Group with generators [(1,2), (4,5), (1,4)(2,5)(3,6)]] + TESTS:: + + sage: _stabilizer_subgroups(SymmetricGroup(2), [1], lambda pi, H: H) + [Permutation Group with generators [(1,2)]] """ from sage.combinat.cyclic_sieving_phenomenon import orbit_decomposition to_gap = {x: i for i, x in enumerate(X, 1)} @@ -706,9 +710,9 @@ def _stabilizer_subgroups(G, X, a): g_orbits = [orbit_decomposition(list(to_gap), lambda x: a(g, x)) for g in G.gens()] - gens = [PermutationGroupElement(gen) for g_orbit in g_orbits - if (gen := [tuple([to_gap[x] for x in o]) - for o in g_orbit if len(o) > 1])] + gens = [PermutationGroupElement([tuple([to_gap[x] for x in o]) + for o in g_orbit]) + for g_orbit in g_orbits] result = [] M = set(range(1, len(to_gap) + 1)) while M: @@ -1651,12 +1655,11 @@ def _element_constructor_(self, G, pi=None): INPUT: - ``G`` - an element of ``self`` (in this case pi must be ``None``) - or a permutation group. - - ``pi`` - a dict mapping sorts to iterables whose union is the domain. - If `k=1`, `pi` can be omitted. - - If `G = (X, a)`, then `X` should be a finite set and `a` an action of - `G` on `X`. + or a permutation group, or a pair ``(X, a)`` consisting of a + finite set and an action. + - ``pi`` - a dict mapping sorts to iterables whose union is the + domain of ``G`` (if ``G`` is a permutation group) or `X` (if ``G``) + is a pair ``(X, a)``. If `k=1`, `pi` can be omitted. EXAMPLES:: @@ -1675,6 +1678,18 @@ def _element_constructor_(self, G, pi=None): sage: a = lambda g, x: SetPartition([[g(e) for e in b] for b in x]) sage: P((X, a), {0: [1,2,3,4]}) E_3*X + P_4 + + The species of permutation groups:: + + sage: P = PolynomialSpecies(ZZ, ["X"]) + sage: n = 4 + sage: S = SymmetricGroup(n) + sage: X = S.subgroups() + sage: def act(pi, G): # WARNING: returning H does not work because of equality problems + ....: H = S.subgroup(G.conjugate(pi).gens()) + ....: return next(K for K in X if K == H) + sage: P((X, act), {0: range(1, n+1)}) + 4*E_4 + 4*P_4 + E_2^2 + 2*X*E_3 """ if parent(G) == self: if pi is not None: From 91bc8e082026d9ff28febddce6b2c12582c68ee3 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Sat, 5 Oct 2024 11:42:50 +0530 Subject: [PATCH 256/537] Corrected linting errors for ideals file --- src/sage/matroids/chow_ring_ideal.py | 69 ++++++++++++---------------- 1 file changed, 30 insertions(+), 39 deletions(-) diff --git a/src/sage/matroids/chow_ring_ideal.py b/src/sage/matroids/chow_ring_ideal.py index 17945640495..e5ea38d3581 100644 --- a/src/sage/matroids/chow_ring_ideal.py +++ b/src/sage/matroids/chow_ring_ideal.py @@ -18,7 +18,7 @@ def matroid(self): Return the matroid of the given Chow ring ideal. EXAMPLES:: - + 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 @@ -26,7 +26,7 @@ def matroid(self): """ M = self._matroid return M - + def flats_generator(self): r""" Return the variables of every corresponding flat/groundset element @@ -48,15 +48,15 @@ def flats_generator(self): frozenset({'a', 'b', 'c', 'd', 'e', 'f', 'g'}): Aabcdefg} """ return dict(self._flats_generator) - -class ChowRingIdeal_nonaug(ChowRingIdeal): + +class ChowRingIdeal_nonaug(ChowRingIdeal): r""" The Chow ring ideal of a matroid `M`. The *Chow ring ideal* for a matroid `M` is defined as the ideal `(I_M + J_M)` of the polynomial ring - + .. MATH:: R[x_{F_1}, \ldots, x_{F_k}], @@ -74,7 +74,7 @@ class ChowRingIdeal_nonaug(ChowRingIdeal): \sum_{a \in F} x_F for all atoms `a` in the lattice of flats. - + INPUT: - ``M`` -- matroid @@ -121,7 +121,7 @@ def __init__(self, M, R): def _gens_constructor(self, poly_ring): r""" Return the generators of ``self``. - + EXAMPLES:: sage: ch = matroids.catalog.NonFano().chow_ring(QQ, False) @@ -231,7 +231,7 @@ def _gens_constructor(self, poly_ring): Ag + Aadg + Abeg + Acfg + Aabcdefg] """ flats = list(self._flats_generator) - reln = lambda x,y: x <= y + reln = lambda x,y: x <= y lattice_flats = Poset((flats, reln)) I = [] subsets = lattice_flats.antichains().elements_of_depth_iterator(2) @@ -260,13 +260,13 @@ def _repr_(self): Chow ring ideal of Fano: Binary matroid of rank 3 on 7 elements, type (3, 0) - non augmented """ return "Chow ring ideal of {} - non augmented".format(self._matroid) - + def _latex_(self): r""" Return a LaTeX representation of ``self``. EXAMPLES:: - + sage: M1 = Matroid(groundset='abcd', bases=['ab','ad', 'bc']) sage: ch = M1.chow_ring(QQ, False) sage: ch.defining_ideal()._latex_() @@ -288,7 +288,7 @@ def groebner_basis(self, algorithm='', *args, **kwargs): [Aa*Abc, Aa*Aabc] sage: ch.defining_ideal().groebner_basis().is_groebner() True - + Another example would be the Groebner basis of the Chow ring ideal of the matroid of the length 3 cycle graph:: @@ -301,11 +301,11 @@ def groebner_basis(self, algorithm='', *args, **kwargs): if algorithm == '': algorithm = 'constructed' if algorithm != 'constructed': - return super().groebner_basis(algorithm=algorithm, *args, **kwargs) + return super().groebner_basis(algorithm=algorithm, *args, **kwargs) flats = sorted(list(self._flats_generator), key=len) gb = list() R = self.ring() - reln = lambda x,y: x<=y + reln = lambda x,y: x <= y flats_gen = self._flats_generator lattice_flats = Poset((flats, reln)) antichains = lattice_flats.antichains().elements_of_depth_iterator(2) @@ -324,7 +324,6 @@ def groebner_basis(self, algorithm='', *args, **kwargs): g_basis = PolynomialSequence(R, [gb]) return g_basis - class AugmentedChowRingIdeal_fy(ChowRingIdeal): r""" The augmented Chow ring ideal of matroid `M` over ring `R` in @@ -349,10 +348,10 @@ class AugmentedChowRingIdeal_fy(ChowRingIdeal): .. MATH:: - y_i - \sum_{i \notin F} x_F + y_i - \sum_{i \notin F} x_F for all `i \in E`. - + REFERENCES: - [MM2022]_ @@ -395,8 +394,7 @@ def __init__(self, M, R): for i,F in enumerate(self._flats): self._flats_generator[F] = poly_ring.gens()[len(E) + i] MPolynomialIdeal.__init__(self, poly_ring, self._gens_constructor(poly_ring)) - - + def _gens_constructor(self, poly_ring): r""" Return the generators of ``self``. @@ -460,13 +458,13 @@ def _repr_(self): Augmented Chow ring ideal of Wheel(3): Regular matroid of rank 3 on 6 elements with 16 bases of Feitchner-Yuzvinsky presentation """ return "Augmented Chow ring ideal of {} of Feitchner-Yuzvinsky presentation".format(self._matroid) - + def _latex_(self): r""" Return a LaTeX representation`self`. EXAMPLES:: - + sage: M1 = Matroid(groundset='abcd', bases=['ab','ad', 'bc']) sage: ch = M1.chow_ring(QQ, True, 'fy') sage: ch.defining_ideal()._latex_() @@ -476,7 +474,7 @@ def _latex_(self): return '\\left(%s\\right)%s' % (", ".join(latex(g) for g in self.gens()), latex(self.ring())) - + def groebner_basis(self, algorithm='constructed', *args, **kwargs): r""" Returns the Groebner basis of `self`. @@ -513,10 +511,10 @@ def groebner_basis(self, algorithm='constructed', *args, **kwargs): if i in G: #if element in flat if term1 != poly_ring.zero(): gb.append(self._flats_generator[i]*((term1)**self._matroid.rank(G))) - - elif not i in G: #if element not in flat + + elif i not in G: #if element not in flat gb.append(self._flats_generator[i]*self._flats_generator[F]) - + elif G < F: #nested flats gb.append(self._flats_generator[G]*term1**(self._matroid.rank(F)-self._matroid.rank(G))) @@ -544,7 +542,7 @@ class AugmentedChowRingIdeal_atom_free(ChowRingIdeal): - `I_{af}M` is the ideal generated by all quadratic forms `x_{F_i} x_{F_j}` where `F_i` and `F_j` are incomparable elements in the lattice of flats, - + .. MATH:: x_F \sum_{i \in F'} x_{F'} @@ -573,7 +571,7 @@ class AugmentedChowRingIdeal_atom_free(ChowRingIdeal): sage: ch = matroids.Wheel(3).chow_ring(QQ, True, 'atom-free') sage: ch.defining_ideal() Augmented Chow ring ideal of Wheel(3): Regular matroid of rank 3 on 6 elements with 16 bases in the atom-free presentation - """ + """ def __init__(self, M, R): r""" Initialize ``self``. @@ -586,7 +584,7 @@ def __init__(self, M, R): self._matroid = M self._flats = [X for i in range(1, self._matroid.rank()) for X in self._matroid.flats(i)] - + E = list(self._matroid.groundset()) flats_containing = {x: [] for x in E} for i,F in enumerate(self._flats): @@ -603,7 +601,6 @@ def __init__(self, M, R): self._flats_generator = dict() self._flats_generator = dict(zip(self._flats, gens)) MPolynomialIdeal.__init__(self, poly_ring, self._gens_constructor(poly_ring)) - def _gens_constructor(self, poly_ring): r""" @@ -643,9 +640,8 @@ def _gens_constructor(self, poly_ring): for H in flats_containing[x]: term += self._flats_generator[H] Q.append(self._flats_generator[F]*term) - return Q - + def _repr_(self): r""" EXAMPLE:: @@ -666,12 +662,12 @@ def _latex_(self): sage: ch = M1.chow_ring(QQ, True, 'atom-free') sage: ch.defining_ideal()._latex_() '\\left(\\mathit{Aac}^{2}, \\mathit{Aac}^{2}, \\mathit{Abd}^{2}, \\mathit{Aac} \\mathit{Abd}, \\mathit{Aac}^{2}, \\mathit{Abd}^{2}, \\mathit{Aac} \\mathit{Abd}, \\mathit{Aac} \\mathit{Abd}, \\mathit{Aac}^{2}, \\mathit{Abd}^{2}, \\mathit{Aac} \\mathit{Abd}, \\mathit{Aac}^{2}, \\mathit{Abd}^{2}, \\mathit{Aac} \\mathit{Abd}, \\mathit{Aac} \\mathit{Abd}, \\mathit{Aac}^{2}, \\mathit{Aac} \\mathit{Abd}, \\mathit{Abd}^{2}, \\mathit{Aac}^{2}, \\mathit{Aac} \\mathit{Abd}, \\mathit{Abd}^{2}, \\mathit{Abd}^{2}, \\mathit{Aac}^{2}, \\mathit{Aac} \\mathit{Abd}, \\mathit{Abd}^{2}, \\mathit{Aac}^{2}, \\mathit{Aac} \\mathit{Abd}, \\mathit{Abd}^{2}\\right)\\Bold{Q}[\\mathit{Aac}, \\mathit{Abd}]' - """ + """ from sage.misc.latex import latex return '\\left(%s\\right)%s' % (", ".join(latex(g) for g in self.gens()), latex(self.ring())) - + def groebner_basis(self, algorithm='constructed', *args, **kwargs): #Copy from fy presentation """ Returns the Groebner basis of `self`. @@ -707,11 +703,6 @@ def groebner_basis(self, algorithm='constructed', *args, **kwargs): #Copy from f g_basis = PolynomialSequence(poly_ring, [gb]) return g_basis - - elif algorithm == 'constructed': - super().groebner_basis(*args, **kwargs) - - - - + elif algorithm == 'constructed': + super().groebner_basis(*args, **kwargs) \ No newline at end of file From b9556d861ab44798c74136ca2dca44cb6ad0aca2 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Sat, 5 Oct 2024 12:11:29 +0530 Subject: [PATCH 257/537] Corrected linting errors in ideals file --- src/sage/matroids/chow_ring_ideal.py | 137 ++++++--------------------- 1 file changed, 30 insertions(+), 107 deletions(-) diff --git a/src/sage/matroids/chow_ring_ideal.py b/src/sage/matroids/chow_ring_ideal.py index e5ea38d3581..aff180557b0 100644 --- a/src/sage/matroids/chow_ring_ideal.py +++ b/src/sage/matroids/chow_ring_ideal.py @@ -126,102 +126,20 @@ def _gens_constructor(self, poly_ring): sage: ch = matroids.catalog.NonFano().chow_ring(QQ, False) sage: ch.defining_ideal()._gens_constructor(ch.defining_ideal().ring()) - [Aa*Ab, - Aa*Ac, - Aa*Ae, - Aa*Ad, - Aa*Ade, - Aa*Abcd, - Aa*Af, - Aa*Adf, - Aa*Aef, - Aa*Ag, - Aa*Abeg, - Aa*Acfg, - Ab*Ac, - Ab*Ae, - Ab*Aace, - Ab*Ad, - Ab*Ade, - Ab*Af, - Ab*Adf, - Ab*Aef, - Ab*Ag, - Ab*Aadg, - Ab*Acfg, - Ac*Ae, - Ac*Ad, - Ac*Ade, - Ac*Af, - Ac*Aabf, - Ac*Adf, - Ac*Aef, - Ac*Ag, - Ac*Aadg, - Ac*Abeg, - Ad*Ae, - Ae*Abcd, - Ae*Af, - Ae*Aabf, - Ae*Adf, - Ae*Ag, - Ae*Aadg, - Ae*Acfg, - Ad*Aace, - Aace*Ade, - Aace*Abcd, - Af*Aace, - Aabf*Aace, - Aace*Adf, - Aace*Aef, - Ag*Aace, - Aace*Aadg, - Aace*Abeg, - Aace*Acfg, - Ad*Af, - Ad*Aabf, - Ad*Aef, - Ad*Ag, - Ad*Abeg, - Ad*Acfg, - Abcd*Ade, - Af*Ade, - Aabf*Ade, - Ade*Adf, - Ade*Aef, - Ag*Ade, - Aadg*Ade, - Abeg*Ade, - Acfg*Ade, - Af*Abcd, - Aabf*Abcd, - Abcd*Adf, - Abcd*Aef, - Ag*Abcd, - Aadg*Abcd, - Abcd*Abeg, - Abcd*Acfg, - Af*Ag, - Af*Aadg, - Af*Abeg, - Aabf*Adf, - Aabf*Aef, - Ag*Aabf, - Aabf*Aadg, - Aabf*Abeg, - Aabf*Acfg, - Adf*Aef, - Ag*Adf, - Aadg*Adf, - Abeg*Adf, - Acfg*Adf, - Ag*Aef, - Aadg*Aef, - Abeg*Aef, - Acfg*Aef, - Aadg*Abeg, - Aadg*Acfg, - Abeg*Acfg, + [Aa*Ab, Aa*Ac, Aa*Ae, Aa*Ad, Aa*Ade, Aa*Abcd, Aa*Af, Aa*Adf, + Aa*Aef, Aa*Ag, Aa*Abeg, Aa*Acfg, Ab*Ac, Ab*Ae, Ab*Aace, Ab*Ad, + Ab*Ade, Ab*Af, Ab*Adf, Ab*Aef, Ab*Ag, Ab*Aadg, Ab*Acfg, Ac*Ae, + Ac*Ad, Ac*Ade, Ac*Af, Ac*Aabf, Ac*Adf, Ac*Aef, Ac*Ag, Ac*Aadg, + Ac*Abeg, Ad*Ae, Ae*Abcd, Ae*Af, Ae*Aabf, Ae*Adf, Ae*Ag, Ae*Aadg, + Ae*Acfg, Ad*Aace, Aace*Ade, Aace*Abcd, Af*Aace, Aabf*Aace, + Aace*Adf, Aace*Aef, Ag*Aace, Aace*Aadg, Aace*Abeg, Aace*Acfg, + Ad*Af, Ad*Aabf, Ad*Aef, Ad*Ag, Ad*Abeg, Ad*Acfg, Abcd*Ade, Af*Ade, + Aabf*Ade, Ade*Adf, Ade*Aef, Ag*Ade, Aadg*Ade, Abeg*Ade, Acfg*Ade, + Af*Abcd, Aabf*Abcd, Abcd*Adf, Abcd*Aef, Ag*Abcd, Aadg*Abcd, + Abcd*Abeg, Abcd*Acfg, Af*Ag, Af*Aadg, Af*Abeg, Aabf*Adf, Aabf*Aef, + Ag*Aabf, Aabf*Aadg, Aabf*Abeg, Aabf*Acfg, Adf*Aef, Ag*Adf, + Aadg*Adf, Abeg*Adf, Acfg*Adf, Ag*Aef, Aadg*Aef, Abeg*Aef, + Acfg*Aef, Aadg*Abeg, Aadg*Acfg, Abeg*Acfg, Aa + Aabf + Aace + Aadg + Aabcdefg, Ab + Aabf + Abcd + Abeg + Aabcdefg, Ac + Aace + Abcd + Acfg + Aabcdefg, @@ -257,7 +175,8 @@ def _repr_(self): sage: ch = matroids.catalog.Fano().chow_ring(QQ, False) sage: ch.defining_ideal() - Chow ring ideal of Fano: Binary matroid of rank 3 on 7 elements, type (3, 0) - non augmented + Chow ring ideal of Fano: Binary matroid of rank 3 on 7 elements, + type (3, 0) - non augmented """ return "Chow ring ideal of {} - non augmented".format(self._matroid) @@ -367,7 +286,8 @@ class AugmentedChowRingIdeal_fy(ChowRingIdeal): sage: ch = matroids.Wheel(3).chow_ring(QQ, True, 'fy') sage: ch.defining_ideal() - Augmented Chow ring ideal of Wheel(3): Regular matroid of rank 3 on 6 elements with 16 bases of Feitchner-Yuzvinsky presentation + Augmented Chow ring ideal of Wheel(3): Regular matroid of rank 3 on 6 + elements with 16 bases of Feitchner-Yuzvinsky presentation """ def __init__(self, M, R): r""" @@ -455,7 +375,8 @@ def _repr_(self): sage: ch = matroids.Wheel(3).chow_ring(QQ, True, 'fy') sage: ch.defining_ideal() - Augmented Chow ring ideal of Wheel(3): Regular matroid of rank 3 on 6 elements with 16 bases of Feitchner-Yuzvinsky presentation + Augmented Chow ring ideal of Wheel(3): Regular matroid of rank 3 on + 6 elements with 16 bases of Feitchner-Yuzvinsky presentation """ return "Augmented Chow ring ideal of {} of Feitchner-Yuzvinsky presentation".format(self._matroid) @@ -468,8 +389,8 @@ def _latex_(self): sage: M1 = Matroid(groundset='abcd', bases=['ab','ad', 'bc']) sage: ch = M1.chow_ring(QQ, True, 'fy') sage: ch.defining_ideal()._latex_() - '\\left(\\mathit{Bac}^{2}, \\mathit{Bac} \\mathit{Bbd}, \\mathit{Bac} \\mathit{Bbd}, \\mathit{Bbd}^{2}, \\mathit{Aa} - \\mathit{Bbd}, \\mathit{Ab} - \\mathit{Bac}, \\mathit{Ac} - \\mathit{Bbd}, \\mathit{Ad} - \\mathit{Bac}\\right)\\Bold{Q}[\\mathit{Aa}, \\mathit{Ab}, \\mathit{Ac}, \\mathit{Ad}, \\mathit{Bac}, \\mathit{Bbd}]' - """ + '\\left(\\mathit{Bac}^{2}, \\mathit{Bac} \\mathit{Bbd}, \\mathit{Bac} \\mathit{Bbd}, \\mathit{Bbd}^{2}, \\mathit{Ac} - \\mathit{Bbd}, \\mathit{Aa} - \\mathit{Bbd}, \\mathit{Ab} - \\mathit{Bac}, \\mathit{Ad} - \\mathit{Bac}\\right)\\Bold{Q}[\\mathit{Ac}, \\mathit{Aa}, \\mathit{Ab}, \\mathit{Ad}, \\mathit{Bac}, \\mathit{Bbd}]' + """ from sage.misc.latex import latex return '\\left(%s\\right)%s' % (", ".join(latex(g) for g in self.gens()), @@ -549,7 +470,7 @@ class AugmentedChowRingIdeal_atom_free(ChowRingIdeal): for all `i \in E` and `i \notin F`, and - ..MATH:: + .. MATH:: \sum_{i \in F'} (x_{F'})^2 @@ -570,7 +491,8 @@ class AugmentedChowRingIdeal_atom_free(ChowRingIdeal): sage: ch = matroids.Wheel(3).chow_ring(QQ, True, 'atom-free') sage: ch.defining_ideal() - Augmented Chow ring ideal of Wheel(3): Regular matroid of rank 3 on 6 elements with 16 bases in the atom-free presentation + Augmented Chow ring ideal of Wheel(3): Regular matroid of rank 3 on 6 + elements with 16 bases in the atom-free presentation """ def __init__(self, M, R): r""" @@ -648,10 +570,11 @@ def _repr_(self): sage: ch = matroids.Wheel(3).chow_ring(QQ, True, 'atom-free') sage: ch.defining_ideal() - Augmented Chow ring ideal of Wheel(3): Regular matroid of rank 3 on 6 elements with 16 bases in the atom-free presentation + Augmented Chow ring ideal of Wheel(3): Regular matroid of rank 3 on + 6 elements with 16 bases in the atom-free presentation """ return "Augmented Chow ring ideal of {} in the atom-free presentation".format(self._matroid) - + def _latex_(self): r""" Return the LaTeX output of the ring and generators of `self`. @@ -661,7 +584,7 @@ def _latex_(self): sage: M1 = Matroid(groundset='abcd', bases=['ab','ad', 'bc']) sage: ch = M1.chow_ring(QQ, True, 'atom-free') sage: ch.defining_ideal()._latex_() - '\\left(\\mathit{Aac}^{2}, \\mathit{Aac}^{2}, \\mathit{Abd}^{2}, \\mathit{Aac} \\mathit{Abd}, \\mathit{Aac}^{2}, \\mathit{Abd}^{2}, \\mathit{Aac} \\mathit{Abd}, \\mathit{Aac} \\mathit{Abd}, \\mathit{Aac}^{2}, \\mathit{Abd}^{2}, \\mathit{Aac} \\mathit{Abd}, \\mathit{Aac}^{2}, \\mathit{Abd}^{2}, \\mathit{Aac} \\mathit{Abd}, \\mathit{Aac} \\mathit{Abd}, \\mathit{Aac}^{2}, \\mathit{Aac} \\mathit{Abd}, \\mathit{Abd}^{2}, \\mathit{Aac}^{2}, \\mathit{Aac} \\mathit{Abd}, \\mathit{Abd}^{2}, \\mathit{Abd}^{2}, \\mathit{Aac}^{2}, \\mathit{Aac} \\mathit{Abd}, \\mathit{Abd}^{2}, \\mathit{Aac}^{2}, \\mathit{Aac} \\mathit{Abd}, \\mathit{Abd}^{2}\\right)\\Bold{Q}[\\mathit{Aac}, \\mathit{Abd}]' + '\\left(\\mathit{Aac}^{2}, \\mathit{Aac}^{2}, \\mathit{Aac}^{2}, \\mathit{Abd}^{2}, \\mathit{Aac} \\mathit{Abd}, \\mathit{Abd}^{2}, \\mathit{Aac} \\mathit{Abd}, \\mathit{Aac} \\mathit{Abd}, \\mathit{Aac}^{2}, \\mathit{Aac}^{2}, \\mathit{Abd}^{2}, \\mathit{Aac} \\mathit{Abd}, \\mathit{Abd}^{2}, \\mathit{Aac} \\mathit{Abd}, \\mathit{Aac} \\mathit{Abd}, \\mathit{Aac}^{2}, \\mathit{Aac} \\mathit{Abd}, \\mathit{Aac}^{2}, \\mathit{Aac} \\mathit{Abd}, \\mathit{Abd}^{2}, \\mathit{Abd}^{2}, \\mathit{Abd}^{2}, \\mathit{Aac}^{2}, \\mathit{Aac} \\mathit{Abd}, \\mathit{Aac}^{2}, \\mathit{Aac} \\mathit{Abd}, \\mathit{Abd}^{2}, \\mathit{Abd}^{2}\\right)\\Bold{Q}[\\mathit{Aac}, \\mathit{Abd}]' """ from sage.misc.latex import latex return '\\left(%s\\right)%s' % (", ".join(latex(g) @@ -698,7 +621,7 @@ def groebner_basis(self, algorithm='constructed', *args, **kwargs): #Copy from f if H < F: term += self._flats_generator[H] if term != poly_ring.zero(): - gb.append(self._flats_generator[F]*(term**self._matroid.rank(G))* + gb.append(self._flats_generator[F]*(term ** self._matroid.rank(G))* (term**(self._matroid.rank(G)-self._matroid.rank(F)))) g_basis = PolynomialSequence(poly_ring, [gb]) From cfb1fbbfc5fe7b4fe2a673d9bed0bb5f9dbcfc44 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Sat, 5 Oct 2024 12:17:53 +0530 Subject: [PATCH 258/537] Corrected doctest output --- src/sage/matroids/chow_ring_ideal.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/sage/matroids/chow_ring_ideal.py b/src/sage/matroids/chow_ring_ideal.py index aff180557b0..ced1ad7ed74 100644 --- a/src/sage/matroids/chow_ring_ideal.py +++ b/src/sage/matroids/chow_ring_ideal.py @@ -386,10 +386,10 @@ def _latex_(self): EXAMPLES:: - sage: M1 = Matroid(groundset='abcd', bases=['ab','ad', 'bc']) + sage: M1 = Matroid(graphs.CycleGraph(3)) sage: ch = M1.chow_ring(QQ, True, 'fy') sage: ch.defining_ideal()._latex_() - '\\left(\\mathit{Bac}^{2}, \\mathit{Bac} \\mathit{Bbd}, \\mathit{Bac} \\mathit{Bbd}, \\mathit{Bbd}^{2}, \\mathit{Ac} - \\mathit{Bbd}, \\mathit{Aa} - \\mathit{Bbd}, \\mathit{Ab} - \\mathit{Bac}, \\mathit{Ad} - \\mathit{Bac}\\right)\\Bold{Q}[\\mathit{Ac}, \\mathit{Aa}, \\mathit{Ab}, \\mathit{Ad}, \\mathit{Bac}, \\mathit{Bbd}]' + '\\left(A_{3}^{2}, A_{3} A_{4}, A_{3} A_{5}, A_{3} A_{4}, A_{4}^{2}, A_{4} A_{5}, A_{3} A_{5}, A_{4} A_{5}, A_{5}^{2}, A_{0} - A_{4} - A_{5}, A_{1} - A_{3} - A_{5}, A_{2} - A_{3} - A_{4}\\right)\\Bold{Q}[A_{0}, A_{1}, A_{2}, A_{3}, A_{4}, A_{5}]' """ from sage.misc.latex import latex return '\\left(%s\\right)%s' % (", ".join(latex(g) @@ -581,10 +581,10 @@ def _latex_(self): EXAMPLES:: - sage: M1 = Matroid(groundset='abcd', bases=['ab','ad', 'bc']) + sage: M1 = Matroid(graphs.CycleGraph(3)) sage: ch = M1.chow_ring(QQ, True, 'atom-free') sage: ch.defining_ideal()._latex_() - '\\left(\\mathit{Aac}^{2}, \\mathit{Aac}^{2}, \\mathit{Aac}^{2}, \\mathit{Abd}^{2}, \\mathit{Aac} \\mathit{Abd}, \\mathit{Abd}^{2}, \\mathit{Aac} \\mathit{Abd}, \\mathit{Aac} \\mathit{Abd}, \\mathit{Aac}^{2}, \\mathit{Aac}^{2}, \\mathit{Abd}^{2}, \\mathit{Aac} \\mathit{Abd}, \\mathit{Abd}^{2}, \\mathit{Aac} \\mathit{Abd}, \\mathit{Aac} \\mathit{Abd}, \\mathit{Aac}^{2}, \\mathit{Aac} \\mathit{Abd}, \\mathit{Aac}^{2}, \\mathit{Aac} \\mathit{Abd}, \\mathit{Abd}^{2}, \\mathit{Abd}^{2}, \\mathit{Abd}^{2}, \\mathit{Aac}^{2}, \\mathit{Aac} \\mathit{Abd}, \\mathit{Aac}^{2}, \\mathit{Aac} \\mathit{Abd}, \\mathit{Abd}^{2}, \\mathit{Abd}^{2}\\right)\\Bold{Q}[\\mathit{Aac}, \\mathit{Abd}]' + '\\left(A_{0}^{2}, A_{0}^{2}, A_{1}^{2}, A_{0} A_{1}, A_{2}^{2}, A_{0} A_{2}, A_{0} A_{1}, A_{0}^{2}, A_{1}^{2}, A_{0} A_{1}, A_{2}^{2}, A_{0} A_{2}, A_{0} A_{2}, A_{0}^{2}, A_{1}^{2}, A_{0} A_{1}, A_{2}^{2}, A_{0} A_{2}, A_{0} A_{1}, A_{0}^{2}, A_{0} A_{1}, A_{1}^{2}, A_{2}^{2}, A_{1} A_{2}, A_{1}^{2}, A_{0}^{2}, A_{0} A_{1}, A_{1}^{2}, A_{2}^{2}, A_{1} A_{2}, A_{1} A_{2}, A_{0}^{2}, A_{0} A_{1}, A_{1}^{2}, A_{2}^{2}, A_{1} A_{2}, A_{0} A_{2}, A_{0}^{2}, A_{0} A_{2}, A_{1}^{2}, A_{1} A_{2}, A_{2}^{2}, A_{1} A_{2}, A_{0}^{2}, A_{0} A_{2}, A_{1}^{2}, A_{1} A_{2}, A_{2}^{2}, A_{2}^{2}, A_{0}^{2}, A_{0} A_{2}, A_{1}^{2}, A_{1} A_{2}, A_{2}^{2}\\right)\\Bold{Q}[A_{0}, A_{1}, A_{2}]' """ from sage.misc.latex import latex return '\\left(%s\\right)%s' % (", ".join(latex(g) From 231cb1f1aac55c9bb19b8efb117e68c716caa9aa Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Mon, 7 Oct 2024 10:44:28 +0530 Subject: [PATCH 259/537] Corrected linting error --- 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 ced1ad7ed74..240f8441269 100644 --- a/src/sage/matroids/chow_ring_ideal.py +++ b/src/sage/matroids/chow_ring_ideal.py @@ -622,7 +622,7 @@ def groebner_basis(self, algorithm='constructed', *args, **kwargs): #Copy from f term += self._flats_generator[H] if term != poly_ring.zero(): gb.append(self._flats_generator[F]*(term ** self._matroid.rank(G))* - (term**(self._matroid.rank(G)-self._matroid.rank(F)))) + (term**(self._matroid.rank(G) - self._matroid.rank(F)))) g_basis = PolynomialSequence(poly_ring, [gb]) return g_basis From 7b60d5167bf170474965f37ce335019688665a30 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Mon, 7 Oct 2024 10:51:14 +0530 Subject: [PATCH 260/537] Resolved linting errors --- src/sage/matroids/chow_ring.py | 35 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/src/sage/matroids/chow_ring.py b/src/sage/matroids/chow_ring.py index 250fd427334..348eb7b33ac 100644 --- a/src/sage/matroids/chow_ring.py +++ b/src/sage/matroids/chow_ring.py @@ -48,8 +48,8 @@ class ChowRing(QuotientRing_generic): .. SEEALSO:: - :mod:`sage.matroids.chow_ring_ideal` - + :mod:`sage.matroids.chow_ring_ideal + INPUT: - ``M`` -- matroid @@ -57,7 +57,7 @@ class ChowRing(QuotientRing_generic): - ``augmented`` -- boolean; when ``True``, this is the augmented Chow ring and if ``False``, this is the non-augmented Chow ring - ``presentation`` -- string (default: ``None``); one of the following: - + * ``"fy"`` - the Feitchner-Yuzvinsky presentation * ``"atom-free"`` - the atom-free presentation @@ -112,7 +112,7 @@ def _repr_(self): return "Augmented Chow ring of {} in Feitchner-Yuzvinsky presentation".format(self._matroid) elif self._presentation == 'atom-free': return "Augmented Chow ring of {} in atom-free presentation".format(self._matroid) - return "Chow ring of {}".format(self._matroid) + return "Chow ring of {}".format(self._matroid) def _latex_(self): r""" @@ -121,7 +121,7 @@ def _latex_(self): EXAMPLES:: sage: from sage.matroids.graphic_matroid import GraphicMatroid - + sage: M1 = GraphicMatroid(graphs.CycleGraph(3)) sage: ch = M1.chow_ring(QQ, True, 'fy') sage: ch._latex_() @@ -150,7 +150,7 @@ def _coerce_map_from_base_ring(self): def basis(self): r""" Return the monomial basis of the given Chow ring. - + EXAMPLES:: sage: ch = matroids.Uniform(3, 6).chow_ring(QQ, True, 'fy') @@ -177,7 +177,7 @@ def basis(self): for subset in subsets: flag = True sorted_list = sorted(subset, key=len) - for i in range (len(sorted_list)): #Taking only chains + for i in range(len(sorted_list)): #Taking only chains if (i != 0) & (len(sorted_list[i]) == len(sorted_list[i-1])): flag = False break @@ -204,7 +204,7 @@ def basis(self): #Generating combinations for all powers including first max_powers expression *= flats_gen[subset[0]]**max_powers[0] monomial_basis.append(expression) - + elif self._presentation == 'atom-free': subsets = [] # Generate all subsets of the frozenset using combinations @@ -213,7 +213,7 @@ def basis(self): for subset in subsets: flag = True sorted_list = sorted(subset, key=len) - for i in range (len(sorted_list)): #Taking only chains + for i in range(len(sorted_list)): #Taking only chains if (i != 0) & (len(sorted_list[i]) == len(sorted_list[i-1])): flag = False break @@ -238,7 +238,7 @@ def basis(self): expression = R.one() if sum(combination) == first_rank: for i in range(k): - expression *= flats_gen[subset[i]]**combination[i] + expression *= flats_gen[subset[i]]**combination[i] monomial_basis.append(expression) max_powers.remove(last_rank) for p in max_powers: @@ -248,13 +248,13 @@ def basis(self): expression = R.one() if sum(combination) == first_rank: for i in range(len(combination)): - expression *= flats_gen[subset[i]]**combination[i] + expression *= flats_gen[subset[i]]**combination[i] monomial_basis.append(expression) else: expression *= flats_gen[subset[k-1]]**last_rank if sum(combination) + last_rank == first_rank: for i in range(k): - expression *= flats_gen[subset[i]]**combination[i] + expression *= flats_gen[subset[i]]**combination[i] monomial_basis.append(expression) else: @@ -267,7 +267,7 @@ def basis(self): for subset in subsets: flag = True sorted_list = sorted(subset, key=len) - for i in range (len(sorted_list)): + for i in range(len(sorted_list)): if (i != 0) & (len(sorted_list[i]) == len(sorted_list[i-1])): flag = False break @@ -278,7 +278,7 @@ def basis(self): if k == 0: monomial_basis.append(R.one()) elif k == 1 & ranks[subset[0]] == 1: - monomial_basis.append(flats_gen[subset[0]]) + monomial_basis.append(flats_gen[subset[0]]) else: for i in range(k): if i == 0: @@ -290,10 +290,9 @@ def basis(self): for combination in product(*(range(1, p))): expression = R.one() for i in range(k): - expression *= flats_gen[subset[i]]**combination[i] + expression *= flats_gen[subset[i]]**combination[i] monomial_basis.append(expression) - from sage.sets.family import Family return Family([self.element_class(self, mon, reduce=False) for mon in monomial_basis]) @@ -369,10 +368,10 @@ def homogeneous_degree(self): ValueError: element is not homogeneous TESTS:: - + sage: ch = matroids.Wheel(3).chow_ring(QQ, False) sage: ch.zero().homogeneous_degree() - Traceback (most recent call last): + Traceback (most recent call last): ... ValueError: the zero element does not have a well-defined degree """ From 12e8d932c1c9cc2a75b1002701790f824d9f0659 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Mon, 7 Oct 2024 11:03:35 +0530 Subject: [PATCH 261/537] Optimized basis() method for all 3 cases --- src/sage/matroids/chow_ring.py | 195 +++++++++++++-------------------- 1 file changed, 78 insertions(+), 117 deletions(-) diff --git a/src/sage/matroids/chow_ring.py b/src/sage/matroids/chow_ring.py index 348eb7b33ac..fe2fc0ee0a4 100644 --- a/src/sage/matroids/chow_ring.py +++ b/src/sage/matroids/chow_ring.py @@ -11,6 +11,7 @@ from sage.categories.graded_algebras_with_basis import GradedAlgebrasWithBasis from sage.categories.commutative_rings import CommutativeRings from itertools import product, combinations +from sage.combinat.posets.posets import Poset class ChowRing(QuotientRing_generic): r""" @@ -122,15 +123,10 @@ def _latex_(self): sage: from sage.matroids.graphic_matroid import GraphicMatroid - sage: M1 = GraphicMatroid(graphs.CycleGraph(3)) - sage: ch = M1.chow_ring(QQ, True, 'fy') + sage: M1 = matroids.Uniform(2,5) + sage: ch = M1.chow_ring(QQ, False) sage: ch._latex_() - \Bold{Q}[A_{0}, A_{1}, A_{2}, B_{0}, B_{1}, B_{2}]/\left(B_{0}^{2}, - B_{0} B_{1}, B_{0} B_{2}, B_{0} B_{1}, B_{1}^{2}, B_{1} B_{2}, - B_{0} B_{2}, B_{1} B_{2}, B_{2}^{2}, A_{0} - B_{1} - B_{2}, - A_{1} - B_{0} - B_{2}, A_{2} - B_{0} - B_{1}\right) - \Bold{Q}[A_{0}, A_{1}, A_{2}, B_{0}, B_{1}, B_{2}] - + '\\Bold{Q}[A_{0}, A_{1}, A_{2}, A_{3}, A_{4}, A_{01234}] / \\left(A_{0} A_{1}, A_{0} A_{2}, A_{0} A_{3}, A_{0} A_{4}, A_{1} A_{2}, A_{1} A_{3}, A_{1} A_{4}, A_{2} A_{3}, A_{2} A_{4}, A_{3} A_{4}, A_{0} + A_{01234}, A_{1} + A_{01234}, A_{2} + A_{01234}, A_{3} + A_{01234}, A_{4} + A_{01234}\\right)\\Bold{Q}[A_{0}, A_{1}, A_{2}, A_{3}, A_{4}, A_{01234}]' """ from sage.misc.latex import latex return "{} / {}".format(latex(self._ideal.ring()), latex(self._ideal)) @@ -160,138 +156,103 @@ def basis(self): [A0*A013, 1] """ flats = [X for i in range(1, self._matroid.rank()) - for X in self._matroid.flats(i)] + for X in self._matroid.flats(i)] #Non empty proper flats flats_gen = self._ideal.flats_generator() R = self._ideal.ring() flats = sorted(flats, key=lambda X: (len(X), sorted(X))) ranks = {F: self._matroid.rank(F) for F in flats} monomial_basis = [] + reln = lambda x,y: x <= y + lattice_flats = Poset((flats, reln)) + chains = lattice_flats.chains() #Only chains if self._augmented: if self._presentation == 'fy': - if frozenset() in flats: - flats.remove(frozenset()) #Non empty proper flats - subsets = [] - # Generate all subsets of the frozenset using combinations - for r in range(len(flats) + 1): # r is the size of the subset - subsets.extend(list(subset) for subset in combinations(flats, r)) - for subset in subsets: - flag = True - sorted_list = sorted(subset, key=len) - for i in range(len(sorted_list)): #Taking only chains - if (i != 0) & (len(sorted_list[i]) == len(sorted_list[i-1])): - flag = False - break - if flag: - k = len(subset) - if k == 0: - monomial_basis.append(R.one()) - elif k == 1 & ranks[subset[0]] == 1: - monomial_basis.append(flats_gen[subset[0]]) - else: - max_powers = [] - max_powers.append(ranks[subset[0]]) - for i in range(1, k): - max_powers.append(ranks[subset[i]] - ranks[subset[i-1]]) - for p in max_powers: - if p != 1 & p != 0: - for combination in product(*(range(1, p))): - #Generating combinations for all powers up to max_powers - expression = R.one() - for i in range(k): - expression *= flats_gen[subset[i]]**combination[i] - monomial_basis.append(expression) - if max_powers.index(p) == 0: - #Generating combinations for all powers including first max_powers - expression *= flats_gen[subset[0]]**max_powers[0] - monomial_basis.append(expression) - - elif self._presentation == 'atom-free': - subsets = [] - # Generate all subsets of the frozenset using combinations - for r in range(len(flats) + 1): # r is the size of the subset - subsets.extend(list(subset) for subset in combinations(flats, r)) - for subset in subsets: - flag = True - sorted_list = sorted(subset, key=len) - for i in range(len(sorted_list)): #Taking only chains - if (i != 0) & (len(sorted_list[i]) == len(sorted_list[i-1])): - flag = False - break - if flag: #For every chain + for subset in chains: + k = len(subset) + if k == 0: + monomial_basis.append(R.one()) + elif k == 1 & ranks[subset[0]] == 1: + monomial_basis.append(flats_gen[subset[0]]) + else: max_powers = [] - k = len(subset) - if subset == []: - monomial_basis.append(R.one()) - else: - for i in range(k-1): - if i == 0: - max_powers.append(ranks[subset[i]]) - else: - max_powers.append(ranks[subset[i]] - ranks[subset[i-1]]) - max_powers.append(ranks[subset[k-1]]) - first_rank = ranks[subset[0]] + 1 - last_rank = ranks[subset[k-1]] - for p in max_powers: - if p != 1 & p != 0: - for combination in product(*(range(1, p))): - #Generating combinations for all powers from 1 to max_powers - expression = R.one() - if sum(combination) == first_rank: - for i in range(k): - expression *= flats_gen[subset[i]]**combination[i] - monomial_basis.append(expression) - max_powers.remove(last_rank) - for p in max_powers: - if p != 1 & p != 0: - for combination in product(*(range(1, p))): - #Generating all combinations including 0 power and max_power for first flat + max_powers.append(ranks[subset[0]]) + for i in range(1, k): + max_powers.append(ranks[subset[i]] - ranks[subset[i-1]]) + for p in max_powers: + if p != 1 & p != 0: + for combination in product(*(range(1, p))): + #Generating combinations for all powers up to max_powers expression = R.one() - if sum(combination) == first_rank: - for i in range(len(combination)): - expression *= flats_gen[subset[i]]**combination[i] - monomial_basis.append(expression) - else: - expression *= flats_gen[subset[k-1]]**last_rank - if sum(combination) + last_rank == first_rank: - for i in range(k): - expression *= flats_gen[subset[i]]**combination[i] + for i in range(k): + expression *= flats_gen[subset[i]]**combination[i] + monomial_basis.append(expression) + if max_powers.index(p) == 0: + #Generating combinations for all powers including first max_powers + expression *= flats_gen[subset[0]]**max_powers[0] monomial_basis.append(expression) - else: - if frozenset() in flats: - flats.remove(frozenset()) #Non empty proper flats - subsets = [] - # Generate all subsets of the frozenset using combinations - for r in range(len(flats) + 1): # r is the size of the subset - subsets.extend(list(subset) for subset in combinations(flats, r)) - for subset in subsets: - flag = True - sorted_list = sorted(subset, key=len) - for i in range(len(sorted_list)): - if (i != 0) & (len(sorted_list[i]) == len(sorted_list[i-1])): - flag = False - break - - if flag: + elif self._presentation == 'atom-free': + for subset in chains: max_powers = [] k = len(subset) - if k == 0: + if subset == []: monomial_basis.append(R.one()) - elif k == 1 & ranks[subset[0]] == 1: - monomial_basis.append(flats_gen[subset[0]]) else: - for i in range(k): + for i in range(k-1): if i == 0: max_powers.append(ranks[subset[i]]) else: max_powers.append(ranks[subset[i]] - ranks[subset[i-1]]) + max_powers.append(ranks[subset[k-1]]) + first_rank = ranks[subset[0]] + 1 + last_rank = ranks[subset[k-1]] for p in max_powers: if p != 1 & p != 0: for combination in product(*(range(1, p))): + #Generating combinations for all powers from 1 to max_powers expression = R.one() - for i in range(k): - expression *= flats_gen[subset[i]]**combination[i] - monomial_basis.append(expression) + if sum(combination) == first_rank: + for i in range(k): + expression *= flats_gen[subset[i]]**combination[i] + monomial_basis.append(expression) + max_powers.remove(last_rank) + for p in max_powers: + if p != 1 & p != 0: + for combination in product(*(range(1, p))): + #Generating all combinations including 0 power and max_power for first flat + expression = R.one() + if sum(combination) == first_rank: + for i in range(len(combination)): + expression *= flats_gen[subset[i]]**combination[i] + monomial_basis.append(expression) + else: + expression *= flats_gen[subset[k-1]]**last_rank + if sum(combination) + last_rank == first_rank: + for i in range(k): + expression *= flats_gen[subset[i]]**combination[i] + monomial_basis.append(expression) + + else: + for subset in chains: + max_powers = [] + k = len(subset) + if k == 0: + monomial_basis.append(R.one()) + elif k == 1 & ranks[subset[0]] == 1: + monomial_basis.append(flats_gen[subset[0]]) + else: + for i in range(k): + if i == 0: + max_powers.append(ranks[subset[i]]) + else: + max_powers.append(ranks[subset[i]] - ranks[subset[i-1]]) + for p in max_powers: + if p != 1 & p != 0: + for combination in product(*(range(1, p))): + expression = R.one() + for i in range(k): + expression *= flats_gen[subset[i]]**combination[i] + monomial_basis.append(expression) from sage.sets.family import Family return Family([self.element_class(self, mon, reduce=False) for mon in monomial_basis]) From 6a72bd39477c26a7c80bc6320e58a85cf54e4060 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Mon, 7 Oct 2024 11:23:31 +0530 Subject: [PATCH 262/537] Corrected doctests for Element() subclass --- src/sage/matroids/chow_ring.py | 34 ++++++++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/src/sage/matroids/chow_ring.py b/src/sage/matroids/chow_ring.py index fe2fc0ee0a4..f6aa75f21f0 100644 --- a/src/sage/matroids/chow_ring.py +++ b/src/sage/matroids/chow_ring.py @@ -152,8 +152,13 @@ def basis(self): sage: ch = matroids.Uniform(3, 6).chow_ring(QQ, True, 'fy') sage: ch.basis() [B0*B01, 1] - sage: ch = matroids.Wheel(3).chow_ring(ZZ, False) + sage: len(ch.defining_ideal().normal_basis()) == ch.basis().cardinality() + True + sage: ch = matroids.catalog.NonFano().chow_ring(QQ, False) [A0*A013, 1] + sage: len(ch.defining_ideal().normal_basis()) == ch.basis().cardinality() + True + """ flats = [X for i in range(1, self._matroid.rank()) for X in self._matroid.flats(i)] #Non empty proper flats @@ -268,6 +273,7 @@ def to_vector(self, order=None): sage: v = ch.an_element(); v A0 sage: v.to_vector() + (0, 0, 0, 1, 0, 0, 0) """ P = self.parent() B = P.basis() @@ -285,8 +291,9 @@ def monomial_coefficients(self, copy=None): sage: ch = matroids.catalog.NonFano().chow_ring(QQ, True, 'fy') sage: v = ch.an_element(); v - 0 + Ag sage: v.monomial_coefficients() + {0: 0, 1: 0, 2: 0, 3: 0, 4: 0, 5: 0, 6: 0, 7: 0} """ B = self.parent().basis() f = self.lift() @@ -301,11 +308,16 @@ def degree(self): sage: ch = matroids.Uniform(3, 6).chow_ring(QQ, False) sage: for b in ch.basis(): ....: print(b, b.degree()) - A0*A01 2 1 0 + A1 1 + A3 1 + A0 1 + A2 1 + A4 1 + A5 1 sage: v = sum(ch.basis()) sage: v.degree() - 2 + 1 """ return self.lift().degree() @@ -316,13 +328,19 @@ def homogeneous_degree(self): EXAMPLES:: - ch = matroids.catalog.Fano().chow_ring(QQ, True, 'fy') + sage: ch = matroids.catalog.Fano().chow_ring(QQ, True, 'fy') sage: for b in ch.basis(): ....: print(b, b.homogeneous_degree()) - Ba*Babf 2 - Ba^2 2 + 1 0 + Bb 1 + Ba 1 + Bc 1 + Bd 1 + Be 1 + Bf 1 + Bg 1 sage: v = sum(ch.basis()); v - Ba^2 + Ba*Babf + Ba + Bb + Bc + Bd + Be + Bf + Bg + 1 sage: v.homogeneous_degree() Traceback (most recent call last): ... From 31b7afb9d9e6dfef43671b2b319b32496b0ecc64 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Mon, 7 Oct 2024 11:33:14 +0530 Subject: [PATCH 263/537] Corrected linting errors in ideals file --- src/sage/matroids/chow_ring_ideal.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/sage/matroids/chow_ring_ideal.py b/src/sage/matroids/chow_ring_ideal.py index 240f8441269..64643e76ac4 100644 --- a/src/sage/matroids/chow_ring_ideal.py +++ b/src/sage/matroids/chow_ring_ideal.py @@ -621,8 +621,7 @@ def groebner_basis(self, algorithm='constructed', *args, **kwargs): #Copy from f if H < F: term += self._flats_generator[H] if term != poly_ring.zero(): - gb.append(self._flats_generator[F]*(term ** self._matroid.rank(G))* - (term**(self._matroid.rank(G) - self._matroid.rank(F)))) + gb.append(self._flats_generator[F]*(term ** self._matroid.rank(G))*(term**(self._matroid.rank(G) - self._matroid.rank(F)))) g_basis = PolynomialSequence(poly_ring, [gb]) return g_basis From e36e4ea50a943ccf77d88716d3a6a90e5db115aa Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Mon, 7 Oct 2024 11:33:35 +0530 Subject: [PATCH 264/537] Corrected linting errors in chow_ring.py --- src/sage/matroids/chow_ring.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/matroids/chow_ring.py b/src/sage/matroids/chow_ring.py index f6aa75f21f0..694fd5b29ed 100644 --- a/src/sage/matroids/chow_ring.py +++ b/src/sage/matroids/chow_ring.py @@ -113,7 +113,7 @@ def _repr_(self): return "Augmented Chow ring of {} in Feitchner-Yuzvinsky presentation".format(self._matroid) elif self._presentation == 'atom-free': return "Augmented Chow ring of {} in atom-free presentation".format(self._matroid) - return "Chow ring of {}".format(self._matroid) + return "Chow ring of {}".format(self._matroid) def _latex_(self): r""" @@ -244,7 +244,7 @@ def basis(self): if k == 0: monomial_basis.append(R.one()) elif k == 1 & ranks[subset[0]] == 1: - monomial_basis.append(flats_gen[subset[0]]) + monomial_basis.append(flats_gen[subset[0]]) else: for i in range(k): if i == 0: From 92219477d3ba88c655909d48bb46fd0da24d4571 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Mon, 7 Oct 2024 11:34:35 +0530 Subject: [PATCH 265/537] Corrected linting errors in ideals file --- 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 64643e76ac4..0cd09de5e12 100644 --- a/src/sage/matroids/chow_ring_ideal.py +++ b/src/sage/matroids/chow_ring_ideal.py @@ -621,7 +621,7 @@ def groebner_basis(self, algorithm='constructed', *args, **kwargs): #Copy from f if H < F: term += self._flats_generator[H] if term != poly_ring.zero(): - gb.append(self._flats_generator[F]*(term ** self._matroid.rank(G))*(term**(self._matroid.rank(G) - self._matroid.rank(F)))) + gb.append(self._flats_generator[F]*(term**self._matroid.rank(G))*(term**(self._matroid.rank(G) - self._matroid.rank(F)))) g_basis = PolynomialSequence(poly_ring, [gb]) return g_basis From 4156022e9b81f2b3387752fb2a6939bd195d7962 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Mon, 7 Oct 2024 11:43:03 +0530 Subject: [PATCH 266/537] Tested ideals file --- src/sage/matroids/chow_ring_ideal.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/sage/matroids/chow_ring_ideal.py b/src/sage/matroids/chow_ring_ideal.py index 0cd09de5e12..bf00e70d992 100644 --- a/src/sage/matroids/chow_ring_ideal.py +++ b/src/sage/matroids/chow_ring_ideal.py @@ -609,8 +609,6 @@ def groebner_basis(self, algorithm='constructed', *args, **kwargs): #Copy from f flats = [X for i in range(1, self._matroid.rank()) for X in self._matroid.flats(i)] poly_ring = self.ring() - if frozenset() in flats: #Non empty proper flats - flats.remove(frozenset()) for F in flats: for G in flats: if not (F > G or G > F): #Non nested flats From 35fd32b2769952e2b99c7c9f49925620f451de91 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Mon, 7 Oct 2024 11:47:43 +0530 Subject: [PATCH 267/537] Corrected basis() method --- 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 694fd5b29ed..b04c5e54598 100644 --- a/src/sage/matroids/chow_ring.py +++ b/src/sage/matroids/chow_ring.py @@ -161,7 +161,7 @@ def basis(self): """ flats = [X for i in range(1, self._matroid.rank()) - for X in self._matroid.flats(i)] #Non empty proper flats + for X in self._matroid.flats(i)] #Non empty flats flats_gen = self._ideal.flats_generator() R = self._ideal.ring() flats = sorted(flats, key=lambda X: (len(X), sorted(X))) From 7710eb594fdc942477f09949332a0bd277dae3c3 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Mon, 7 Oct 2024 11:50:54 +0530 Subject: [PATCH 268/537] Fixed linting error in matroid.pyx --- src/sage/matroids/matroid.pyx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/matroids/matroid.pyx b/src/sage/matroids/matroid.pyx index 6999c30252a..310580e1d18 100644 --- a/src/sage/matroids/matroid.pyx +++ b/src/sage/matroids/matroid.pyx @@ -8054,14 +8054,14 @@ cdef class Matroid(SageObject): sage: M = matroids.catalog.Fano() sage: A = M.chow_ring(QQ, augmented=False); A Chow ring of Fano: Binary matroid of rank 3 on 7 elements, - type (3, 0) over Rational Field. + type (3, 0) over Rational Field. The augmented Chow ring can also be constructed with the Feitchner-Yuzvinsky and atom-free presentation:: sage: M = matroids.Wheel(3) sage: ch = M.chow_ring(QQ, augmented=True, presentation='fy') - Augmented Chow ring of Wheel(3): Regular matroid of rank 3 on + Augmented Chow ring of Wheel(3): Regular matroid of rank 3 on 6 elements with 16 bases of Feitchner-Yuzvinsky presentation sage: M = matroids.Uniform(3, 6) sage: ch = M.chow_ring(QQ, augmented=True, presentation='atom-free') From d15176e222e95bebc1a356ac0d8fda18eb579ab7 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Wed, 9 Oct 2024 09:59:55 +0530 Subject: [PATCH 269/537] Edited basis() method --- src/sage/matroids/chow_ring.py | 77 +++++++++++++++------------------- 1 file changed, 34 insertions(+), 43 deletions(-) diff --git a/src/sage/matroids/chow_ring.py b/src/sage/matroids/chow_ring.py index b04c5e54598..d8ad6a638d8 100644 --- a/src/sage/matroids/chow_ring.py +++ b/src/sage/matroids/chow_ring.py @@ -160,7 +160,7 @@ def basis(self): True """ - flats = [X for i in range(1, self._matroid.rank()) + flats = [X for i in range(1, self._matroid.rank() + 1) for X in self._matroid.flats(i)] #Non empty flats flats_gen = self._ideal.flats_generator() R = self._ideal.ring() @@ -184,8 +184,8 @@ def basis(self): for i in range(1, k): max_powers.append(ranks[subset[i]] - ranks[subset[i-1]]) for p in max_powers: - if p != 1 & p != 0: - for combination in product(*(range(1, p))): + if p != 1 | p != 0: + for combination in product((range(1, p))): #Generating combinations for all powers up to max_powers expression = R.one() for i in range(k): @@ -203,61 +203,52 @@ def basis(self): if subset == []: monomial_basis.append(R.one()) else: - for i in range(k-1): + for i in range(k): if i == 0: max_powers.append(ranks[subset[i]]) else: max_powers.append(ranks[subset[i]] - ranks[subset[i-1]]) - max_powers.append(ranks[subset[k-1]]) - first_rank = ranks[subset[0]] + 1 - last_rank = ranks[subset[k-1]] - for p in max_powers: - if p != 1 & p != 0: - for combination in product(*(range(1, p))): - #Generating combinations for all powers from 1 to max_powers - expression = R.one() - if sum(combination) == first_rank: - for i in range(k): - expression *= flats_gen[subset[i]]**combination[i] - monomial_basis.append(expression) - max_powers.remove(last_rank) - for p in max_powers: - if p != 1 & p != 0: - for combination in product(*(range(1, p))): - #Generating all combinations including 0 power and max_power for first flat - expression = R.one() - if sum(combination) == first_rank: - for i in range(len(combination)): - expression *= flats_gen[subset[i]]**combination[i] - monomial_basis.append(expression) - else: - expression *= flats_gen[subset[k-1]]**last_rank - if sum(combination) + last_rank == first_rank: - for i in range(k): - expression *= flats_gen[subset[i]]**combination[i] - monomial_basis.append(expression) + first_rank = ranks[subset[k-1]] + 1 + last_rank = ranks[subset[0]] + for combination in product(*(range(1, p) for p in max_powers)): + #Generating combinations for all powers from 1 to max_powers + if sum(combination) == first_rank: + expression = R.one() + for i in range(k): + expression *= flats_gen[subset[i]]**combination[i] + monomial_basis.append(expression) + max_powers[0] = 0 + for combination in product(*(range(1, p) for p in max_powers)): + #Generating all combinations including 0 power and max_power for first flat + if sum(combination) == first_rank: + expression = R.one() + for i in range(len(combination)): + expression *= flats_gen[subset[i]]**combination[i] + monomial_basis.append(expression) + else: + expression *= flats_gen[subset[0]]**last_rank + if sum(combination) + last_rank == first_rank: + for i in range(k): + expression *= flats_gen[subset[i]]**combination[i] + monomial_basis.append(expression) else: for subset in chains: max_powers = [] k = len(subset) - if k == 0: + if (k == 0): monomial_basis.append(R.one()) - elif k == 1 & ranks[subset[0]] == 1: - monomial_basis.append(flats_gen[subset[0]]) - else: + elif not ((k == 1) & (ranks[subset[0]] == 1)): for i in range(k): if i == 0: max_powers.append(ranks[subset[i]]) else: max_powers.append(ranks[subset[i]] - ranks[subset[i-1]]) - for p in max_powers: - if p != 1 & p != 0: - for combination in product(*(range(1, p))): - expression = R.one() - for i in range(k): - expression *= flats_gen[subset[i]]**combination[i] - monomial_basis.append(expression) + for combination in product(*(range(1, p) for p in max_powers)): + expression = R.one() + for i in range(k): + expression *= flats_gen[subset[i]]**combination[i] + monomial_basis.append(expression) from sage.sets.family import Family return Family([self.element_class(self, mon, reduce=False) for mon in monomial_basis]) From 7614be81c52020057d82e727959dbb04af9e9c7f Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Wed, 9 Oct 2024 10:00:22 +0530 Subject: [PATCH 270/537] Edited definition of augmented Chow ring ideal for both presentations --- src/sage/matroids/chow_ring_ideal.py | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/sage/matroids/chow_ring_ideal.py b/src/sage/matroids/chow_ring_ideal.py index bf00e70d992..5b8cc0d1d74 100644 --- a/src/sage/matroids/chow_ring_ideal.py +++ b/src/sage/matroids/chow_ring_ideal.py @@ -299,7 +299,7 @@ def __init__(self, M, R): sage: TestSuite(I).run(skip="_test_category") """ self._matroid = M - self._flats = [X for i in range(1, self._matroid.rank()) + self._flats = [X for i in range(1, self._matroid.rank() + 1) for X in self._matroid.flats(i)] E = list(self._matroid.groundset()) self._flats_generator = dict() @@ -347,7 +347,6 @@ def _gens_constructor(self, poly_ring): A3 - B0 - B1 - B2 - B4 - B5 - B025 - B04 - B124 - B15, A4 - B0 - B1 - B2 - B3 - B5 - B013 - B025 - B15 - B23, A5 - B0 - B1 - B2 - B3 - B4 - B013 - B04 - B124 - B23] - """ E = list(self._matroid.groundset()) flats_containing = {x: [] for x in E} @@ -504,7 +503,7 @@ def __init__(self, M, R): sage: TestSuite(I).run(skip="_test_category") """ self._matroid = M - self._flats = [X for i in range(1, self._matroid.rank()) + self._flats = [X for i in range(1, self._matroid.rank() + 1) for X in self._matroid.flats(i)] E = list(self._matroid.groundset()) @@ -606,16 +605,14 @@ def groebner_basis(self, algorithm='constructed', *args, **kwargs): #Copy from f """ if algorithm == '': gb = [] - flats = [X for i in range(1, self._matroid.rank()) - for X in self._matroid.flats(i)] poly_ring = self.ring() - for F in flats: - for G in flats: + for F in self._flats: + for G in self._flats: if not (F > G or G > F): #Non nested flats gb.append(self._flats_generator[F]*self._flats_generator[G]) elif F < G: #Nested flats term = poly_ring.zero() - for H in flats: + for H in self._flats: if H < F: term += self._flats_generator[H] if term != poly_ring.zero(): From 697085f2248edfd1fb301a49aedea7e195fa0957 Mon Sep 17 00:00:00 2001 From: dcoudert Date: Wed, 9 Oct 2024 15:32:46 +0200 Subject: [PATCH 271/537] non recursive version of method gomory_hu_tree --- src/sage/graphs/graph.py | 196 +++++++++++++++++++-------------------- 1 file changed, 96 insertions(+), 100 deletions(-) diff --git a/src/sage/graphs/graph.py b/src/sage/graphs/graph.py index 976b629d49a..1d2f6ee7c0e 100644 --- a/src/sage/graphs/graph.py +++ b/src/sage/graphs/graph.py @@ -8100,97 +8100,9 @@ def is_prime(self, algorithm=None): return D[0] == NodeType.PRIME and len(D[1]) == self.order() - def _gomory_hu_tree(self, vertices, algorithm=None): - r""" - Return a Gomory-Hu tree associated to ``self``. - - This function is the private counterpart of ``gomory_hu_tree()``, with - the difference that it has an optional argument needed for recursive - computations, which the user is not interested in defining himself. - - See the documentation of ``gomory_hu_tree()`` for more information. - - INPUT: - - - ``vertices`` -- set of "real" vertices, as opposed to the fakes one - introduced during the computations. This variable is useful for the - algorithm and for recursion purposes. - - - ``algorithm`` -- select the algorithm used by the :meth:`edge_cut` - method. Refer to its documentation for allowed values and default - behaviour. - - EXAMPLES: - - This function is actually tested in ``gomory_hu_tree()``, this example - is only present to have a doctest coverage of 100%:: - - sage: g = graphs.PetersenGraph() - sage: t = g._gomory_hu_tree(frozenset(g.vertices(sort=False))) - """ - self._scream_if_not_simple() - - # Small case, not really a problem ;-) - if len(vertices) == 1: - g = Graph() - g.add_vertices(vertices) - return g - - # Take any two vertices (u,v) - it = iter(vertices) - u, v = next(it), next(it) - - # Compute a uv min-edge-cut. - # - # The graph is split into U,V with u \in U and v\in V. - flow, edges, [U, V] = self.edge_cut(u, v, use_edge_labels=True, - vertices=True, algorithm=algorithm) - - # One graph for each part of the previous one - gU, gV = self.subgraph(U, immutable=False), self.subgraph(V, immutable=False) - - # A fake vertex fU (resp. fV) to represent U (resp. V) - fU = frozenset(U) - fV = frozenset(V) - - # Each edge (uu,vv) with uu \in U and vv\in V yields: - # - an edge (uu,fV) in gU - # - an edge (vv,fU) in gV - # - # If the same edge is added several times their capacities add up. - - from sage.rings.real_mpfr import RR - for uu, vv, capacity in edges: - capacity = capacity if capacity in RR else 1 - - # Assume uu is in gU - if uu in V: - uu, vv = vv, uu - - # Create the new edges if necessary - if not gU.has_edge(uu, fV): - gU.add_edge(uu, fV, 0) - if not gV.has_edge(vv, fU): - gV.add_edge(vv, fU, 0) - - # update the capacities - gU.set_edge_label(uu, fV, gU.edge_label(uu, fV) + capacity) - gV.set_edge_label(vv, fU, gV.edge_label(vv, fU) + capacity) - - # Recursion on each side - gU_tree = gU._gomory_hu_tree(vertices & frozenset(gU), algorithm=algorithm) - gV_tree = gV._gomory_hu_tree(vertices & frozenset(gV), algorithm=algorithm) - - # Union of the two partial trees - g = gU_tree.union(gV_tree) - - # An edge to connect them, with the appropriate label - g.add_edge(u, v, flow) - - return g - @doc_index("Connectivity, orientations, trees") - def gomory_hu_tree(self, algorithm=None): + def gomory_hu_tree(self, algorithm=None, solver=None, verbose=0, + *, integrality_tolerance=1e-3): r""" Return a Gomory-Hu tree of ``self``. @@ -8211,6 +8123,27 @@ def gomory_hu_tree(self, algorithm=None): method. Refer to its documentation for allowed values and default behaviour. + - ``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 + `. + + Only useful when ``algorithm == "LP"``. + + - ``verbose`` -- integer (default: 0); sets the level of + verbosity. Set to 0 by default, which means quiet. + + Only useful when ``algorithm == "LP"``. + + - ``integrality_tolerance`` -- float; parameter for use with MILP + solvers over an inexact base ring; see + :meth:`MixedIntegerLinearProgram.get_values`. + + Only useful when ``algorithm == "LP"``. + OUTPUT: a graph with labeled edges EXAMPLES: @@ -8269,18 +8202,81 @@ def gomory_hu_tree(self, algorithm=None): sage: graphs.EmptyGraph().gomory_hu_tree() Graph on 0 vertices """ - if not self.order(): - return Graph() - if not self.is_connected(): - g = Graph() - for cc in self.connected_components_subgraphs(): - g = g.union(cc._gomory_hu_tree(frozenset(cc.vertex_iterator()), algorithm=algorithm)) - else: - g = self._gomory_hu_tree(frozenset(self.vertex_iterator()), algorithm=algorithm) + self._scream_if_not_simple() + + if self.order() <= 1: + return Graph([self, []], format='vertices_and_edges') + from sage.rings.real_mpfr import RR + + # Graph to store the Gomory-Hu tree + T = Graph([self, []], format='vertices_and_edges') if self.get_pos() is not None: - g.set_pos(dict(self.get_pos())) - return g + T.set_pos(dict(self.get_pos())) + + # We use a stack to avoid recursion. An element of the stack contains + # the graph to be processed and the corresponding set of "real" vertices + # (as opposed to the fakes one introduced during the computations. + if self.is_connected(): + stack = [(self, frozenset(self))] + else: + stack = [(cc, frozenset(cc)) for cc in self.connected_components_subgraphs()] + + # We now iteratively decompose the graph to build the tree + while stack: + G, vertices = stack.pop() + + if len(vertices) == 1: + continue + + # Take any two vertices (u,v) + it = iter(vertices) + u, v = next(it), next(it) + + # Compute a uv min-edge-cut. + # + # The graph is split into U,V with u \in U and v\in V. + flow, edges, [U, V] = G.edge_cut(u, v, use_edge_labels=True, + vertices=True, algorithm=algorithm, + solver=solver, verbose=verbose, + integrality_tolerance=integrality_tolerance) + + # Add edge (u, v, flow) to the Gomory-Hu tree + T.add_edge(u, v, flow) + + # Build one graph for each part of the previous graph and store the + # instances to process + for X, Y in ((U, V), (V, U)): + if len(X) == 1 or len(vertices & frozenset(X)) == 1: + continue + + # build the graph of part X + gX = G.subgraph(X, immutable=False) + + # A fake vertex fY to represent Y + fY = frozenset(Y) + + # For each edge (x, y) in G with x \in X and y\in Y, add edge + # (x, fY) in gX. If the same edge is added several times their + # capacities add up. + for xx, yy, capacity in edges: + capacity = capacity if capacity in RR else 1 + + # Assume xx is in gX + if xx in fY: + xx, yy = yy, xx + + # Create the new edge or update its capacity + if gX.has_edge(xx, fY): + gX.set_edge_label(xx, fY, gX.edge_label(xx, fY) + capacity) + else: + gX.add_edge(xx, fY, capacity) + + # Store instance to process + stack.append((gX, vertices & frozenset(gX))) + + # Finally return the Gomory-Hu tree + return T @doc_index("Leftovers") def two_factor_petersen(self, solver=None, verbose=0, *, integrality_tolerance=1e-3): From b5a2727e738a66c4094fed5d6272e627b5081060 Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Sun, 13 Oct 2024 09:50:44 +0200 Subject: [PATCH 272/537] very minor docstring fixes --- src/sage/rings/species.py | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/sage/rings/species.py b/src/sage/rings/species.py index 082403e0875..8e6d534c1a2 100644 --- a/src/sage/rings/species.py +++ b/src/sage/rings/species.py @@ -292,7 +292,6 @@ def __classcall__(cls, parent, dis, domain_partition): False sage: a is c True - """ mc = tuple(len(v) for v in domain_partition) domain = list(chain(*map(sorted, domain_partition))) @@ -586,7 +585,7 @@ def _rename(self, n): def __contains__(self, x): r""" - Return if ``x`` is in ``self``. + Return whether ``x`` is in ``self``. TESTS:: @@ -1429,7 +1428,6 @@ def _compose_with_singletons(self, names, args): T^2*S + E_2(T)*S sage: F._compose_with_singletons(["T", "S"], [[1, 2]]) T*E_2(S) + T*S^2 - """ # TODO: possibly check that all args are compositions, # and that sums match cardinalities @@ -1512,7 +1510,6 @@ def _compose_with_weighted_singletons(self, names, multiplicities, degrees): sage: (C4+E2^2)._compose_with_weighted_singletons(["X"], [-1], [[4]]) -C_4 + {((1,2)(3,4),)} + E_2^2 - 2*X^2*E_2 + X^4 - """ P = self.parent() if not self.support(): @@ -1527,7 +1524,8 @@ def _compose_with_weighted_singletons(self, names, multiplicities, degrees): return left.hadamard_product(right) def __call__(self, *args): - """ + r""" + Substitute the arguments into ``self``. EXAMPLES:: @@ -1558,7 +1556,6 @@ def __call__(self, *args): sage: E2 = P(SymmetricGroup(2)) sage: E2(q*X) q^2*E_2 - """ P = self.parent() if len(args) != P._arity: @@ -1711,7 +1708,7 @@ def _element_constructor_(self, G, pi=None): return self.sum_of_terms((self._indices(H, pi), ZZ.one()) for H in Hs) def _first_ngens(self, n): - """ + r""" Used by the preparser for ``F. = ...``. We do not use the generic implementation of @@ -1882,7 +1879,8 @@ def exponential(self, multiplicities, degrees): """ def stretch(c, k): r""" - Return c + Substitute in ``c`` all variables appearing in the + base ring with their ``k``-th power. """ if callable(c): B = self.base_ring() From 470fa711d5721f4101984370af4af1b750620cb0 Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Sun, 13 Oct 2024 12:07:38 +0200 Subject: [PATCH 273/537] add factorization of polynomial species --- src/sage/rings/species.py | 41 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/src/sage/rings/species.py b/src/sage/rings/species.py index 8e6d534c1a2..a4ba9dee5ac 100644 --- a/src/sage/rings/species.py +++ b/src/sage/rings/species.py @@ -22,9 +22,11 @@ IndexedFreeAbelianMonoidElement) from sage.rings.rational_field import QQ from sage.rings.integer_ring import ZZ +from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing from sage.sets.set import Set from sage.structure.category_object import normalize_names from sage.structure.element import Element, parent +from sage.structure.factorization import Factorization from sage.structure.parent import Parent from sage.structure.unique_representation import UniqueRepresentation @@ -1586,6 +1588,45 @@ def __call__(self, *args): result += P0.sum_of_terms(FG) return result + def factor(self): + r""" + Return the factorization of this species. + + EXAMPLES:: + + sage: from sage.rings.species import PolynomialSpecies + sage: P = PolynomialSpecies(ZZ, ["X"]) + sage: C3 = P(CyclicPermutationGroup(3)) + sage: X = P(SymmetricGroup(1)) + sage: E2 = P(SymmetricGroup(2)) + sage: f = (3*E2*X + C3)*(2*E2 + C3) + sage: factor(f) + (2*E_2 + C_3) * (3*E_2*X + C_3) + """ + # find the set of atoms and fix an order + atoms = list(set(a for m in self.monomial_coefficients() + for a in m.support())) + R = PolynomialRing(self.base_ring(), "x", len(atoms)) + var_dict = dict(zip(atoms, R.gens())) + # create the polynomial + poly = R.sum(c * R.prod(var_dict[a] ** e for a, e in m.dict().items()) + for m, c in self) + factors = poly.factor() + unit = self.base_ring()(factors.unit()) + if factors.universe() == self.base_ring(): + return Factorization(factors, unit=unit) + P = self.parent() + M = P._indices + + def _from_etuple(e): + return M.element_class(M, {a: i for a, i in zip(atoms, e) if i}) + + factors = [(P.sum_of_terms((_from_etuple(mon), c) + for mon, c in factor.monomial_coefficients().items()), + exponent) + for factor, exponent in factors] + return Factorization(factors, unit=unit, sort=False) + class PolynomialSpecies(CombinatorialFreeModule): def __classcall__(cls, base_ring, names): From d54f0cba7f459d1c9d47af67865b1029b9e58b66 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Sun, 13 Oct 2024 19:36:57 +0530 Subject: [PATCH 274/537] Changed defn of augmented Chow ring ideal FY presentation --- src/sage/matroids/chow_ring_ideal.py | 32 +++++++++++++++++----------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/src/sage/matroids/chow_ring_ideal.py b/src/sage/matroids/chow_ring_ideal.py index 5b8cc0d1d74..8ee112abc23 100644 --- a/src/sage/matroids/chow_ring_ideal.py +++ b/src/sage/matroids/chow_ring_ideal.py @@ -192,9 +192,7 @@ def _latex_(self): '\\left(\\mathit{Aac} \\mathit{Abd}, \\mathit{Aac} + \\mathit{Aabcd}, \\mathit{Abd} + \\mathit{Aabcd}\\right)\\Bold{Q}[\\mathit{Aac}, \\mathit{Abd}, \\mathit{Aabcd}]' """ from sage.misc.latex import latex - return '\\left(%s\\right)%s' % (", ".join(latex(g) - for g in self.gens()), - latex(self.ring())) + return 'I_{M} + J_{M} of matroid ' + (latex(self._matroid)) def groebner_basis(self, algorithm='', *args, **kwargs): r""" @@ -299,7 +297,7 @@ def __init__(self, M, R): sage: TestSuite(I).run(skip="_test_category") """ self._matroid = M - self._flats = [X for i in range(1, self._matroid.rank() + 1) + self._flats = [X for i in range(self._matroid.rank() + 1) for X in self._matroid.flats(i)] E = list(self._matroid.groundset()) self._flats_generator = dict() @@ -355,17 +353,23 @@ def _gens_constructor(self, poly_ring): flats_containing[x].append(F) Q = list() + L = list() + term = poly_ring.zero() for F in self._flats: + term += self._flats_generator[F] for G in self._flats: if not (F < G or G < F): Q.append(self._flats_generator[F] * self._flats_generator[G]) #Quadratic Generators - L = list() + L.append(term) + for x in E: term = poly_ring.zero() for F in self._flats: if F not in flats_containing[x]: + Q.append(self._flats_generator[x] * self._flats_generator[F]) + else: term += self._flats_generator[F] - L.append(self._flats_generator[x] - term) #Linear Generators + L.append(self._flats_generator[x] + term) #Linear Generators return Q + L def _repr_(self): @@ -408,25 +412,26 @@ def groebner_basis(self, algorithm='constructed', *args, **kwargs): True """ if algorithm == '': - gb = [] #Don't use flats. Get lattice of flats and use order_filter() + gb = [] E = list(self._matroid.groundset()) poly_ring = self.ring() for F in self._flats: for G in self._flats: if not (F < G or G < F): #Non-nested flats gb.append(self._flats_generator[F]*self._flats_generator[G]) + for i in E: term = poly_ring.zero() term1 = poly_ring.zero() - for H in self._flats: #Remove it somehow - if i in H: #WASTEFUL + for H in self._flats: + if i in H: term += self._flats_generator[H] - if H > G: #WASTEFUL + if H > G: term1 += self._flats_generator[H] if term != poly_ring.zero(): gb.append(self._flats_generator[i] + term) #5.7 if term1 != poly_ring.zero(): - gb.append(term1**(self._matroid.rank(G)) + 1) #5.6 + gb.append(term1**(self._matroid.rank(F) + 1)) #5.6 if i in G: #if element in flat if term1 != poly_ring.zero(): @@ -435,8 +440,9 @@ def groebner_basis(self, algorithm='constructed', *args, **kwargs): elif i not in G: #if element not in flat gb.append(self._flats_generator[i]*self._flats_generator[F]) - elif G < F: #nested flats - gb.append(self._flats_generator[G]*term1**(self._matroid.rank(F)-self._matroid.rank(G))) + if G < F: #nested flats + if term1 != poly_ring.zero(): + gb.append(self._flats_generator[G]*term1**(self._matroid.rank(F)-self._matroid.rank(G))) g_basis = PolynomialSequence(poly_ring, [gb]) return g_basis From 846690ea16e434b40ad8e30be3248d9878960ce5 Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Sun, 13 Oct 2024 18:17:45 +0200 Subject: [PATCH 275/537] introduce comparisons and add subset and graded_component for atomic species --- src/sage/rings/species.py | 300 ++++++++++++++++++++++++++++++++++---- 1 file changed, 269 insertions(+), 31 deletions(-) diff --git a/src/sage/rings/species.py b/src/sage/rings/species.py index a4ba9dee5ac..0ce15903664 100644 --- a/src/sage/rings/species.py +++ b/src/sage/rings/species.py @@ -30,6 +30,8 @@ from sage.structure.parent import Parent from sage.structure.unique_representation import UniqueRepresentation +GAP_FAIL = libgap.eval('fail') + class ConjugacyClassOfDirectlyIndecomposableSubgroups(UniqueRepresentation, Element, metaclass=InheritComparisonClasscallMetaclass): @@ -389,6 +391,76 @@ def grade(self): S = self.parent().grading_set() return S(self._mc) + def __le__(self, other): + r""" + Return if this element is less than or equal to ``other``. + + ``self`` is less than or equal to ``other`` if it is + conjugate to a subgroup of ``other`` in the parent group. + + EXAMPLES: + + We create the poset of atomic species of degree four:: + + sage: from sage.rings.species import AtomicSpecies + sage: A = AtomicSpecies("X") + sage: P = Poset([A.subset(4), lambda b, c: b <= c]) + sage: len(P.cover_relations()) + 7 + sage: P.cover_relations() # random + [[E_4, Eo_4], + [E_4, P_4], + [Eo_4, Pb_4], + [P_4, C_4], + [P_4, Pb_4], + [C_4, {((1,2)(3,4),)}], + [Pb_4, {((1,2)(3,4),)}]] + + TESTS:: + + sage: [(a, b) for a, b in Subsets(A.subset(4), 2) if (a < b) != (b > a)] + [] + sage: A = AtomicSpecies("X, Y") + sage: [(a, b) for a, b in Subsets(A.subset(3), 2) if (a < b) != (b > a)] + [] + """ + if (not isinstance(other, AtomicSpeciesElement) + or len(self._mc) != len(other._mc)): + return False + if self._mc != other._mc: + # X should come before Y + return (sum(self._mc) < sum(other._mc) + or (sum(self._mc) == sum(other._mc) + and self._mc > other._mc)) + S = SymmetricGroup(sum(self._mc)).young_subgroup(self._mc) + # conjugate self and other to match S + g = list(chain.from_iterable(self._dompart)) + conj_self = PermutationGroupElement(g).inverse() + G = libgap.ConjugateGroup(self._dis._C, conj_self) + h = list(chain.from_iterable(other._dompart)) + conj_other = PermutationGroupElement(h).inverse() + H = libgap.ConjugateGroup(other._dis._C, conj_other) + return GAP_FAIL != libgap.ContainedConjugates(S, G, H, True) + + def __lt__(self, other): + r""" + Return if this element is less than ``other``. + + ``self`` is less than or equal to ``other`` if it is + conjugate to a subgroup of ``other`` in the parent group. + + EXAMPLES:: + + sage: from sage.rings.species import AtomicSpecies + sage: A = AtomicSpecies("X") + sage: A(SymmetricGroup(4)) < A(CyclicPermutationGroup(4)) + True + """ + if (not isinstance(other, AtomicSpeciesElement) + or len(self._mc) != len(other._mc)): + return False + return self is not other and self <= other + class AtomicSpecies(UniqueRepresentation, Parent): """ @@ -634,6 +706,43 @@ def grading_set(self): """ return IntegerVectors(length=self._arity) + def subset(self, size): + """ + Return the set of atomic species with given total cardinality. + + EXAMPLES:: + + sage: from sage.rings.species import AtomicSpecies + sage: A = AtomicSpecies(["X", "Y"]) + sage: sorted(A.subset(3)) + [E_3(X), C_3(X), E_3(Y), C_3(Y)] + """ + result = Set() + for grade in IntegerVectors(size, length=self._arity): + result = result.union(self.graded_component(grade)) + return result + + def graded_component(self, grade): + """ + Return the set of atomic species with given multicardinality. + + EXAMPLES:: + + sage: from sage.rings.species import AtomicSpecies + sage: A = AtomicSpecies(["X", "Y"]) + sage: len(A.graded_component([2, 3])) + 1 + sage: A.graded_component([2, 3]) # random + {{((2,3)(4,5), (1,2,3)): ({4, 5}, {1, 2, 3})}} + """ + assert len(grade) == self._arity + n = sum(grade) + S = SymmetricGroup(n).young_subgroup(grade) + dom = S.domain() + dompart = {i: dom[sum(grade[:i]): sum(grade[:i+1])] for i in range(len(grade))} + return Set([self(G, dompart) for G in S.conjugacy_classes_subgroups() + if len(G.disjoint_direct_product_decomposition()) <= 1]) + @cached_method def an_element(self): """ @@ -767,7 +876,7 @@ def __init__(self, *args, **kwds): sage: M = MolecularSpecies("X,Y") sage: G = PermutationGroup([[(1,2),(3,4)], [(5,6)]]) sage: M(G, {0: [5,6], 1: [1,2,3,4]}) - {((1,2)(3,4),): ({}, {1, 2, 3, 4})}*E_2(X) + E_2(X)*{((1,2)(3,4),): ({}, {1, 2, 3, 4})} TESTS: @@ -832,7 +941,7 @@ def _element_constructor_(self, G, pi=None): sage: X = SetPartitions(8, [4, 2, 2]) sage: M((X, a), {0: X.base_set()}) - P_4*E_4 + E_4*P_4 TESTS:: @@ -933,7 +1042,7 @@ def graded_component(self, grade): sage: from sage.rings.species import MolecularSpecies sage: M = MolecularSpecies(["X", "Y"]) - sage: M.graded_component([3,2]) # random + sage: M.graded_component([3, 2]) # random {E_3(X)*Y^2, X^3*Y^2, X*E_2(X)*E_2(Y), X^3*E_2(Y), {((1,2,3), (1,3)(4,5)): ({1, 2, 3}, {4, 5})}, X*{((1,2)(3,4),): ({1, 2}, {3, 4})}, X*E_2(X)*Y^2, E_3(X)*E_2(Y), @@ -999,6 +1108,131 @@ def grade(self): mc = sum(n * vector(a._mc) for a, n in mons.items()) return S(mc) + def __le__(self, other): + r""" + Return if this element is less than or equal to ``other``. + + ``self`` is less or equal to ``other`` if it is conjugate to + a subgroup of ``other`` in the parent group. + + EXAMPLES: + + We create the lattice of molecular species of degree four:: + + sage: from sage.rings.species import MolecularSpecies + sage: M = MolecularSpecies("X") + sage: P = Poset([M.subset(4), lambda b, c: b <= c]) + sage: len(P.cover_relations()) + 17 + sage: P.cover_relations() # random + [[E_4, P_4], + [E_4, Eo_4], + [E_4, X*E_3], + [P_4, C_4], + [P_4, E_2^2], + [P_4, Pb_4], + [C_4, {((1,2)(3,4),)}], + [E_2^2, {((1,2)(3,4),)}], + [E_2^2, X^2*E_2], + [Eo_4, Pb_4], + [Eo_4, X*C_3], + [Pb_4, {((1,2)(3,4),)}], + [{((1,2)(3,4),)}, X^4], + [X*E_3, X^2*E_2], + [X*E_3, X*C_3], + [X^2*E_2, X^4], + [X*C_3, X^4]] + + TESTS:: + + sage: [(a, b) for a, b in Subsets(M.subset(4), 2) if (a < b) != (b > a)] + [] + + sage: M = MolecularSpecies("S, T") + sage: S = M(SymmetricGroup(1), {0: [1]}) + sage: T = M(SymmetricGroup(1), {1: [1]}) + sage: E2S = M(SymmetricGroup(2), {0: [1,2]}) + sage: T * E2S < S^2 * T + True + """ + if (not isinstance(other, MolecularSpecies.Element) + or len(self.grade()) != len(other.grade())): + return False + if self.grade() != other.grade(): + # X should come before Y + return (sum(self.grade()) < sum(other.grade()) + or (sum(self.grade()) == sum(other.grade()) + and self.grade() > other.grade())) + + S = SymmetricGroup(sum(self.grade())).young_subgroup(self.grade()) + # conjugate self and other to match S + G, G_dompart = self.group_and_partition() + g = list(chain.from_iterable(G_dompart)) + conj_self = PermutationGroupElement(g).inverse() + G = libgap.ConjugateGroup(G, conj_self) + H, H_dompart = other.group_and_partition() + h = list(chain.from_iterable(H_dompart)) + conj_other = PermutationGroupElement(h).inverse() + H = libgap.ConjugateGroup(H, conj_other) + return GAP_FAIL != libgap.ContainedConjugates(S, G, H, True) + + def __lt__(self, other): + r""" + Return if this element is less than ``other``. + + ``self`` is less than or equal to ``other`` if it is + conjugate to a subgroup of ``other`` in the parent group. + + EXAMPLES:: + + sage: from sage.rings.species import MolecularSpecies + sage: M = MolecularSpecies("X") + sage: M(SymmetricGroup(4)) < M(CyclicPermutationGroup(4)) + True + """ + if (not isinstance(other, MolecularSpecies.Element) + or len(self.grade()) != len(other.grade())): + return False + return self != other and self <= other + + def __gt__(self, other): + r""" + Return if this element is greater than ``other``. + + ``self`` is less than or equal to ``other`` if it is + conjugate to a subgroup of ``other`` in the parent group. + + EXAMPLES:: + + sage: from sage.rings.species import MolecularSpecies + sage: M = MolecularSpecies("X") + sage: M(SymmetricGroup(4)) > M(CyclicPermutationGroup(4)) + False + """ + if (not isinstance(other, MolecularSpecies.Element) + or len(self.grade()) != len(other.grade())): + return False + return other < self + + def __ge__(self, other): + r""" + Return if this element is greater than or equal to ``other``. + + ``self`` is less than or equal to ``other`` if it is + conjugate to a subgroup of ``other`` in the parent group. + + EXAMPLES:: + + sage: from sage.rings.species import MolecularSpecies + sage: M = MolecularSpecies("X") + sage: M(SymmetricGroup(4)) >= M(CyclicPermutationGroup(4)) + False + """ + if (not isinstance(other, MolecularSpecies.Element) + or len(self.grade()) != len(other.grade())): + return False + return other <= self + @cached_method def group_and_partition(self): """ @@ -1009,24 +1243,28 @@ def group_and_partition(self): sage: from sage.rings.species import MolecularSpecies sage: M = MolecularSpecies("X,Y") sage: G = PermutationGroup([[(1,2),(3,4)], [(5,6)]]) - sage: A = M(G, {0: [5,6], 1: [1,2,3,4]}) + sage: A = M(G, {0: [5,6], 1: [1,2,3,4]}); A + E_2(X)*{((1,2)(3,4),): ({}, {1, 2, 3, 4})} sage: A.group_and_partition() - (Permutation Group with generators [(5,6), (1,2)(3,4)], - (frozenset({5, 6}), frozenset({1, 2, 3, 4}))) + (Permutation Group with generators [(3,4)(5,6), (1,2)], + (frozenset({1, 2}), frozenset({3, 4, 5, 6}))) TESTS:: - sage: M = MolecularSpecies("X,Y") - sage: B = M(PermutationGroup([(1,2,3)]), {0: [1,2,3]}) + sage: B = M(PermutationGroup([(1,2,3)]), {0: [1,2,3]}); B + C_3(X) sage: B.group_and_partition() (Permutation Group with generators [(1,2,3)], (frozenset({1, 2, 3}), frozenset())) + sage: A*B + E_2(X)*C_3(X)*{((1,2)(3,4),): ({}, {1, 2, 3, 4})} sage: (A*B).group_and_partition() - (Permutation Group with generators [(7,8,9), (5,6), (1,2)(3,4)], - (frozenset({5, 6, 7, 8, 9}), frozenset({1, 2, 3, 4}))) + (Permutation Group with generators [(6,7)(8,9), (3,4,5), (1,2)], + (frozenset({1, 2, 3, 4, 5}), frozenset({6, 7, 8, 9}))) - sage: C = M(PermutationGroup([(2,3)]), {0: [1], 1: [2,3]}) + sage: C = M(PermutationGroup([(2,3)]), {0: [1], 1: [2,3]}); C + X*E_2(Y) sage: C.group_and_partition() (Permutation Group with generators [(2,3)], (frozenset({1}), frozenset({2, 3}))) @@ -1409,7 +1647,7 @@ def _compose_with_singletons(self, names, args): sage: P = PolynomialSpecies(ZZ, "X") sage: C4 = P(CyclicPermutationGroup(4)) sage: C4._compose_with_singletons("X, Y", [[2, 2]]) - X^2*Y^2 + E_2(XY) + E_2(XY) + X^2*Y^2 sage: P = PolynomialSpecies(ZZ, ["X", "Y"]) sage: F = P(PermutationGroup([[(1,2,3), (4,5,6)]]), {0: [1,2,3], 1: [4,5,6]}) @@ -1426,10 +1664,10 @@ def _compose_with_singletons(self, names, args): 1 sage: F = P(SymmetricGroup(1)) * P(SymmetricGroup(2)) - sage: F._compose_with_singletons(["T", "S"], [[2, 1]]) - T^2*S + E_2(T)*S - sage: F._compose_with_singletons(["T", "S"], [[1, 2]]) - T*E_2(S) + T*S^2 + sage: F._compose_with_singletons(["S", "T"], [[2, 1]]) + T*E_2(S) + S^2*T + sage: F._compose_with_singletons(["S", "T"], [[1, 2]]) + S*E_2(T) + S*T^2 """ # TODO: possibly check that all args are compositions, # and that sums match cardinalities @@ -1497,7 +1735,7 @@ def _compose_with_weighted_singletons(self, names, multiplicities, degrees): Exercise (2.5.17) in [BLL1998]_:: sage: C4._compose_with_weighted_singletons(["X", "Y"], [1, 1], [[2, 2]]) - X^2*Y^2 + E_2(XY) + E_2(XY) + X^2*Y^2 sage: C4._compose_with_weighted_singletons(["X", "Y"], [1, 1], [[3, 1]]) X^3*Y sage: C4._compose_with_weighted_singletons(["X", "Y"], [1, 1], [[4, 0]]) @@ -1506,12 +1744,12 @@ def _compose_with_weighted_singletons(self, names, multiplicities, degrees): Equation (4.60) in [ALL2002]_:: sage: C4._compose_with_weighted_singletons(["X", "Y"], [1, -1], [[2, 2]]) - 2*X^2*Y^2 - E_2(XY) + -E_2(XY) + 2*X^2*Y^2 TESTS:: sage: (C4+E2^2)._compose_with_weighted_singletons(["X"], [-1], [[4]]) - -C_4 + {((1,2)(3,4),)} + E_2^2 - 2*X^2*E_2 + X^4 + -C_4 + E_2^2 + {((1,2)(3,4),)} - 2*X^2*E_2 + X^4 """ P = self.parent() if not self.support(): @@ -1547,7 +1785,7 @@ def __call__(self, *args): sage: X = P2(SymmetricGroup(1), {0: [1]}) sage: Y = P2(SymmetricGroup(1), {1: [1]}) sage: E2(X + Y) - E_2(Y) + Y*X + E_2(X) + E_2(X) + X*Y + E_2(Y) sage: E2(X*Y)(E2(X), E2(Y)) {((7,8), (5,6), (3,4), (1,2), (1,3)(2,4)(5,7)(6,8)): ({1, 2, 3, 4}, {5, 6, 7, 8})} @@ -1601,7 +1839,7 @@ def factor(self): sage: E2 = P(SymmetricGroup(2)) sage: f = (3*E2*X + C3)*(2*E2 + C3) sage: factor(f) - (2*E_2 + C_3) * (3*E_2*X + C_3) + (2*E_2 + C_3) * (3*X*E_2 + C_3) """ # find the set of atoms and fix an order atoms = list(set(a for m in self.monomial_coefficients() @@ -1709,13 +1947,13 @@ def _element_constructor_(self, G, pi=None): sage: X = SetPartitions(4, 2) sage: a = lambda g, x: SetPartition([[g(e) for e in b] for b in x]) sage: P((X, a), {0: [1,2], 1: [3,4]}) - X^2*E_2(Y) + E_2(XY) + E_2(X)*Y^2 + E_2(X)*E_2(Y) + E_2(X)*E_2(Y) + X^2*E_2(Y) + E_2(XY) + Y^2*E_2(X) sage: P = PolynomialSpecies(ZZ, ["X"]) sage: X = SetPartitions(4, 2) sage: a = lambda g, x: SetPartition([[g(e) for e in b] for b in x]) sage: P((X, a), {0: [1,2,3,4]}) - E_3*X + P_4 + X*E_3 + P_4 The species of permutation groups:: @@ -1845,8 +2083,8 @@ def product_on_basis(self, H, K): sage: L1 = [P(H) for H in SymmetricGroup(3).conjugacy_classes_subgroups()] sage: L2 = [P(H) for H in SymmetricGroup(2).conjugacy_classes_subgroups()] sage: matrix([[F * G for F in L1] for G in L2]) # indirect doctest - [ X^5 X^3*E_2 C_3*X^2 E_3*X^2] - [X^3*E_2 X*E_2^2 C_3*E_2 E_3*E_2] + [ X^5 X^3*E_2 X^2*C_3 X^2*E_3] + [X^3*E_2 X*E_2^2 E_2*C_3 E_2*E_3] TESTS:: @@ -1871,7 +2109,7 @@ def powersum(self, s, n): sage: from sage.rings.species import PolynomialSpecies sage: P = PolynomialSpecies(ZZ, "X") sage: P.powersum(0, 4) - 4*E_4 - 4*X*E_3 + 4*X^2*E_2 - X^4 - 2*E_2^2 + 4*E_4 - 4*X*E_3 - 2*E_2^2 + 4*X^2*E_2 - X^4 """ assert n in ZZ and n > 0 if n == 1: @@ -1889,11 +2127,11 @@ def exponential(self, multiplicities, degrees): sage: from sage.rings.species import PolynomialSpecies sage: P = PolynomialSpecies(QQ, ["X"]) - sage: P.exponential([3/2], [7]) # random - 3/2*E_7 + 3/4*X*E_6 - 3/16*X^2*E_5 + 3/32*X^3*E_4 - 15/256*E_3*X^4 - + 21/512*X^5*E_2 - 9/2048*X^7 - 15/128*X^3*E_2^2 - 3/8*E_2*E_4*X - + 3/32*X*E_2^3 - 3/16*X*E_3^2 + 3/4*E_2*E_5 - 3/16*E_3*E_2^2 - + 3/4*E_3*E_4 + 9/32*E_3*E_2*X^2 + sage: P.exponential([3/2], [7]) + 3/2*E_7 + 3/4*X*E_6 + 3/4*E_2*E_5 - 3/16*X^2*E_5 + 3/4*E_3*E_4 + - 3/8*X*E_2*E_4 + 3/32*X^3*E_4 - 3/16*X*E_3^2 - 3/16*E_2^2*E_3 + + 9/32*X^2*E_2*E_3 - 15/256*X^4*E_3 + 3/32*X*E_2^3 + - 15/128*X^3*E_2^2 + 21/512*X^5*E_2 - 9/2048*X^7 We support weights:: From 55a416a88d7f1edbef8fec41608954a73a118acb Mon Sep 17 00:00:00 2001 From: janmenjayap Date: Sun, 13 Oct 2024 21:56:52 +0530 Subject: [PATCH 276/537] introduced self.matching --- src/sage/graphs/matching_covered_graph.py | 71 +++++++++++++++++++++-- 1 file changed, 66 insertions(+), 5 deletions(-) diff --git a/src/sage/graphs/matching_covered_graph.py b/src/sage/graphs/matching_covered_graph.py index fb22608c30c..e90b404a9ee 100644 --- a/src/sage/graphs/matching_covered_graph.py +++ b/src/sage/graphs/matching_covered_graph.py @@ -80,12 +80,18 @@ class MatchingCoveredGraph(Graph): sage: G = MatchingCoveredGraph(graphs.PetersenGraph()) sage: G Matching covered petersen graph: graph on 10 vertices + sage: G.matching + [(0, 5, None), (1, 6, None), (2, 7, None), (3, 8, None), (4, 9, None)] + sage: G = graphs.StaircaseGraph(4) sage: H = MatchingCoveredGraph(G) sage: H Matching covered staircase graph: graph on 8 vertices sage: H == G True + sage: H.matching + [(0, 1, None), (2, 7, None), (3, 6, None), (4, 5, None)] + sage: G = Graph({0: [1, 2, 3, 4], 1: [2, 5], ....: 2: [5], 3: [4, 5], 4: [5]}) sage: H = MatchingCoveredGraph(G) @@ -93,6 +99,8 @@ class MatchingCoveredGraph(Graph): Matching covered graph on 6 vertices sage: H == G True + sage: H.matching + [(0, 4, None), (1, 2, None), (3, 5, None)] sage: # needs networkx sage: import networkx @@ -102,12 +110,17 @@ class MatchingCoveredGraph(Graph): Matching covered graph on 24 vertices sage: H == G True + sage: H.matching + [(4, 23, None), (6, 21, None), (11, 16, None), (7, 20, None), (10, 17, None), (1, 14, None), (2, 13, None), (8, 19, None), (9, 18, None), (3, 12, None), (5, 22, None), (0, 15, None)] + sage: G = Graph('E|fG', sparse=True) sage: H = MatchingCoveredGraph(G) sage: H Matching covered graph on 6 vertices sage: H == G True + sage: H.matching + [(0, 5, None), (1, 2, None), (3, 4, None)] sage: # needs sage.modules sage: M = Matrix([(0,1,0,0,1,1,0,0,0,0), @@ -135,6 +148,8 @@ class MatchingCoveredGraph(Graph): sage: H = MatchingCoveredGraph(G) sage: H == G True + sage: H.matching + [(0, 5, None), (1, 6, None), (2, 7, None), (3, 8, None), (4, 9, None)] sage: # needs sage.modules sage: M = Matrix([(-1, 0, 0, 0, 1, 0, 0, 0, 0, 0,-1, 0, 0, 0, 0), @@ -162,11 +177,16 @@ class MatchingCoveredGraph(Graph): sage: H = MatchingCoveredGraph(G) sage: H == G True + sage: H.matching + [(0, 5, None), (1, 6, None), (2, 7, None), (3, 8, None), (4, 9, None)] + sage: G = Graph([(0, 1), (0, 3), (0, 4), (1, 2), (1, 5), (2, 3), ....: (2, 6), (3, 7), (4, 5), (4, 7), (5, 6), (6, 7)]) sage: H = MatchingCoveredGraph(G) sage: H == G True + sage: H.matching + [(0, 4, None), (1, 5, None), (2, 6, None), (3, 7, None)] sage: # optional - python_igraph sage: import igraph @@ -174,23 +194,34 @@ class MatchingCoveredGraph(Graph): sage: H = MatchingCoveredGraph(G) sage: H Matching covered graph on 4 vertices + sage: H.matching + [(0, 3, {}), (1, 2, {})] One may specify a matching:: sage: P = graphs.PetersenGraph() sage: M = P.matching() + sage: M + [(0, 5, None), (1, 6, None), (2, 7, None), (3, 8, None), (4, 9, None)] sage: G = MatchingCoveredGraph(P, matching=M) sage: G Matching covered petersen graph: graph on 10 vertices sage: P == G True + sage: G.matching + [(0, 5, None), (1, 6, None), (2, 7, None), (3, 8, None), (4, 9, None)] + sage: G = graphs.TruncatedBiwheelGraph(14) sage: M = G.matching() + sage: M + [(20, 21, None), (1, 26, None), (10, 11, None), (14, 15, None), (16, 17, None), (4, 5, None), (22, 23, None), (24, 25, None), (6, 7, None), (8, 9, None), (12, 13, None), (0, 27, None), (18, 19, None), (2, 3, None)] sage: H = MatchingCoveredGraph(G, M) sage: H Matching covered truncated biwheel graph: graph on 28 vertices sage: H == G True + sage: H.matching == M + True TESTS: @@ -406,6 +437,8 @@ def __init__(self, data=None, matching=None, algorithm='Edmonds', See documentation ``MatchingCoveredGraph?`` for detailed information. """ + success = False + if kwds is None: kwds = {'loops': False} else: @@ -418,13 +451,41 @@ def __init__(self, data=None, matching=None, algorithm='Edmonds', raise ValueError('the graph is trivial') elif isinstance(data, MatchingCoveredGraph): - Graph.__init__(self, data, *args, **kwds) + try: + Graph.__init__(self, data, *args, **kwds) + success = True + + except ValueError as error: + raise error elif isinstance(data, Graph): - Graph.__init__(self, data, *args, **kwds) - self._upgrade_from_graph(matching=matching, algorithm=algorithm, - solver=solver, verbose=verbose, - integrality_tolerance=integrality_tolerance) + try: + Graph.__init__(self, data, *args, **kwds) + self._upgrade_from_graph(matching=matching, algorithm=algorithm, + solver=solver, verbose=verbose, + integrality_tolerance=integrality_tolerance) + success = True + + except ValueError as error: + raise error + + if success: + if matching: + # The input matching must be a valid perfect matching of the graph + M = Graph(matching) + G_simple = self.to_simple() + + if any(d != 1 for d in M.degree()): + raise ValueError("the input is not a matching") + if any(not G_simple.has_edge(edge) for edge in M.edge_iterator()): + raise ValueError("the input is not a matching of the graph") + if (G_simple.order() != M.order()) or (G_simple.order() != 2*M.size()): + raise ValueError("the input is not a perfect matching of the graph") + + self.matching = matching + else: + self.matching = Graph(self).matching() + else: raise ValueError('input data is of unknown type') From 34bef53b9b8e3957bc93b5aa469a00f8c34d378b Mon Sep 17 00:00:00 2001 From: janmenjayap Date: Sun, 13 Oct 2024 22:06:23 +0530 Subject: [PATCH 277/537] updated the documentation --- src/sage/graphs/matching_covered_graph.py | 29 ++++++++++++++++++----- 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/src/sage/graphs/matching_covered_graph.py b/src/sage/graphs/matching_covered_graph.py index e90b404a9ee..0cc4e20133a 100644 --- a/src/sage/graphs/matching_covered_graph.py +++ b/src/sage/graphs/matching_covered_graph.py @@ -34,7 +34,7 @@ class MatchingCoveredGraph(Graph): - ``data`` -- can be any of the following: - - Empty or ``None`` (throws a :class:`ValueError` as the graph must be + - Empty or ``None`` (throws a :exc:`ValueError` as the graph must be nontrival). - An arbitrary graph. @@ -68,6 +68,11 @@ class MatchingCoveredGraph(Graph): solvers over an inexact base ring; see :meth:`MixedIntegerLinearProgram.get_values`. + OUTPUT: + + - An object of the class :class:`~MatchingCoveredGraph` if the input is + valid and the graph is matching covered, or otherwise an error is thrown. + .. NOTE:: All remaining arguments are passed to the ``Graph`` constructor @@ -197,7 +202,7 @@ class MatchingCoveredGraph(Graph): sage: H.matching [(0, 3, {}), (1, 2, {})] - One may specify a matching:: + One may specify a perfect matching:: sage: P = graphs.PetersenGraph() sage: M = P.matching() @@ -395,6 +400,12 @@ class MatchingCoveredGraph(Graph): Providing with a wrong matching:: + sage: P = graphs.PetersenGraph() + sage: M = str('0') + sage: H = MatchingCoveredGraph(P, matching=M) + Traceback (most recent call last): + ... + RuntimeError: the string seems corrupt: valid characters are ?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ sage: G = graphs.CompleteGraph(6) sage: M = Graph(G.matching()) sage: M.add_edges([(0, 1), (0, 2)]) @@ -417,7 +428,7 @@ class MatchingCoveredGraph(Graph): Note that data shall be one of empty or ``None`` or an instance of ``Graph`` or an instance of ``MatchingCoveredGraph``. Otherwise a - :class:`ValueError` is returned:: + :exc:`ValueError` is returned:: sage: D = digraphs.Complete(10) sage: D @@ -512,7 +523,7 @@ def _upgrade_from_graph(self, matching=None, algorithm='Edmonds', def __repr__(self): r""" - Return a short string representation of the matching covered graph. + Return a short string representation of the (matching covered) graph. EXAMPLES: @@ -554,13 +565,13 @@ def __repr__(self): def allow_loops(self, new, check=True): r""" - Check whether loops are allowed in (matching covered) graphs. + Change whether loops are allowed in (matching covered) graphs. .. NOTE:: This method overwrites the :meth:`~sage.graphs.generic_graph.GenericGraph.allow_loops` method - to ensure that loops are forbidden in :class:`~BipartiteGraph`. + to ensure that loops are forbidden in :class:`~MatchingCoveredGraph`. INPUT: @@ -572,6 +583,12 @@ def allow_loops(self, new, check=True): :meth:`~sage.graphs.generic_graph.GenericGraph.allow_loops` method and is not used in this overwritten one. + OUTPUT: + + - A :exc:`ValueError` is returned if ``new`` is ``True`` since a + matching covered graph, by definition, is free of self-loops. If + ``new`` is set to ``False``, there is no output. + EXAMPLES: Petersen graph is matching covered:: From adc35e0ddea2c62a8583eb82572605548dc00a59 Mon Sep 17 00:00:00 2001 From: janmenjayap Date: Sun, 13 Oct 2024 23:03:36 +0530 Subject: [PATCH 278/537] introduced get_matching() --- src/sage/graphs/matching_covered_graph.py | 57 ++++++++++++++++++----- 1 file changed, 45 insertions(+), 12 deletions(-) diff --git a/src/sage/graphs/matching_covered_graph.py b/src/sage/graphs/matching_covered_graph.py index 0cc4e20133a..bf693aef2b3 100644 --- a/src/sage/graphs/matching_covered_graph.py +++ b/src/sage/graphs/matching_covered_graph.py @@ -85,7 +85,7 @@ class MatchingCoveredGraph(Graph): sage: G = MatchingCoveredGraph(graphs.PetersenGraph()) sage: G Matching covered petersen graph: graph on 10 vertices - sage: G.matching + sage: G.get_matching() [(0, 5, None), (1, 6, None), (2, 7, None), (3, 8, None), (4, 9, None)] sage: G = graphs.StaircaseGraph(4) @@ -94,7 +94,7 @@ class MatchingCoveredGraph(Graph): Matching covered staircase graph: graph on 8 vertices sage: H == G True - sage: H.matching + sage: H.get_matching() [(0, 1, None), (2, 7, None), (3, 6, None), (4, 5, None)] sage: G = Graph({0: [1, 2, 3, 4], 1: [2, 5], @@ -104,7 +104,7 @@ class MatchingCoveredGraph(Graph): Matching covered graph on 6 vertices sage: H == G True - sage: H.matching + sage: H.get_matching() [(0, 4, None), (1, 2, None), (3, 5, None)] sage: # needs networkx @@ -115,7 +115,7 @@ class MatchingCoveredGraph(Graph): Matching covered graph on 24 vertices sage: H == G True - sage: H.matching + sage: H.get_matching() [(4, 23, None), (6, 21, None), (11, 16, None), (7, 20, None), (10, 17, None), (1, 14, None), (2, 13, None), (8, 19, None), (9, 18, None), (3, 12, None), (5, 22, None), (0, 15, None)] sage: G = Graph('E|fG', sparse=True) @@ -124,7 +124,7 @@ class MatchingCoveredGraph(Graph): Matching covered graph on 6 vertices sage: H == G True - sage: H.matching + sage: H.get_matching() [(0, 5, None), (1, 2, None), (3, 4, None)] sage: # needs sage.modules @@ -153,7 +153,7 @@ class MatchingCoveredGraph(Graph): sage: H = MatchingCoveredGraph(G) sage: H == G True - sage: H.matching + sage: H.get_matching() [(0, 5, None), (1, 6, None), (2, 7, None), (3, 8, None), (4, 9, None)] sage: # needs sage.modules @@ -182,7 +182,7 @@ class MatchingCoveredGraph(Graph): sage: H = MatchingCoveredGraph(G) sage: H == G True - sage: H.matching + sage: H.get_matching() [(0, 5, None), (1, 6, None), (2, 7, None), (3, 8, None), (4, 9, None)] sage: G = Graph([(0, 1), (0, 3), (0, 4), (1, 2), (1, 5), (2, 3), @@ -190,7 +190,7 @@ class MatchingCoveredGraph(Graph): sage: H = MatchingCoveredGraph(G) sage: H == G True - sage: H.matching + sage: H.get_matching() [(0, 4, None), (1, 5, None), (2, 6, None), (3, 7, None)] sage: # optional - python_igraph @@ -199,7 +199,7 @@ class MatchingCoveredGraph(Graph): sage: H = MatchingCoveredGraph(G) sage: H Matching covered graph on 4 vertices - sage: H.matching + sage: H.get_matching() [(0, 3, {}), (1, 2, {})] One may specify a perfect matching:: @@ -213,7 +213,7 @@ class MatchingCoveredGraph(Graph): Matching covered petersen graph: graph on 10 vertices sage: P == G True - sage: G.matching + sage: G.get_matching() [(0, 5, None), (1, 6, None), (2, 7, None), (3, 8, None), (4, 9, None)] sage: G = graphs.TruncatedBiwheelGraph(14) @@ -225,7 +225,7 @@ class MatchingCoveredGraph(Graph): Matching covered truncated biwheel graph: graph on 28 vertices sage: H == G True - sage: H.matching == M + sage: H.get_matching() == M True TESTS: @@ -604,4 +604,37 @@ def allow_loops(self, new, check=True): """ if new: raise ValueError('loops are not allowed in ' - 'matching covered graphs') \ No newline at end of file + 'matching covered graphs') + + def get_matching(self): + r""" + Return ``self.matching``, which is a perfect matching of the (matching + covered) graph computed at the initialization. + + EXAMPLES: + + If one specifies a perfect matching while initializing the object, the + value of ``self.matching`` is captures the same matching:: + + sage: P = graphs.PetersenGraph() + sage: M = [(0, 1), (2, 3), (4, 9), (5, 7), (6, 8)] + sage: G = MatchingCoveredGraph(P, M) + sage: G.get_matching() + [(0, 1), (2, 3), (4, 9), (5, 7), (6, 8)] + sage: M == G.get_matching() + True + + If no matching is specified while initilizing a matching covered graph, + a perfect is computed + :meth:`~sage.graphs.graph.Graph.matching` and that is captured as + ``self.matching``:: + + sage: P = graphs.PetersenGraph() + sage: M = P.matching() + sage: G = MatchingCoveredGraph(P) + sage: G.get_matching() + [(0, 5, None), (1, 6, None), (2, 7, None), (3, 8, None), (4, 9, None)] + sage: M == G.get_matching() + True + """ + return self.matching \ No newline at end of file From f2b2b3dbd6253aff15f76ff30bc3cb35e317cc06 Mon Sep 17 00:00:00 2001 From: janmenjayap Date: Sun, 13 Oct 2024 23:05:52 +0530 Subject: [PATCH 279/537] made self.matching private --- src/sage/graphs/matching_covered_graph.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/sage/graphs/matching_covered_graph.py b/src/sage/graphs/matching_covered_graph.py index bf693aef2b3..be60db5626a 100644 --- a/src/sage/graphs/matching_covered_graph.py +++ b/src/sage/graphs/matching_covered_graph.py @@ -493,9 +493,9 @@ def __init__(self, data=None, matching=None, algorithm='Edmonds', if (G_simple.order() != M.order()) or (G_simple.order() != 2*M.size()): raise ValueError("the input is not a perfect matching of the graph") - self.matching = matching + self._matching = matching else: - self.matching = Graph(self).matching() + self._matching = Graph(self).matching() else: raise ValueError('input data is of unknown type') @@ -608,13 +608,13 @@ def allow_loops(self, new, check=True): def get_matching(self): r""" - Return ``self.matching``, which is a perfect matching of the (matching + Return ``self._matching``, which is a perfect matching of the (matching covered) graph computed at the initialization. EXAMPLES: If one specifies a perfect matching while initializing the object, the - value of ``self.matching`` is captures the same matching:: + value of ``self._matching`` is captures the same matching:: sage: P = graphs.PetersenGraph() sage: M = [(0, 1), (2, 3), (4, 9), (5, 7), (6, 8)] @@ -627,7 +627,7 @@ def get_matching(self): If no matching is specified while initilizing a matching covered graph, a perfect is computed :meth:`~sage.graphs.graph.Graph.matching` and that is captured as - ``self.matching``:: + ``self._matching``:: sage: P = graphs.PetersenGraph() sage: M = P.matching() @@ -637,4 +637,4 @@ def get_matching(self): sage: M == G.get_matching() True """ - return self.matching \ No newline at end of file + return self._matching \ No newline at end of file From cce406383776e8977dee69c21022119b10b75852 Mon Sep 17 00:00:00 2001 From: janmenjayap Date: Mon, 14 Oct 2024 00:48:17 +0530 Subject: [PATCH 280/537] rearranged the methods in lexicographical order --- src/sage/graphs/matching_covered_graph.py | 42 +++++++++++------------ 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/src/sage/graphs/matching_covered_graph.py b/src/sage/graphs/matching_covered_graph.py index be60db5626a..1c73c4cdead 100644 --- a/src/sage/graphs/matching_covered_graph.py +++ b/src/sage/graphs/matching_covered_graph.py @@ -500,27 +500,6 @@ def __init__(self, data=None, matching=None, algorithm='Edmonds', else: raise ValueError('input data is of unknown type') - def _upgrade_from_graph(self, matching=None, algorithm='Edmonds', - solver=None, verbose=0, - integrality_tolerance=0.001): - r""" - Upgrade the given graph to a matching covered graph if eligible. - - See documentation ``MatchingCoveredGraph?`` for detailed information. - """ - try: - check = Graph.is_matching_covered(G=self, matching=matching, - algorithm=algorithm, - coNP_certificate=False, - solver=solver, verbose=verbose, - integrality_tolerance=integrality_tolerance) - - if not check: - raise ValueError("input graph is not matching covered") - - except ValueError as error: - raise error - def __repr__(self): r""" Return a short string representation of the (matching covered) graph. @@ -563,6 +542,27 @@ def __repr__(self): return s.capitalize() return "".join(["Matching covered ", s]) + def _upgrade_from_graph(self, matching=None, algorithm='Edmonds', + solver=None, verbose=0, + integrality_tolerance=0.001): + r""" + Upgrade the given graph to a matching covered graph if eligible. + + See documentation ``MatchingCoveredGraph?`` for detailed information. + """ + try: + check = Graph.is_matching_covered(G=self, matching=matching, + algorithm=algorithm, + coNP_certificate=False, + solver=solver, verbose=verbose, + integrality_tolerance=integrality_tolerance) + + if not check: + raise ValueError("input graph is not matching covered") + + except ValueError as error: + raise error + def allow_loops(self, new, check=True): r""" Change whether loops are allowed in (matching covered) graphs. From d83be127fb16ad261b7dcaf668800bebd9adc18d Mon Sep 17 00:00:00 2001 From: janmenjayap Date: Mon, 14 Oct 2024 00:55:10 +0530 Subject: [PATCH 281/537] added add_vertex() --- src/sage/graphs/matching_covered_graph.py | 64 +++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/src/sage/graphs/matching_covered_graph.py b/src/sage/graphs/matching_covered_graph.py index 1c73c4cdead..0f48c05875d 100644 --- a/src/sage/graphs/matching_covered_graph.py +++ b/src/sage/graphs/matching_covered_graph.py @@ -563,6 +563,70 @@ def _upgrade_from_graph(self, matching=None, algorithm='Edmonds', except ValueError as error: raise error + def add_vertex(self, name=None): + r""" + Add a vertex to the (matching covered) graph. + + .. NOTE:: + + This method overwrites the + :meth:`~sage.graphs.generic_graph.GenericGraph.add_vertex` method + to ensure that isolated vertices are forbidden in + :class:`~MatchingCoveredGraph`. + + INPUT: + + - ``name`` -- an immutable object (default: ``None``); when no name is + specified (default), then the new vertex will be represented by the + least integer not already representing a vertex. ``name`` must be an + immutable object (e.g., an integer, a tuple, etc.). + + OUTPUT: + + - If ``name`` specifies an existing vertex, then nothing is done. + Otherwise a :exc:`ValueError` is returned since matching covered + graphs are free of isolated vertices. + + EXAMPLES: + + Adding an existing vertex:: + + sage: P = graphs.PetersenGraph() + sage: P + Petersen graph: Graph on 10 vertices + sage: G = MatchingCoveredGraph(P) + sage: G + Matching covered petersen graph: graph on 10 vertices + sage: # needs random + sage: u = random.choice(list(G)) + sage: G.add_vertex(u) + sage: G + Matching covered petersen graph: graph on 10 vertices + + Adding a new/ non-existing vertex:: + + sage: P = graphs.PetersenGraph() + sage: P + Petersen graph: Graph on 10 vertices + sage: G = MatchingCoveredGraph(P) + sage: G + Matching covered petersen graph: graph on 10 vertices + sage: G.add_vertex() + Traceback (most recent call last): + ... + ValueError: isolated vertices are not allowed in matching covered graphs + sage: u = 0 + sage: while u in G: + ....: u += 1 + sage: G.add_vertex(u) + Traceback (most recent call last): + ... + ValueError: isolated vertices are not allowed in matching covered graphs + """ + if name not in self: + raise ValueError('isolated vertices are not allowed in ' + 'matching covered graphs') + def allow_loops(self, new, check=True): r""" Change whether loops are allowed in (matching covered) graphs. From 1367acf7c894e1a96d6d47e6038a0b989622c1b9 Mon Sep 17 00:00:00 2001 From: janmenjayap Date: Mon, 14 Oct 2024 00:55:53 +0530 Subject: [PATCH 282/537] added add_vertices() --- src/sage/graphs/matching_covered_graph.py | 72 +++++++++++++++++++++++ 1 file changed, 72 insertions(+) diff --git a/src/sage/graphs/matching_covered_graph.py b/src/sage/graphs/matching_covered_graph.py index 0f48c05875d..da167f21fb2 100644 --- a/src/sage/graphs/matching_covered_graph.py +++ b/src/sage/graphs/matching_covered_graph.py @@ -563,6 +563,78 @@ def _upgrade_from_graph(self, matching=None, algorithm='Edmonds', except ValueError as error: raise error + def add_vertices(self, vertices): + r""" + Add vertices to the (matching covered) graph from an iterable container + of vertices. + + .. NOTE:: + + This method overwrites the + :meth:`~sage.graphs.generic_graph.GenericGraph.add_vertices` method + to ensure that isolated vertices are forbidden in + :class:`~MatchingCoveredGraph`. + + INPUT: + + - ``vertices`` -- iterator container of vertex labels. A new label is + created, used and returned in the output list for all ``None`` values + in ``vertices``. + + OUTPUT: + + - If all of the vertices are existing vertices of the (matching + covered) graph, then nothing is done; otherwise a :exc:`ValueError` + is returned since matching covered graphs are free of isolated + vertices. + + EXAMPLES: + + Adding a list of already existing vertices:: + + sage: T = graphs.TruncatedBiwheelGraph(15) + sage: T + Truncated biwheel graph: Graph on 30 vertices + sage: G = MatchingCoveredGraph(T) + sage: G + Matching covered truncated biwheel graph: graph on 30 vertices + sage: # needs random + sage: import random + sage: S = random.sample(G, 4) # We choose 4 existing vertices + sage: G.add_vertices(S) + sage: G + Matching covered truncated biwheel graph: graph on 30 vertices + + Adding a list of vertices in which at least one is non-existent or + ``None`` or possibly both:: + + sage: T = graphs.CompleteGraph(2) + sage: T + Truncated biwheel graph: Graph on 30 vertices + sage: G = MatchingCoveredGraph(T) + sage: G + Matching covered truncated biwheel graph: graph on 30 vertices + sage: S1 = [2, 3, 4] + sage: G.add_vertices(G, S1) + Traceback (most recent call last): + ... + ValueError: isolated vertices are not allowed in matching covered graphs + sage: S2 = [None, None] + sage: G.add_vertices(G, S2) + Traceback (most recent call last): + ... + ValueError: isolated vertices are not allowed in matching covered graphs + sage: S3 = [2, None, None, 5] + sage: G.add_vertices(G, S3) + Traceback (most recent call last): + ... + ValueError: isolated vertices are not allowed in matching covered graphs + """ + for vertex in vertices: + if vertex not in self: + raise ValueError('isolated vertices are not allowed in ' + 'matching covered graphs') + def add_vertex(self, name=None): r""" Add a vertex to the (matching covered) graph. From f6bbd32f814de368dc9df1c8051e36e460d52923 Mon Sep 17 00:00:00 2001 From: janmenjayap Date: Mon, 14 Oct 2024 01:00:34 +0530 Subject: [PATCH 283/537] added delete_vertex() --- src/sage/graphs/matching_covered_graph.py | 59 +++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/src/sage/graphs/matching_covered_graph.py b/src/sage/graphs/matching_covered_graph.py index da167f21fb2..cb66bedd992 100644 --- a/src/sage/graphs/matching_covered_graph.py +++ b/src/sage/graphs/matching_covered_graph.py @@ -742,6 +742,65 @@ def allow_loops(self, new, check=True): raise ValueError('loops are not allowed in ' 'matching covered graphs') + def delete_vertex(self, vertex, in_order=False): + """ + Delete a vertex, removing all incident edges. + + .. NOTE:: + + This method overwrites the + :meth:`~sage.graphs.generic_graph.GenericGraph.delete_vertex` + method to ensure that an odd order is forbidden in + :class:`~MatchingCoveredGraph`. + + INPUT: + + - ``vertex`` -- a vertex that is to be deleted. + + - ``in_order`` -- boolean (default: ``False``); if ``True``, this + deletes the `i`-th vertex in the sorted list of vertices, i.e. + ``G.vertices(sort=True)[i]`` + + OUTPUT: + + - Deleting a non-existent vertex raises a :exc:`ValueError` exception; + also a (different) :exc:`ValueError` is returned on deleting an + existing vertex since matching covered graphs are of even order. + + EXAMPLES: + + Deleting a non-existent vertex:: + + sage: W = graphs.WheelGraph(12) + sage: G = MatchingCoveredGraph(W) + sage: u = 0 + sage: while u in G: + ....: u += 1 + sage: G.delete_vertex(u) + Traceback (most recent call last): + ... + ValueError: vertex (12) not in the graph + + Deleting an existing vertex:: + + sage: W = graphs.WheelGraph(12) + sage: G = MatchingCoveredGraph(W) + sage: # need random + sage: u = random.choice(list(G)) + sage: G.delete_vertex(u) + Traceback (most recent call last): + ... + ValueError: odd order is not allowed for matching covered graphs + """ + if in_order: + vertex = self.vertices(sort=True)[vertex] + + if vertex not in self: + raise ValueError('vertex (%s) not in the graph' % str(vertex)) + + raise ValueError('odd order is not allowered for ' + 'matching covered graphs') + def get_matching(self): r""" Return ``self._matching``, which is a perfect matching of the (matching From 26deafe84453165a0dd66374dff06c0d5395e28b Mon Sep 17 00:00:00 2001 From: janmenjayap Date: Mon, 14 Oct 2024 01:08:16 +0530 Subject: [PATCH 284/537] added delete_vertices() --- src/sage/graphs/matching_covered_graph.py | 103 ++++++++++++++++++++++ 1 file changed, 103 insertions(+) diff --git a/src/sage/graphs/matching_covered_graph.py b/src/sage/graphs/matching_covered_graph.py index cb66bedd992..8d459fd3f38 100644 --- a/src/sage/graphs/matching_covered_graph.py +++ b/src/sage/graphs/matching_covered_graph.py @@ -742,6 +742,109 @@ def allow_loops(self, new, check=True): raise ValueError('loops are not allowed in ' 'matching covered graphs') + def delete_vertices(self, vertices): + r""" + Delete vertices (along with the incident edges) from the (matching + covered) graph taken from an iterable container of vertices. + + .. NOTE:: + + This method overwrites the + :meth:`~sage.graphs.generic_graph.GenericGraph.delete_vertices` + method to ensure that an odd order is forbidden in + :class:`~MatchingCoveredGraph`. + + INPUT: + + - ``vertices`` -- a list/ set of vertices that are to be deleted. + + OUTPUT: + + - Deleting a non-existent vertex will raise a :exc:`ValueError` + exception, in which case none of the vertices in ``vertices`` + is deleted. + + - If all of the vertices in the list/ set provided exist in the graph, + but the resulting graph after deletion of all of those is not + matching covered, then a :exc:`ValueError` exception is raised, + otherwise nothing is returned. + + EXAMPLES: + + Providing with a list of vertices with at least one non-existent + vertex:: + + sage: S = graphs.StaircaseGraph(4) + sage: S + Staircase graph: Graph on 8 vertices + sage: G = MatchingCoveredGraph(S) + sage: G + Matching covered staircase graph: graph on 8 vertices + sage: T = list(range(5, 20, 2)) + sage: G.delete_vertices(T) + Traceback (most recent call last): + ... + ValueError: vertex (9) not in the graph + + Providing with a list of existent vertices whose deletion results in a + graph which is not matching covered:: + + sage: S = graphs.StaircaseGraph(4) + sage: S + Staircase graph: Graph on 8 vertices + sage: G = MatchingCoveredGraph(S) + sage: G + Matching covered staircase graph: graph on 8 vertices + sage: T = [1, 4] + sage: G.delete_vertices(T) + Traceback (most recent call last): + ... + ValueError: the resulting graph after the removal of the vertices is not matching covered + + Providing with a list of existent vertices after the deletion of which + the resulting graph is still matching covered; note that in the + following example, after the deletion of two vertices from a staircase + graph, the resulting graph is NOT a staircase graph + (see :issue:`38768`):: + + sage: S = graphs.StaircaseGraph(4) + sage: S + Staircase graph: Graph on 8 vertices + sage: G = MatchingCoveredGraph(S) + sage: G + Matching covered staircase graph: graph on 8 vertices + sage: T = [6, 7] + sage: G.delete_vertices(T) + sage: G # Matching covered graph on 6 vertices + Matching covered staircase graph: graph on 6 vertices + """ + + for vertex in vertices: + if vertex not in self: + raise ValueError('vertex (%s) not in the graph' % str(vertex)) + + try: + G = Graph(self) + M = Graph(self.get_matching()) + G_simple = G.to_simple() + + if M: + M.delete_vertices(vertices) + # The resulting matching after the removal of the input vertices + # must be a valid perfect matching of the resulting graph obtained + # after the removal of the vertices + + if any(d != 1 for d in G_simple.degree()) \ + or any(not G_simple.has_edge(edge) for edge in M.edge_iterator()) \ + or (G_simple.order() != M.order()) or (G_simple.order() != 2*M.size()): + M = None + + self.__init__(data=G, matching=M) + + except: + raise ValueError('the resulting graph after the removal of ' + 'the vertices is not matching covered') + def delete_vertex(self, vertex, in_order=False): """ Delete a vertex, removing all incident edges. From a90aa338b20ff0f0f580abf7422bd4e10758e9b5 Mon Sep 17 00:00:00 2001 From: janmenjayap Date: Mon, 14 Oct 2024 01:39:01 +0530 Subject: [PATCH 285/537] added update_matching() --- src/sage/graphs/matching_covered_graph.py | 85 ++++++++++++++++++++++- 1 file changed, 84 insertions(+), 1 deletion(-) diff --git a/src/sage/graphs/matching_covered_graph.py b/src/sage/graphs/matching_covered_graph.py index 8d459fd3f38..96e8370e6d5 100644 --- a/src/sage/graphs/matching_covered_graph.py +++ b/src/sage/graphs/matching_covered_graph.py @@ -935,4 +935,87 @@ def get_matching(self): sage: M == G.get_matching() True """ - return self._matching \ No newline at end of file + return self._matching + + def update_matching(self, matching): + r""" + Update the pefect matching captured in ``self._matching``. + + INPUT: + + - ``matching`` -- a perfect matching of the graph, that can be given + using any valid input format of :class:`~sage.graphs.graph.Graph`. + + OUTPUT: + + - If ``matching`` is a valid perfect matching of the graph, then + ``self._matching`` gets updated to this provided matching, or + otherwise an exception is returned. + + EXAMPLES: + + Providing with a valid perfect matching of the graph:: + + sage: P = graphs.PetersenGraph() + sage: G = MatchingCoveredGraph(P) + sage: G.get_matching() + [(0, 5, None), (1, 6, None), (2, 7, None), (3, 8, None), (4, 9, None)] + sage: M = [(0, 1), (2, 3), (4, 9), (5, 7), (6, 8)] + sage: G.update_matching(M) + sage: G.get_matching() + [(0, 1), (2, 3), (4, 9), (5, 7), (6, 8)] + + TESTS: + + Providing with a wrong matching:: + + sage: P = graphs.PetersenGraph() + sage: G = MatchingCoveredGraph(P) + sage: G.get_matching() + [(0, 5, None), (1, 6, None), (2, 7, None), (3, 8, None), (4, 9, None)] + sage: S = str('0') + sage: G.update_matching(S) + Traceback (most recent call last): + ... + RuntimeError: the string seems corrupt: valid characters are ?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ + sage: T = str('graph') + Traceback (most recent call last): + ... + RuntimeError: the string (graph) seems corrupt: for n = 40, the string is too short + sage: M = Graph(G.matching()) + sage: M.add_edges([(0, 1), (0, 2)]) + sage: G.update_matching(M) + Traceback (most recent call last): + ... + ValueError: the input is not a matching + sage: N = Graph(G.matching()) + sage: N.add_edge(6, 7) + sage: G.update_matching(N) + Traceback (most recent call last): + ... + ValueError: the input is not a matching of the graph + sage: J = Graph() + sage: J.add_edges([(0, 1), (2, 3)]) + sage: G.update_matching(J) + Traceback (most recent call last): + ... + ValueError: the input is not a perfect matching of the graph + """ + try: + M = Graph(matching) + G = Graph(self) + G_simple = G.to_simple() + + if any(d != 1 for d in M.degree()): + raise ValueError("the input is not a matching") + + if any(not G_simple.has_edge(edge) for edge in M.edge_iterator()): + raise ValueError("the input is not a matching of the graph") + + if (G_simple.order() != M.order()) or (G_simple.order() != 2*M.size()): + raise ValueError("the input is not a perfect matching of the graph") + + self._matching = M.edges() + + except Exception as exception: + raise exception \ No newline at end of file From 9c2252a9d436c12638585c6b8cc6e00175e66b7e Mon Sep 17 00:00:00 2001 From: janmenjayap Date: Mon, 14 Oct 2024 01:44:36 +0530 Subject: [PATCH 286/537] added a doctest --- src/sage/graphs/matching_covered_graph.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/sage/graphs/matching_covered_graph.py b/src/sage/graphs/matching_covered_graph.py index 96e8370e6d5..c3c50d2ee6a 100644 --- a/src/sage/graphs/matching_covered_graph.py +++ b/src/sage/graphs/matching_covered_graph.py @@ -406,6 +406,12 @@ class MatchingCoveredGraph(Graph): Traceback (most recent call last): ... RuntimeError: the string seems corrupt: valid characters are ?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ + sage: N = str('graph') + sage: J = MatchingCoveredGraph(P, matching=N) + Traceback (most recent call last): + ... + RuntimeError: the string (graph) seems corrupt: for n = 40, the string is too short + sage: G = graphs.CompleteGraph(6) sage: M = Graph(G.matching()) sage: M.add_edges([(0, 1), (0, 2)]) @@ -513,6 +519,7 @@ def __repr__(self): sage: H = MatchingCoveredGraph(G) sage: H Matching covered complete graph: graph on 10 vertices + sage: G = graphs.HexahedralGraph() sage: H = MatchingCoveredGraph(BipartiteGraph(G)) sage: H # An object of the class MatchingCoveredGraph From eec57ab382c1e621d3a94bd9f8951b105bad67ee Mon Sep 17 00:00:00 2001 From: janmenjayap Date: Mon, 14 Oct 2024 01:46:12 +0530 Subject: [PATCH 287/537] updated exception statement --- src/sage/graphs/matching_covered_graph.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/sage/graphs/matching_covered_graph.py b/src/sage/graphs/matching_covered_graph.py index c3c50d2ee6a..18da3f3dbb0 100644 --- a/src/sage/graphs/matching_covered_graph.py +++ b/src/sage/graphs/matching_covered_graph.py @@ -411,7 +411,7 @@ class MatchingCoveredGraph(Graph): Traceback (most recent call last): ... RuntimeError: the string (graph) seems corrupt: for n = 40, the string is too short - + sage: G = graphs.CompleteGraph(6) sage: M = Graph(G.matching()) sage: M.add_edges([(0, 1), (0, 2)]) @@ -472,8 +472,8 @@ def __init__(self, data=None, matching=None, algorithm='Edmonds', Graph.__init__(self, data, *args, **kwds) success = True - except ValueError as error: - raise error + except Exception as exception: + raise exception elif isinstance(data, Graph): try: @@ -483,8 +483,8 @@ def __init__(self, data=None, matching=None, algorithm='Edmonds', integrality_tolerance=integrality_tolerance) success = True - except ValueError as error: - raise error + except Exception as exception: + raise exception if success: if matching: @@ -567,8 +567,8 @@ def _upgrade_from_graph(self, matching=None, algorithm='Edmonds', if not check: raise ValueError("input graph is not matching covered") - except ValueError as error: - raise error + except Exception as exception: + raise exception def add_vertices(self, vertices): r""" From 31062047788eca6e01a9c82cfa49730ccba7e222 Mon Sep 17 00:00:00 2001 From: janmenjayap Date: Mon, 14 Oct 2024 22:20:45 +0530 Subject: [PATCH 288/537] updated the doctests --- src/sage/graphs/matching_covered_graph.py | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/src/sage/graphs/matching_covered_graph.py b/src/sage/graphs/matching_covered_graph.py index 18da3f3dbb0..d11d31b3974 100644 --- a/src/sage/graphs/matching_covered_graph.py +++ b/src/sage/graphs/matching_covered_graph.py @@ -617,22 +617,22 @@ def add_vertices(self, vertices): sage: T = graphs.CompleteGraph(2) sage: T - Truncated biwheel graph: Graph on 30 vertices + Complete graph: Graph on 2 vertices sage: G = MatchingCoveredGraph(T) sage: G - Matching covered truncated biwheel graph: graph on 30 vertices + Matching covered complete graph: graph on 2 vertices sage: S1 = [2, 3, 4] - sage: G.add_vertices(G, S1) + sage: G.add_vertices(S1) Traceback (most recent call last): ... ValueError: isolated vertices are not allowed in matching covered graphs sage: S2 = [None, None] - sage: G.add_vertices(G, S2) + sage: G.add_vertices(S2) Traceback (most recent call last): ... ValueError: isolated vertices are not allowed in matching covered graphs sage: S3 = [2, None, None, 5] - sage: G.add_vertices(G, S3) + sage: G.add_vertices(S3) Traceback (most recent call last): ... ValueError: isolated vertices are not allowed in matching covered graphs @@ -832,6 +832,7 @@ def delete_vertices(self, vertices): try: G = Graph(self) + G.delete_vertices(vertices) M = Graph(self.get_matching()) G_simple = G.to_simple() @@ -896,6 +897,7 @@ def delete_vertex(self, vertex, in_order=False): sage: W = graphs.WheelGraph(12) sage: G = MatchingCoveredGraph(W) sage: # need random + sage: import random sage: u = random.choice(list(G)) sage: G.delete_vertex(u) Traceback (most recent call last): @@ -908,7 +910,7 @@ def delete_vertex(self, vertex, in_order=False): if vertex not in self: raise ValueError('vertex (%s) not in the graph' % str(vertex)) - raise ValueError('odd order is not allowered for ' + raise ValueError('odd order is not allowed for ' 'matching covered graphs') def get_matching(self): @@ -970,7 +972,7 @@ def update_matching(self, matching): sage: M = [(0, 1), (2, 3), (4, 9), (5, 7), (6, 8)] sage: G.update_matching(M) sage: G.get_matching() - [(0, 1), (2, 3), (4, 9), (5, 7), (6, 8)] + [(0, 1, None), (2, 3, None), (4, 9, None), (5, 7, None), (6, 8, None)] TESTS: @@ -986,6 +988,7 @@ def update_matching(self, matching): ... RuntimeError: the string seems corrupt: valid characters are ?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ sage: T = str('graph') + sage: G.update_matching(T) Traceback (most recent call last): ... RuntimeError: the string (graph) seems corrupt: for n = 40, the string is too short @@ -996,7 +999,7 @@ def update_matching(self, matching): ... ValueError: the input is not a matching sage: N = Graph(G.matching()) - sage: N.add_edge(6, 7) + sage: N.add_edge(10, 11) sage: G.update_matching(N) Traceback (most recent call last): ... @@ -1005,8 +1008,8 @@ def update_matching(self, matching): sage: J.add_edges([(0, 1), (2, 3)]) sage: G.update_matching(J) Traceback (most recent call last): - ... - ValueError: the input is not a perfect matching of the graph + ... + ValueError: the input is not a perfect matching of the graph """ try: M = Graph(matching) From 46f067a6374cc4b17016e14f9cfa08024348f920 Mon Sep 17 00:00:00 2001 From: janmenjayap Date: Mon, 14 Oct 2024 22:47:34 +0530 Subject: [PATCH 289/537] corrected the use of bare 'except' --- src/sage/graphs/matching_covered_graph.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/graphs/matching_covered_graph.py b/src/sage/graphs/matching_covered_graph.py index d11d31b3974..c1de469589f 100644 --- a/src/sage/graphs/matching_covered_graph.py +++ b/src/sage/graphs/matching_covered_graph.py @@ -849,7 +849,7 @@ def delete_vertices(self, vertices): self.__init__(data=G, matching=M) - except: + except Exception: raise ValueError('the resulting graph after the removal of ' 'the vertices is not matching covered') From fb94e5026ca05954a5f0d9bce1742ab9c8547006 Mon Sep 17 00:00:00 2001 From: janmenjayap Date: Mon, 14 Oct 2024 23:04:15 +0530 Subject: [PATCH 290/537] rearranged the methods in lexicographical order --- src/sage/graphs/matching_covered_graph.py | 248 +++++++++++----------- 1 file changed, 124 insertions(+), 124 deletions(-) diff --git a/src/sage/graphs/matching_covered_graph.py b/src/sage/graphs/matching_covered_graph.py index c1de469589f..74eaf504b33 100644 --- a/src/sage/graphs/matching_covered_graph.py +++ b/src/sage/graphs/matching_covered_graph.py @@ -570,6 +570,70 @@ def _upgrade_from_graph(self, matching=None, algorithm='Edmonds', except Exception as exception: raise exception + def add_vertex(self, name=None): + r""" + Add a vertex to the (matching covered) graph. + + .. NOTE:: + + This method overwrites the + :meth:`~sage.graphs.generic_graph.GenericGraph.add_vertex` method + to ensure that isolated vertices are forbidden in + :class:`~MatchingCoveredGraph`. + + INPUT: + + - ``name`` -- an immutable object (default: ``None``); when no name is + specified (default), then the new vertex will be represented by the + least integer not already representing a vertex. ``name`` must be an + immutable object (e.g., an integer, a tuple, etc.). + + OUTPUT: + + - If ``name`` specifies an existing vertex, then nothing is done. + Otherwise a :exc:`ValueError` is returned since matching covered + graphs are free of isolated vertices. + + EXAMPLES: + + Adding an existing vertex:: + + sage: P = graphs.PetersenGraph() + sage: P + Petersen graph: Graph on 10 vertices + sage: G = MatchingCoveredGraph(P) + sage: G + Matching covered petersen graph: graph on 10 vertices + sage: # needs random + sage: u = random.choice(list(G)) + sage: G.add_vertex(u) + sage: G + Matching covered petersen graph: graph on 10 vertices + + Adding a new/ non-existing vertex:: + + sage: P = graphs.PetersenGraph() + sage: P + Petersen graph: Graph on 10 vertices + sage: G = MatchingCoveredGraph(P) + sage: G + Matching covered petersen graph: graph on 10 vertices + sage: G.add_vertex() + Traceback (most recent call last): + ... + ValueError: isolated vertices are not allowed in matching covered graphs + sage: u = 0 + sage: while u in G: + ....: u += 1 + sage: G.add_vertex(u) + Traceback (most recent call last): + ... + ValueError: isolated vertices are not allowed in matching covered graphs + """ + if name not in self: + raise ValueError('isolated vertices are not allowed in ' + 'matching covered graphs') + def add_vertices(self, vertices): r""" Add vertices to the (matching covered) graph from an iterable container @@ -642,70 +706,6 @@ def add_vertices(self, vertices): raise ValueError('isolated vertices are not allowed in ' 'matching covered graphs') - def add_vertex(self, name=None): - r""" - Add a vertex to the (matching covered) graph. - - .. NOTE:: - - This method overwrites the - :meth:`~sage.graphs.generic_graph.GenericGraph.add_vertex` method - to ensure that isolated vertices are forbidden in - :class:`~MatchingCoveredGraph`. - - INPUT: - - - ``name`` -- an immutable object (default: ``None``); when no name is - specified (default), then the new vertex will be represented by the - least integer not already representing a vertex. ``name`` must be an - immutable object (e.g., an integer, a tuple, etc.). - - OUTPUT: - - - If ``name`` specifies an existing vertex, then nothing is done. - Otherwise a :exc:`ValueError` is returned since matching covered - graphs are free of isolated vertices. - - EXAMPLES: - - Adding an existing vertex:: - - sage: P = graphs.PetersenGraph() - sage: P - Petersen graph: Graph on 10 vertices - sage: G = MatchingCoveredGraph(P) - sage: G - Matching covered petersen graph: graph on 10 vertices - sage: # needs random - sage: u = random.choice(list(G)) - sage: G.add_vertex(u) - sage: G - Matching covered petersen graph: graph on 10 vertices - - Adding a new/ non-existing vertex:: - - sage: P = graphs.PetersenGraph() - sage: P - Petersen graph: Graph on 10 vertices - sage: G = MatchingCoveredGraph(P) - sage: G - Matching covered petersen graph: graph on 10 vertices - sage: G.add_vertex() - Traceback (most recent call last): - ... - ValueError: isolated vertices are not allowed in matching covered graphs - sage: u = 0 - sage: while u in G: - ....: u += 1 - sage: G.add_vertex(u) - Traceback (most recent call last): - ... - ValueError: isolated vertices are not allowed in matching covered graphs - """ - if name not in self: - raise ValueError('isolated vertices are not allowed in ' - 'matching covered graphs') - def allow_loops(self, new, check=True): r""" Change whether loops are allowed in (matching covered) graphs. @@ -749,6 +749,66 @@ def allow_loops(self, new, check=True): raise ValueError('loops are not allowed in ' 'matching covered graphs') + def delete_vertex(self, vertex, in_order=False): + """ + Delete a vertex, removing all incident edges. + + .. NOTE:: + + This method overwrites the + :meth:`~sage.graphs.generic_graph.GenericGraph.delete_vertex` + method to ensure that an odd order is forbidden in + :class:`~MatchingCoveredGraph`. + + INPUT: + + - ``vertex`` -- a vertex that is to be deleted. + + - ``in_order`` -- boolean (default: ``False``); if ``True``, this + deletes the `i`-th vertex in the sorted list of vertices, i.e. + ``G.vertices(sort=True)[i]`` + + OUTPUT: + + - Deleting a non-existent vertex raises a :exc:`ValueError` exception; + also a (different) :exc:`ValueError` is returned on deleting an + existing vertex since matching covered graphs are of even order. + + EXAMPLES: + + Deleting a non-existent vertex:: + + sage: W = graphs.WheelGraph(12) + sage: G = MatchingCoveredGraph(W) + sage: u = 0 + sage: while u in G: + ....: u += 1 + sage: G.delete_vertex(u) + Traceback (most recent call last): + ... + ValueError: vertex (12) not in the graph + + Deleting an existing vertex:: + + sage: W = graphs.WheelGraph(12) + sage: G = MatchingCoveredGraph(W) + sage: # need random + sage: import random + sage: u = random.choice(list(G)) + sage: G.delete_vertex(u) + Traceback (most recent call last): + ... + ValueError: odd order is not allowed for matching covered graphs + """ + if in_order: + vertex = self.vertices(sort=True)[vertex] + + if vertex not in self: + raise ValueError('vertex (%s) not in the graph' % str(vertex)) + + raise ValueError('odd order is not allowed for ' + 'matching covered graphs') + def delete_vertices(self, vertices): r""" Delete vertices (along with the incident edges) from the (matching @@ -853,66 +913,6 @@ def delete_vertices(self, vertices): raise ValueError('the resulting graph after the removal of ' 'the vertices is not matching covered') - def delete_vertex(self, vertex, in_order=False): - """ - Delete a vertex, removing all incident edges. - - .. NOTE:: - - This method overwrites the - :meth:`~sage.graphs.generic_graph.GenericGraph.delete_vertex` - method to ensure that an odd order is forbidden in - :class:`~MatchingCoveredGraph`. - - INPUT: - - - ``vertex`` -- a vertex that is to be deleted. - - - ``in_order`` -- boolean (default: ``False``); if ``True``, this - deletes the `i`-th vertex in the sorted list of vertices, i.e. - ``G.vertices(sort=True)[i]`` - - OUTPUT: - - - Deleting a non-existent vertex raises a :exc:`ValueError` exception; - also a (different) :exc:`ValueError` is returned on deleting an - existing vertex since matching covered graphs are of even order. - - EXAMPLES: - - Deleting a non-existent vertex:: - - sage: W = graphs.WheelGraph(12) - sage: G = MatchingCoveredGraph(W) - sage: u = 0 - sage: while u in G: - ....: u += 1 - sage: G.delete_vertex(u) - Traceback (most recent call last): - ... - ValueError: vertex (12) not in the graph - - Deleting an existing vertex:: - - sage: W = graphs.WheelGraph(12) - sage: G = MatchingCoveredGraph(W) - sage: # need random - sage: import random - sage: u = random.choice(list(G)) - sage: G.delete_vertex(u) - Traceback (most recent call last): - ... - ValueError: odd order is not allowed for matching covered graphs - """ - if in_order: - vertex = self.vertices(sort=True)[vertex] - - if vertex not in self: - raise ValueError('vertex (%s) not in the graph' % str(vertex)) - - raise ValueError('odd order is not allowed for ' - 'matching covered graphs') - def get_matching(self): r""" Return ``self._matching``, which is a perfect matching of the (matching From 264bb9a9b8fb78398e49b08202a868fd6cb9a0c0 Mon Sep 17 00:00:00 2001 From: janmenjayap Date: Mon, 14 Oct 2024 23:39:53 +0530 Subject: [PATCH 291/537] updated the documentation --- src/sage/graphs/matching_covered_graph.py | 30 +++++++++++++++-------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/src/sage/graphs/matching_covered_graph.py b/src/sage/graphs/matching_covered_graph.py index 74eaf504b33..96a1c827516 100644 --- a/src/sage/graphs/matching_covered_graph.py +++ b/src/sage/graphs/matching_covered_graph.py @@ -591,7 +591,8 @@ def add_vertex(self, name=None): OUTPUT: - If ``name`` specifies an existing vertex, then nothing is done. - Otherwise a :exc:`ValueError` is returned since matching covered + Otherwise a :exc:`ValueError` is returned with no change to the + existing (matching covered) graph is returned since matching covered graphs are free of isolated vertices. EXAMPLES: @@ -656,8 +657,8 @@ def add_vertices(self, vertices): - If all of the vertices are existing vertices of the (matching covered) graph, then nothing is done; otherwise a :exc:`ValueError` - is returned since matching covered graphs are free of isolated - vertices. + is returned with no change to the existing (matching covered) graph + since matching covered graphs are free of isolated vertices. EXAMPLES: @@ -728,9 +729,10 @@ def allow_loops(self, new, check=True): OUTPUT: - - A :exc:`ValueError` is returned if ``new`` is ``True`` since a - matching covered graph, by definition, is free of self-loops. If - ``new`` is set to ``False``, there is no output. + - A :exc:`ValueError` is returned with no change to the existing + (matching covered) graph if ``new`` is ``True`` since a matching + covered graph, by definition, is free of self-loops. If ``new`` is + set to ``False``, there is no output. EXAMPLES: @@ -772,7 +774,9 @@ def delete_vertex(self, vertex, in_order=False): - Deleting a non-existent vertex raises a :exc:`ValueError` exception; also a (different) :exc:`ValueError` is returned on deleting an - existing vertex since matching covered graphs are of even order. + existing vertex since matching covered graphs are of even order. In + both cases no modifications are made to the existing (matching + covered) graph. EXAMPLES: @@ -833,8 +837,9 @@ def delete_vertices(self, vertices): - If all of the vertices in the list/ set provided exist in the graph, but the resulting graph after deletion of all of those is not - matching covered, then a :exc:`ValueError` exception is raised, - otherwise nothing is returned. + matching covered, then a :exc:`ValueError` exception is raised + without any alterations to the existing (matching covered) graph, + otherwise the vertices are deleted and nothing is returned. EXAMPLES: @@ -918,6 +923,10 @@ def get_matching(self): Return ``self._matching``, which is a perfect matching of the (matching covered) graph computed at the initialization. + OUTPUT: + + - A perfect matching of the (matching covered) graph. + EXAMPLES: If one specifies a perfect matching while initializing the object, the @@ -959,7 +968,8 @@ def update_matching(self, matching): - If ``matching`` is a valid perfect matching of the graph, then ``self._matching`` gets updated to this provided matching, or - otherwise an exception is returned. + otherwise an exception is returned without any alterations to + ``self._matching``. EXAMPLES: From 99b8faa63a318639cf785a4b5e485020648cb78a Mon Sep 17 00:00:00 2001 From: janmenjayap Date: Tue, 15 Oct 2024 08:39:42 +0530 Subject: [PATCH 292/537] updated the documentation --- src/sage/graphs/matching_covered_graph.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/graphs/matching_covered_graph.py b/src/sage/graphs/matching_covered_graph.py index 96a1c827516..d96509962db 100644 --- a/src/sage/graphs/matching_covered_graph.py +++ b/src/sage/graphs/matching_covered_graph.py @@ -752,7 +752,7 @@ def allow_loops(self, new, check=True): 'matching covered graphs') def delete_vertex(self, vertex, in_order=False): - """ + r""" Delete a vertex, removing all incident edges. .. NOTE:: From d2720e3d984dfa42a7b8b1c07e4f3d6213e20161 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Tue, 15 Oct 2024 10:15:09 +0530 Subject: [PATCH 293/537] Debugged basis() method for atom-free case --- src/sage/matroids/chow_ring.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/sage/matroids/chow_ring.py b/src/sage/matroids/chow_ring.py index d8ad6a638d8..a4f01221007 100644 --- a/src/sage/matroids/chow_ring.py +++ b/src/sage/matroids/chow_ring.py @@ -170,6 +170,8 @@ def basis(self): reln = lambda x,y: x <= y lattice_flats = Poset((flats, reln)) chains = lattice_flats.chains() #Only chains + for ch in chains: + print(ch) if self._augmented: if self._presentation == 'fy': for subset in chains: From f296378e98a8efe30a2b15555f4374d2035ac554 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Tue, 15 Oct 2024 10:15:34 +0530 Subject: [PATCH 294/537] Optimized definition of atom-free presentation --- src/sage/matroids/chow_ring_ideal.py | 27 ++++++++------------------- 1 file changed, 8 insertions(+), 19 deletions(-) diff --git a/src/sage/matroids/chow_ring_ideal.py b/src/sage/matroids/chow_ring_ideal.py index 8ee112abc23..72b2b73107e 100644 --- a/src/sage/matroids/chow_ring_ideal.py +++ b/src/sage/matroids/chow_ring_ideal.py @@ -426,7 +426,7 @@ def groebner_basis(self, algorithm='constructed', *args, **kwargs): for H in self._flats: if i in H: term += self._flats_generator[H] - if H > G: + if H >= G: term1 += self._flats_generator[H] if term != poly_ring.zero(): gb.append(self._flats_generator[i] + term) #5.7 @@ -511,21 +511,12 @@ def __init__(self, M, R): self._matroid = M self._flats = [X for i in range(1, self._matroid.rank() + 1) for X in self._matroid.flats(i)] - - E = list(self._matroid.groundset()) - flats_containing = {x: [] for x in E} - for i,F in enumerate(self._flats): - for x in F: - flats_containing[x].append(i) - names = ['A{}'.format(''.join(str(x) for x in sorted(F, key=cmp_elements_key))) for F in self._flats] - try: poly_ring = PolynomialRing(R, names) #self.ring except ValueError: # variables are not proper names poly_ring = PolynomialRing(R, 'A', len(self._flats)) gens = poly_ring.gens() - self._flats_generator = dict() self._flats_generator = dict(zip(self._flats, gens)) MPolynomialIdeal.__init__(self, poly_ring, self._gens_constructor(poly_ring)) @@ -556,17 +547,15 @@ def _gens_constructor(self, poly_ring): for G in self._flats: if not (G > F or F > G): #generators for every pair of non-nested flats Q.append(self._flats_generator[F]*self._flats_generator[G]) - for x in E: #generators for every set of flats containing element - term = poly_ring.zero() - for H in flats_containing[x]: - term += self._flats_generator[H] + for x in E: #generators for every set of flats containing element + term = poly_ring.zero() + for H in flats_containing[x]: + term += self._flats_generator[H] + if term**2 not in Q: Q.append(term**2) - if F not in flats_containing[x]: #generators for every set of flats not containing element - term = poly_ring.zero() - for H in flats_containing[x]: - term += self._flats_generator[H] - Q.append(self._flats_generator[F]*term) + if F not in flats_containing[x]: #generators for every set of flats not containing element + Q.append(self._flats_generator[F]*term) return Q def _repr_(self): From ab57cd98f70715ea96bfed1ca19a558b77842bc9 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Tue, 15 Oct 2024 11:49:27 +0530 Subject: [PATCH 295/537] Debugged groebner_basis() --- src/sage/matroids/chow_ring_ideal.py | 29 ++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/src/sage/matroids/chow_ring_ideal.py b/src/sage/matroids/chow_ring_ideal.py index 72b2b73107e..29e4977d293 100644 --- a/src/sage/matroids/chow_ring_ideal.py +++ b/src/sage/matroids/chow_ring_ideal.py @@ -237,7 +237,7 @@ def groebner_basis(self, algorithm='', *args, **kwargs): term += flats_gen[flats[j]] for j in range(i): if term != R.zero(): - gb.append(flats_gen[flats[j]]*term) + gb.append(flats_gen[flats[j]]*(term)**(self._matroid.rank(flats[i]) - self._matroid.rank(flats[j]))) g_basis = PolynomialSequence(R, [gb]) return g_basis @@ -358,7 +358,7 @@ def _gens_constructor(self, poly_ring): for F in self._flats: term += self._flats_generator[F] for G in self._flats: - if not (F < G or G < F): + if not (F <= G or G < F): Q.append(self._flats_generator[F] * self._flats_generator[G]) #Quadratic Generators L.append(term) @@ -417,7 +417,7 @@ def groebner_basis(self, algorithm='constructed', *args, **kwargs): poly_ring = self.ring() for F in self._flats: for G in self._flats: - if not (F < G or G < F): #Non-nested flats + if not (F <= G or G <= F): #Non-nested flats gb.append(self._flats_generator[F]*self._flats_generator[G]) for i in E: @@ -431,18 +431,18 @@ def groebner_basis(self, algorithm='constructed', *args, **kwargs): if term != poly_ring.zero(): gb.append(self._flats_generator[i] + term) #5.7 if term1 != poly_ring.zero(): - gb.append(term1**(self._matroid.rank(F) + 1)) #5.6 + gb.append(term1**(self._matroid.rank(G) + 1)) #5.6 if i in G: #if element in flat if term1 != poly_ring.zero(): gb.append(self._flats_generator[i]*((term1)**self._matroid.rank(G))) elif i not in G: #if element not in flat - gb.append(self._flats_generator[i]*self._flats_generator[F]) + gb.append(self._flats_generator[i]*self._flats_generator[G]) - if G < F: #nested flats + if G > F: #nested flats if term1 != poly_ring.zero(): - gb.append(self._flats_generator[G]*term1**(self._matroid.rank(F)-self._matroid.rank(G))) + gb.append(self._flats_generator[F]*term1**(self._matroid.rank(G)-self._matroid.rank(F))) g_basis = PolynomialSequence(poly_ring, [gb]) return g_basis @@ -545,7 +545,7 @@ def _gens_constructor(self, poly_ring): flats_containing[x].append(F) for F in self._flats: for G in self._flats: - if not (G > F or F > G): #generators for every pair of non-nested flats + if not (G >= F or F > G): #generators for every pair of non-nested flats Q.append(self._flats_generator[F]*self._flats_generator[G]) for x in E: #generators for every set of flats containing element term = poly_ring.zero() @@ -603,15 +603,16 @@ def groebner_basis(self, algorithm='constructed', *args, **kwargs): #Copy from f poly_ring = self.ring() for F in self._flats: for G in self._flats: - if not (F > G or G > F): #Non nested flats + term = poly_ring.zero() + for H in self._flats: + if H < F: + term += self._flats_generator[H] + if not (F >= G or G > F): #Non nested flats gb.append(self._flats_generator[F]*self._flats_generator[G]) elif F < G: #Nested flats - term = poly_ring.zero() - for H in self._flats: - if H < F: - term += self._flats_generator[H] if term != poly_ring.zero(): - gb.append(self._flats_generator[F]*(term**self._matroid.rank(G))*(term**(self._matroid.rank(G) - self._matroid.rank(F)))) + gb.append(self._flats_generator[F]*(term**(self._matroid.rank(G) - self._matroid.rank(F)))) + gb.append((term**self._matroid.rank(F)) + 1) g_basis = PolynomialSequence(poly_ring, [gb]) return g_basis From 8b2d98ff362f102b9dfd30df1e569a83947f31c7 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Tue, 15 Oct 2024 11:49:42 +0530 Subject: [PATCH 296/537] Debugged basis() --- src/sage/matroids/chow_ring.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/sage/matroids/chow_ring.py b/src/sage/matroids/chow_ring.py index a4f01221007..5877567d87c 100644 --- a/src/sage/matroids/chow_ring.py +++ b/src/sage/matroids/chow_ring.py @@ -170,8 +170,6 @@ def basis(self): reln = lambda x,y: x <= y lattice_flats = Poset((flats, reln)) chains = lattice_flats.chains() #Only chains - for ch in chains: - print(ch) if self._augmented: if self._presentation == 'fy': for subset in chains: @@ -195,7 +193,7 @@ def basis(self): monomial_basis.append(expression) if max_powers.index(p) == 0: #Generating combinations for all powers including first max_powers - expression *= flats_gen[subset[0]]**max_powers[0] + expression *= flats_gen[subset[0]]**ranks[flats[0]] monomial_basis.append(expression) elif self._presentation == 'atom-free': @@ -222,7 +220,7 @@ def basis(self): max_powers[0] = 0 for combination in product(*(range(1, p) for p in max_powers)): #Generating all combinations including 0 power and max_power for first flat - if sum(combination) == first_rank: + if sum(combination) <= first_rank: expression = R.one() for i in range(len(combination)): expression *= flats_gen[subset[i]]**combination[i] From 0e5c8f6d2e9a312acc882926861324b1284aca31 Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Tue, 15 Oct 2024 11:56:36 +0200 Subject: [PATCH 297/537] replace UniqueRepresentation of the Element classes with WithPicklingByInitArgs --- src/sage/rings/species.py | 78 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 72 insertions(+), 6 deletions(-) diff --git a/src/sage/rings/species.py b/src/sage/rings/species.py index 0ce15903664..5b0b61757b2 100644 --- a/src/sage/rings/species.py +++ b/src/sage/rings/species.py @@ -16,6 +16,7 @@ from sage.groups.perm_gps.permgroup_named import SymmetricGroup from sage.libs.gap.libgap import libgap from sage.misc.cachefunc import cached_method +from sage.misc.fast_methods import WithEqualityById from sage.misc.inherit_comparison import InheritComparisonClasscallMetaclass from sage.modules.free_module_element import vector from sage.monoids.indexed_free_monoid import (IndexedFreeAbelianMonoid, @@ -28,12 +29,14 @@ from sage.structure.element import Element, parent from sage.structure.factorization import Factorization from sage.structure.parent import Parent -from sage.structure.unique_representation import UniqueRepresentation +from sage.structure.unique_representation import (UniqueRepresentation, + WithPicklingByInitArgs) GAP_FAIL = libgap.eval('fail') -class ConjugacyClassOfDirectlyIndecomposableSubgroups(UniqueRepresentation, Element, +class ConjugacyClassOfDirectlyIndecomposableSubgroups(Element, WithEqualityById, + WithPicklingByInitArgs, metaclass=InheritComparisonClasscallMetaclass): r""" A directly indecomposable conjugacy class of subgroups of a @@ -42,6 +45,28 @@ class ConjugacyClassOfDirectlyIndecomposableSubgroups(UniqueRepresentation, Elem Two conjugacy classes of subgroups are equal if they have the same degree (say `n`) and are conjugate within `S_n`. """ + @staticmethod + def _invariant(C): + r""" + Return an invariant of the permutation group ``C`` used for + hashing and as key in the cache. + + EXAMPLES:: + + sage: from sage.rings.species import ConjugacyClassOfDirectlyIndecomposableSubgroups + sage: C = ConjugacyClassOfDirectlyIndecomposableSubgroups + sage: G = PermutationGroup([[(1,2),(3,4)]]) + sage: H = PermutationGroup([[(1,3),(2,4)], [(1,2),(3,4)]]) + sage: K = PermutationGroup([[(1,2,3,4)]]) + sage: C._invariant(G) + (2, (2, 2)) + sage: C._invariant(H) + (4, (4,)) + sage: C._invariant(K) + (4, (4,)) + """ + return C.cardinality(), tuple(sorted(len(o) for o in C.orbits())) + @staticmethod def __classcall__(cls, parent, C): """ @@ -86,7 +111,7 @@ def standardize(C): G = PermutationGroup(G.SmallGeneratingSet().sage()) return G.conjugate(pi.inverse()) - key = C.cardinality(), tuple(sorted(len(o) for o in C.orbits())) + key = cls._invariant(C) if key in parent._cache: lookup = parent._cache[key] for elm in lookup: @@ -95,10 +120,30 @@ def standardize(C): else: lookup = parent._cache[key] = [] - elm = super().__classcall__(cls, parent, standardize(C)) + elm = WithPicklingByInitArgs.__classcall__(cls, parent, standardize(C)) lookup.append(elm) return elm + def __hash__(self): + """ + Return a hash of ``self``. + + EXAMPLES:: + + sage: from sage.rings.species import ConjugacyClassesOfDirectlyIndecomposableSubgroups + sage: C = ConjugacyClassesOfDirectlyIndecomposableSubgroups() + sage: G = PermutationGroup([[(1,2),(3,4)]]) + sage: H = PermutationGroup([[(1,3),(2,4)], [(1,2),(3,4)]]) + sage: K = PermutationGroup([[(1,2,3,4)]]) + sage: hash(C(G)) == hash(C(H)) + False + sage: hash(C(H)) == hash(C(K)) + True + sage: C(H) == C(K) + False + """ + return hash(self._invariant(self._C)) + def __init__(self, parent, C): r""" Initialize a conjugacy class of directly indecomposable subgroups @@ -244,7 +289,8 @@ def an_element(self): Element = ConjugacyClassOfDirectlyIndecomposableSubgroups -class AtomicSpeciesElement(UniqueRepresentation, Element, +class AtomicSpeciesElement(Element, WithEqualityById, + WithPicklingByInitArgs, metaclass=InheritComparisonClasscallMetaclass): r""" An atomic species. @@ -322,7 +368,7 @@ def is_equal(elm): else: lookup = parent._cache[key] = [] - elm = super().__classcall__(cls, parent, dis, domain_partition) + elm = WithPicklingByInitArgs.__classcall__(cls, parent, dis, domain_partition) lookup.append(elm) return elm @@ -354,6 +400,26 @@ def __init__(self, parent, dis, domain_partition): self._mc = tuple(len(v) for v in self._dompart) self._tc = sum(self._mc) + def __hash__(self): + """ + Return a hash of ``self``. + + EXAMPLES:: + + sage: from sage.rings.species import AtomicSpecies + sage: A = AtomicSpecies("X") + sage: G = PermutationGroup([[(1,2),(3,4)]]) + sage: H = PermutationGroup([[(1,3),(2,4)], [(1,2),(3,4)]]) + sage: K = PermutationGroup([[(1,2,3,4)]]) + sage: hash(A(G)) == hash(A(H)) + False + sage: hash(A(H)) == hash(A(K)) + True + sage: A(H) == A(K) + False + """ + return hash((self._dis, self._dompart)) + def _repr_(self): r""" Return a string representation of ``self``. From 7133a28eeed0d9a952148a74d73869fca710f76e Mon Sep 17 00:00:00 2001 From: janmenjayap Date: Tue, 15 Oct 2024 18:05:53 +0530 Subject: [PATCH 298/537] removed _upgrade_from_graph() --- src/sage/graphs/matching_covered_graph.py | 36 +++++++---------------- 1 file changed, 11 insertions(+), 25 deletions(-) diff --git a/src/sage/graphs/matching_covered_graph.py b/src/sage/graphs/matching_covered_graph.py index d96509962db..93c3f1454ba 100644 --- a/src/sage/graphs/matching_covered_graph.py +++ b/src/sage/graphs/matching_covered_graph.py @@ -477,11 +477,17 @@ def __init__(self, data=None, matching=None, algorithm='Edmonds', elif isinstance(data, Graph): try: - Graph.__init__(self, data, *args, **kwds) - self._upgrade_from_graph(matching=matching, algorithm=algorithm, - solver=solver, verbose=verbose, - integrality_tolerance=integrality_tolerance) - success = True + check = Graph.is_matching_covered(G=data, matching=matching, + algorithm=algorithm, + coNP_certificate=False, + solver=solver, verbose=verbose, + integrality_tolerance=integrality_tolerance) + + if check: + Graph.__init__(self, data, *args, **kwds) + success = True + else: + raise ValueError("input graph is not matching covered") except Exception as exception: raise exception @@ -549,26 +555,6 @@ def __repr__(self): return s.capitalize() return "".join(["Matching covered ", s]) - def _upgrade_from_graph(self, matching=None, algorithm='Edmonds', - solver=None, verbose=0, - integrality_tolerance=0.001): - r""" - Upgrade the given graph to a matching covered graph if eligible. - - See documentation ``MatchingCoveredGraph?`` for detailed information. - """ - try: - check = Graph.is_matching_covered(G=self, matching=matching, - algorithm=algorithm, - coNP_certificate=False, - solver=solver, verbose=verbose, - integrality_tolerance=integrality_tolerance) - - if not check: - raise ValueError("input graph is not matching covered") - - except Exception as exception: - raise exception def add_vertex(self, name=None): r""" From b19e4db0da37022f62ed00c9644a495a75a9e797 Mon Sep 17 00:00:00 2001 From: janmenjayap Date: Tue, 15 Oct 2024 18:07:17 +0530 Subject: [PATCH 299/537] updated the code --- src/sage/graphs/matching_covered_graph.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/sage/graphs/matching_covered_graph.py b/src/sage/graphs/matching_covered_graph.py index 93c3f1454ba..f33f3629eab 100644 --- a/src/sage/graphs/matching_covered_graph.py +++ b/src/sage/graphs/matching_covered_graph.py @@ -884,9 +884,10 @@ def delete_vertices(self, vertices): try: G = Graph(self) G.delete_vertices(vertices) - M = Graph(self.get_matching()) G_simple = G.to_simple() + M = Graph(self.get_matching()) + if M: M.delete_vertices(vertices) # The resulting matching after the removal of the input vertices From 57670f16877924aef4f57609e87e5fce6e06c15a Mon Sep 17 00:00:00 2001 From: janmenjayap Date: Tue, 15 Oct 2024 18:11:26 +0530 Subject: [PATCH 300/537] added add_edge() --- src/sage/graphs/matching_covered_graph.py | 193 +++++++++++++++++++++- 1 file changed, 192 insertions(+), 1 deletion(-) diff --git a/src/sage/graphs/matching_covered_graph.py b/src/sage/graphs/matching_covered_graph.py index f33f3629eab..84763103bd4 100644 --- a/src/sage/graphs/matching_covered_graph.py +++ b/src/sage/graphs/matching_covered_graph.py @@ -266,7 +266,7 @@ class MatchingCoveredGraph(Graph): sage: G.add_edge(0, 0) Traceback (most recent call last): ... - ValueError: cannot add edge from 0 to 0 in graph without loops + ValueError: loops are not allowed in matching covered graphs sage: H = MatchingCoveredGraph(P, loops=True) Traceback (most recent call last): ... @@ -556,6 +556,197 @@ def __repr__(self): return "".join(["Matching covered ", s]) + def add_edge(self, u, v=None, label=None): + r""" + Add an edge from vertex ``u`` to vertex ``v``. + + .. NOTE:: + + This method overwrites the + :meth:`~sage.graphs.generic_graph.GenericGraph.add_edge` method + to ensure that resultant graph is also matching covered. + + INPUT: + + The following forms are all accepted: + + - G.add_edge(1, 2) + - G.add_edge((1, 2)) + - G.add_edges([(1, 2)]) + - G.add_edge(1, 2, 'label') + - G.add_edge((1, 2, 'label')) + - G.add_edges([(1, 2, 'label')]) + + OUTPUT: + + - If an edge is provided with a valid format, but addition of the edge + leaves the resulting graph not being matching covered, a + :exc:`ValueError` is returned without any alteration to the existing + matching covered graph. If the addition of the edge preserves the + property of matching covered, then the graph is updated and nothing + is returned. + + - If the edge is provided with an invalid format, a :exc:`ValueError` + is returned. + + WARNING: + + The following intuitive input results in nonintuitive output, + even though the resulting graph behind the intuition might be matching + covered:: + + sage: P = graphs.WheelGraph(6) + sage: G = MatchingCoveredGraph(P) + sage: G.add_edge((1, 4), 'label') + Traceback (most recent call last): + ... + ValueError: the graph obtained after the addition of edge (((1, 4), 'label', None)) is not matching covered + sage: G.edges(sort=False) + [(0, 1, None), (0, 2, None), (0, 3, None), (0, 4, None), (0, 5, None), (1, 2, None), (1, 5, None), (2, 3, None), (3, 4, None), (4, 5, None)] + + The key word ``label`` must be used:: + + sage: W = graphs.WheelGraph(6) + sage: G = MatchingCoveredGraph(W) + sage: G.add_edge((1, 4), label='label') + sage: G.edges(sort=False) + [(0, 1, None), (0, 2, None), (0, 3, None), (0, 4, None), (0, 5, None), (1, 2, None), (1, 4, 'label'), (1, 5, None), (2, 3, None), (3, 4, None), (4, 5, None)] + + An expression, analogous to the syntax mentioned above may be used:: + + sage: W = graphs.WheelGraph(6) + sage: G = MatchingCoveredGraph(W) + sage: G.add_edge(1, 4) + sage: G.edges(sort=False) + [(0, 1, None), (0, 2, None), (0, 3, None), (0, 4, None), (0, 5, None), (1, 2, None), (1, 4, None), (1, 5, None), (2, 3, None), (3, 4, None), (4, 5, None)] + + sage: W = graphs.WheelGraph(6) + sage: G = MatchingCoveredGraph(W) + sage: G.add_edge((1, 4)) + sage: G.edges(sort=False) + [(0, 1, None), (0, 2, None), (0, 3, None), (0, 4, None), (0, 5, None), (1, 2, None), (1, 4, None), (1, 5, None), (2, 3, None), (3, 4, None), (4, 5, None)] + + sage: W = graphs.WheelGraph(6) + sage: G = MatchingCoveredGraph(W) + sage: G.add_edges([(1, 4)]) + sage: G.edges(sort=False) + [(0, 1, None), (0, 2, None), (0, 3, None), (0, 4, None), (0, 5, None), (1, 2, None), (1, 4, None), (1, 5, None), (2, 3, None), (3, 4, None), (4, 5, None)] + + sage: W = graphs.WheelGraph(6) + sage: G = MatchingCoveredGraph(W) + sage: G.add_edge(1, 4, 'label') + sage: G.edges(sort=False) + [(0, 1, None), (0, 2, None), (0, 3, None), (0, 4, None), (0, 5, None), (1, 2, None), (1, 4, 'label'), (1, 5, None), (2, 3, None), (3, 4, None), (4, 5, None)] + + sage: W = graphs.WheelGraph(6) + sage: G = MatchingCoveredGraph(W) + sage: G.add_edge((1, 4, 'label')) + sage: G.edges(sort=False) + [(0, 1, None), (0, 2, None), (0, 3, None), (0, 4, None), (0, 5, None), (1, 2, None), (1, 4, 'label'), (1, 5, None), (2, 3, None), (3, 4, None), (4, 5, None)] + + sage: W = graphs.WheelGraph(6) + sage: G = MatchingCoveredGraph(W) + sage: G.add_edges([(1, 4, 'label')]) + sage: G.edges(sort=False) + [(0, 1, None), (0, 2, None), (0, 3, None), (0, 4, None), (0, 5, None), (1, 2, None), (1, 4, 'label'), (1, 5, None), (2, 3, None), (3, 4, None), (4, 5, None)] + + Vertex name cannot be ``None``, so:: + + sage: W = graphs.WheelGraph(6) + sage: H = MatchingCoveredGraph(W) + sage: H.add_edge(None, 1) + Traceback (most recent call last): + ... + ValueError: the graph obtained after the addition of edge ((None, 1, None)) is not matching covered + + sage: W = graphs.WheelGraph(6) + sage: H = MatchingCoveredGraph(W) + sage: H.add_edge(None, 7) + Traceback (most recent call last): + ... + ValueError: the graph obtained after the addition of edge ((None, 7, None)) is not matching covered + + EXAMPLES: + + Adding an edge such that the resulting graph is matching covered:: + + sage: P = graphs.PetersenGraph() + sage: G = MatchingCoveredGraph(P) + sage: G.add_edge(1, 4) + sage: G.edges(sort=False) + [(0, 1, None), (0, 4, None), (0, 5, None), (1, 2, None), (1, 4, None), (1, 6, None), (2, 3, None), (2, 7, None), (3, 4, None), (3, 8, None), (4, 9, None), (5, 7, None), (5, 8, None), (6, 8, None), (6, 9, None), (7, 9, None)] + + Adding an edge with both the incident vertices being existent such + that the resulting graph is not matching covered:: + + sage: C = graphs.CycleGraph(4) + sage: G = MatchingCoveredGraph(C) + sage: G.add_edge(0, 2) + Traceback (most recent call last): + ... + ValueError: the graph obtained after the addition of edge ((0, 2, None)) is not matching covered + + Adding an edge with exactly one incident vertex that is nonexistent + throws a :exc:`ValueError` exception, as the resulting graph would + have an odd order:: + + sage: C = graphs.CycleGraph(4) + sage: G = MatchingCoveredGraph(C) + sage: G.add_edge(0, 4) + Traceback (most recent call last): + ... + ValueError: the graph obtained after the addition of edge ((0, 4, None)) is not matching covered + + Adding an edge with both the incident vertices that is nonexistent + throws a :exc:`ValueError` exception, as the resulting graph would + have been disconnected:: + + sage: C = graphs.CycleGraph(4) + sage: G = MatchingCoveredGraph(C) + sage: G.add_edge(4, 5) + Traceback (most recent call last): + ... + ValueError: the graph obtained after the addition of edge ((4, 5, None)) is not matching covered + """ + if label is None: + if v is None: + try: + u, v, label = u + except Exception: + try: + u, v = u + except Exception: + pass + + else: + if v is None: + try: + u, v = u + except Exception: + pass + + if u in self and v in self: + if u == v: + raise ValueError('loops are not allowed in ' + 'matching covered graphs') + G = Graph(self) + G.add_edge(u, v, label=label) + + try: + self.__init__(data=G, matching=self.get_matching()) + except: + raise ValueError('the graph obtained after the addition of ' + 'edge (%s) is not matching covered' \ + % str((u, v, label))) + + else: + # At least one of u or v is a nonexistent vertex. + # Thus, the resulting graph is either disconnected + # or has an odd order, hence not matching covered + raise ValueError('the graph obtained after the addition of edge ' + '(%s) is not matching covered' \ + % str((u, v, label))) + def add_vertex(self, name=None): r""" Add a vertex to the (matching covered) graph. From f0f7bae52ac21373fb97dda3d9290fe7193d09ef Mon Sep 17 00:00:00 2001 From: janmenjayap Date: Tue, 15 Oct 2024 18:49:36 +0530 Subject: [PATCH 301/537] corrected the use of bare 'except' --- src/sage/graphs/matching_covered_graph.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/graphs/matching_covered_graph.py b/src/sage/graphs/matching_covered_graph.py index 84763103bd4..8d7c0611aef 100644 --- a/src/sage/graphs/matching_covered_graph.py +++ b/src/sage/graphs/matching_covered_graph.py @@ -734,7 +734,7 @@ def add_edge(self, u, v=None, label=None): try: self.__init__(data=G, matching=self.get_matching()) - except: + except Exception: raise ValueError('the graph obtained after the addition of ' 'edge (%s) is not matching covered' \ % str((u, v, label))) From c0d90d5d9dc159f55cdd9a72c09d2a730ea7014e Mon Sep 17 00:00:00 2001 From: janmenjayap Date: Tue, 15 Oct 2024 19:03:30 +0530 Subject: [PATCH 302/537] updated the doctests --- src/sage/graphs/matching_covered_graph.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/sage/graphs/matching_covered_graph.py b/src/sage/graphs/matching_covered_graph.py index 8d7c0611aef..aef0d4ccfaa 100644 --- a/src/sage/graphs/matching_covered_graph.py +++ b/src/sage/graphs/matching_covered_graph.py @@ -609,7 +609,7 @@ def add_edge(self, u, v=None, label=None): sage: W = graphs.WheelGraph(6) sage: G = MatchingCoveredGraph(W) sage: G.add_edge((1, 4), label='label') - sage: G.edges(sort=False) + sage: G.edges(sort=False) # No alteration to the existing graph [(0, 1, None), (0, 2, None), (0, 3, None), (0, 4, None), (0, 5, None), (1, 2, None), (1, 4, 'label'), (1, 5, None), (2, 3, None), (3, 4, None), (4, 5, None)] An expression, analogous to the syntax mentioned above may be used:: @@ -658,6 +658,8 @@ def add_edge(self, u, v=None, label=None): Traceback (most recent call last): ... ValueError: the graph obtained after the addition of edge ((None, 1, None)) is not matching covered + sage: H.edges(sort=False) # No alteration to the existing graph + [(0, 1, None), (0, 2, None), (0, 3, None), (0, 4, None), (0, 5, None), (1, 2, None), (1, 5, None), (2, 3, None), (3, 4, None), (4, 5, None)] sage: W = graphs.WheelGraph(6) sage: H = MatchingCoveredGraph(W) @@ -665,6 +667,8 @@ def add_edge(self, u, v=None, label=None): Traceback (most recent call last): ... ValueError: the graph obtained after the addition of edge ((None, 7, None)) is not matching covered + sage: H.edges(sort=False) # No alteration to the existing graph + [(0, 1, None), (0, 2, None), (0, 3, None), (0, 4, None), (0, 5, None), (1, 2, None), (1, 5, None), (2, 3, None), (3, 4, None), (4, 5, None)] EXAMPLES: @@ -685,6 +689,8 @@ def add_edge(self, u, v=None, label=None): Traceback (most recent call last): ... ValueError: the graph obtained after the addition of edge ((0, 2, None)) is not matching covered + sage: G.edges(sort=False) # No alteration to the existing graph + [(0, 1, None), (0, 3, None), (1, 2, None), (2, 3, None)] Adding an edge with exactly one incident vertex that is nonexistent throws a :exc:`ValueError` exception, as the resulting graph would @@ -696,6 +702,8 @@ def add_edge(self, u, v=None, label=None): Traceback (most recent call last): ... ValueError: the graph obtained after the addition of edge ((0, 4, None)) is not matching covered + sage: G.edges(sort=False) # No alteration to the existing graph + [(0, 1, None), (0, 3, None), (1, 2, None), (2, 3, None)] Adding an edge with both the incident vertices that is nonexistent throws a :exc:`ValueError` exception, as the resulting graph would @@ -707,6 +715,8 @@ def add_edge(self, u, v=None, label=None): Traceback (most recent call last): ... ValueError: the graph obtained after the addition of edge ((4, 5, None)) is not matching covered + sage: G.edges(sort=False) # No alteration to the existing graph + [(0, 1, None), (0, 3, None), (1, 2, None), (2, 3, None)] """ if label is None: if v is None: From 7efae8d79c257918b511438a6a985584fdda6f40 Mon Sep 17 00:00:00 2001 From: janmenjayap Date: Tue, 15 Oct 2024 20:56:24 +0530 Subject: [PATCH 303/537] removed redundant backslashes --- src/sage/graphs/matching_covered_graph.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/graphs/matching_covered_graph.py b/src/sage/graphs/matching_covered_graph.py index aef0d4ccfaa..3a61c6dbf1c 100644 --- a/src/sage/graphs/matching_covered_graph.py +++ b/src/sage/graphs/matching_covered_graph.py @@ -746,7 +746,7 @@ def add_edge(self, u, v=None, label=None): self.__init__(data=G, matching=self.get_matching()) except Exception: raise ValueError('the graph obtained after the addition of ' - 'edge (%s) is not matching covered' \ + 'edge (%s) is not matching covered' % str((u, v, label))) else: @@ -754,7 +754,7 @@ def add_edge(self, u, v=None, label=None): # Thus, the resulting graph is either disconnected # or has an odd order, hence not matching covered raise ValueError('the graph obtained after the addition of edge ' - '(%s) is not matching covered' \ + '(%s) is not matching covered' % str((u, v, label))) def add_vertex(self, name=None): From 928bfa582ab8945bf2a8e280ad236bc191dec483 Mon Sep 17 00:00:00 2001 From: janmenjayap Date: Wed, 16 Oct 2024 01:07:10 +0530 Subject: [PATCH 304/537] removed an unnecessary blank line --- src/sage/graphs/matching_covered_graph.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/sage/graphs/matching_covered_graph.py b/src/sage/graphs/matching_covered_graph.py index 3a61c6dbf1c..fc638daa12f 100644 --- a/src/sage/graphs/matching_covered_graph.py +++ b/src/sage/graphs/matching_covered_graph.py @@ -555,7 +555,6 @@ def __repr__(self): return s.capitalize() return "".join(["Matching covered ", s]) - def add_edge(self, u, v=None, label=None): r""" Add an edge from vertex ``u`` to vertex ``v``. From c07f0b833882147d9153248a7c85caf5f7cd6c69 Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Wed, 16 Oct 2024 22:18:12 +0200 Subject: [PATCH 305/537] fix and doctest bug in group_and_partition --- src/sage/rings/species.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/sage/rings/species.py b/src/sage/rings/species.py index 5b0b61757b2..5ae832796a5 100644 --- a/src/sage/rings/species.py +++ b/src/sage/rings/species.py @@ -1299,7 +1299,6 @@ def __ge__(self, other): return False return other <= self - @cached_method def group_and_partition(self): """ Return the (transitive) permutation group corresponding to ``self``. @@ -1347,6 +1346,10 @@ def group_and_partition(self): sage: F = M(PermutationGroup([(1,2),(3,)])) sage: F.group_and_partition()[0].domain() {1, 2, 3} + + sage: F = M(AlternatingGroup(2)) + sage: F.group_and_partition()[0].domain() + {1, 2} """ def shift_gens(gens, n): """ @@ -1369,19 +1372,22 @@ def shift_gens(gens, n): return a._dis._C, a._dompart if n % 2 == 1: + # split off a single monomial a = list(A._monomial)[0] # as atomic species b, b_dompart = (A ** (n-1)).group_and_partition() gens = a._dis._C.gens() + shift_gens(b.gens(), a._tc) new_dompart = tuple([frozenset(list(p_a) + [a._tc + e for e in p_b]) for p_a, p_b in zip(a._dompart, b_dompart)]) + domain = range(1, n * a._tc + 1) else: f, f_dompart = (A ** (n // 2)).group_and_partition() tc = sum(len(p) for p in f_dompart) gens = f.gens() + shift_gens(f.gens(), tc) new_dompart = tuple([frozenset(list(p) + [tc + e for e in p]) for p in f_dompart]) + domain = range(1, 2 * tc + 1) - G = PermutationGroup(gens) + G = PermutationGroup(gens, domain=domain) return G, new_dompart f_dompart_list = [(A ** n).group_and_partition() for A, n in factors] From 5fea8af41a7f393f0a2770641970e2c2d919a119 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Thu, 17 Oct 2024 10:12:49 +0530 Subject: [PATCH 306/537] Debugged groebner_basis() for all 3 ideals --- src/sage/matroids/chow_ring_ideal.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/sage/matroids/chow_ring_ideal.py b/src/sage/matroids/chow_ring_ideal.py index 29e4977d293..0d95e59f30a 100644 --- a/src/sage/matroids/chow_ring_ideal.py +++ b/src/sage/matroids/chow_ring_ideal.py @@ -220,6 +220,7 @@ def groebner_basis(self, algorithm='', *args, **kwargs): if algorithm != 'constructed': return super().groebner_basis(algorithm=algorithm, *args, **kwargs) flats = sorted(list(self._flats_generator), key=len) + ranks = {F: self._matroid.rank(F) for F in flats} gb = list() R = self.ring() reln = lambda x,y: x <= y @@ -231,13 +232,12 @@ def groebner_basis(self, algorithm='', *args, **kwargs): for x in subset: term *= flats_gen[x] gb.append(term) - for i in range(len(flats)): #Reduced groebner basis by computing the sum first and then the product + for F in flats: #Reduced groebner basis by computing the sum first and then the product term = R.zero() - for j in range(i+1, len(flats)): - term += flats_gen[flats[j]] - for j in range(i): - if term != R.zero(): - gb.append(flats_gen[flats[j]]*(term)**(self._matroid.rank(flats[i]) - self._matroid.rank(flats[j]))) + for G in lattice_flats.order_filter([F]): + term += flats_gen[G] + for G in lattice_flats.order_ideal([F]): + gb.append(flats_gen[G]*(term)**(ranks[F] - ranks[G])) g_basis = PolynomialSequence(R, [gb]) return g_basis From 283a45bf7d731d9a9d786f77318fe674d059a947 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Thu, 17 Oct 2024 11:28:09 +0530 Subject: [PATCH 307/537] Corrected doctests --- src/sage/matroids/chow_ring_ideal.py | 226 +++++++++++++++------------ 1 file changed, 125 insertions(+), 101 deletions(-) diff --git a/src/sage/matroids/chow_ring_ideal.py b/src/sage/matroids/chow_ring_ideal.py index 0d95e59f30a..2953ecd4dc6 100644 --- a/src/sage/matroids/chow_ring_ideal.py +++ b/src/sage/matroids/chow_ring_ideal.py @@ -189,7 +189,7 @@ def _latex_(self): sage: M1 = Matroid(groundset='abcd', bases=['ab','ad', 'bc']) sage: ch = M1.chow_ring(QQ, False) sage: ch.defining_ideal()._latex_() - '\\left(\\mathit{Aac} \\mathit{Abd}, \\mathit{Aac} + \\mathit{Aabcd}, \\mathit{Abd} + \\mathit{Aabcd}\\right)\\Bold{Q}[\\mathit{Aac}, \\mathit{Abd}, \\mathit{Aabcd}]' + I_{M} + J_{M} of matroid \text{\texttt{Matroid{ }of{ }rank{ }2{ }on{ }4{ }elements{ }with{ }3{ }bases}} """ from sage.misc.latex import latex return 'I_{M} + J_{M} of matroid ' + (latex(self._matroid)) @@ -202,7 +202,7 @@ def groebner_basis(self, algorithm='', *args, **kwargs): sage: ch = Matroid(groundset='abc', bases=['ab', 'ac']).chow_ring(QQ, False) sage: ch.defining_ideal().groebner_basis() - [Aa*Abc, Aa*Aabc] + [Aa*Abc, Aa, Abc, Aa*Aabc, Abc*Aabc, Aabc] sage: ch.defining_ideal().groebner_basis().is_groebner() True @@ -211,7 +211,7 @@ def groebner_basis(self, algorithm='', *args, **kwargs): sage: ch = Matroid(graphs.CycleGraph(3)).chow_ring(QQ, False) sage: ch.defining_ideal().groebner_basis() - [A0*A1, A0*A2, A1*A2, A0*A2 + A0*A3, A0*A3, A1*A3] + [A0*A1, A0*A2, A1*A2, A0, A1, A2, A0*A3, A1*A3, A2*A3, A3] sage: ch.defining_ideal().groebner_basis().is_groebner() True """ @@ -246,8 +246,7 @@ class AugmentedChowRingIdeal_fy(ChowRingIdeal): The augmented Chow ring ideal of matroid `M` over ring `R` in Feitchner-Yuzvinsky presentation. - The augmented Chow ring ideal in the Feitchner-Yuzvinsky presentation - for a matroid `M` is defined as the ideal + The augmented Chow ring ideal for a matroid `M` is defined as the ideal `(I_M + J_M)` of the following polynomial ring .. MATH:: @@ -256,7 +255,7 @@ class AugmentedChowRingIdeal_fy(ChowRingIdeal): where - - `F_1, \ldots, F_k` are the flats of `M`, + - `F_1, \ldots, F_k` are the proper flats of `M`, - `e_1 \ldots, e_n` are `n` elements of groundset of `M`, - `J_M` is the ideal generated by all quadratic forms `x_{F_i} x_{F_j}`, where `F_i` and `F_j` are incomparable elements in the lattice of @@ -268,7 +267,38 @@ class AugmentedChowRingIdeal_fy(ChowRingIdeal): y_i - \sum_{i \notin F} x_F for all `i \in E`. + + The augmented Chow ring ideal in the Feitchner Yuzvinsky presentation + for a simple matroid `M` is defined as the ideal + `(I_{FY}(M))` of the following polynomial ring + + .. MATH:: + + R[y_{e_1}, \ldots, y_{e_n}, y_{F_1 \union e}, \ldots, y_{F_k \union e}], + + where + + - `F_1, \ldots, F_k` are the flats of `M`, + - `e_1 \ldots, e_n` are `n` elements of groundset of `M`, + - `I_{FY}(M) is the ideal generated by all quadratic forms + `y_{F_i \union e} y_{F_j \union e}`, where `F_i` and `F_j` + are incomparable elements in the lattice of flats, `y_{i} y_{F \union e}` + for every `i \in E` and `i \notin F`, linear forms + + .. MATH:: + y_i + \sum_{i \in F} y_{F \union e} + + for all `i \in E` and, + + .. MATH:: + + \sum_{F} y_{F \union e}. + + Setting `x_F = y_{F \union e}` and using the last linear + form to eliminate `x_E` recovers the usual presentation of + augmented Chow ring of M. + REFERENCES: - [MM2022]_ @@ -321,30 +351,37 @@ def _gens_constructor(self, poly_ring): sage: ch = matroids.Wheel(3).chow_ring(QQ, True, 'fy') sage: ch.defining_ideal()._gens_constructor(ch.defining_ideal().ring()) - [B0^2, B0*B1, B0*B2, B0*B3, B0*B4, B0*B5, B0*B124, B0*B15, B0*B23, - B0*B345, B0*B1, B1^2, B1*B2, B1*B3, B1*B4, B1*B5, B1*B025, B1*B04, - B1*B23, B1*B345, B0*B2, B1*B2, B2^2, B2*B3, B2*B4, B2*B5, B2*B013, - B2*B04, B2*B15, B2*B345, B0*B3, B1*B3, B2*B3, B3^2, B3*B4, B3*B5, - B3*B025, B3*B04, B3*B124, B3*B15, B0*B4, B1*B4, B2*B4, B3*B4, B4^2, - B4*B5, B4*B013, B4*B025, B4*B15, B4*B23, B0*B5, B1*B5, B2*B5, - B3*B5, B4*B5, B5^2, B5*B013, B5*B04, B5*B124, B5*B23, B2*B013, - B4*B013, B5*B013, B013^2, B013*B025, B013*B04, B013*B124, B013*B15, - B013*B23, B013*B345, B1*B025, B3*B025, B4*B025, B013*B025, B025^2, - B025*B04, B025*B124, B025*B15, B025*B23, B025*B345, B1*B04, B2*B04, - B3*B04, B5*B04, B013*B04, B025*B04, B04^2, B04*B124, B04*B15, - B04*B23, B04*B345, B0*B124, B3*B124, B5*B124, B013*B124, B025*B124, - B04*B124, B124^2, B124*B15, B124*B23, B124*B345, B0*B15, B2*B15, - B3*B15, B4*B15, B013*B15, B025*B15, B04*B15, B124*B15, B15^2, - B15*B23, B15*B345, B0*B23, B1*B23, B4*B23, B5*B23, B013*B23, - B025*B23, B04*B23, B124*B23, B15*B23, B23^2, B23*B345, B0*B345, - B1*B345, B2*B345, B013*B345, B025*B345, B04*B345, B124*B345, - B15*B345, B23*B345, B345^2, - A0 - B1 - B2 - B3 - B4 - B5 - B124 - B15 - B23 - B345, - A1 - B0 - B2 - B3 - B4 - B5 - B025 - B04 - B23 - B345, - A2 - B0 - B1 - B3 - B4 - B5 - B013 - B04 - B15 - B345, - A3 - B0 - B1 - B2 - B4 - B5 - B025 - B04 - B124 - B15, - A4 - B0 - B1 - B2 - B3 - B5 - B013 - B025 - B15 - B23, - A5 - B0 - B1 - B2 - B3 - B4 - B013 - B04 - B124 - B23] + [B0*B1, B0*B2, B0*B3, B0*B4, B0*B5, B0*B124, B0*B15, B0*B23, + B0*B345, B0*B1, B1*B2, B1*B3, B1*B4, B1*B5, B1*B025, B1*B04, + B1*B23, B1*B345, B0*B2, B1*B2, B2*B3, B2*B4, B2*B5, B2*B013, + B2*B04, B2*B15, B2*B345, B0*B3, B1*B3, B2*B3, B3*B4, B3*B5, + B3*B025, B3*B04, B3*B124, B3*B15, B0*B4, B1*B4, B2*B4, B3*B4, + B4*B5, B4*B013, B4*B025, B4*B15, B4*B23, B0*B5, B1*B5, B2*B5, + B3*B5, B4*B5, B5*B013, B5*B04, B5*B124, B5*B23, B2*B013, B4*B013, + B5*B013, B013*B025, B013*B04, B013*B124, B013*B15, B013*B23, + B013*B345, B1*B025, B3*B025, B4*B025, B013*B025, B025*B04, + B025*B124, B025*B15, B025*B23, B025*B345, B1*B04, B2*B04, B3*B04, + B5*B04, B013*B04, B025*B04, B04*B124, B04*B15, B04*B23, B04*B345, + B0*B124, B3*B124, B5*B124, B013*B124, B025*B124, B04*B124, + B124*B15, B124*B23, B124*B345, B0*B15, B2*B15, B3*B15, B4*B15, + B013*B15, B025*B15, B04*B15, B124*B15, B15*B23, B15*B345, B0*B23, + B1*B23, B4*B23, B5*B23, B013*B23, B025*B23, B04*B23, B124*B23, + B15*B23, B23*B345, B0*B345, B1*B345, B2*B345, B013*B345, + B025*B345, B04*B345, B124*B345, B15*B345, B23*B345, A0*B, A0*B1, + A0*B2, A0*B3, A0*B4, A0*B5, A0*B124, A0*B15, A0*B23, A0*B345, + A1*B, A1*B0, A1*B2, A1*B3, A1*B4, A1*B5, A1*B025, A1*B04, A1*B23, + A1*B345, A2*B, A2*B0, A2*B1, A2*B3, A2*B4, A2*B5, A2*B013, A2*B04, + A2*B15, A2*B345, A3*B, A3*B0, A3*B1, A3*B2, A3*B4, A3*B5, A3*B025, + A3*B04, A3*B124, A3*B15, A4*B, A4*B0, A4*B1, A4*B2, A4*B3, A4*B5, + A4*B013, A4*B025, A4*B15, A4*B23, A5*B, A5*B0, A5*B1, A5*B2, + A5*B3, A5*B4, A5*B013, A5*B04, A5*B124, A5*B23, + B + B0 + B1 + B2 + B3 + B4 + B5 + B013 + B025 + B04 + B124 + B15 + B23 + B345 + B012345, + A0 + B0 + B013 + B025 + B04 + B012345, + A1 + B1 + B013 + B124 + B15 + B012345, + A2 + B2 + B025 + B124 + B23 + B012345, + A3 + B3 + B013 + B23 + B345 + B012345, + A4 + B4 + B04 + B124 + B345 + B012345, + A5 + B5 + B025 + B15 + B345 + B012345] """ E = list(self._matroid.groundset()) flats_containing = {x: [] for x in E} @@ -392,12 +429,10 @@ def _latex_(self): sage: M1 = Matroid(graphs.CycleGraph(3)) sage: ch = M1.chow_ring(QQ, True, 'fy') sage: ch.defining_ideal()._latex_() - '\\left(A_{3}^{2}, A_{3} A_{4}, A_{3} A_{5}, A_{3} A_{4}, A_{4}^{2}, A_{4} A_{5}, A_{3} A_{5}, A_{4} A_{5}, A_{5}^{2}, A_{0} - A_{4} - A_{5}, A_{1} - A_{3} - A_{5}, A_{2} - A_{3} - A_{4}\\right)\\Bold{Q}[A_{0}, A_{1}, A_{2}, A_{3}, A_{4}, A_{5}]' + I_{FY} of matroid \text{\texttt{Graphic{ }matroid{ }of{ }rank{ }2{ }on{ }3{ }elements}} """ from sage.misc.latex import latex - return '\\left(%s\\right)%s' % (", ".join(latex(g) - for g in self.gens()), - latex(self.ring())) + return 'I_{FY} of matroid ' + (latex(self._matroid)) def groebner_basis(self, algorithm='constructed', *args, **kwargs): r""" @@ -407,47 +442,41 @@ def groebner_basis(self, algorithm='constructed', *args, **kwargs): sage: ch = matroids.Uniform(2,5).chow_ring(QQ, True, 'fy') sage: ch.defining_ideal().groebner_basis(algorithm='') - Polynomial Sequence with 250 Polynomials in 10 Variables + Polynomial Sequence with 565 Polynomials in 12 Variables sage: ch.defining_ideal().groebner_basis(algorithm='').is_groebner() True """ if algorithm == '': - gb = [] - E = list(self._matroid.groundset()) - poly_ring = self.ring() - for F in self._flats: - for G in self._flats: - if not (F <= G or G <= F): #Non-nested flats - gb.append(self._flats_generator[F]*self._flats_generator[G]) - - for i in E: - term = poly_ring.zero() - term1 = poly_ring.zero() - for H in self._flats: - if i in H: - term += self._flats_generator[H] - if H >= G: - term1 += self._flats_generator[H] - if term != poly_ring.zero(): - gb.append(self._flats_generator[i] + term) #5.7 - if term1 != poly_ring.zero(): - gb.append(term1**(self._matroid.rank(G) + 1)) #5.6 - - if i in G: #if element in flat - if term1 != poly_ring.zero(): - gb.append(self._flats_generator[i]*((term1)**self._matroid.rank(G))) - - elif i not in G: #if element not in flat - gb.append(self._flats_generator[i]*self._flats_generator[G]) + algorithm = 'constructed' + if algorithm != 'constructed': + return super().groebner_basis(algorithm=algorithm, *args, **kwargs) + gb = [] #Reduced groebner basis with two eliminated cases + E = list(self._matroid.groundset()) + poly_ring = self.ring() + for F in self._flats: + for G in self._flats: + if not (F <= G or G <= F): #Non-nested flats + gb.append(self._flats_generator[F]*self._flats_generator[G]) - if G > F: #nested flats - if term1 != poly_ring.zero(): - gb.append(self._flats_generator[F]*term1**(self._matroid.rank(G)-self._matroid.rank(F))) + for i in E: + term = poly_ring.zero() + term1 = poly_ring.zero() + for H in self._flats: + if i in H: + term += self._flats_generator[H] + if H >= G: + term1 += self._flats_generator[H] + if term != poly_ring.zero(): + gb.append(self._flats_generator[i] + term) #5.7 + if term1 != poly_ring.zero(): + gb.append(term1**(self._matroid.rank(G) + 1)) #5.6 + + if G > F: #nested flats + if term1 != poly_ring.zero(): + gb.append(self._flats_generator[F]*term1**(self._matroid.rank(G)-self._matroid.rank(F))) - g_basis = PolynomialSequence(poly_ring, [gb]) - return g_basis - elif algorithm == 'constructed': - super().groebner_basis(*args, **kwargs) + g_basis = PolynomialSequence(poly_ring, [gb]) + return g_basis class AugmentedChowRingIdeal_atom_free(ChowRingIdeal): r""" @@ -529,13 +558,10 @@ def _gens_constructor(self, poly_ring): sage: M1 = Matroid(graphs.CycleGraph(3)) sage: ch = M1.chow_ring(QQ, True, 'atom-free') sage: ch.defining_ideal()._gens_constructor(ch.defining_ideal().ring()) - [A0^2, A0^2, A1^2, A0*A1, A2^2, A0*A2, A0*A1, A0^2, A1^2, A0*A1, - A2^2, A0*A2, A0*A2, A0^2, A1^2, A0*A1, A2^2, A0*A2, A0*A1, A0^2, - A0*A1, A1^2, A2^2, A1*A2, A1^2, A0^2, A0*A1, A1^2, A2^2, A1*A2, - A1*A2, A0^2, A0*A1, A1^2, A2^2, A1*A2, A0*A2, A0^2, A0*A2, A1^2, - A1*A2, A2^2, A1*A2, A0^2, A0*A2, A1^2, A1*A2, A2^2, A2^2, A0^2, - A0*A2, A1^2, A1*A2, A2^2] - + [A0*A1, A0*A2, A0^2 + 2*A0*A3 + A3^2, A1^2 + 2*A1*A3 + A3^2, + A0*A1 + A0*A3, A2^2 + 2*A2*A3 + A3^2, A0*A2 + A0*A3, + A0*A1, A1*A2, A0*A1 + A1*A3, A1*A2 + A1*A3, A0*A2, A1*A2, + A0*A2 + A2*A3, A1*A2 + A2*A3] """ E = list(self._matroid.groundset()) Q = [] #Quadratic Generators @@ -578,12 +604,10 @@ def _latex_(self): sage: M1 = Matroid(graphs.CycleGraph(3)) sage: ch = M1.chow_ring(QQ, True, 'atom-free') sage: ch.defining_ideal()._latex_() - '\\left(A_{0}^{2}, A_{0}^{2}, A_{1}^{2}, A_{0} A_{1}, A_{2}^{2}, A_{0} A_{2}, A_{0} A_{1}, A_{0}^{2}, A_{1}^{2}, A_{0} A_{1}, A_{2}^{2}, A_{0} A_{2}, A_{0} A_{2}, A_{0}^{2}, A_{1}^{2}, A_{0} A_{1}, A_{2}^{2}, A_{0} A_{2}, A_{0} A_{1}, A_{0}^{2}, A_{0} A_{1}, A_{1}^{2}, A_{2}^{2}, A_{1} A_{2}, A_{1}^{2}, A_{0}^{2}, A_{0} A_{1}, A_{1}^{2}, A_{2}^{2}, A_{1} A_{2}, A_{1} A_{2}, A_{0}^{2}, A_{0} A_{1}, A_{1}^{2}, A_{2}^{2}, A_{1} A_{2}, A_{0} A_{2}, A_{0}^{2}, A_{0} A_{2}, A_{1}^{2}, A_{1} A_{2}, A_{2}^{2}, A_{1} A_{2}, A_{0}^{2}, A_{0} A_{2}, A_{1}^{2}, A_{1} A_{2}, A_{2}^{2}, A_{2}^{2}, A_{0}^{2}, A_{0} A_{2}, A_{1}^{2}, A_{1} A_{2}, A_{2}^{2}\\right)\\Bold{Q}[A_{0}, A_{1}, A_{2}]' + I_{af} of matroid \text{\texttt{Graphic{ }matroid{ }of{ }rank{ }2{ }on{ }3{ }elements}} """ from sage.misc.latex import latex - return '\\left(%s\\right)%s' % (", ".join(latex(g) - for g in self.gens()), - latex(self.ring())) + return 'I_{af} of matroid ' + latex(self._matroid) def groebner_basis(self, algorithm='constructed', *args, **kwargs): #Copy from fy presentation """ @@ -594,28 +618,28 @@ def groebner_basis(self, algorithm='constructed', *args, **kwargs): #Copy from f sage: M1 = Matroid(graphs.CycleGraph(3)) sage: ch = M1.chow_ring(QQ, True, 'atom-free') sage: ch.defining_ideal().groebner_basis(algorithm='') - [A0^2, A0*A1, A0*A2, A0*A1, A1^2, A1*A2, A0*A2, A1*A2, A2^2] + Polynomial Sequence with 22 Polynomials in 3 Variables sage: ch.defining_ideal().groebner_basis(algorithm='').is_groebner() True """ if algorithm == '': - gb = [] - poly_ring = self.ring() - for F in self._flats: - for G in self._flats: - term = poly_ring.zero() - for H in self._flats: - if H < F: - term += self._flats_generator[H] - if not (F >= G or G > F): #Non nested flats - gb.append(self._flats_generator[F]*self._flats_generator[G]) - elif F < G: #Nested flats - if term != poly_ring.zero(): - gb.append(self._flats_generator[F]*(term**(self._matroid.rank(G) - self._matroid.rank(F)))) - gb.append((term**self._matroid.rank(F)) + 1) - - g_basis = PolynomialSequence(poly_ring, [gb]) - return g_basis - - elif algorithm == 'constructed': - super().groebner_basis(*args, **kwargs) \ No newline at end of file + algorithm = 'constructed' + if algorithm != 'constructed': + return super().groebner_basis(algorithm=algorithm, *args, **kwargs) + gb = [] + poly_ring = self.ring() + for F in self._flats: + for G in self._flats: + term = poly_ring.zero() + for H in self._flats: + if H < F: + term += self._flats_generator[H] + if not (F >= G or G > F): #Non nested flats + gb.append(self._flats_generator[F]*self._flats_generator[G]) + elif F < G: #Nested flats + if term != poly_ring.zero(): + gb.append(self._flats_generator[F]*(term**(self._matroid.rank(G) - self._matroid.rank(F)))) + gb.append((term**self._matroid.rank(F)) + 1) + + g_basis = PolynomialSequence(poly_ring, [gb]) + return g_basis \ No newline at end of file From 058252f285cca18aecb82adb151369aa7e9e8f01 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Thu, 17 Oct 2024 12:15:34 +0530 Subject: [PATCH 308/537] Debugged basis() for FY presentation of the augmented Chow ring --- src/sage/matroids/chow_ring.py | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/src/sage/matroids/chow_ring.py b/src/sage/matroids/chow_ring.py index 5877567d87c..b9dee33c6fa 100644 --- a/src/sage/matroids/chow_ring.py +++ b/src/sage/matroids/chow_ring.py @@ -176,25 +176,19 @@ def basis(self): k = len(subset) if k == 0: monomial_basis.append(R.one()) - elif k == 1 & ranks[subset[0]] == 1: - monomial_basis.append(flats_gen[subset[0]]) else: max_powers = [] max_powers.append(ranks[subset[0]]) for i in range(1, k): max_powers.append(ranks[subset[i]] - ranks[subset[i-1]]) - for p in max_powers: - if p != 1 | p != 0: - for combination in product((range(1, p))): - #Generating combinations for all powers up to max_powers - expression = R.one() - for i in range(k): - expression *= flats_gen[subset[i]]**combination[i] - monomial_basis.append(expression) - if max_powers.index(p) == 0: - #Generating combinations for all powers including first max_powers - expression *= flats_gen[subset[0]]**ranks[flats[0]] - monomial_basis.append(expression) + ranges = [range(1, p) for p in max_powers] + ranges[0] = range(1, max_powers[0] + 1) + for combination in product(*(r for r in ranges)): + #Generating combinations for all powers up to max_powers + expression = R.one() + for i in range(k): + expression *= flats_gen[subset[i]]**combination[i] + monomial_basis.append(expression) elif self._presentation == 'atom-free': for subset in chains: From 1922a1a0c768a5b465dcfaf1e817fe650051feb7 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Thu, 17 Oct 2024 12:27:37 +0530 Subject: [PATCH 309/537] Debugged basis() for augmented Chow ring for both presentations --- src/sage/matroids/chow_ring.py | 21 ++++----------------- 1 file changed, 4 insertions(+), 17 deletions(-) diff --git a/src/sage/matroids/chow_ring.py b/src/sage/matroids/chow_ring.py index b9dee33c6fa..72904bbd5a4 100644 --- a/src/sage/matroids/chow_ring.py +++ b/src/sage/matroids/chow_ring.py @@ -202,29 +202,16 @@ def basis(self): max_powers.append(ranks[subset[i]]) else: max_powers.append(ranks[subset[i]] - ranks[subset[i-1]]) + ranges = [range(1, p) for p in max_powers] + ranges[0] = range(1, max_powers[0] + 1) first_rank = ranks[subset[k-1]] + 1 - last_rank = ranks[subset[0]] - for combination in product(*(range(1, p) for p in max_powers)): + for combination in product(*(r for r in ranges)): #Generating combinations for all powers from 1 to max_powers - if sum(combination) == first_rank: - expression = R.one() - for i in range(k): - expression *= flats_gen[subset[i]]**combination[i] - monomial_basis.append(expression) - max_powers[0] = 0 - for combination in product(*(range(1, p) for p in max_powers)): - #Generating all combinations including 0 power and max_power for first flat if sum(combination) <= first_rank: expression = R.one() - for i in range(len(combination)): + for i in range(k): expression *= flats_gen[subset[i]]**combination[i] monomial_basis.append(expression) - else: - expression *= flats_gen[subset[0]]**last_rank - if sum(combination) + last_rank == first_rank: - for i in range(k): - expression *= flats_gen[subset[i]]**combination[i] - monomial_basis.append(expression) else: for subset in chains: From 1d2e204660974f3fd6c650f5782605a8f121aef2 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Thu, 17 Oct 2024 12:57:33 +0530 Subject: [PATCH 310/537] Corrected linting errors --- src/sage/matroids/chow_ring_ideal.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/sage/matroids/chow_ring_ideal.py b/src/sage/matroids/chow_ring_ideal.py index 2953ecd4dc6..6eb14139828 100644 --- a/src/sage/matroids/chow_ring_ideal.py +++ b/src/sage/matroids/chow_ring_ideal.py @@ -267,7 +267,7 @@ class AugmentedChowRingIdeal_fy(ChowRingIdeal): y_i - \sum_{i \notin F} x_F for all `i \in E`. - + The augmented Chow ring ideal in the Feitchner Yuzvinsky presentation for a simple matroid `M` is defined as the ideal `(I_{FY}(M))` of the following polynomial ring @@ -280,7 +280,7 @@ class AugmentedChowRingIdeal_fy(ChowRingIdeal): - `F_1, \ldots, F_k` are the flats of `M`, - `e_1 \ldots, e_n` are `n` elements of groundset of `M`, - - `I_{FY}(M) is the ideal generated by all quadratic forms + - `I_{FY}(M) is the ideal generated by all quadratic forms `y_{F_i \union e} y_{F_j \union e}`, where `F_i` and `F_j` are incomparable elements in the lattice of flats, `y_{i} y_{F \union e}` for every `i \in E` and `i \notin F`, linear forms @@ -288,17 +288,17 @@ class AugmentedChowRingIdeal_fy(ChowRingIdeal): .. MATH:: y_i + \sum_{i \in F} y_{F \union e} - + for all `i \in E` and, .. MATH:: \sum_{F} y_{F \union e}. - + Setting `x_F = y_{F \union e}` and using the last linear form to eliminate `x_E` recovers the usual presentation of augmented Chow ring of M. - + REFERENCES: - [MM2022]_ @@ -609,7 +609,7 @@ def _latex_(self): from sage.misc.latex import latex return 'I_{af} of matroid ' + latex(self._matroid) - def groebner_basis(self, algorithm='constructed', *args, **kwargs): #Copy from fy presentation + def groebner_basis(self, algorithm='constructed', *args, **kwargs): """ Returns the Groebner basis of `self`. From 49276c192bd3127392962c8b3bfe5ad847b6b549 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Thu, 17 Oct 2024 12:57:42 +0530 Subject: [PATCH 311/537] Corrected doctests --- src/sage/matroids/chow_ring.py | 103 +++++++++++++++++++++++++-------- 1 file changed, 80 insertions(+), 23 deletions(-) diff --git a/src/sage/matroids/chow_ring.py b/src/sage/matroids/chow_ring.py index 72904bbd5a4..39b969d84c7 100644 --- a/src/sage/matroids/chow_ring.py +++ b/src/sage/matroids/chow_ring.py @@ -10,7 +10,7 @@ from sage.rings.quotient_ring import QuotientRing_generic from sage.categories.graded_algebras_with_basis import GradedAlgebrasWithBasis from sage.categories.commutative_rings import CommutativeRings -from itertools import product, combinations +from itertools import product from sage.combinat.posets.posets import Poset class ChowRing(QuotientRing_generic): @@ -126,7 +126,7 @@ def _latex_(self): sage: M1 = matroids.Uniform(2,5) sage: ch = M1.chow_ring(QQ, False) sage: ch._latex_() - '\\Bold{Q}[A_{0}, A_{1}, A_{2}, A_{3}, A_{4}, A_{01234}] / \\left(A_{0} A_{1}, A_{0} A_{2}, A_{0} A_{3}, A_{0} A_{4}, A_{1} A_{2}, A_{1} A_{3}, A_{1} A_{4}, A_{2} A_{3}, A_{2} A_{4}, A_{3} A_{4}, A_{0} + A_{01234}, A_{1} + A_{01234}, A_{2} + A_{01234}, A_{3} + A_{01234}, A_{4} + A_{01234}\\right)\\Bold{Q}[A_{0}, A_{1}, A_{2}, A_{3}, A_{4}, A_{01234}]' + '\\Bold{Q}[A_{0}, A_{1}, A_{2}, A_{3}, A_{4}, A_{01234}] / I_{M} + J_{M} of matroid \\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}' """ from sage.misc.latex import latex return "{} / {}".format(latex(self._ideal.ring()), latex(self._ideal)) @@ -151,14 +151,28 @@ def basis(self): sage: ch = matroids.Uniform(3, 6).chow_ring(QQ, True, 'fy') sage: ch.basis() - [B0*B01, 1] - sage: len(ch.defining_ideal().normal_basis()) == ch.basis().cardinality() + Family (1, B1, B1*B012345, B0, B0*B012345, B01, B01^2, B2, + B2*B012345, B02, B02^2, B12, B12^2, B3, B3*B012345, B03, B03^2, + B13, B13^2, B23, B23^2, B4, B4*B012345, B24, B24^2, B34, B34^2, + B04, B04^2, B14, B14^2, B5, B5*B012345, B25, B25^2, B35, B35^2, + B45, B45^2, B05, B05^2, B15, B15^2, B012345, B012345^2, + B012345^3) + sage: set(ch.defining_ideal().normal_basis()) == set(ch.basis()) True - sage: ch = matroids.catalog.NonFano().chow_ring(QQ, False) - [A0*A013, 1] - sage: len(ch.defining_ideal().normal_basis()) == ch.basis().cardinality() + sage: ch = matroids.catalog.Fano().chow_ring(QQ, False) + sage: ch.basis() + Family (1, Abcd, Aace, Aabf, Adef, Aadg, Abeg, Acfg, Aabcdefg, + Aabcdefg^2) + sage: set(ch.defining_ideal().normal_basis()) == set(ch.basis()) + True + sage: ch = matroids.Wheel(3).chow_ring(QQ, True, 'atom-free') + sage: ch.basis() + Family (1, A0, A0*A012345, A2, A2*A012345, A3, A3*A012345, A23, + A23^2, A1, A1*A012345, A013, A013^2, A4, A4*A012345, A04, A04^2, + A124, A124^2, A5, A5*A012345, A025, A025^2, A15, A15^2, A345, + A345^2, A012345, A012345^2, A012345^3) + sage: set(ch.defining_ideal().normal_basis()) == set(ch.basis()) True - """ flats = [X for i in range(1, self._matroid.rank() + 1) for X in self._matroid.flats(i)] #Non empty flats @@ -243,9 +257,9 @@ def to_vector(self, order=None): sage: ch = matroids.Uniform(3, 6).chow_ring(QQ, False) sage: v = ch.an_element(); v - A0 + 0 sage: v.to_vector() - (0, 0, 0, 1, 0, 0, 0) + (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) """ P = self.parent() B = P.basis() @@ -261,11 +275,15 @@ def monomial_coefficients(self, copy=None): EXAMPLES:: - sage: ch = matroids.catalog.NonFano().chow_ring(QQ, True, 'fy') + sage: ch = matroids.catalog.NonFano().chow_ring(QQ, True, 'atom-free') sage: v = ch.an_element(); v - Ag + 0 sage: v.monomial_coefficients() - {0: 0, 1: 0, 2: 0, 3: 0, 4: 0, 5: 0, 6: 0, 7: 0} + {0: 0, 1: 0, 2: 0, 3: 0, 4: 0, 5: 0, 6: 0, 7: 0, 8: 0, 9: 0, + 10: 0, 11: 0, 12: 0, 13: 0, 14: 0, 15: 0, 16: 0, 17: 0, + 18: 0, 19: 0, 20: 0, 21: 0, 22: 0, 23: 0, 24: 0, 25: 0, + 26: 0, 27: 0, 28: 0, 29: 0, 30: 0, 31: 0, 32: 0, 33: 0, + 34: 0, 35: 0} """ B = self.parent().basis() f = self.lift() @@ -281,15 +299,26 @@ def degree(self): sage: for b in ch.basis(): ....: print(b, b.degree()) 1 0 - A1 1 - A3 1 - A0 1 - A2 1 - A4 1 - A5 1 + A01 1 + A02 1 + A12 1 + A03 1 + A13 1 + A23 1 + A24 1 + A34 1 + A04 1 + A14 1 + A25 1 + A35 1 + A45 1 + A05 1 + A15 1 + A012345 1 + A012345^2 2 sage: v = sum(ch.basis()) sage: v.degree() - 1 + 0 """ return self.lift().degree() @@ -304,15 +333,43 @@ def homogeneous_degree(self): sage: for b in ch.basis(): ....: print(b, b.homogeneous_degree()) 1 0 - Bb 1 Ba 1 + Ba*Babcdefg 2 + Bb 1 + Bb*Babcdefg 2 Bc 1 + Bc*Babcdefg 2 Bd 1 + Bd*Babcdefg 2 + Bbcd 1 + Bbcd^2 2 Be 1 + Be*Babcdefg 2 + Bace 1 + Bace^2 2 Bf 1 + Bf*Babcdefg 2 + Babf 1 + Babf^2 2 + Bdef 1 + Bdef^2 2 Bg 1 + Bg*Babcdefg 2 + Badg 1 + Badg^2 2 + Bbeg 1 + Bbeg^2 2 + Bcfg 1 + Bcfg^2 2 + Babcdefg 1 + Babcdefg^2 2 + Babcdefg^3 3 sage: v = sum(ch.basis()); v - Ba + Bb + Bc + Bd + Be + Bf + Bg + 1 + Babcdefg^3 + Babf^2 + Bace^2 + Badg^2 + Bbcd^2 + Bbeg^2 + + Bcfg^2 + Bdef^2 + Ba*Babcdefg + Bb*Babcdefg + Bc*Babcdefg + + Bd*Babcdefg + Be*Babcdefg + Bf*Babcdefg + Bg*Babcdefg + + Babcdefg^2 + Ba + Bb + Bc + Bd + Be + Bf + Bg + Babf + Bace + + Badg + Bbcd + Bbeg + Bcfg + Bdef + Babcdefg + 1 sage: v.homogeneous_degree() Traceback (most recent call last): ... @@ -320,7 +377,7 @@ def homogeneous_degree(self): TESTS:: - sage: ch = matroids.Wheel(3).chow_ring(QQ, False) + sage: ch = matroids.Wheel(3).chow_ring(QQ, True, 'atom-free') sage: ch.zero().homogeneous_degree() Traceback (most recent call last): ... From 94527d8b2fcbffef6cea32b7a4a75fef89e73203 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Thu, 17 Oct 2024 14:08:54 +0530 Subject: [PATCH 312/537] Corrected doctests in chow_ring() method --- src/sage/matroids/matroid.pyx | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/src/sage/matroids/matroid.pyx b/src/sage/matroids/matroid.pyx index 310580e1d18..496a76fa292 100644 --- a/src/sage/matroids/matroid.pyx +++ b/src/sage/matroids/matroid.pyx @@ -8041,32 +8041,30 @@ cdef class Matroid(SageObject): sage: M = matroids.Wheel(2) sage: A = M.chow_ring(R=ZZ, augmented=False); A - Chow ring of Wheel(2): Regular matroid of rank 2 on 4 elements - with 5 bases over Integer Ring - sage: A._gens_constructor() # needs sage.libs.singular + Chow ring of Wheel(2): Regular matroid of rank 2 on 4 elements with 5 bases + sage: A.defining_ideal()._gens_constructor() (A23, A23, A23) - sage: A23 = A.gen(0) # needs sage.libs.singular - sage: A23*A23 # needs sage.libs.singular + sage: A23 = A.gen(0) + sage: A23*A23 0 We construct a more interesting example using the Fano matroid:: sage: M = matroids.catalog.Fano() sage: A = M.chow_ring(QQ, augmented=False); A - Chow ring of Fano: Binary matroid of rank 3 on 7 elements, - type (3, 0) over Rational Field. + Chow ring of Fano: Binary matroid of rank 3 on 7 elements, type (3, 0) The augmented Chow ring can also be constructed with the Feitchner-Yuzvinsky and atom-free presentation:: sage: M = matroids.Wheel(3) - sage: ch = M.chow_ring(QQ, augmented=True, presentation='fy') + sage: ch = M.chow_ring(QQ, augmented=True, presentation='fy'); ch Augmented Chow ring of Wheel(3): Regular matroid of rank 3 on - 6 elements with 16 bases of Feitchner-Yuzvinsky presentation + 6 elements with 16 bases in Feitchner-Yuzvinsky presentation sage: M = matroids.Uniform(3, 6) - sage: ch = M.chow_ring(QQ, augmented=True, presentation='atom-free') + sage: ch = M.chow_ring(QQ, augmented=True, presentation='atom-free'); ch Augmented Chow ring of U(3, 6): Matroid of rank 3 on 6 elements with circuit-closures - {3: {{0, 1, 2, 3, 4, 5}}} of atom-free presentation + {3: {{0, 1, 2, 3, 4, 5}}} in atom-free presentation """ from sage.matroids.chow_ring import ChowRing return ChowRing(M=self, R=R, augmented=augmented, presentation=presentation) From 8fdd62544e1e7860adbecef9b8758831160d92f9 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Thu, 17 Oct 2024 14:26:00 +0530 Subject: [PATCH 313/537] Corrected Doctests for chow_ring() method --- src/sage/matroids/matroid.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/matroids/matroid.pyx b/src/sage/matroids/matroid.pyx index 496a76fa292..138ffdd4e13 100644 --- a/src/sage/matroids/matroid.pyx +++ b/src/sage/matroids/matroid.pyx @@ -8042,7 +8042,7 @@ cdef class Matroid(SageObject): sage: M = matroids.Wheel(2) sage: A = M.chow_ring(R=ZZ, augmented=False); A Chow ring of Wheel(2): Regular matroid of rank 2 on 4 elements with 5 bases - sage: A.defining_ideal()._gens_constructor() + sage: A.defining_ideal()._gens_constructor(A.defining_ideal().ring()) (A23, A23, A23) sage: A23 = A.gen(0) sage: A23*A23 From 193ca4ed73095e4131a842516e3f726e149ce128 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Thu, 17 Oct 2024 14:43:51 +0530 Subject: [PATCH 314/537] Corrected doctests in chow_ring() method --- src/sage/matroids/matroid.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/matroids/matroid.pyx b/src/sage/matroids/matroid.pyx index 138ffdd4e13..2bf1fd8abc3 100644 --- a/src/sage/matroids/matroid.pyx +++ b/src/sage/matroids/matroid.pyx @@ -8043,7 +8043,7 @@ cdef class Matroid(SageObject): sage: A = M.chow_ring(R=ZZ, augmented=False); A Chow ring of Wheel(2): Regular matroid of rank 2 on 4 elements with 5 bases sage: A.defining_ideal()._gens_constructor(A.defining_ideal().ring()) - (A23, A23, A23) + [A0*A1, A0*A23, A1*A23, A0 + A0123, A1 + A0123, A23 + A0123] sage: A23 = A.gen(0) sage: A23*A23 0 From a92e227bb910823bfdcab4f5ae3e5ab217d3de1e Mon Sep 17 00:00:00 2001 From: janmenjayap Date: Fri, 18 Oct 2024 10:35:30 +0530 Subject: [PATCH 315/537] updated the documentation --- src/sage/graphs/matching_covered_graph.py | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/src/sage/graphs/matching_covered_graph.py b/src/sage/graphs/matching_covered_graph.py index fc638daa12f..3b2cc58239c 100644 --- a/src/sage/graphs/matching_covered_graph.py +++ b/src/sage/graphs/matching_covered_graph.py @@ -671,6 +671,14 @@ def add_edge(self, u, v=None, label=None): EXAMPLES: + Adding an already existing edge:: + + sage: P = graphs.PetersenGraph() + sage: G = MatchingCoveredGraph(P) + sage: G.add_edge(next(G.edge_iterator())) + sage: P == G + True + Adding an edge such that the resulting graph is matching covered:: sage: P = graphs.PetersenGraph() @@ -716,6 +724,16 @@ def add_edge(self, u, v=None, label=None): ValueError: the graph obtained after the addition of edge ((4, 5, None)) is not matching covered sage: G.edges(sort=False) # No alteration to the existing graph [(0, 1, None), (0, 3, None), (1, 2, None), (2, 3, None)] + + Adding a self-loop:: + + sage: H = graphs.HeawoodGraph() + sage: G = MatchingCoveredGraph(P) + sage: v = next(G.vertex_iterator()) + sage: G.add_edge(v, v) + Traceback (most recent call last): + ... + ValueError: loops are not allowed in matching covered graphs """ if label is None: if v is None: @@ -1112,7 +1130,8 @@ def get_matching(self): OUTPUT: - - A perfect matching of the (matching covered) graph. + - This method returns :class:`EdgesView` of the edges of a + perfect matching of the (matching covered) graph. EXAMPLES: From addfe088a12ba8926a3a46886f75a707391823d6 Mon Sep 17 00:00:00 2001 From: janmenjayap Date: Fri, 18 Oct 2024 12:24:33 +0530 Subject: [PATCH 316/537] made doctests more concise --- src/sage/graphs/matching_covered_graph.py | 50 ++++++++--------------- 1 file changed, 16 insertions(+), 34 deletions(-) diff --git a/src/sage/graphs/matching_covered_graph.py b/src/sage/graphs/matching_covered_graph.py index 3b2cc58239c..751c0101214 100644 --- a/src/sage/graphs/matching_covered_graph.py +++ b/src/sage/graphs/matching_covered_graph.py @@ -613,41 +613,26 @@ def add_edge(self, u, v=None, label=None): An expression, analogous to the syntax mentioned above may be used:: - sage: W = graphs.WheelGraph(6) - sage: G = MatchingCoveredGraph(W) - sage: G.add_edge(1, 4) + sage: S = graphs.StaircaseGraph(4) + sage: G = MatchingCoveredGraph(S) + sage: G.add_edge(0, 5) sage: G.edges(sort=False) - [(0, 1, None), (0, 2, None), (0, 3, None), (0, 4, None), (0, 5, None), (1, 2, None), (1, 4, None), (1, 5, None), (2, 3, None), (3, 4, None), (4, 5, None)] - - sage: W = graphs.WheelGraph(6) - sage: G = MatchingCoveredGraph(W) - sage: G.add_edge((1, 4)) + [(0, 1, None), (0, 3, None), (0, 5, None), (0, 6, None), (1, 2, None), (1, 4, None), (2, 5, None), (2, 7, None), (3, 4, None), (3, 6, None), (4, 5, None), (5, 7, None), (6, 7, None)] + sage: G.add_edge((2, 3)) sage: G.edges(sort=False) - [(0, 1, None), (0, 2, None), (0, 3, None), (0, 4, None), (0, 5, None), (1, 2, None), (1, 4, None), (1, 5, None), (2, 3, None), (3, 4, None), (4, 5, None)] - - sage: W = graphs.WheelGraph(6) - sage: G = MatchingCoveredGraph(W) - sage: G.add_edges([(1, 4)]) + [(0, 1, None), (0, 3, None), (0, 5, None), (0, 6, None), (1, 2, None), (1, 4, None), (2, 3, None), (2, 5, None), (2, 7, None), (3, 4, None), (3, 6, None), (4, 5, None), (5, 7, None), (6, 7, None)] + sage: G.add_edges([(0, 4)]) sage: G.edges(sort=False) - [(0, 1, None), (0, 2, None), (0, 3, None), (0, 4, None), (0, 5, None), (1, 2, None), (1, 4, None), (1, 5, None), (2, 3, None), (3, 4, None), (4, 5, None)] - - sage: W = graphs.WheelGraph(6) - sage: G = MatchingCoveredGraph(W) - sage: G.add_edge(1, 4, 'label') + [(0, 1, None), (0, 3, None), (0, 4, None), (0, 5, None), (0, 6, None), (1, 2, None), (1, 4, None), (2, 3, None), (2, 5, None), (2, 7, None), (3, 4, None), (3, 6, None), (4, 5, None), (5, 7, None), (6, 7, None)] + sage: G.add_edge(2, 4, 'label') sage: G.edges(sort=False) - [(0, 1, None), (0, 2, None), (0, 3, None), (0, 4, None), (0, 5, None), (1, 2, None), (1, 4, 'label'), (1, 5, None), (2, 3, None), (3, 4, None), (4, 5, None)] - - sage: W = graphs.WheelGraph(6) - sage: G = MatchingCoveredGraph(W) - sage: G.add_edge((1, 4, 'label')) + [(0, 1, None), (0, 3, None), (0, 4, None), (0, 5, None), (0, 6, None), (1, 2, None), (1, 4, None), (2, 3, None), (2, 4, 'label'), (2, 5, None), (2, 7, None), (3, 4, None), (3, 6, None), (4, 5, None), (5, 7, None), (6, 7, None)] + sage: G.add_edge((4, 6, 'label')) sage: G.edges(sort=False) - [(0, 1, None), (0, 2, None), (0, 3, None), (0, 4, None), (0, 5, None), (1, 2, None), (1, 4, 'label'), (1, 5, None), (2, 3, None), (3, 4, None), (4, 5, None)] - - sage: W = graphs.WheelGraph(6) - sage: G = MatchingCoveredGraph(W) - sage: G.add_edges([(1, 4, 'label')]) + [(0, 1, None), (0, 3, None), (0, 4, None), (0, 5, None), (0, 6, None), (1, 2, None), (1, 4, None), (2, 3, None), (2, 4, 'label'), (2, 5, None), (2, 7, None), (3, 4, None), (3, 6, None), (4, 5, None), (4, 6, 'label'), (5, 7, None), (6, 7, None)] + sage: G.add_edges([(4, 7, 'label')]) sage: G.edges(sort=False) - [(0, 1, None), (0, 2, None), (0, 3, None), (0, 4, None), (0, 5, None), (1, 2, None), (1, 4, 'label'), (1, 5, None), (2, 3, None), (3, 4, None), (4, 5, None)] + [(0, 1, None), (0, 3, None), (0, 4, None), (0, 5, None), (0, 6, None), (1, 2, None), (1, 4, None), (2, 3, None), (2, 4, 'label'), (2, 5, None), (2, 7, None), (3, 4, None), (3, 6, None), (4, 5, None), (4, 6, 'label'), (4, 7, 'label'), (5, 7, None), (6, 7, None)] Vertex name cannot be ``None``, so:: @@ -659,13 +644,10 @@ def add_edge(self, u, v=None, label=None): ValueError: the graph obtained after the addition of edge ((None, 1, None)) is not matching covered sage: H.edges(sort=False) # No alteration to the existing graph [(0, 1, None), (0, 2, None), (0, 3, None), (0, 4, None), (0, 5, None), (1, 2, None), (1, 5, None), (2, 3, None), (3, 4, None), (4, 5, None)] - - sage: W = graphs.WheelGraph(6) - sage: H = MatchingCoveredGraph(W) - sage: H.add_edge(None, 7) + sage: H.add_edge(None, None) Traceback (most recent call last): ... - ValueError: the graph obtained after the addition of edge ((None, 7, None)) is not matching covered + ValueError: the graph obtained after the addition of edge ((None, None, None)) is not matching covered sage: H.edges(sort=False) # No alteration to the existing graph [(0, 1, None), (0, 2, None), (0, 3, None), (0, 4, None), (0, 5, None), (1, 2, None), (1, 5, None), (2, 3, None), (3, 4, None), (4, 5, None)] From c0b1493d587293e78878fb4ea67e8991ce908bfd Mon Sep 17 00:00:00 2001 From: janmenjayap Date: Fri, 18 Oct 2024 12:36:14 +0530 Subject: [PATCH 317/537] updated the doc --- src/sage/graphs/matching_covered_graph.py | 38 +++++++++-------------- 1 file changed, 15 insertions(+), 23 deletions(-) diff --git a/src/sage/graphs/matching_covered_graph.py b/src/sage/graphs/matching_covered_graph.py index 751c0101214..79f5644436a 100644 --- a/src/sage/graphs/matching_covered_graph.py +++ b/src/sage/graphs/matching_covered_graph.py @@ -791,8 +791,7 @@ def add_vertex(self, name=None): sage: G = MatchingCoveredGraph(P) sage: G Matching covered petersen graph: graph on 10 vertices - sage: # needs random - sage: u = random.choice(list(G)) + sage: u = next(G.vertex_iterator()) sage: G.add_vertex(u) sage: G Matching covered petersen graph: graph on 10 vertices @@ -809,9 +808,7 @@ def add_vertex(self, name=None): Traceback (most recent call last): ... ValueError: isolated vertices are not allowed in matching covered graphs - sage: u = 0 - sage: while u in G: - ....: u += 1 + sage: u = 100 sage: G.add_vertex(u) Traceback (most recent call last): ... @@ -856,9 +853,7 @@ def add_vertices(self, vertices): sage: G = MatchingCoveredGraph(T) sage: G Matching covered truncated biwheel graph: graph on 30 vertices - sage: # needs random - sage: import random - sage: S = random.sample(G, 4) # We choose 4 existing vertices + sage: S = [0, 1, 2, 3] # We choose 4 existing vertices sage: G.add_vertices(S) sage: G Matching covered truncated biwheel graph: graph on 30 vertices @@ -888,10 +883,9 @@ def add_vertices(self, vertices): ... ValueError: isolated vertices are not allowed in matching covered graphs """ - for vertex in vertices: - if vertex not in self: - raise ValueError('isolated vertices are not allowed in ' - 'matching covered graphs') + if any(vertex not in self for vertex in vertices): + raise ValueError('isolated vertices are not allowed in ' + 'matching covered graphs') def allow_loops(self, new, check=True): r""" @@ -970,21 +964,17 @@ def delete_vertex(self, vertex, in_order=False): sage: W = graphs.WheelGraph(12) sage: G = MatchingCoveredGraph(W) - sage: u = 0 - sage: while u in G: - ....: u += 1 + sage: u = 100 sage: G.delete_vertex(u) Traceback (most recent call last): ... - ValueError: vertex (12) not in the graph + ValueError: vertex (100) not in the graph Deleting an existing vertex:: sage: W = graphs.WheelGraph(12) sage: G = MatchingCoveredGraph(W) - sage: # need random - sage: import random - sage: u = random.choice(list(G)) + sage: u = next(G.vertex_iterator()) sage: G.delete_vertex(u) Traceback (most recent call last): ... @@ -1001,8 +991,11 @@ def delete_vertex(self, vertex, in_order=False): def delete_vertices(self, vertices): r""" - Delete vertices (along with the incident edges) from the (matching - covered) graph taken from an iterable container of vertices. + Delete specified vertices form ``self``. + + This method deletes the vertices from the iterable container + ``vertices`` from ``self`` along with incident edges. An error is + raised if the resulting graph is not matching covered. .. NOTE:: @@ -1076,7 +1069,6 @@ def delete_vertices(self, vertices): sage: G # Matching covered graph on 6 vertices Matching covered staircase graph: graph on 6 vertices """ - for vertex in vertices: if vertex not in self: raise ValueError('vertex (%s) not in the graph' % str(vertex)) @@ -1145,7 +1137,7 @@ def get_matching(self): def update_matching(self, matching): r""" - Update the pefect matching captured in ``self._matching``. + Update the perfect matching captured in ``self._matching``. INPUT: From 719d270d24f14a6e3a0cb78cdb009d398700e4c6 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Sat, 19 Oct 2024 11:45:13 +0530 Subject: [PATCH 318/537] Formatted docstrings --- src/sage/matroids/chow_ring.py | 5 +---- src/sage/matroids/chow_ring_ideal.py | 20 ++++++++++---------- 2 files changed, 11 insertions(+), 14 deletions(-) diff --git a/src/sage/matroids/chow_ring.py b/src/sage/matroids/chow_ring.py index 39b969d84c7..673b48cfa15 100644 --- a/src/sage/matroids/chow_ring.py +++ b/src/sage/matroids/chow_ring.py @@ -49,7 +49,7 @@ class ChowRing(QuotientRing_generic): .. SEEALSO:: - :mod:`sage.matroids.chow_ring_ideal + :mod:`sage.matroids.chow_ring_ideal` INPUT: @@ -120,9 +120,6 @@ def _latex_(self): Return the LaTeX output of the polynomial ring and Chow ring ideal. EXAMPLES:: - - sage: from sage.matroids.graphic_matroid import GraphicMatroid - sage: M1 = matroids.Uniform(2,5) sage: ch = M1.chow_ring(QQ, False) sage: ch._latex_() diff --git a/src/sage/matroids/chow_ring_ideal.py b/src/sage/matroids/chow_ring_ideal.py index 6eb14139828..38f63c87b9f 100644 --- a/src/sage/matroids/chow_ring_ideal.py +++ b/src/sage/matroids/chow_ring_ideal.py @@ -287,13 +287,13 @@ class AugmentedChowRingIdeal_fy(ChowRingIdeal): .. MATH:: - y_i + \sum_{i \in F} y_{F \union e} + y_i + \sum_{i \in F} y_{F \union e} for all `i \in E` and, .. MATH:: - \sum_{F} y_{F \union e}. + \sum_{F} y_{F \union e}. Setting `x_F = y_{F \union e}` and using the last linear form to eliminate `x_E` recovers the usual presentation of @@ -495,20 +495,20 @@ class AugmentedChowRingIdeal_atom_free(ChowRingIdeal): - `F_1, \ldots, F_k` are the non-empty flats of `M`, - `I_{af}M` is the ideal generated by all quadratic forms `x_{F_i} x_{F_j}` - where `F_i` and `F_j` are incomparable elements in the lattice of - flats, + where `F_i` and `F_j` are incomparable elements in the lattice of + flats, - .. MATH:: + .. MATH:: - x_F \sum_{i \in F'} x_{F'} + x_F \sum_{i \in F'} x_{F'} - for all `i \in E` and `i \notin F`, and + for all `i \in E` and `i \notin F`, and - .. MATH:: + .. MATH:: - \sum_{i \in F'} (x_{F'})^2 + \sum_{i \in F'} (x_{F'})^2 - for all `i \in E`. + for all `i \in E`. REFERENCES: From 8caea48273db7015ff1d1cd503314d15859008c9 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Sat, 19 Oct 2024 12:24:28 +0530 Subject: [PATCH 319/537] Formatted docstrings --- src/sage/matroids/chow_ring.py | 4 ++-- src/sage/matroids/chow_ring_ideal.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sage/matroids/chow_ring.py b/src/sage/matroids/chow_ring.py index 673b48cfa15..48815f53973 100644 --- a/src/sage/matroids/chow_ring.py +++ b/src/sage/matroids/chow_ring.py @@ -21,9 +21,9 @@ class ChowRing(QuotientRing_generic): .. MATH:: - A^*(M)_R := R[x_{F_1}, \ldots, x_{F_k}] / (Q_M + L_M), + A^*(M)_R := R[x_{F_1}, \ldots, x_{F_k}] / (I_M + J_M), - where `(Q_M + L_M)` is the :class:`Chow ring ideal + where `(I_M + J_M)` is the :class:`Chow ring ideal ` of matroid `M`. The *augmented Chow ring of matroid* `M` in the Feitchner-Yuzvinsky presentation diff --git a/src/sage/matroids/chow_ring_ideal.py b/src/sage/matroids/chow_ring_ideal.py index 38f63c87b9f..83270c7faca 100644 --- a/src/sage/matroids/chow_ring_ideal.py +++ b/src/sage/matroids/chow_ring_ideal.py @@ -65,7 +65,7 @@ class ChowRingIdeal_nonaug(ChowRingIdeal): - `F_1, \ldots, F_k` are the non-empty flats of `M`, - `I_M` is the Stanley-Reisner ideal, i.e., it is generated - by products `x_{F_1}, \ldots, x_{F_t}` for subsets `{F_1}, \ldots, {F_t}` + by products `x_{F_1}, \ldots, x_{F_t}` for subsets `{F_1, \ldots, F_t}` of flats that are not chains, and - `J_M` is the ideal generated by all linear forms From 2abf2cceb61921fa02d89b0de924cfbcfcb2066f Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Sat, 19 Oct 2024 12:49:46 +0530 Subject: [PATCH 320/537] Edited docstrings --- src/sage/matroids/chow_ring_ideal.py | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/src/sage/matroids/chow_ring_ideal.py b/src/sage/matroids/chow_ring_ideal.py index 83270c7faca..44026c74a17 100644 --- a/src/sage/matroids/chow_ring_ideal.py +++ b/src/sage/matroids/chow_ring_ideal.py @@ -256,7 +256,7 @@ class AugmentedChowRingIdeal_fy(ChowRingIdeal): where - `F_1, \ldots, F_k` are the proper flats of `M`, - - `e_1 \ldots, e_n` are `n` elements of groundset of `M`, + - `e_1, \ldots, e_n` are `n` elements of groundset of `M`, - `J_M` is the ideal generated by all quadratic forms `x_{F_i} x_{F_j}`, where `F_i` and `F_j` are incomparable elements in the lattice of flats and `y_{i} x_F` for every `i \in E` and `i \notin F`, and @@ -269,8 +269,8 @@ class AugmentedChowRingIdeal_fy(ChowRingIdeal): for all `i \in E`. The augmented Chow ring ideal in the Feitchner Yuzvinsky presentation - for a simple matroid `M` is defined as the ideal - `(I_{FY}(M))` of the following polynomial ring + for a simple matroid `M` is defined as the ideal `(I_{FY}(M))` of the + following polynomial ring .. MATH:: @@ -279,8 +279,8 @@ class AugmentedChowRingIdeal_fy(ChowRingIdeal): where - `F_1, \ldots, F_k` are the flats of `M`, - - `e_1 \ldots, e_n` are `n` elements of groundset of `M`, - - `I_{FY}(M) is the ideal generated by all quadratic forms + - `e_1, \ldots, e_n` are `n` elements of groundset of `M`, + - `I_{FY}(M)` is the ideal generated by all quadratic forms `y_{F_i \union e} y_{F_j \union e}`, where `F_i` and `F_j` are incomparable elements in the lattice of flats, `y_{i} y_{F \union e}` for every `i \in E` and `i \notin F`, linear forms @@ -297,7 +297,7 @@ class AugmentedChowRingIdeal_fy(ChowRingIdeal): Setting `x_F = y_{F \union e}` and using the last linear form to eliminate `x_E` recovers the usual presentation of - augmented Chow ring of M. + augmented Chow ring of `M`. REFERENCES: @@ -422,7 +422,7 @@ def _repr_(self): def _latex_(self): r""" - Return a LaTeX representation`self`. + Return a LaTeX representation of ``self``. EXAMPLES:: @@ -436,7 +436,7 @@ def _latex_(self): def groebner_basis(self, algorithm='constructed', *args, **kwargs): r""" - Returns the Groebner basis of `self`. + Returns the Groebner basis of ``self``. EXAMPLES:: @@ -484,8 +484,7 @@ class AugmentedChowRingIdeal_atom_free(ChowRingIdeal): atom-free presentation. The augmented Chow ring ideal in the atom-free presentation for a matroid - `M` is defined as the ideal - `I_{af}(M)` of the polynomial ring: + `M` is defined as the ideal `I_{af}(M)` of the polynomial ring: .. MATH:: @@ -597,7 +596,7 @@ def _repr_(self): def _latex_(self): r""" - Return the LaTeX output of the ring and generators of `self`. + Return the LaTeX output of the ring and generators of ``self``. EXAMPLES:: @@ -611,7 +610,7 @@ def _latex_(self): def groebner_basis(self, algorithm='constructed', *args, **kwargs): """ - Returns the Groebner basis of `self`. + Returns the Groebner basis of ``self``. EXAMPLES:: From 109cb91f1512e745a362e4c91cb0fb2fd0d87f4a Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Sun, 20 Oct 2024 14:33:31 +0000 Subject: [PATCH 321/537] Clarify how to use Jupyter with conda --- src/doc/en/installation/launching.rst | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/src/doc/en/installation/launching.rst b/src/doc/en/installation/launching.rst index ce445a02f16..b612a89a9c1 100644 --- a/src/doc/en/installation/launching.rst +++ b/src/doc/en/installation/launching.rst @@ -165,7 +165,28 @@ SageMath documentation at http://doc.sagemath.org/. Setting up SageMath as a Jupyter kernel in an existing Jupyter notebook or JupyterLab installation -------------------------------------------------------------------------------------------------- -You may already have a global installation of Jupyter. For added +By default, SageMath installs itself as a Jupyter kernel in the same +environment as the SageMath installation. This is the most convenient way to +use SageMath in a Jupyter notebook. To check if the Sage kernel is +available, start a Jupyter notebook and look for the kernel named +``sagemath`` in the list of available kernels. +Alternatively, you can use the following command to check which kernels are +available: + +.. code-block:: shell-session + + $ jupyter kernelspec list + Available kernels: + python3 /share/jupyter/kernels/python3 + sagemath /share/jupyter/kernels/sagemath + +.. note:: + + The kernel is not automatically available if you have installed SageMath + in editable mode (``pip install -e``). In that case, it is recommended + to reinstall SageMath in a non-editable way. + +You may already have a global installation of Jupyter. For added convenience, it is possible to link your installation of SageMath into your Jupyter installation, adding it to the list of available kernels that can be selected in the notebook or JupyterLab interface. @@ -177,6 +198,8 @@ Assuming that SageMath can be invoked by typing ``sage``, you can use sage -sh -c 'ls -d $SAGE_VENV/share/jupyter/kernels/sagemath' to find the location of the SageMath kernel description. +Alternatively, use ``jupyter kernelspec list`` from the same environment +where SageMath is installed to find the location of the SageMath kernel. Now pick a name for the kernel that identifies it clearly and uniquely. @@ -196,7 +219,7 @@ new kernel named ``sagemath-dev``. The ``jupyter kernelspec`` approach by default does lead to about 2Gb of SageMath documentation being copied into your personal jupyter configuration -directory. You can avoid that by instead putting a symlink in the relevant spot. +directory. You can avoid that by instead putting a symlink in the relevant spot and .. CODE-BLOCK:: bash From 1362973ad6b6d0c5ef13de5ad1a2f25c44aa36b9 Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Mon, 21 Oct 2024 08:44:28 +0200 Subject: [PATCH 322/537] Apply suggestions from code review Co-authored-by: Travis Scrimshaw --- src/sage/rings/species.py | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/src/sage/rings/species.py b/src/sage/rings/species.py index 5ae832796a5..4af5c8dd300 100644 --- a/src/sage/rings/species.py +++ b/src/sage/rings/species.py @@ -171,7 +171,7 @@ def _repr_(self): sage: C(G) ((5,6)(7,8), (1,2)(3,4), (1,3)(2,4)(5,6)) """ - return f"{self._C.gens()}" + return repr(self._C.gens()) class ConjugacyClassesOfDirectlyIndecomposableSubgroups(UniqueRepresentation, Parent): @@ -226,7 +226,7 @@ def _repr_(self): sage: C = ConjugacyClassesOfDirectlyIndecomposableSubgroups(); C Infinite set of conjugacy classes of directly indecomposable subgroups """ - return "Infinite set of conjugacy classes of directly indecomposable subgroups" + return "Set of conjugacy classes of directly indecomposable subgroups" def __iter__(self): r""" @@ -843,9 +843,9 @@ def _stabilizer_subgroups(G, X, a): INPUT: - - ``G``, the acting group - - ``X``, the set ``G`` is acting on - - ``a``, the (left) action + - ``G`` -- the acting group + - ``X`` -- the set ``G`` is acting on + - ``a`` -- the (left) action EXAMPLES:: @@ -1128,7 +1128,7 @@ def __init__(self, parent, x): INPUT: - - ``x``, a dictionary mapping atomic species to exponents + - ``x`` -- a dictionary mapping atomic species to exponents EXAMPLES:: @@ -1775,20 +1775,18 @@ def _compose_with_singletons(self, names, args): def _compose_with_weighted_singletons(self, names, multiplicities, degrees): r""" Compute the composition with - `(\sum_j m_{1,j} X_{1,j}, \sum_j m_{2,j} X_{2,j}, \dots)` + `(\sum_j m_{1,j} X_{1,j}, \sum_j m_{2,j} X_{2,j}, \ldots)` in the specified degrees. The `k`-sort species ``self`` should be homogeneous. INPUT: - - ``names``, the (flat) list of names of the result - - - ``multiplicities``, a (flat) list of constants - - - ``degrees``, a `k`-tuple of compositions `c_1, - \dots, c_k`, such that the size of `c_i` is the - degree of self in sort `i`. + - ``names`` -- the (flat) list of names of the result + - ``multiplicities`` -- a (flat) list of constants + - ``degrees`` -- a `k`-tuple of compositions `c_1, + \ldots, c_k`, such that the size of `c_i` is the + degree of ``self`` in sort `i` EXAMPLES: @@ -1975,7 +1973,6 @@ def __init__(self, base_ring, names): CombinatorialFreeModule.__init__(self, base_ring, basis_keys=MolecularSpecies(names), category=category, - element_class=self.Element, prefix='', bracket=False) self._arity = len(names) @@ -2114,7 +2111,7 @@ def degree_on_basis(self, m): @cached_method def one_basis(self): r""" - Returns SymmetricGroup(0), which indexes the one of this algebra, + Return ``SymmetricGroup(0)``, which indexes the one of this algebra, as per :meth:`AlgebrasWithBasis.ParentMethods.one_basis`. EXAMPLES:: @@ -2134,6 +2131,8 @@ def an_element(self): """ Return an element of ``self``. + EXAMPLES:: + sage: from sage.rings.species import PolynomialSpecies sage: P = PolynomialSpecies(ZZ, "X") sage: P.an_element() @@ -2165,7 +2164,7 @@ def product_on_basis(self, H, K): sage: type(list(X^2)[0][1]) """ - return self._from_dict({H * K: ZZ(1)}) + return self.element_class(self, {H * K: ZZ.one()}) @cached_method def powersum(self, s, n): @@ -2183,7 +2182,8 @@ def powersum(self, s, n): sage: P.powersum(0, 4) 4*E_4 - 4*X*E_3 - 2*E_2^2 + 4*X^2*E_2 - X^4 """ - assert n in ZZ and n > 0 + if not (n in ZZ and n > 0): + raise ValueError("n must be a positive integer") if n == 1: return self(SymmetricGroup(1), {s: [1]}) return (ZZ(n) * self(SymmetricGroup(n), {s: range(1, n+1)}) From ef0e1d69044f7db2a7949d1ce7b82d67b27b1817 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Mon, 21 Oct 2024 13:59:21 +0530 Subject: [PATCH 323/537] Edited doctests --- src/doc/en/reference/matroids/index.rst | 4 +-- src/sage/matroids/chow_ring.py | 9 ++--- src/sage/matroids/chow_ring_ideal.py | 47 ++++++++++++------------- 3 files changed, 30 insertions(+), 30 deletions(-) diff --git a/src/doc/en/reference/matroids/index.rst b/src/doc/en/reference/matroids/index.rst index 5f1bf9f5f45..59453ff2fdc 100644 --- a/src/doc/en/reference/matroids/index.rst +++ b/src/doc/en/reference/matroids/index.rst @@ -65,8 +65,8 @@ Internals sage/matroids/set_system sage/matroids/unpickling - Chow rings of matroids - ---------------------- +Chow rings of matroids +---------------------- .. toctree:: :maxdepth: 1 diff --git a/src/sage/matroids/chow_ring.py b/src/sage/matroids/chow_ring.py index 48815f53973..95130e7f316 100644 --- a/src/sage/matroids/chow_ring.py +++ b/src/sage/matroids/chow_ring.py @@ -17,7 +17,7 @@ class ChowRing(QuotientRing_generic): r""" The Chow ring of a matroid. - The *Chow ring of a matroid* `M` is defined as the quotient ring + The *Chow ring of the matroid* `M` is defined as the quotient ring .. MATH:: @@ -26,8 +26,8 @@ class ChowRing(QuotientRing_generic): where `(I_M + J_M)` is the :class:`Chow ring ideal ` of matroid `M`. - The *augmented Chow ring of matroid* `M` in the Feitchner-Yuzvinsky presentation - is the quotient ring + The *augmented Chow ring of matroid* `M` in the Feitchner-Yuzvinsky + presentation is the quotient ring .. MATH:: @@ -35,7 +35,7 @@ class ChowRing(QuotientRing_generic): where `(I_M + J_M)` is the :class:`augmented Chow ring ideal ` of matroid `M` - in Feitchner-Yuzvinsky presentation. + in the Feitchner-Yuzvinsky presentation. The *augmented Chow ring of atom-free presentation* is the quotient ring @@ -120,6 +120,7 @@ def _latex_(self): Return the LaTeX output of the polynomial ring and Chow ring ideal. EXAMPLES:: + sage: M1 = matroids.Uniform(2,5) sage: ch = M1.chow_ring(QQ, False) sage: ch._latex_() diff --git a/src/sage/matroids/chow_ring_ideal.py b/src/sage/matroids/chow_ring_ideal.py index 44026c74a17..0ddd9a6f9c7 100644 --- a/src/sage/matroids/chow_ring_ideal.py +++ b/src/sage/matroids/chow_ring_ideal.py @@ -65,7 +65,7 @@ class ChowRingIdeal_nonaug(ChowRingIdeal): - `F_1, \ldots, F_k` are the non-empty flats of `M`, - `I_M` is the Stanley-Reisner ideal, i.e., it is generated - by products `x_{F_1}, \ldots, x_{F_t}` for subsets `{F_1, \ldots, F_t}` + by products `x_{F_1}, \ldots, x_{F_t}` for subsets `\{F_1, \ldots, F_t\}` of flats that are not chains, and - `J_M` is the ideal generated by all linear forms @@ -244,7 +244,7 @@ def groebner_basis(self, algorithm='', *args, **kwargs): class AugmentedChowRingIdeal_fy(ChowRingIdeal): r""" The augmented Chow ring ideal of matroid `M` over ring `R` in - Feitchner-Yuzvinsky presentation. + the Feitchner-Yuzvinsky presentation. The augmented Chow ring ideal for a matroid `M` is defined as the ideal `(I_M + J_M)` of the following polynomial ring @@ -274,28 +274,28 @@ class AugmentedChowRingIdeal_fy(ChowRingIdeal): .. MATH:: - R[y_{e_1}, \ldots, y_{e_n}, y_{F_1 \union e}, \ldots, y_{F_k \union e}], + R[y_{e_1}, \ldots, y_{e_n}, y_{F_1 \cup e}, \ldots, y_{F_k \cup e}], where - `F_1, \ldots, F_k` are the flats of `M`, - `e_1, \ldots, e_n` are `n` elements of groundset of `M`, - `I_{FY}(M)` is the ideal generated by all quadratic forms - `y_{F_i \union e} y_{F_j \union e}`, where `F_i` and `F_j` - are incomparable elements in the lattice of flats, `y_{i} y_{F \union e}` + `y_{F_i \cup e} y_{F_j \cup e}`, where `F_i` and `F_j` + are incomparable elements in the lattice of flats, `y_{i} y_{F \cup e}` for every `i \in E` and `i \notin F`, linear forms .. MATH:: - y_i + \sum_{i \in F} y_{F \union e} + y_i + \sum_{i \in F} y_{F \cup e} for all `i \in E` and, .. MATH:: - \sum_{F} y_{F \union e}. + \sum_{F} y_{F \cup e}. - Setting `x_F = y_{F \union e}` and using the last linear + Setting `x_F = y_{F \cup e}` and using the last linear form to eliminate `x_E` recovers the usual presentation of augmented Chow ring of `M`. @@ -434,9 +434,9 @@ def _latex_(self): from sage.misc.latex import latex return 'I_{FY} of matroid ' + (latex(self._matroid)) - def groebner_basis(self, algorithm='constructed', *args, **kwargs): + def groebner_basis(self, algorithm='', *args, **kwargs): r""" - Returns the Groebner basis of ``self``. + Return the Groebner basis of ``self``. EXAMPLES:: @@ -488,26 +488,25 @@ class AugmentedChowRingIdeal_atom_free(ChowRingIdeal): .. MATH:: - R[x_{F_1}, \ldots, x_{F_k}] + R[x_{F_1}, \ldots, x_{F_k}], where - - `F_1, \ldots, F_k` are the non-empty flats of `M`, - - `I_{af}M` is the ideal generated by all quadratic forms `x_{F_i} x_{F_j}` - where `F_i` and `F_j` are incomparable elements in the lattice of - flats, + - `F_1, \ldots, F_k` are the non-empty flats of `M`, + - `I_{af}M` is the ideal generated by all quadratic forms `x_{F_i} x_{F_j}` + where `F_i` and `F_j` are incomparable elements in the lattice of flats, - .. MATH:: + .. MATH:: - x_F \sum_{i \in F'} x_{F'} + x_F \sum_{i \in F'} x_{F'} - for all `i \in E` and `i \notin F`, and + for all `i \in E` and `i \notin F`, and - .. MATH:: + .. MATH:: - \sum_{i \in F'} (x_{F'})^2 + \sum_{i \in F'} (x_{F'})^2 - for all `i \in E`. + for all `i \in E`. REFERENCES: @@ -585,7 +584,7 @@ def _gens_constructor(self, poly_ring): def _repr_(self): r""" - EXAMPLE:: + EXAMPLES:: sage: ch = matroids.Wheel(3).chow_ring(QQ, True, 'atom-free') sage: ch.defining_ideal() @@ -608,9 +607,9 @@ def _latex_(self): from sage.misc.latex import latex return 'I_{af} of matroid ' + latex(self._matroid) - def groebner_basis(self, algorithm='constructed', *args, **kwargs): + def groebner_basis(self, algorithm='', *args, **kwargs): """ - Returns the Groebner basis of ``self``. + Return the Groebner basis of ``self``. EXAMPLES:: From c9d45536e6fbf8c3433dc76e9ed75dcfaf036ffa Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Mon, 21 Oct 2024 14:01:47 +0530 Subject: [PATCH 324/537] Edited references formatting --- src/doc/en/reference/references/index.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/en/reference/references/index.rst b/src/doc/en/reference/references/index.rst index d700aa8661b..98cfe8b3fe1 100644 --- a/src/doc/en/reference/references/index.rst +++ b/src/doc/en/reference/references/index.rst @@ -4929,7 +4929,7 @@ REFERENCES: Int. Math. Res. Not. IMRN, 2015, 3121-3149. .. [MM2022] Matthew Mastroeni and Jason McCullough. Chow rings of matroids are - koszul. *Mathematische Annalen*, 387(3–4):1819–1851, November 2022. + Koszul. *Mathematische Annalen*, 387(3-4):1819-1851, November 2022. .. [MMRS2022] Ruslan G. Marzo, Rafael A. Melo, Celso C. Ribeiro and Marcio C. Santos: *New formulations and branch-and-cut procedures From 8f52723f9c179a9d0a9d55d4b3cfdeb55f95ca45 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Mon, 21 Oct 2024 15:39:18 +0530 Subject: [PATCH 325/537] Reformatted references file --- src/doc/en/reference/references/index.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/doc/en/reference/references/index.rst b/src/doc/en/reference/references/index.rst index 98cfe8b3fe1..c189bf296f5 100644 --- a/src/doc/en/reference/references/index.rst +++ b/src/doc/en/reference/references/index.rst @@ -262,7 +262,7 @@ REFERENCES: 369–379. https://doi.org/10.1007/BF02677478 .. [ANR2023] Robert Angarone, Anastasia Nathanson, and Victor Reiner. *Chow rings of - matroids as permutation representations*, 2023. :arxiv: `2309.14312`. + matroids as permutation representations*, 2023. :arxiv:`2309.14312`. .. [AP1986] \S. Arnborg, A. Proskurowski, *Characterization and Recognition of Partial 3-Trees*, @@ -4928,8 +4928,8 @@ REFERENCES: .. [MM2015] \J. Matherne and \G. Muller, *Computing upper cluster algebras*, Int. Math. Res. Not. IMRN, 2015, 3121-3149. -.. [MM2022] Matthew Mastroeni and Jason McCullough. Chow rings of matroids are - Koszul. *Mathematische Annalen*, 387(3-4):1819-1851, November 2022. +.. [MM2022] Matthew Mastroeni and Jason McCullough. *Chow rings of matroids are + Koszul*. Mathematische Annalen, 387(3-4):1819-1851, November 2022. .. [MMRS2022] Ruslan G. Marzo, Rafael A. Melo, Celso C. Ribeiro and Marcio C. Santos: *New formulations and branch-and-cut procedures From cb6dcc6d81cf22cba59749705c05dd0e3f918ffb Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Mon, 21 Oct 2024 16:58:21 +0530 Subject: [PATCH 326/537] Formatted definitions --- src/sage/matroids/chow_ring.py | 8 ++++---- src/sage/matroids/chow_ring_ideal.py | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/sage/matroids/chow_ring.py b/src/sage/matroids/chow_ring.py index 95130e7f316..ba668f4ad4a 100644 --- a/src/sage/matroids/chow_ring.py +++ b/src/sage/matroids/chow_ring.py @@ -31,9 +31,9 @@ class ChowRing(QuotientRing_generic): .. MATH:: - A(M)_R := R[y_{e_1}, \ldots, y_{e_n}, x_{F_1}, \ldots, x_{F_k}] / (I_M + J_M), + A(M)_R := R[y_{e_1}, \ldots, y_{e_n}, x_{F_1}, \ldots, x_{F_k}] / I_{FY}(M), - where `(I_M + J_M)` is the :class:`augmented Chow ring ideal + where `I_{FY}(M)` is the :class:`augmented Chow ring ideal ` of matroid `M` in the Feitchner-Yuzvinsky presentation. @@ -41,9 +41,9 @@ class ChowRing(QuotientRing_generic): .. MATH:: - A(M)_R := R[x_{F_1}, \ldots, x_{F_k}] / I_M^{af}, + A(M)_R := R[x_{F_1}, \ldots, x_{F_k}] / I_{af}(M), - where `I_M^{af}` is the :class:`augmented Chow ring ideal + where `I_{af}(M)` is the :class:`augmented Chow ring ideal ` of matroid `M` in the atom-free presentation. diff --git a/src/sage/matroids/chow_ring_ideal.py b/src/sage/matroids/chow_ring_ideal.py index 0ddd9a6f9c7..49f3aa0752c 100644 --- a/src/sage/matroids/chow_ring_ideal.py +++ b/src/sage/matroids/chow_ring_ideal.py @@ -269,7 +269,7 @@ class AugmentedChowRingIdeal_fy(ChowRingIdeal): for all `i \in E`. The augmented Chow ring ideal in the Feitchner Yuzvinsky presentation - for a simple matroid `M` is defined as the ideal `(I_{FY}(M))` of the + for a simple matroid `M` is defined as the ideal `I_{FY}(M)` of the following polynomial ring .. MATH:: @@ -493,7 +493,7 @@ class AugmentedChowRingIdeal_atom_free(ChowRingIdeal): where - `F_1, \ldots, F_k` are the non-empty flats of `M`, - - `I_{af}M` is the ideal generated by all quadratic forms `x_{F_i} x_{F_j}` + - `I_{af}(M)` is the ideal generated by all quadratic forms `x_{F_i} x_{F_j}` where `F_i` and `F_j` are incomparable elements in the lattice of flats, .. MATH:: From 8b88db8fd133ac275ebd815633e7a8b53879207e Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Mon, 21 Oct 2024 19:25:04 +0200 Subject: [PATCH 327/537] adapt doctest, improve some docstrings --- src/sage/rings/species.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/sage/rings/species.py b/src/sage/rings/species.py index 4af5c8dd300..4526d73d290 100644 --- a/src/sage/rings/species.py +++ b/src/sage/rings/species.py @@ -224,7 +224,7 @@ def _repr_(self): sage: from sage.rings.species import ConjugacyClassesOfDirectlyIndecomposableSubgroups sage: C = ConjugacyClassesOfDirectlyIndecomposableSubgroups(); C - Infinite set of conjugacy classes of directly indecomposable subgroups + Set of conjugacy classes of directly indecomposable subgroups """ return "Set of conjugacy classes of directly indecomposable subgroups" @@ -554,11 +554,12 @@ def __classcall__(cls, names): def __init__(self, names): r""" - Infinite set of multivariate atomic species. + Initialize the class of (multivariate) atomic species. INPUT: - - ``names`` -- an iterable of ``k`` strings for the sorts of the species + - ``names`` -- an iterable of ``k`` strings for the sorts of + the species TESTS: @@ -571,6 +572,7 @@ def __init__(self, names): sage: A2 = AtomicSpecies(["X", "Y"]) sage: TestSuite(A1).run(skip="_test_graded_components") sage: TestSuite(A2).run(skip="_test_graded_components") + """ category = SetsWithGrading().Infinite() Parent.__init__(self, names=names, category=category) @@ -901,7 +903,7 @@ def _stabilizer_subgroups(G, X, a): class MolecularSpecies(IndexedFreeAbelianMonoid): """ - The set of (multivariate) molecular species. + The monoid of (multivariate) molecular species. """ @staticmethod def __classcall__(cls, *args, **kwds): @@ -1534,7 +1536,7 @@ def __call__(self, *args): class PolynomialSpeciesElement(CombinatorialFreeModule.Element): r""" - Multivariate polynomial (virtual) species. + A (virtual) polynomial species. TESTS:: From 5e9cf420aa55dcd9ca02b1c2ada68766ea170e14 Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Mon, 21 Oct 2024 20:03:46 +0200 Subject: [PATCH 328/537] test error cases of element constructors --- src/sage/rings/species.py | 117 ++++++++++++++++++++++++++++++++++---- 1 file changed, 105 insertions(+), 12 deletions(-) diff --git a/src/sage/rings/species.py b/src/sage/rings/species.py index 4526d73d290..f496b832fdb 100644 --- a/src/sage/rings/species.py +++ b/src/sage/rings/species.py @@ -189,8 +189,7 @@ def __init__(self): self._cache = dict() def _element_constructor_(self, x): - r""" - Construct a conjugacy class from ``x``. + r"""Construct a conjugacy class from ``x``. INPUT: @@ -207,6 +206,31 @@ def _element_constructor_(self, x): ((1,2,3),) sage: C(PermutationGroup([[(1,3),(4,7)],[(2,5),(6,8)], [(1,4),(2,5),(3,7)]])) ((5,6)(7,8), (1,2)(3,4), (1,3)(2,4)(5,6)) + + TESTS: + + Providing a group that decomposes as a direct product raises + an error:: + + sage: C(PermutationGroup([[(1,2,3),(4,5)]])) + Traceback (most recent call last): + ... + ValueError: Permutation Group with generators [(1,2,3)(4,5)] is not directly indecomposable + + Check some trivial cases:: + + sage: C(0) + Traceback (most recent call last): + ... + ValueError: unable to convert 0 to Set of conjugacy classes of + directly indecomposable subgroups + + sage: C(groups.presentation.KleinFour()) + Traceback (most recent call last): + ... + ValueError: unable to convert Finitely presented group + < a, b | a^2, b^2, a^-1*b^-1*a*b > to Set of conjugacy classes of + directly indecomposable subgroups """ if parent(x) == self: return x @@ -628,6 +652,43 @@ def _element_constructor_(self, G, pi=None): sage: G = PermutationGroup([[(1,3),(5,7)]], domain=[1,3,5,7]) sage: A(G, ([1,3], [5,7])) {((1,2)(3,4),): ({1, 2}, {3, 4})} + + Test that errors are raised on some possible misuses:: + + sage: A = AtomicSpecies("X, Y") + sage: G = PermutationGroup([[(1,2), (3,4,5,6)]]) + sage: a = A(G, {0:[1,2], 1:[3,4,5,6]}) + sage: A(a, {0:[3,4,5,6], 1:[1,2]}) + Traceback (most recent call last): + ... + ValueError: cannot reassign sorts to an atomic species + + sage: A(G) + Traceback (most recent call last): + ... + ValueError: the assignment of sorts to the domain elements must be + provided + + sage: A(G, {0:[1,2], 1:[]}) + Traceback (most recent call last): + ... + ValueError: values of pi (=dict_values([[1, 2], []])) must + partition the domain of G (={1, 2, 3, 4, 5, 6}) + + sage: A(G, {1:[1,2], 2:[3,4,5,6]}) + Traceback (most recent call last): + ... + ValueError: keys of pi (=dict_keys([1, 2])) must be in range(2) + + sage: A(G, {0:[1], 1:[2,3,4,5,6]}) + Traceback (most recent call last): + ... + ValueError: All elements of orbit (1, 2) must have the same sort + + sage: A(0) + Traceback (most recent call last): + ... + ValueError: 0 must be a permutation group """ if parent(G) == self: if pi is not None: @@ -751,14 +812,15 @@ def __contains__(self, x): else: G, pi = x if not isinstance(G, PermutationGroup_generic): - raise ValueError(f"{G} must be a permutation group") + return False if not set(pi.keys()).issubset(range(self._arity)): - raise ValueError(f"keys of pi (={pi.keys()}) must be in range({self._arity})") - if sum(len(p) for p in pi.values()) != len(G.domain()) or set(chain.from_iterable(pi.values())) != set(G.domain()): - raise ValueError(f"values of pi (={pi.values()}) must partition the domain of G (={G.domain()})") + return False + if (sum(len(p) for p in pi.values()) != len(G.domain()) + or set(chain.from_iterable(pi.values())) != set(G.domain())): + return False for orbit in G.orbits(): if not any(set(orbit).issubset(p) for p in pi.values()): - raise ValueError(f"All elements of orbit {orbit} must have the same sort") + return False return len(G.disjoint_direct_product_decomposition()) <= 1 def grading_set(self): @@ -1033,6 +1095,36 @@ def _element_constructor_(self, G, pi=None): sage: G = PermutationGroup([[(1,3),(5,7)]], domain=[1,3,5,7]) sage: M(G, ([1,3], [5,7])) E_2(XY) + + sage: G = PermutationGroup([[(1,2), (3,4,5,6)]]) + sage: a = M(G, {0:[1,2], 1:[3,4,5,6]}) + sage: M(a, {0:[3,4,5,6], 1:[1,2]}) + Traceback (most recent call last): + ... + ValueError: cannot reassign sorts to a molecular species + + sage: M(G) + Traceback (most recent call last): + ... + ValueError: the assignment of sorts to the domain elements must be + provided + + sage: M(G, {0:[1,2], 1:[]}) + Traceback (most recent call last): + ... + ValueError: values of pi (=dict_values([[1, 2], []])) must + partition the domain of G (={1, 2, 3, 4, 5, 6}) + + sage: M(G, {1:[1,2], 2:[3,4,5,6]}) + Traceback (most recent call last): + ... + ValueError: keys of pi (=dict_keys([1, 2])) must be in range(2) + + sage: M(0) + Traceback (most recent call last): + ... + ValueError: 0 must be a permutation group or a pair specifying a + group action on the given domain pi=None """ if parent(G) == self: if pi is not None: @@ -1048,10 +1140,8 @@ def _element_constructor_(self, G, pi=None): elif not isinstance(pi, dict): pi = {i: v for i, v in enumerate(pi)} domain = [e for p in pi.values() for e in p] - if len(domain) != len(set(domain)): - raise ValueError("each domain element must have exactly one sort") - if set(G.domain()) != set(domain): - raise ValueError("each element of the domain of the group must have one sort") + if len(domain) != len(set(domain)) or set(G.domain()) != set(domain): + raise ValueError(f"values of pi (={pi.values()}) must partition the domain of G (={G.domain()})") components = G.disjoint_direct_product_decomposition() elm = self.one() for component in components: @@ -1064,7 +1154,10 @@ def _element_constructor_(self, G, pi=None): elm *= self.gen(self._indices(H, dompart)) return elm - X, a = G + try: + X, a = G + except TypeError: + raise ValueError(f"{G} must be a permutation group or a pair specifying a group action on the given domain pi={pi}") L = [len(pi.get(i, [])) for i in range(self._arity)] S = SymmetricGroup(sum(L)).young_subgroup(L) H = _stabilizer_subgroups(S, X, a) From 650bd551939a650435dd57adcf66aaca015c0136 Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Mon, 21 Oct 2024 20:07:13 +0200 Subject: [PATCH 329/537] remove forgotten error in __contains__ --- src/sage/rings/species.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/rings/species.py b/src/sage/rings/species.py index f496b832fdb..83238778f88 100644 --- a/src/sage/rings/species.py +++ b/src/sage/rings/species.py @@ -808,7 +808,7 @@ def __contains__(self, x): G = x pi = {0: G.domain()} else: - raise ValueError("the assignment of sorts to the domain elements must be provided") + return False else: G, pi = x if not isinstance(G, PermutationGroup_generic): From 8aea71dea929cd959482ee48542be14a16928366 Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Tue, 22 Oct 2024 07:35:42 +0200 Subject: [PATCH 330/537] restore accidentally deleted caching --- src/sage/rings/species.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/sage/rings/species.py b/src/sage/rings/species.py index 83238778f88..fae8184da26 100644 --- a/src/sage/rings/species.py +++ b/src/sage/rings/species.py @@ -1394,6 +1394,7 @@ def __ge__(self, other): return False return other <= self + @cached_method def group_and_partition(self): """ Return the (transitive) permutation group corresponding to ``self``. From 9c673c23d0e748db662aa039bc8f52935e6345a9 Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Tue, 22 Oct 2024 08:02:13 +0200 Subject: [PATCH 331/537] Apply suggestions from code review Co-authored-by: Travis Scrimshaw --- src/sage/rings/species.py | 44 +++++++++++++++++++-------------------- 1 file changed, 21 insertions(+), 23 deletions(-) diff --git a/src/sage/rings/species.py b/src/sage/rings/species.py index fae8184da26..e3e61ff86da 100644 --- a/src/sage/rings/species.py +++ b/src/sage/rings/species.py @@ -402,11 +402,10 @@ def __init__(self, parent, dis, domain_partition): INPUT: - - ``dis``, a :class:`ConjugacyClassOfDirectlyIndecomposableSubgroups` - - - ``domain_partition``, a dict representing the - assignment of each element of the domain of ``dis`` to - a "variable". + - ``dis`` -- :class:`ConjugacyClassOfDirectlyIndecomposableSubgroups` + - ``domain_partition`` -- ``dict`` representing the + assignment of each element of the domain of ``dis`` to + a "variable" TESTS:: @@ -626,12 +625,11 @@ def _element_constructor_(self, G, pi=None): INPUT: - - ``G`` - an element of ``self`` (in this case pi must be ``None``) - or a permutation group. - - - ``pi`` - a `k`-tuple or list of iterables or a dict mapping - sorts to iterables whose union is the domain. If `k=1`, - `pi` can be omitted. + - ``G`` -- element of ``self`` (in this case ``pi`` must be ``None``) + or permutation group + - ``pi`` -- `k`-tuple or list of iterables or a dict mapping + sorts to iterables whose union is the domain; if `k=1`, + ``pi`` can be omitted EXAMPLES:: @@ -1044,12 +1042,12 @@ def _element_constructor_(self, G, pi=None): INPUT: - - ``G`` - an element of ``self`` (in this case pi must be ``None``) - or a permutation group, or a pair ``(X, a)`` consisting of a - finite set and a transitive action. - - ``pi`` - a dict mapping sorts to iterables whose union is the - domain of ``G`` (if ``G`` is a permutation group) or `X` (if ``G``) - is a pair ``(X, a)``. If `k=1`, `pi` can be omitted. + - ``G`` -- element of ``self`` (in this case ``pi`` must be ``None``) + permutation group, or pair ``(X, a)`` consisting of a + finite set and a transitive action + - ``pi`` -- ``dict`` mapping sorts to iterables whose union is the + domain of ``G`` (if ``G`` is a permutation group) or `X` (if ``G`` + is a pair ``(X, a)``); if `k=1`, ``pi`` can be omitted EXAMPLES: @@ -2095,12 +2093,12 @@ def _element_constructor_(self, G, pi=None): INPUT: - - ``G`` - an element of ``self`` (in this case pi must be ``None``) - or a permutation group, or a pair ``(X, a)`` consisting of a - finite set and an action. - - ``pi`` - a dict mapping sorts to iterables whose union is the - domain of ``G`` (if ``G`` is a permutation group) or `X` (if ``G``) - is a pair ``(X, a)``. If `k=1`, `pi` can be omitted. + - ``G`` -- element of ``self`` (in this case ``pi`` must be ``None``) + permutation group, or pair ``(X, a)`` consisting of a + finite set and an action + - ``pi`` -- ``dict`` mapping sorts to iterables whose union is the + domain of ``G`` (if ``G`` is a permutation group) or `X` (if ``G`` + is a pair ``(X, a)``); if `k=1`, ``pi`` can be omitted EXAMPLES:: From 8b6ef90f81cce61e68ad99d202c2bda30206c8fb Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Tue, 22 Oct 2024 08:30:48 +0200 Subject: [PATCH 332/537] test that we create every group only once --- src/sage/rings/species.py | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/sage/rings/species.py b/src/sage/rings/species.py index fae8184da26..c16c02a64b6 100644 --- a/src/sage/rings/species.py +++ b/src/sage/rings/species.py @@ -103,7 +103,7 @@ def is_equal(elm): def standardize(C): if not C.degree(): return SymmetricGroup(0) - # an directly indecomposable group is transitive, so we + # a directly indecomposable group is transitive, so we # can use the gap group without worrying about the domain G = C.gap() sorted_orbits = sorted(G.Orbits().sage(), key=len, reverse=True) @@ -183,13 +183,14 @@ def __init__(self): sage: from sage.rings.species import ConjugacyClassesOfDirectlyIndecomposableSubgroups sage: C = ConjugacyClassesOfDirectlyIndecomposableSubgroups() - sage: TestSuite(C).run(max_runs=5) # It takes far too long otherwise + sage: TestSuite(C).run(max_runs=5) # it takes far too long otherwise """ Parent.__init__(self, category=InfiniteEnumeratedSets()) self._cache = dict() def _element_constructor_(self, x): - r"""Construct a conjugacy class from ``x``. + r""" + Construct a conjugacy class from ``x``. INPUT: @@ -257,7 +258,7 @@ def __iter__(self): An iterator over all conjugacy classes of directly indecomposable subgroups. - TESTS:: + EXAMPLES:: sage: from sage.rings.species import ConjugacyClassesOfDirectlyIndecomposableSubgroups sage: C = ConjugacyClassesOfDirectlyIndecomposableSubgroups() @@ -269,6 +270,13 @@ def __iter__(self): ((1,2),) ((1,2,3),) ((2,3), (1,2,3)) + + TESTS:: + + sage: it = iter(C) + sage: l = [next(it) for _ in range(100)] # long time + sage: len(set(l)) == len(l) # long time + True """ n = 0 while True: From 518a46373819d2d8bd614e50a0516661ec435644 Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Tue, 22 Oct 2024 12:30:37 +0200 Subject: [PATCH 333/537] clarify output of group_and_partition --- src/sage/rings/species.py | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/src/sage/rings/species.py b/src/sage/rings/species.py index 5b01c3af7ce..f3599e08ca0 100644 --- a/src/sage/rings/species.py +++ b/src/sage/rings/species.py @@ -1402,8 +1402,10 @@ def __ge__(self, other): @cached_method def group_and_partition(self): - """ - Return the (transitive) permutation group corresponding to ``self``. + r""" + Return the (transitive) permutation group + corresponding to ``self``, together with the partition of + the domain into sorts. EXAMPLES:: @@ -1416,6 +1418,15 @@ def group_and_partition(self): (Permutation Group with generators [(3,4)(5,6), (1,2)], (frozenset({1, 2}), frozenset({3, 4, 5, 6}))) + Note that we cannot rely on blocks of the partition being + consecutive:: + + sage: A = M(PermutationGroup([(3,4)]), {0:[1,3,4], 1:[2]}) + sage: A + X*Y*E_2(X) + sage: A.group_and_partition()[1] + (frozenset({1, 3, 4}), frozenset({2})) + TESTS:: sage: B = M(PermutationGroup([(1,2,3)]), {0: [1,2,3]}); B @@ -1424,7 +1435,9 @@ def group_and_partition(self): (Permutation Group with generators [(1,2,3)], (frozenset({1, 2, 3}), frozenset())) - sage: A*B + sage: G = PermutationGroup([[(1,2),(3,4)], [(5,6)]]) + sage: A = M(G, {0: [5,6], 1: [1,2,3,4]}) + sage: A * B E_2(X)*C_3(X)*{((1,2)(3,4),): ({}, {1, 2, 3, 4})} sage: (A*B).group_and_partition() (Permutation Group with generators [(6,7)(8,9), (3,4,5), (1,2)], From df0554a81a4497a93e487760decd6755e062bd3e Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Wed, 23 Oct 2024 09:30:58 +0200 Subject: [PATCH 334/537] fix some codecov reports --- src/sage/rings/species.py | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/src/sage/rings/species.py b/src/sage/rings/species.py index f3599e08ca0..fc3b3d15c55 100644 --- a/src/sage/rings/species.py +++ b/src/sage/rings/species.py @@ -379,10 +379,8 @@ def __classcall__(cls, parent, dis, domain_partition): domain = list(chain(*map(sorted, domain_partition))) def is_equal(elm): - # check if multicardinalities match - if elm._mc != mc: - return False - # If they do, construct the mapping between the groups + # mc and dis match because they are part of the key, we + # construct the mapping between the groups elm_domain = list(chain(*map(sorted, elm._dompart))) mapping = libgap.MappingPermListList(elm_domain, domain) G = PermutationGroup(gap_group=libgap.ConjugateGroup(elm._dis._C, @@ -806,6 +804,25 @@ def __contains__(self, x): {{1, 2}, {3, 4}} sage: G in A False + + For convenience, directly indecomposable permutation groups + are regarded as being in `AtomicSpecies`:: + + sage: G = PermutationGroup([(1,2)]) + sage: G in AtomicSpecies("X") + True + sage: G in AtomicSpecies("X, Y") + False + sage: (G, {0: [1,2]}) in AtomicSpecies("X, Y") + True + sage: (G, {3: [1,2]}) in AtomicSpecies("X, Y") + False + sage: (G, {0: [1]}) in AtomicSpecies("X, Y") + False + sage: (G, {0: [1], 1: [2]}) in AtomicSpecies("X, Y") + False + sage: (0, {0: []}) in AtomicSpecies("X, Y") + False """ if parent(x) == self: return True From 05770967876b4d025b068439f94994e230e74a5f Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Wed, 23 Oct 2024 21:32:34 +0200 Subject: [PATCH 335/537] implement _richcmp_ instead of __le__ and friends --- src/sage/rings/species.py | 197 ++++++++++++++------------------------ 1 file changed, 74 insertions(+), 123 deletions(-) diff --git a/src/sage/rings/species.py b/src/sage/rings/species.py index fc3b3d15c55..4b47f1cdbda 100644 --- a/src/sage/rings/species.py +++ b/src/sage/rings/species.py @@ -29,6 +29,7 @@ from sage.structure.element import Element, parent from sage.structure.factorization import Factorization from sage.structure.parent import Parent +from sage.structure.richcmp import op_LT, op_LE, op_EQ, op_NE, op_GT, op_GE from sage.structure.unique_representation import (UniqueRepresentation, WithPicklingByInitArgs) @@ -486,19 +487,23 @@ def grade(self): S = self.parent().grading_set() return S(self._mc) - def __le__(self, other): + def _richcmp_(self, other, op): r""" - Return if this element is less than or equal to ``other``. + Compare ``self`` with ``other`` with respect to the comparison + operator ``op``. ``self`` is less than or equal to ``other`` if it is conjugate to a subgroup of ``other`` in the parent group. - EXAMPLES: - - We create the poset of atomic species of degree four:: + EXAMPLES:: sage: from sage.rings.species import AtomicSpecies sage: A = AtomicSpecies("X") + sage: A(DihedralGroup(4)) < A(CyclicPermutationGroup(4)) + True + + We create the poset of atomic species of degree four:: + sage: P = Poset([A.subset(4), lambda b, c: b <= c]) sage: len(P.cover_relations()) 7 @@ -519,42 +524,33 @@ def __le__(self, other): sage: [(a, b) for a, b in Subsets(A.subset(3), 2) if (a < b) != (b > a)] [] """ - if (not isinstance(other, AtomicSpeciesElement) - or len(self._mc) != len(other._mc)): - return False - if self._mc != other._mc: - # X should come before Y - return (sum(self._mc) < sum(other._mc) + if op is op_EQ: + return self is other + if op is op_NE: + return self is not other + if op is op_LE: + return self is other or self < other + if op is op_GE: + return other <= self + if op is op_GT: + return other < self + if op is op_LT: + if len(self._mc) != len(other._mc): + return False + if self._mc != other._mc: + # X should come before Y + return (sum(self._mc) < sum(other._mc) or (sum(self._mc) == sum(other._mc) and self._mc > other._mc)) - S = SymmetricGroup(sum(self._mc)).young_subgroup(self._mc) - # conjugate self and other to match S - g = list(chain.from_iterable(self._dompart)) - conj_self = PermutationGroupElement(g).inverse() - G = libgap.ConjugateGroup(self._dis._C, conj_self) - h = list(chain.from_iterable(other._dompart)) - conj_other = PermutationGroupElement(h).inverse() - H = libgap.ConjugateGroup(other._dis._C, conj_other) - return GAP_FAIL != libgap.ContainedConjugates(S, G, H, True) - - def __lt__(self, other): - r""" - Return if this element is less than ``other``. - - ``self`` is less than or equal to ``other`` if it is - conjugate to a subgroup of ``other`` in the parent group. - - EXAMPLES:: - - sage: from sage.rings.species import AtomicSpecies - sage: A = AtomicSpecies("X") - sage: A(SymmetricGroup(4)) < A(CyclicPermutationGroup(4)) - True - """ - if (not isinstance(other, AtomicSpeciesElement) - or len(self._mc) != len(other._mc)): - return False - return self is not other and self <= other + S = SymmetricGroup(sum(self._mc)).young_subgroup(self._mc) + # conjugate self and other to match S + g = list(chain.from_iterable(self._dompart)) + conj_self = PermutationGroupElement(g).inverse() + G = libgap.ConjugateGroup(self._dis._C, conj_self) + h = list(chain.from_iterable(other._dompart)) + conj_other = PermutationGroupElement(h).inverse() + H = libgap.ConjugateGroup(other._dis._C, conj_other) + return GAP_FAIL != libgap.ContainedConjugates(S, G, H, True) class AtomicSpecies(UniqueRepresentation, Parent): @@ -1292,19 +1288,23 @@ def grade(self): mc = sum(n * vector(a._mc) for a, n in mons.items()) return S(mc) - def __le__(self, other): + def _richcmp_(self, other, op): r""" - Return if this element is less than or equal to ``other``. - - ``self`` is less or equal to ``other`` if it is conjugate to - a subgroup of ``other`` in the parent group. + Compare ``self`` with ``other`` with respect to the + comparison operator ``op``. - EXAMPLES: + ``self`` is less than or equal to ``other`` if it is + conjugate to a subgroup of ``other`` in the parent group. - We create the lattice of molecular species of degree four:: + EXAMPLES:: sage: from sage.rings.species import MolecularSpecies sage: M = MolecularSpecies("X") + sage: M(DihedralGroup(4)) < M(CyclicPermutationGroup(4)) + True + + We create the lattice of molecular species of degree four:: + sage: P = Poset([M.subset(4), lambda b, c: b <= c]) sage: len(P.cover_relations()) 17 @@ -1339,83 +1339,34 @@ def __le__(self, other): sage: T * E2S < S^2 * T True """ - if (not isinstance(other, MolecularSpecies.Element) - or len(self.grade()) != len(other.grade())): - return False - if self.grade() != other.grade(): - # X should come before Y - return (sum(self.grade()) < sum(other.grade()) - or (sum(self.grade()) == sum(other.grade()) - and self.grade() > other.grade())) - - S = SymmetricGroup(sum(self.grade())).young_subgroup(self.grade()) - # conjugate self and other to match S - G, G_dompart = self.group_and_partition() - g = list(chain.from_iterable(G_dompart)) - conj_self = PermutationGroupElement(g).inverse() - G = libgap.ConjugateGroup(G, conj_self) - H, H_dompart = other.group_and_partition() - h = list(chain.from_iterable(H_dompart)) - conj_other = PermutationGroupElement(h).inverse() - H = libgap.ConjugateGroup(H, conj_other) - return GAP_FAIL != libgap.ContainedConjugates(S, G, H, True) - - def __lt__(self, other): - r""" - Return if this element is less than ``other``. - - ``self`` is less than or equal to ``other`` if it is - conjugate to a subgroup of ``other`` in the parent group. - - EXAMPLES:: - - sage: from sage.rings.species import MolecularSpecies - sage: M = MolecularSpecies("X") - sage: M(SymmetricGroup(4)) < M(CyclicPermutationGroup(4)) - True - """ - if (not isinstance(other, MolecularSpecies.Element) - or len(self.grade()) != len(other.grade())): - return False - return self != other and self <= other - - def __gt__(self, other): - r""" - Return if this element is greater than ``other``. - - ``self`` is less than or equal to ``other`` if it is - conjugate to a subgroup of ``other`` in the parent group. - - EXAMPLES:: - - sage: from sage.rings.species import MolecularSpecies - sage: M = MolecularSpecies("X") - sage: M(SymmetricGroup(4)) > M(CyclicPermutationGroup(4)) - False - """ - if (not isinstance(other, MolecularSpecies.Element) - or len(self.grade()) != len(other.grade())): - return False - return other < self - - def __ge__(self, other): - r""" - Return if this element is greater than or equal to ``other``. - - ``self`` is less than or equal to ``other`` if it is - conjugate to a subgroup of ``other`` in the parent group. - - EXAMPLES:: - - sage: from sage.rings.species import MolecularSpecies - sage: M = MolecularSpecies("X") - sage: M(SymmetricGroup(4)) >= M(CyclicPermutationGroup(4)) - False - """ - if (not isinstance(other, MolecularSpecies.Element) - or len(self.grade()) != len(other.grade())): - return False - return other <= self + if op is op_EQ or op is op_NE: + return super()._richcmp_(other, op) + if op is op_LE: + return self == other or self < other + if op is op_GE: + return other <= self + if op is op_GT: + return other < self + if op is op_LT: + if len(self.grade()) != len(other.grade()): + return False + if self.grade() != other.grade(): + # X should come before Y + return (sum(self.grade()) < sum(other.grade()) + or (sum(self.grade()) == sum(other.grade()) + and self.grade() > other.grade())) + + S = SymmetricGroup(sum(self.grade())).young_subgroup(self.grade()) + # conjugate self and other to match S + G, G_dompart = self.group_and_partition() + g = list(chain.from_iterable(G_dompart)) + conj_self = PermutationGroupElement(g).inverse() + G = libgap.ConjugateGroup(G, conj_self) + H, H_dompart = other.group_and_partition() + h = list(chain.from_iterable(H_dompart)) + conj_other = PermutationGroupElement(h).inverse() + H = libgap.ConjugateGroup(H, conj_other) + return GAP_FAIL != libgap.ContainedConjugates(S, G, H, True) @cached_method def group_and_partition(self): From 4104cc20320202b87ba6311c9e3b5fe049cc08da Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Thu, 24 Oct 2024 09:37:58 +0200 Subject: [PATCH 336/537] remove dead code discovered by codecov --- src/sage/rings/species.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/sage/rings/species.py b/src/sage/rings/species.py index 4b47f1cdbda..1536e4feae9 100644 --- a/src/sage/rings/species.py +++ b/src/sage/rings/species.py @@ -518,8 +518,11 @@ def _richcmp_(self, other, op): TESTS:: + sage: A = AtomicSpecies("X") sage: [(a, b) for a, b in Subsets(A.subset(4), 2) if (a < b) != (b > a)] [] + sage: [(a, b) for a, b in Subsets(A.subset(4), 2) if (a <= b) != (b >= a)] + [] sage: A = AtomicSpecies("X, Y") sage: [(a, b) for a, b in Subsets(A.subset(3), 2) if (a < b) != (b > a)] [] @@ -535,8 +538,7 @@ def _richcmp_(self, other, op): if op is op_GT: return other < self if op is op_LT: - if len(self._mc) != len(other._mc): - return False + # the arities match because the parents are equal if self._mc != other._mc: # X should come before Y return (sum(self._mc) < sum(other._mc) @@ -1331,6 +1333,8 @@ def _richcmp_(self, other, op): sage: [(a, b) for a, b in Subsets(M.subset(4), 2) if (a < b) != (b > a)] [] + sage: [(a, b) for a, b in Subsets(M.subset(4), 2) if (a <= b) != (b >= a)] + [] sage: M = MolecularSpecies("S, T") sage: S = M(SymmetricGroup(1), {0: [1]}) @@ -1348,8 +1352,7 @@ def _richcmp_(self, other, op): if op is op_GT: return other < self if op is op_LT: - if len(self.grade()) != len(other.grade()): - return False + # the arities match because the parents are equal if self.grade() != other.grade(): # X should come before Y return (sum(self.grade()) < sum(other.grade()) From 0e84c392b03e4260e06da3c739eea37f4b0de912 Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Thu, 24 Oct 2024 17:43:34 +0200 Subject: [PATCH 337/537] test more errors and remove more dead code discovered by codecov --- src/sage/rings/species.py | 63 ++++++++++++++++++++++++++++++++++----- 1 file changed, 55 insertions(+), 8 deletions(-) diff --git a/src/sage/rings/species.py b/src/sage/rings/species.py index 1536e4feae9..c78b00b6dac 100644 --- a/src/sage/rings/species.py +++ b/src/sage/rings/species.py @@ -234,8 +234,6 @@ def _element_constructor_(self, x): < a, b | a^2, b^2, a^-1*b^-1*a*b > to Set of conjugacy classes of directly indecomposable subgroups """ - if parent(x) == self: - return x if isinstance(x, PermutationGroup_generic): if len(x.disjoint_direct_product_decomposition()) > 1: raise ValueError(f"{x} is not directly indecomposable") @@ -660,6 +658,8 @@ def _element_constructor_(self, G, pi=None): sage: A = AtomicSpecies("X, Y") sage: G = PermutationGroup([[(1,2), (3,4,5,6)]]) sage: a = A(G, {0:[1,2], 1:[3,4,5,6]}) + sage: A(a) == a + True sage: A(a, {0:[3,4,5,6], 1:[1,2]}) Traceback (most recent call last): ... @@ -693,9 +693,8 @@ def _element_constructor_(self, G, pi=None): ValueError: 0 must be a permutation group """ if parent(G) == self: - if pi is not None: - raise ValueError("cannot reassign sorts to an atomic species") - return G + # pi cannot be None because of framework + raise ValueError("cannot reassign sorts to an atomic species") if not isinstance(G, PermutationGroup_generic): raise ValueError(f"{G} must be a permutation group") if pi is None: @@ -809,6 +808,8 @@ def __contains__(self, x): sage: G = PermutationGroup([(1,2)]) sage: G in AtomicSpecies("X") True + sage: A(G) in A + True sage: G in AtomicSpecies("X, Y") False sage: (G, {0: [1,2]}) in AtomicSpecies("X, Y") @@ -1119,6 +1120,8 @@ def _element_constructor_(self, G, pi=None): sage: G = PermutationGroup([[(1,2), (3,4,5,6)]]) sage: a = M(G, {0:[1,2], 1:[3,4,5,6]}) + sage: M(a) == a + True sage: M(a, {0:[3,4,5,6], 1:[1,2]}) Traceback (most recent call last): ... @@ -1148,9 +1151,8 @@ def _element_constructor_(self, G, pi=None): group action on the given domain pi=None """ if parent(G) == self: - if pi is not None: - raise ValueError("cannot reassign sorts to a molecular species") - return G + # pi cannot be None because of framework + raise ValueError("cannot reassign sorts to a molecular species") if isinstance(G, PermutationGroup_generic): if pi is None: @@ -1496,6 +1498,10 @@ def cycle_index(self, parent=None): r""" Return the cycle index of ``self``. + This is essentially a variant of + :meth:`~sage.categories.finite_permutation_groups.FinitePermutationGroups.ParentMethods.cycle_index` + for subgroups of a Young subgroup of the symmetric group. + EXAMPLES:: sage: from sage.rings.species import MolecularSpecies @@ -1504,6 +1510,24 @@ def cycle_index(self, parent=None): sage: A = M(G, {0: [5,6], 1: [1,2,3,4]}) sage: A.cycle_index() 1/4*p[1, 1] # p[1, 1, 1, 1] + 1/4*p[1, 1] # p[2, 2] + 1/4*p[2] # p[1, 1, 1, 1] + 1/4*p[2] # p[2, 2] + + TESTS: + + Check that we support different parents:: + + sage: F = CombinatorialFreeModule(QQ, Partitions()) + sage: P = A.cycle_index(parent=tensor([F, F])) + sage: P + 1/4*B[[1, 1]] # B[[1, 1, 1, 1]] + 1/4*B[[1, 1]] # B[[2, 2]] + 1/4*B[[2]] # B[[1, 1, 1, 1]] + 1/4*B[[2]] # B[[2, 2]] + sage: P.parent() is tensor([F, F]) + True + + This parent should be a module with basis indexed by partitions:: + + sage: A.cycle_index(parent=QQ) + Traceback (most recent call last): + ... + ValueError: `parent` should be a module with basis indexed by partitions """ k = self.parent()._arity if parent is None: @@ -1577,6 +1601,20 @@ def __call__(self, *args): Traceback (most recent call last): ... ValueError: number of args must match arity of self + + sage: M.one()(2) + Traceback (most recent call last): + ... + ValueError: all args must be molecular species + + sage: M2 = MolecularSpecies("X, Y") + sage: X2 = M2(SymmetricGroup(1), {0: [1]}) + sage: Y2 = M2(SymmetricGroup(1), {1: [1]}) + sage: X = M(SymmetricGroup(1)) + sage: (X2*Y2)(X2, X) + Traceback (most recent call last): + ... + ValueError: all args must have the same parent """ if len(args) != self.parent()._arity: raise ValueError("number of args must match arity of self") @@ -1737,10 +1775,19 @@ def hadamard_product(self, other): sage: (X*E2).hadamard_product(X*E2) X*E_2 + X^3 + sage: C3.hadamard_product(E2^2) + 0 + TESTS:: sage: C3.hadamard_product(-C3) -2*C_3 + + sage: Q = PolynomialSpecies(ZZ, ["Y"]) + sage: P.one().hadamard_product(Q.one()) + Traceback (most recent call last): + ... + ValueError: the factors of a Hadamard product must have the same parent """ P = self.parent() if P is not other.parent(): From 03fd6f40abd1e7d5d536c6949a7a6193c0ce43fd Mon Sep 17 00:00:00 2001 From: Verrel Rievaldo Wijaya Date: Fri, 25 Oct 2024 01:54:24 +0700 Subject: [PATCH 338/537] Fix docstring based on review --- .../rings/semirings/tropical_mpolynomial.py | 22 ++++++++--------- .../rings/semirings/tropical_polynomial.py | 6 +++-- src/sage/rings/semirings/tropical_variety.py | 24 ++++++++++--------- 3 files changed, 28 insertions(+), 24 deletions(-) diff --git a/src/sage/rings/semirings/tropical_mpolynomial.py b/src/sage/rings/semirings/tropical_mpolynomial.py index 48323fadaf2..d9328118b95 100644 --- a/src/sage/rings/semirings/tropical_mpolynomial.py +++ b/src/sage/rings/semirings/tropical_mpolynomial.py @@ -405,7 +405,7 @@ def tropical_variety(self): return TropicalSurface(self) return TropicalVariety(self) - def Newton_polytope(self): + def newton_polytope(self): """ Return the Newton polytope of ``self``. @@ -413,11 +413,11 @@ def Newton_polytope(self): corresponding to the exponents of the monomials of tropical polynomial. - OUTPUT: :class:`sage.geometry.polyhedron.constructor.Polyhedron` + OUTPUT: :class:`~sage.geometry.polyhedron.constructor.Polyhedron` EXAMPLES: - Newton polytope for a two-variable tropical polynomial:: + A Newton polytope for a two-variable tropical polynomial:: sage: T = TropicalSemiring(QQ) sage: R. = PolynomialRing(T) @@ -434,7 +434,7 @@ def Newton_polytope(self): p1 = x + y sphinx_plot(p1.Newton_polytope().plot()) - Newton polytope in three dimension:: + A Newton polytope in three dimension:: sage: T = TropicalSemiring(QQ) sage: R. = PolynomialRing(T) @@ -468,7 +468,7 @@ def dual_subdivision(self): the intersection of multiple components. Edges of the dual subdivision correspond to the individual components. - OUTPUT: :class:`sage.geometry.polyhedral_complex.PolyhedralComplex` + OUTPUT: :class:`~sage.geometry.polyhedral_complex.PolyhedralComplex` EXAMPLES: @@ -506,9 +506,9 @@ def dual_subdivision(self): A subdivision with many faces, not all of which are triangles:: - sage: p3 = R(8) + R(4)*x + R(2)*y + R(1)*x^2 + x*y + R(1)*y^2 \ - ....: + R(2)*x^3 + x^2*y + x*y^2 + R(4)*y^3 + R(8)*x^4 \ - ....: + R(4)*x^3*y + x^2*y^2 + R(2)*x*y^3 + y^4 + sage: p3 = (R(8) + R(4)*x + R(2)*y + R(1)*x^2 + x*y + R(1)*y^2 + ....: + R(2)*x^3 + x^2*y + x*y^2 + R(4)*y^3 + R(8)*x^4 + ....: + R(4)*x^3*y + x^2*y^2 + R(2)*x*y^3 + y^4) sage: p3.dual_subdivision().plot() Graphics object consisting of 10 graphics primitives @@ -518,9 +518,9 @@ def dual_subdivision(self): T = TropicalSemiring(QQ, use_min=False) R = PolynomialRing(T, ('x,y')) x, y = R.gen(), R.gen(1) - p3 = R(8) + R(4)*x + R(2)*y + R(1)*x**2 + x*y + R(1)*y**2 \ - + R(2)*x**3 + x**2*y + x*y**2 + R(4)*y**3 + R(8)*x**4 \ - + R(4)*x**3*y + x**2*y**2 + R(2)*x*y**3 + y**4 + p3 = (R(8) + R(4)*x + R(2)*y + R(1)*x**2 + x*y + R(1)*y**2 + + R(2)*x**3 + x**2*y + x*y**2 + R(4)*y**3 + R(8)*x**4 + + R(4)*x**3*y + x**2*y**2 + R(2)*x*y**3 + y**4) sphinx_plot(p3.dual_subdivision().plot()) Dual subdivision of a tropical surface:: diff --git a/src/sage/rings/semirings/tropical_polynomial.py b/src/sage/rings/semirings/tropical_polynomial.py index 59286800dbc..72608c91aac 100644 --- a/src/sage/rings/semirings/tropical_polynomial.py +++ b/src/sage/rings/semirings/tropical_polynomial.py @@ -11,6 +11,8 @@ sage: R. = PolynomialRing(T) sage: x.parent() Univariate Tropical Polynomial Semiring in x over Rational Field + sage: (R(3)*x + R(1)) * (x^2 + x) + 3*x^3 + 3*x^2 + 1*x sage: (x^2 + x + R(0))^2 0*x^4 + 0*x^3 + 0*x^2 + 0*x + 0 @@ -166,7 +168,7 @@ def roots(self): Return the list of all tropical roots of ``self``, counted with multiplicity. - OUTPUT: A list of tropical numbers + OUTPUT: a list of tropical numbers ALGORITHM: @@ -344,7 +346,7 @@ def piecewise_function(self): its corresponding linear function. Next, we must determine which term achieves the minimum (maximum) at each interval. - OUTPUT: A piecewise function + OUTPUT: a piecewise function EXAMPLES:: diff --git a/src/sage/rings/semirings/tropical_variety.py b/src/sage/rings/semirings/tropical_variety.py index 6d0342a3d74..21ef4d3469c 100644 --- a/src/sage/rings/semirings/tropical_variety.py +++ b/src/sage/rings/semirings/tropical_variety.py @@ -544,7 +544,7 @@ def weight_vectors(self): Suppose `L` is an intersection lying within the components `S_1, ldots, S_k` with respective weights `w_1, ldots, w_k`. This `L` is a linear structure in `\RR^{n-1}` and has `n-1` - direction vectors `d_1,d_2,\dots, d_{n-1}`. Each component + direction vectors `d_1,d_2,\ldots, d_{n-1}`. Each component `S_1, ldots, S_k` has a normal vector `n_1, \ldots, n_k`. Then, we scale each normal vector to an integer vector such that the greatest common divisor of its elements is 1. @@ -674,7 +674,6 @@ def weight_vectors(self): WV = {i: [] for i in range(len(line_comps))} for k, index in line_comps.items(): - # Calculate direction vector of the line dir_vecs = [] line = index_line[k][0] @@ -1230,7 +1229,7 @@ def vertices(self): Return all vertices of ``self``, which is the point where three or more edges intersect. - OUTPUT: A set of `(x,y)` points + OUTPUT: a set of `(x,y)` points EXAMPLES:: @@ -1307,11 +1306,11 @@ def weight_vectors(self): that vertex and points in the direction of the edge. Suppose `v` is a vertex adjacent to the edges `e_1, ldots, e_k` - with respective weights `w_1, ldots, w_k`. Every edge `e_i` is + with respective weights `w_1, \ldots, w_k`. Every edge `e_i` is contained in a line (component) defined by an equation. Therefore, - there exists a unique integer vector `v_i=(\alpha, \beta)` in + there exists a unique integer vector `v_i = (\alpha, \beta)` in the direction of `e_i` such that `\gcd(\alpha, \beta)=1`. Then, - each vertex `v` yield the vectors `w_1v_1,ldots,w_kv_k`. + each vertex `v` yield the vectors `w_1 v_1, ldots, w_k v_k`. These vectors will satisfy the following balancing condition: `\sum_{i=1}^k w_i v_i = 0`. @@ -1428,7 +1427,10 @@ def genus(self): Let `t(C)` be the number of trivalent vertices, and let `r(C)` be the number of unbounded edges of `C`. The genus of simple tropical curve `C` is defined by the formula: - `g(C) = \frac{1}{2}t(C) - \frac{1}{2}r(C) + 1`. + + .. MATH:: + + g(C) = \frac{1}{2}t(C) - \frac{1}{2}r(C) + 1. EXAMPLES:: @@ -1518,7 +1520,7 @@ def _parameter_intervals(self): r""" Return the intervals of each component's parameter of ``self``. - OUTPUT: A list of ``RealSet`` + OUTPUT: a list of ``RealSet`` EXAMPLES:: @@ -1617,9 +1619,9 @@ def plot(self): T = TropicalSemiring(QQ) R = PolynomialRing(T, ('x,y')) x, y = R.gen(), R.gen(1) - p2 = R(8) + R(4)*x + R(2)*y + R(1)*x**2 + x*y + R(1)*y**2 \ - + R(2)*x**3 + x**2*y + x*y**2 + R(4)*y**3 + R(8)*x**4 \ - + R(4)*x**3*y + x**2*y**2 + R(2)*x*y**3 + y**4 + p2 = (R(8) + R(4)*x + R(2)*y + R(1)*x**2 + x*y + R(1)*y**2 + + R(2)*x**3 + x**2*y + x*y**2 + R(4)*y**3 + R(8)*x**4 + + R(4)*x**3*y + x**2*y**2 + R(2)*x*y**3 + y**4) sphinx_plot(p2.tropical_variety().plot()) """ from sage.plot.plot import plot From a05ec06087ad33c04a64d7c4af9501bcd00f7dac Mon Sep 17 00:00:00 2001 From: Verrel Rievaldo Wijaya Date: Fri, 25 Oct 2024 15:13:39 +0700 Subject: [PATCH 339/537] Fix docstring and weight_vectors --- .../rings/semirings/tropical_mpolynomial.py | 10 ++-- src/sage/rings/semirings/tropical_variety.py | 51 ++++++++++--------- 2 files changed, 31 insertions(+), 30 deletions(-) diff --git a/src/sage/rings/semirings/tropical_mpolynomial.py b/src/sage/rings/semirings/tropical_mpolynomial.py index d9328118b95..2e217b06787 100644 --- a/src/sage/rings/semirings/tropical_mpolynomial.py +++ b/src/sage/rings/semirings/tropical_mpolynomial.py @@ -152,7 +152,7 @@ class TropicalMPolynomial(MPolynomial_polydict): Another way to represent tropical curve is through dual subdivision, which is a subdivision of Newton polytope of tropical polynomial:: - sage: p1.Newton_polytope() + sage: p1.newton_polytope() A 2-dimensional polyhedron in ZZ^2 defined as the convex hull of 3 vertices sage: p1.dual_subdivision() Polyhedral complex with 1 maximal cell @@ -422,7 +422,7 @@ def newton_polytope(self): sage: T = TropicalSemiring(QQ) sage: R. = PolynomialRing(T) sage: p1 = x + y - sage: p1.Newton_polytope() + sage: p1.newton_polytope() A 1-dimensional polyhedron in ZZ^2 defined as the convex hull of 2 vertices .. PLOT:: @@ -432,14 +432,14 @@ def newton_polytope(self): R = PolynomialRing(T, ('x,y')) x, y = R.gen(), R.gen(1) p1 = x + y - sphinx_plot(p1.Newton_polytope().plot()) + sphinx_plot(p1.newton_polytope().plot()) A Newton polytope in three dimension:: sage: T = TropicalSemiring(QQ) sage: R. = PolynomialRing(T) sage: p1 = x^2 + x*y*z + x + y + z + R(0) - sage: p1.Newton_polytope() + sage: p1.newton_polytope() A 3-dimensional polyhedron in ZZ^3 defined as the convex hull of 5 vertices .. PLOT:: @@ -449,7 +449,7 @@ def newton_polytope(self): R = PolynomialRing(T, ('x,y,z')) x, y, z = R.gen(), R.gen(1), R.gen(2) p1 = x**2 + x*y*z + x + y + z + R(0) - sphinx_plot(p1.Newton_polytope().plot()) + sphinx_plot(p1.newton_polytope().plot()) """ from sage.geometry.polyhedron.constructor import Polyhedron diff --git a/src/sage/rings/semirings/tropical_variety.py b/src/sage/rings/semirings/tropical_variety.py index 21ef4d3469c..699eeb57fd1 100644 --- a/src/sage/rings/semirings/tropical_variety.py +++ b/src/sage/rings/semirings/tropical_variety.py @@ -580,22 +580,18 @@ def weight_vectors(self): 2: [(1, 0, 2), (0, 0, -2), (-1, 0, 0)], 3: [(0, 1, 1), (0, 0, -1), (0, -1, 0)]}) - Weight vectors of tropical hypersurface:: + Checking the balance condition of weight vectors:: sage: T = TropicalSemiring(QQ) sage: R. = PolynomialRing(T) - sage: p1 = R(2)*a*b + R(3)*a*c + R(-1)*c^2 + R(-1/3)*a*d - sage: tv = p1.tropical_variety() - sage: tv.weight_vectors() - ({0: ((u1, u3 - 7/3, u3 - 10/3, u3), {u1 <= u3 - 22/3}), - 1: ((u2 - 4, u2 + 1, u2, u3), {u2 <= u3 - 10/3}), - 2: ((2*u1 - u3 - 2/3, u3 - 7/3, u1, u3), {u3 - 10/3 <= u1}), - 3: ((u3 - 22/3, u2, u3 - 10/3, u3), {u3 - 7/3 <= u2})}, - {0: [0, 2, 4], 1: [0, 1, 3], 2: [1, 2, 5], 3: [3, 4, 5]}, - {0: [(0, -1, -1, 2), (0, -1, 2, -1), (0, 2, -1, -1)], - 1: [(2, -1, -1, 0), (-3, 3, 0, 0), (1, -2, 1, 0)], - 2: [(1, -5, -2, 6), (-2, -1, 4, -1), (1, 6, -2, -5)], - 3: [(1, 0, 1, -2), (2, 0, -1, -1), (-3, 0, 0, 3)]}) + sage: balance_list = [] + sage: for _ in range(5): + ....: f = R.random_element() + ....: vec = f.tropical_variety().weight_vectors()[2].values() + ....: balance = all(a == vector([0,0,0,0]) for a in [sum(lst) for lst in vec]) + ....: balance_list.append(balance) + sage: all(balance == True for balance in balance_list) + True """ from sage.symbolic.ring import SR from sage.symbolic.relation import solve @@ -603,6 +599,7 @@ def weight_vectors(self): from sage.arith.misc import gcd from sage.matrix.constructor import matrix from sage.modules.free_module_element import vector, zero_vector + from itertools import combinations dim = self.dimension() t = SR.var('t') @@ -659,11 +656,9 @@ def weight_vectors(self): is_unique = False break if is_unique: - new_eqn = [eq.subs(convert_tu) for eq in eqn] - new_eqn = tuple(new_eqn) + new_eqn = tuple([eq.subs(convert_tu) for eq in eqn]) cdns = line[1] - new_cdn = [cdn.subs(convert_tu) for cdn in cdns] - new_cdn = set(new_cdn) + new_cdn = set([cdn.subs(convert_tu) for cdn in cdns]) unique_line.add(new_eqn) index_line[index] = tuple([new_eqn, new_cdn]) line_comps[index] = [i] @@ -672,8 +667,8 @@ def weight_vectors(self): match_key = [k for k, v in index_line.items() if v[0] == tuple(new_line)][0] line_comps[match_key].append(i) - WV = {i: [] for i in range(len(line_comps))} - for k, index in line_comps.items(): + WV = {i: [] for i in range(len(line_comps)) if len(line_comps[i]) > 1} + for k in WV: # Calculate direction vector of the line dir_vecs = [] line = index_line[k][0] @@ -690,7 +685,7 @@ def weight_vectors(self): # Calculate the outgoing normal vector of each surface in the # direction of the line - for i in index: + for i in line_comps[k]: surface = self._hypersurface[i][0] drv_vectors = [] for vpar in self._vars: @@ -725,11 +720,17 @@ def weight_vectors(self): weight_vec *= order WV[k].append(weight_vec) - for i in range(len(WV[k])): - test_vectors = [v for v in WV[k]] - test_vectors[i] = -test_vectors[i] - if sum(test_vectors) == zero_vector(QQ, dim): - WV[k] = test_vectors + 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]] + for idx in j: + test_vectors[idx] = -test_vectors[idx] + if sum(test_vectors) == zero_vector(QQ, dim): + WV[k] = test_vectors + balance = True + break + if balance: break return index_line, line_comps, WV From 1adcd0eff265119971d7bea19c767385675af9f1 Mon Sep 17 00:00:00 2001 From: Verrel Rievaldo Wijaya Date: Fri, 25 Oct 2024 15:24:50 +0700 Subject: [PATCH 340/537] Add test to weight_vectors --- src/sage/rings/semirings/tropical_variety.py | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/sage/rings/semirings/tropical_variety.py b/src/sage/rings/semirings/tropical_variety.py index 699eeb57fd1..0b92fc035c1 100644 --- a/src/sage/rings/semirings/tropical_variety.py +++ b/src/sage/rings/semirings/tropical_variety.py @@ -580,17 +580,15 @@ def weight_vectors(self): 2: [(1, 0, 2), (0, 0, -2), (-1, 0, 0)], 3: [(0, 1, 1), (0, 0, -1), (0, -1, 0)]}) + TESTS: + Checking the balance condition of weight vectors:: sage: T = TropicalSemiring(QQ) sage: R. = PolynomialRing(T) - sage: balance_list = [] - sage: for _ in range(5): - ....: f = R.random_element() - ....: vec = f.tropical_variety().weight_vectors()[2].values() - ....: balance = all(a == vector([0,0,0,0]) for a in [sum(lst) for lst in vec]) - ....: balance_list.append(balance) - sage: all(balance == True for balance in balance_list) + sage: f = R.random_element() + sage: vec = f.tropical_variety().weight_vectors()[2].values() + 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 ba1164b42a9ad07ff90c58a260c4cbda05304283 Mon Sep 17 00:00:00 2001 From: janmenjayap Date: Fri, 25 Oct 2024 15:58:31 +0530 Subject: [PATCH 341/537] updated the doc and the code --- src/sage/graphs/matching_covered_graph.py | 165 ++++++++++++++-------- 1 file changed, 109 insertions(+), 56 deletions(-) diff --git a/src/sage/graphs/matching_covered_graph.py b/src/sage/graphs/matching_covered_graph.py index 79f5644436a..d2a0f4a9100 100644 --- a/src/sage/graphs/matching_covered_graph.py +++ b/src/sage/graphs/matching_covered_graph.py @@ -85,7 +85,7 @@ class MatchingCoveredGraph(Graph): sage: G = MatchingCoveredGraph(graphs.PetersenGraph()) sage: G Matching covered petersen graph: graph on 10 vertices - sage: G.get_matching() + sage: sorted(G.get_matching()) [(0, 5, None), (1, 6, None), (2, 7, None), (3, 8, None), (4, 9, None)] sage: G = graphs.StaircaseGraph(4) @@ -94,7 +94,7 @@ class MatchingCoveredGraph(Graph): Matching covered staircase graph: graph on 8 vertices sage: H == G True - sage: H.get_matching() + sage: sorted(H.get_matching()) [(0, 1, None), (2, 7, None), (3, 6, None), (4, 5, None)] sage: G = Graph({0: [1, 2, 3, 4], 1: [2, 5], @@ -104,7 +104,7 @@ class MatchingCoveredGraph(Graph): Matching covered graph on 6 vertices sage: H == G True - sage: H.get_matching() + sage: sorted(H.get_matching()) [(0, 4, None), (1, 2, None), (3, 5, None)] sage: # needs networkx @@ -115,8 +115,10 @@ class MatchingCoveredGraph(Graph): Matching covered graph on 24 vertices sage: H == G True - sage: H.get_matching() - [(4, 23, None), (6, 21, None), (11, 16, None), (7, 20, None), (10, 17, None), (1, 14, None), (2, 13, None), (8, 19, None), (9, 18, None), (3, 12, None), (5, 22, None), (0, 15, None)] + sage: sorted(H.get_matching()) + [(0, 15, None), (1, 14, None), (2, 13, None), (3, 12, None), + (4, 23, None), (5, 22, None), (6, 21, None), (7, 20, None), + (8, 19, None), (9, 18, None), (10, 17, None), (11, 16, None)] sage: G = Graph('E|fG', sparse=True) sage: H = MatchingCoveredGraph(G) @@ -124,7 +126,7 @@ class MatchingCoveredGraph(Graph): Matching covered graph on 6 vertices sage: H == G True - sage: H.get_matching() + sage: sorted(H.get_matching()) [(0, 5, None), (1, 2, None), (3, 4, None)] sage: # needs sage.modules @@ -153,7 +155,7 @@ class MatchingCoveredGraph(Graph): sage: H = MatchingCoveredGraph(G) sage: H == G True - sage: H.get_matching() + sage: sorted(H.get_matching()) [(0, 5, None), (1, 6, None), (2, 7, None), (3, 8, None), (4, 9, None)] sage: # needs sage.modules @@ -182,7 +184,7 @@ class MatchingCoveredGraph(Graph): sage: H = MatchingCoveredGraph(G) sage: H == G True - sage: H.get_matching() + sage: sorted(H.get_matching()) [(0, 5, None), (1, 6, None), (2, 7, None), (3, 8, None), (4, 9, None)] sage: G = Graph([(0, 1), (0, 3), (0, 4), (1, 2), (1, 5), (2, 3), @@ -190,7 +192,7 @@ class MatchingCoveredGraph(Graph): sage: H = MatchingCoveredGraph(G) sage: H == G True - sage: H.get_matching() + sage: sorted(H.get_matching()) [(0, 4, None), (1, 5, None), (2, 6, None), (3, 7, None)] sage: # optional - python_igraph @@ -199,33 +201,38 @@ class MatchingCoveredGraph(Graph): sage: H = MatchingCoveredGraph(G) sage: H Matching covered graph on 4 vertices - sage: H.get_matching() + sage: sorted(H.get_matching()) [(0, 3, {}), (1, 2, {})] One may specify a perfect matching:: sage: P = graphs.PetersenGraph() sage: M = P.matching() - sage: M + sage: sorted(M) [(0, 5, None), (1, 6, None), (2, 7, None), (3, 8, None), (4, 9, None)] sage: G = MatchingCoveredGraph(P, matching=M) sage: G Matching covered petersen graph: graph on 10 vertices sage: P == G True - sage: G.get_matching() + sage: sorted(G.get_matching()) [(0, 5, None), (1, 6, None), (2, 7, None), (3, 8, None), (4, 9, None)] + sage: sorted(G.get_matching()) == sorted(M) + True sage: G = graphs.TruncatedBiwheelGraph(14) sage: M = G.matching() - sage: M - [(20, 21, None), (1, 26, None), (10, 11, None), (14, 15, None), (16, 17, None), (4, 5, None), (22, 23, None), (24, 25, None), (6, 7, None), (8, 9, None), (12, 13, None), (0, 27, None), (18, 19, None), (2, 3, None)] + sage: sorted(M) + [(0, 27, None), (1, 26, None), (2, 3, None), (4, 5, None), + (6, 7, None), (8, 9, None), (10, 11, None), (12, 13, None), + (14, 15, None), (16, 17, None), (18, 19, None), (20, 21, None), + (22, 23, None), (24, 25, None)] sage: H = MatchingCoveredGraph(G, M) sage: H Matching covered truncated biwheel graph: graph on 28 vertices sage: H == G True - sage: H.get_matching() == M + sage: sorted(H.get_matching()) == sorted(M) True TESTS: @@ -405,12 +412,14 @@ class MatchingCoveredGraph(Graph): sage: H = MatchingCoveredGraph(P, matching=M) Traceback (most recent call last): ... - RuntimeError: the string seems corrupt: valid characters are ?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ + RuntimeError: the string seems corrupt: valid characters are + ?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ sage: N = str('graph') sage: J = MatchingCoveredGraph(P, matching=N) Traceback (most recent call last): ... - RuntimeError: the string (graph) seems corrupt: for n = 40, the string is too short + RuntimeError: the string (graph) seems corrupt: for n = 40, + the string is too short sage: G = graphs.CompleteGraph(6) sage: M = Graph(G.matching()) @@ -496,13 +505,16 @@ def __init__(self, data=None, matching=None, algorithm='Edmonds', if matching: # The input matching must be a valid perfect matching of the graph M = Graph(matching) - G_simple = self.to_simple() if any(d != 1 for d in M.degree()): raise ValueError("the input is not a matching") - if any(not G_simple.has_edge(edge) for edge in M.edge_iterator()): + + G = Graph(self, multiedges=False) + + if any(not G.has_edge(edge) for edge in M.edge_iterator()): raise ValueError("the input is not a matching of the graph") - if (G_simple.order() != M.order()) or (G_simple.order() != 2*M.size()): + + if (G.order() != M.order()): raise ValueError("the input is not a perfect matching of the graph") self._matching = matching @@ -599,9 +611,12 @@ def add_edge(self, u, v=None, label=None): sage: G.add_edge((1, 4), 'label') Traceback (most recent call last): ... - ValueError: the graph obtained after the addition of edge (((1, 4), 'label', None)) is not matching covered + ValueError: the graph obtained after the addition of edge + (((1, 4), 'label', None)) is not matching covered sage: G.edges(sort=False) - [(0, 1, None), (0, 2, None), (0, 3, None), (0, 4, None), (0, 5, None), (1, 2, None), (1, 5, None), (2, 3, None), (3, 4, None), (4, 5, None)] + [(0, 1, None), (0, 2, None), (0, 3, None), (0, 4, None), + (0, 5, None), (1, 2, None), (1, 5, None), (2, 3, None), + (3, 4, None), (4, 5, None)] The key word ``label`` must be used:: @@ -609,7 +624,9 @@ def add_edge(self, u, v=None, label=None): sage: G = MatchingCoveredGraph(W) sage: G.add_edge((1, 4), label='label') sage: G.edges(sort=False) # No alteration to the existing graph - [(0, 1, None), (0, 2, None), (0, 3, None), (0, 4, None), (0, 5, None), (1, 2, None), (1, 4, 'label'), (1, 5, None), (2, 3, None), (3, 4, None), (4, 5, None)] + [(0, 1, None), (0, 2, None), (0, 3, None), (0, 4, None), + (0, 5, None), (1, 2, None), (1, 4, 'label'), (1, 5, None), + (2, 3, None), (3, 4, None), (4, 5, None)] An expression, analogous to the syntax mentioned above may be used:: @@ -617,22 +634,42 @@ def add_edge(self, u, v=None, label=None): sage: G = MatchingCoveredGraph(S) sage: G.add_edge(0, 5) sage: G.edges(sort=False) - [(0, 1, None), (0, 3, None), (0, 5, None), (0, 6, None), (1, 2, None), (1, 4, None), (2, 5, None), (2, 7, None), (3, 4, None), (3, 6, None), (4, 5, None), (5, 7, None), (6, 7, None)] + [(0, 1, None), (0, 3, None), (0, 5, None), (0, 6, None), + (1, 2, None), (1, 4, None), (2, 5, None), (2, 7, None), + (3, 4, None), (3, 6, None), (4, 5, None), (5, 7, None), + (6, 7, None)] sage: G.add_edge((2, 3)) sage: G.edges(sort=False) - [(0, 1, None), (0, 3, None), (0, 5, None), (0, 6, None), (1, 2, None), (1, 4, None), (2, 3, None), (2, 5, None), (2, 7, None), (3, 4, None), (3, 6, None), (4, 5, None), (5, 7, None), (6, 7, None)] + [(0, 1, None), (0, 3, None), (0, 5, None), (0, 6, None), + (1, 2, None), (1, 4, None), (2, 3, None), (2, 5, None), + (2, 7, None), (3, 4, None), (3, 6, None), (4, 5, None), + (5, 7, None), (6, 7, None)] sage: G.add_edges([(0, 4)]) sage: G.edges(sort=False) - [(0, 1, None), (0, 3, None), (0, 4, None), (0, 5, None), (0, 6, None), (1, 2, None), (1, 4, None), (2, 3, None), (2, 5, None), (2, 7, None), (3, 4, None), (3, 6, None), (4, 5, None), (5, 7, None), (6, 7, None)] + [(0, 1, None), (0, 3, None), (0, 4, None), (0, 5, None), + (0, 6, None), (1, 2, None), (1, 4, None), (2, 3, None), + (2, 5, None), (2, 7, None), (3, 4, None), (3, 6, None), + (4, 5, None), (5, 7, None), (6, 7, None)] sage: G.add_edge(2, 4, 'label') sage: G.edges(sort=False) - [(0, 1, None), (0, 3, None), (0, 4, None), (0, 5, None), (0, 6, None), (1, 2, None), (1, 4, None), (2, 3, None), (2, 4, 'label'), (2, 5, None), (2, 7, None), (3, 4, None), (3, 6, None), (4, 5, None), (5, 7, None), (6, 7, None)] + [(0, 1, None), (0, 3, None), (0, 4, None), (0, 5, None), + (0, 6, None), (1, 2, None), (1, 4, None), (2, 3, None), + (2, 4, 'label'), (2, 5, None), (2, 7, None), (3, 4, None), + (3, 6, None), (4, 5, None), (5, 7, None), (6, 7, None)] sage: G.add_edge((4, 6, 'label')) sage: G.edges(sort=False) - [(0, 1, None), (0, 3, None), (0, 4, None), (0, 5, None), (0, 6, None), (1, 2, None), (1, 4, None), (2, 3, None), (2, 4, 'label'), (2, 5, None), (2, 7, None), (3, 4, None), (3, 6, None), (4, 5, None), (4, 6, 'label'), (5, 7, None), (6, 7, None)] + [(0, 1, None), (0, 3, None), (0, 4, None), (0, 5, None), + (0, 6, None), (1, 2, None), (1, 4, None), (2, 3, None), + (2, 4, 'label'), (2, 5, None), (2, 7, None), (3, 4, None), + (3, 6, None), (4, 5, None), (4, 6, 'label'), (5, 7, None), + (6, 7, None)] sage: G.add_edges([(4, 7, 'label')]) sage: G.edges(sort=False) - [(0, 1, None), (0, 3, None), (0, 4, None), (0, 5, None), (0, 6, None), (1, 2, None), (1, 4, None), (2, 3, None), (2, 4, 'label'), (2, 5, None), (2, 7, None), (3, 4, None), (3, 6, None), (4, 5, None), (4, 6, 'label'), (4, 7, 'label'), (5, 7, None), (6, 7, None)] + [(0, 1, None), (0, 3, None), (0, 4, None), (0, 5, None), + (0, 6, None), (1, 2, None), (1, 4, None), (2, 3, None), + (2, 4, 'label'), (2, 5, None), (2, 7, None), (3, 4, None), + (3, 6, None), (4, 5, None), (4, 6, 'label'), (4, 7, 'label'), + (5, 7, None), (6, 7, None)] Vertex name cannot be ``None``, so:: @@ -641,15 +678,21 @@ def add_edge(self, u, v=None, label=None): sage: H.add_edge(None, 1) Traceback (most recent call last): ... - ValueError: the graph obtained after the addition of edge ((None, 1, None)) is not matching covered + ValueError: the graph obtained after the addition of edge + ((None, 1, None)) is not matching covered sage: H.edges(sort=False) # No alteration to the existing graph - [(0, 1, None), (0, 2, None), (0, 3, None), (0, 4, None), (0, 5, None), (1, 2, None), (1, 5, None), (2, 3, None), (3, 4, None), (4, 5, None)] + [(0, 1, None), (0, 2, None), (0, 3, None), (0, 4, None), + (0, 5, None), (1, 2, None), (1, 5, None), (2, 3, None), + (3, 4, None), (4, 5, None)] sage: H.add_edge(None, None) Traceback (most recent call last): ... - ValueError: the graph obtained after the addition of edge ((None, None, None)) is not matching covered + ValueError: the graph obtained after the addition of edge + ((None, None, None)) is not matching covered sage: H.edges(sort=False) # No alteration to the existing graph - [(0, 1, None), (0, 2, None), (0, 3, None), (0, 4, None), (0, 5, None), (1, 2, None), (1, 5, None), (2, 3, None), (3, 4, None), (4, 5, None)] + [(0, 1, None), (0, 2, None), (0, 3, None), (0, 4, None), + (0, 5, None), (1, 2, None), (1, 5, None), (2, 3, None), + (3, 4, None), (4, 5, None)] EXAMPLES: @@ -667,7 +710,10 @@ def add_edge(self, u, v=None, label=None): sage: G = MatchingCoveredGraph(P) sage: G.add_edge(1, 4) sage: G.edges(sort=False) - [(0, 1, None), (0, 4, None), (0, 5, None), (1, 2, None), (1, 4, None), (1, 6, None), (2, 3, None), (2, 7, None), (3, 4, None), (3, 8, None), (4, 9, None), (5, 7, None), (5, 8, None), (6, 8, None), (6, 9, None), (7, 9, None)] + [(0, 1, None), (0, 4, None), (0, 5, None), (1, 2, None), + (1, 4, None), (1, 6, None), (2, 3, None), (2, 7, None), + (3, 4, None), (3, 8, None), (4, 9, None), (5, 7, None), + (5, 8, None), (6, 8, None), (6, 9, None), (7, 9, None)] Adding an edge with both the incident vertices being existent such that the resulting graph is not matching covered:: @@ -677,7 +723,8 @@ def add_edge(self, u, v=None, label=None): sage: G.add_edge(0, 2) Traceback (most recent call last): ... - ValueError: the graph obtained after the addition of edge ((0, 2, None)) is not matching covered + ValueError: the graph obtained after the addition of edge + ((0, 2, None)) is not matching covered sage: G.edges(sort=False) # No alteration to the existing graph [(0, 1, None), (0, 3, None), (1, 2, None), (2, 3, None)] @@ -690,7 +737,8 @@ def add_edge(self, u, v=None, label=None): sage: G.add_edge(0, 4) Traceback (most recent call last): ... - ValueError: the graph obtained after the addition of edge ((0, 4, None)) is not matching covered + ValueError: the graph obtained after the addition of edge + ((0, 4, None)) is not matching covered sage: G.edges(sort=False) # No alteration to the existing graph [(0, 1, None), (0, 3, None), (1, 2, None), (2, 3, None)] @@ -703,7 +751,8 @@ def add_edge(self, u, v=None, label=None): sage: G.add_edge(4, 5) Traceback (most recent call last): ... - ValueError: the graph obtained after the addition of edge ((4, 5, None)) is not matching covered + ValueError: the graph obtained after the addition of edge + ((4, 5, None)) is not matching covered sage: G.edges(sort=False) # No alteration to the existing graph [(0, 1, None), (0, 3, None), (1, 2, None), (2, 3, None)] @@ -738,6 +787,10 @@ def add_edge(self, u, v=None, label=None): if u == v: raise ValueError('loops are not allowed in ' 'matching covered graphs') + + # TODO: A ligher incremental method to check whether the new graph + # is matching covered instead of creating a new graph and checking + G = Graph(self) G.add_edge(u, v, label=label) @@ -1050,7 +1103,8 @@ def delete_vertices(self, vertices): sage: G.delete_vertices(T) Traceback (most recent call last): ... - ValueError: the resulting graph after the removal of the vertices is not matching covered + ValueError: the resulting graph after the removal of + the vertices is not matching covered Providing with a list of existent vertices after the deletion of which the resulting graph is still matching covered; note that in the @@ -1074,9 +1128,8 @@ def delete_vertices(self, vertices): raise ValueError('vertex (%s) not in the graph' % str(vertex)) try: - G = Graph(self) + G = Graph(self, multiedges=False) G.delete_vertices(vertices) - G_simple = G.to_simple() M = Graph(self.get_matching()) @@ -1086,9 +1139,7 @@ def delete_vertices(self, vertices): # must be a valid perfect matching of the resulting graph obtained # after the removal of the vertices - if any(d != 1 for d in G_simple.degree()) \ - or any(not G_simple.has_edge(edge) for edge in M.edge_iterator()) \ - or (G_simple.order() != M.order()) or (G_simple.order() != 2*M.size()): + if (G.order() != 2*M.size()): M = None self.__init__(data=G, matching=M) @@ -1115,9 +1166,9 @@ def get_matching(self): sage: P = graphs.PetersenGraph() sage: M = [(0, 1), (2, 3), (4, 9), (5, 7), (6, 8)] sage: G = MatchingCoveredGraph(P, M) - sage: G.get_matching() + sage: sorted(G.get_matching()) [(0, 1), (2, 3), (4, 9), (5, 7), (6, 8)] - sage: M == G.get_matching() + sage: M == sorted(G.get_matching()) True If no matching is specified while initilizing a matching covered graph, @@ -1128,9 +1179,9 @@ def get_matching(self): sage: P = graphs.PetersenGraph() sage: M = P.matching() sage: G = MatchingCoveredGraph(P) - sage: G.get_matching() + sage: sorted(G.get_matching()) [(0, 5, None), (1, 6, None), (2, 7, None), (3, 8, None), (4, 9, None)] - sage: M == G.get_matching() + sage: sorted(M) == sorted(G.get_matching()) True """ return self._matching @@ -1157,11 +1208,11 @@ def update_matching(self, matching): sage: P = graphs.PetersenGraph() sage: G = MatchingCoveredGraph(P) - sage: G.get_matching() + sage: sorted(G.get_matching()) [(0, 5, None), (1, 6, None), (2, 7, None), (3, 8, None), (4, 9, None)] sage: M = [(0, 1), (2, 3), (4, 9), (5, 7), (6, 8)] sage: G.update_matching(M) - sage: G.get_matching() + sage: sorted(G.get_matching()) [(0, 1, None), (2, 3, None), (4, 9, None), (5, 7, None), (6, 8, None)] TESTS: @@ -1170,18 +1221,20 @@ def update_matching(self, matching): sage: P = graphs.PetersenGraph() sage: G = MatchingCoveredGraph(P) - sage: G.get_matching() + sage: sorted(G.get_matching()) [(0, 5, None), (1, 6, None), (2, 7, None), (3, 8, None), (4, 9, None)] sage: S = str('0') sage: G.update_matching(S) Traceback (most recent call last): ... - RuntimeError: the string seems corrupt: valid characters are ?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ + RuntimeError: the string seems corrupt: valid characters are + ?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ sage: T = str('graph') sage: G.update_matching(T) Traceback (most recent call last): ... - RuntimeError: the string (graph) seems corrupt: for n = 40, the string is too short + RuntimeError: the string (graph) seems corrupt: for n = 40, + the string is too short sage: M = Graph(G.matching()) sage: M.add_edges([(0, 1), (0, 2)]) sage: G.update_matching(M) @@ -1203,16 +1256,16 @@ def update_matching(self, matching): """ try: M = Graph(matching) - G = Graph(self) - G_simple = G.to_simple() if any(d != 1 for d in M.degree()): raise ValueError("the input is not a matching") - if any(not G_simple.has_edge(edge) for edge in M.edge_iterator()): + G = Graph(self, multiedges=False) + + if any(not G.has_edge(edge) for edge in M.edge_iterator()): raise ValueError("the input is not a matching of the graph") - if (G_simple.order() != M.order()) or (G_simple.order() != 2*M.size()): + if (G.order() != M.order()): raise ValueError("the input is not a perfect matching of the graph") self._matching = M.edges() From 67b315aba6b69fd27bbfb075ef2d36318f737294 Mon Sep 17 00:00:00 2001 From: janmenjayap Date: Fri, 25 Oct 2024 16:52:38 +0530 Subject: [PATCH 342/537] updated the doctests --- src/sage/graphs/matching_covered_graph.py | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/sage/graphs/matching_covered_graph.py b/src/sage/graphs/matching_covered_graph.py index d2a0f4a9100..b2c6822ba0d 100644 --- a/src/sage/graphs/matching_covered_graph.py +++ b/src/sage/graphs/matching_covered_graph.py @@ -759,7 +759,7 @@ def add_edge(self, u, v=None, label=None): Adding a self-loop:: sage: H = graphs.HeawoodGraph() - sage: G = MatchingCoveredGraph(P) + sage: G = MatchingCoveredGraph(H) sage: v = next(G.vertex_iterator()) sage: G.add_edge(v, v) Traceback (most recent call last): @@ -851,12 +851,6 @@ def add_vertex(self, name=None): Adding a new/ non-existing vertex:: - sage: P = graphs.PetersenGraph() - sage: P - Petersen graph: Graph on 10 vertices - sage: G = MatchingCoveredGraph(P) - sage: G - Matching covered petersen graph: graph on 10 vertices sage: G.add_vertex() Traceback (most recent call last): ... From 60aa80496f2ee06e4d996d965af598198d44e0aa Mon Sep 17 00:00:00 2001 From: Verrel Rievaldo Wijaya Date: Fri, 25 Oct 2024 19:21:55 +0700 Subject: [PATCH 343/537] Fix lint error --- src/sage/rings/semirings/tropical_variety.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/rings/semirings/tropical_variety.py b/src/sage/rings/semirings/tropical_variety.py index 0b92fc035c1..7ef364d3ec2 100644 --- a/src/sage/rings/semirings/tropical_variety.py +++ b/src/sage/rings/semirings/tropical_variety.py @@ -581,7 +581,7 @@ def weight_vectors(self): 3: [(0, 1, 1), (0, 0, -1), (0, -1, 0)]}) TESTS: - + Checking the balance condition of weight vectors:: sage: T = TropicalSemiring(QQ) From c22759a647a9c082607c42428378d55d46a3a776 Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Sat, 26 Oct 2024 14:42:41 +0200 Subject: [PATCH 344/537] remove ConjugacyClassOfDirectlyIndecomposableSubgroups and ConjugacyClassesOfDirectlyIndecomposableSubgroups and reorganize AtomicSpeciesElement.__classcall__ for significant performance improvement --- src/sage/rings/species.py | 525 ++++++++++++-------------------------- 1 file changed, 166 insertions(+), 359 deletions(-) diff --git a/src/sage/rings/species.py b/src/sage/rings/species.py index c78b00b6dac..c1b0f67f0a3 100644 --- a/src/sage/rings/species.py +++ b/src/sage/rings/species.py @@ -1,7 +1,6 @@ from itertools import accumulate, chain from sage.categories.graded_algebras_with_basis import GradedAlgebrasWithBasis -from sage.categories.infinite_enumerated_sets import InfiniteEnumeratedSets from sage.categories.modules import Modules from sage.categories.monoids import Monoids from sage.categories.sets_cat import cartesian_product @@ -36,290 +35,6 @@ GAP_FAIL = libgap.eval('fail') -class ConjugacyClassOfDirectlyIndecomposableSubgroups(Element, WithEqualityById, - WithPicklingByInitArgs, - metaclass=InheritComparisonClasscallMetaclass): - r""" - A directly indecomposable conjugacy class of subgroups of a - symmetric group. - - Two conjugacy classes of subgroups are equal if they have the - same degree (say `n`) and are conjugate within `S_n`. - """ - @staticmethod - def _invariant(C): - r""" - Return an invariant of the permutation group ``C`` used for - hashing and as key in the cache. - - EXAMPLES:: - - sage: from sage.rings.species import ConjugacyClassOfDirectlyIndecomposableSubgroups - sage: C = ConjugacyClassOfDirectlyIndecomposableSubgroups - sage: G = PermutationGroup([[(1,2),(3,4)]]) - sage: H = PermutationGroup([[(1,3),(2,4)], [(1,2),(3,4)]]) - sage: K = PermutationGroup([[(1,2,3,4)]]) - sage: C._invariant(G) - (2, (2, 2)) - sage: C._invariant(H) - (4, (4,)) - sage: C._invariant(K) - (4, (4,)) - """ - return C.cardinality(), tuple(sorted(len(o) for o in C.orbits())) - - @staticmethod - def __classcall__(cls, parent, C): - """ - Normalize the input for unique representation. - - TESTS:: - - sage: from sage.rings.species import ConjugacyClassesOfDirectlyIndecomposableSubgroups - sage: C = ConjugacyClassesOfDirectlyIndecomposableSubgroups() - - Check that the domain is standardized:: - - sage: G = PermutationGroup([("a", "b", "c"), ("d", "a"), ("d", "b"), ("d", "c")]) - sage: C(G) - ((2,4,3), (1,2)) - - sage: G = PermutationGroup([[(1,2),(3,4),(5,6),(7,8,9,10)]]); G - Permutation Group with generators [(1,2)(3,4)(5,6)(7,8,9,10)] - sage: H = PermutationGroup([[(1,2,3,4),(5,6),(7,8),(9,10)]]); H - Permutation Group with generators [(1,2,3,4)(5,6)(7,8)(9,10)] - sage: C(G) is C(H) - True - - Two different transitive groups with the same cardinality:: - - sage: a = C(PermutationGroup([[(1,3),(2,4)], [(1,4),(2,3)]])) - sage: b = C(PermutationGroup([[(1,3,2,4)]])) - sage: a == b - False - """ - def is_equal(elm): - return SymmetricGroup(elm._C.degree()).are_conjugate(elm._C, C) - - def standardize(C): - if not C.degree(): - return SymmetricGroup(0) - # a directly indecomposable group is transitive, so we - # can use the gap group without worrying about the domain - G = C.gap() - sorted_orbits = sorted(G.Orbits().sage(), key=len, reverse=True) - pi = PermutationGroupElement([e for o in sorted_orbits for e in o]) - G = PermutationGroup(G.SmallGeneratingSet().sage()) - return G.conjugate(pi.inverse()) - - key = cls._invariant(C) - if key in parent._cache: - lookup = parent._cache[key] - for elm in lookup: - if is_equal(elm): - return elm - else: - lookup = parent._cache[key] = [] - - elm = WithPicklingByInitArgs.__classcall__(cls, parent, standardize(C)) - lookup.append(elm) - return elm - - def __hash__(self): - """ - Return a hash of ``self``. - - EXAMPLES:: - - sage: from sage.rings.species import ConjugacyClassesOfDirectlyIndecomposableSubgroups - sage: C = ConjugacyClassesOfDirectlyIndecomposableSubgroups() - sage: G = PermutationGroup([[(1,2),(3,4)]]) - sage: H = PermutationGroup([[(1,3),(2,4)], [(1,2),(3,4)]]) - sage: K = PermutationGroup([[(1,2,3,4)]]) - sage: hash(C(G)) == hash(C(H)) - False - sage: hash(C(H)) == hash(C(K)) - True - sage: C(H) == C(K) - False - """ - return hash(self._invariant(self._C)) - - def __init__(self, parent, C): - r""" - Initialize a conjugacy class of directly indecomposable subgroups - of a symmetric group. - - TESTS:: - - sage: from sage.rings.species import ConjugacyClassesOfDirectlyIndecomposableSubgroups - sage: C = ConjugacyClassesOfDirectlyIndecomposableSubgroups() - sage: G = C(PermutationGroup([[(1,2),(3,4)],[(1,2),(5,6)]])) - sage: TestSuite(G).run() - """ - Element.__init__(self, parent) - self._C = C - - def _repr_(self): - r""" - Return a string representation of ``self``. - - EXAMPLES:: - - sage: from sage.rings.species import ConjugacyClassesOfDirectlyIndecomposableSubgroups - sage: C = ConjugacyClassesOfDirectlyIndecomposableSubgroups() - sage: G = PermutationGroup([[(1,3),(4,7)], [(2,5),(6,8)], [(1,4),(2,5),(3,7)]]) - sage: C(G) - ((5,6)(7,8), (1,2)(3,4), (1,3)(2,4)(5,6)) - """ - return repr(self._C.gens()) - - -class ConjugacyClassesOfDirectlyIndecomposableSubgroups(UniqueRepresentation, Parent): - def __init__(self): - r""" - Conjugacy classes of directly indecomposable subgroups of a symmetric group. - - TESTS:: - - sage: from sage.rings.species import ConjugacyClassesOfDirectlyIndecomposableSubgroups - sage: C = ConjugacyClassesOfDirectlyIndecomposableSubgroups() - sage: TestSuite(C).run(max_runs=5) # it takes far too long otherwise - """ - Parent.__init__(self, category=InfiniteEnumeratedSets()) - self._cache = dict() - - def _element_constructor_(self, x): - r""" - Construct a conjugacy class from ``x``. - - INPUT: - - - ``x``, an element of ``self`` or a directly indecomposable - permutation group. - - EXAMPLES:: - - sage: from sage.rings.species import ConjugacyClassesOfDirectlyIndecomposableSubgroups - sage: C = ConjugacyClassesOfDirectlyIndecomposableSubgroups() - sage: C(PermutationGroup([("a", "b", "c")])) - ((1,2,3),) - sage: C(PermutationGroup([(1, 3, 5)], domain=[1,3,5])) - ((1,2,3),) - sage: C(PermutationGroup([[(1,3),(4,7)],[(2,5),(6,8)], [(1,4),(2,5),(3,7)]])) - ((5,6)(7,8), (1,2)(3,4), (1,3)(2,4)(5,6)) - - TESTS: - - Providing a group that decomposes as a direct product raises - an error:: - - sage: C(PermutationGroup([[(1,2,3),(4,5)]])) - Traceback (most recent call last): - ... - ValueError: Permutation Group with generators [(1,2,3)(4,5)] is not directly indecomposable - - Check some trivial cases:: - - sage: C(0) - Traceback (most recent call last): - ... - ValueError: unable to convert 0 to Set of conjugacy classes of - directly indecomposable subgroups - - sage: C(groups.presentation.KleinFour()) - Traceback (most recent call last): - ... - ValueError: unable to convert Finitely presented group - < a, b | a^2, b^2, a^-1*b^-1*a*b > to Set of conjugacy classes of - directly indecomposable subgroups - """ - if isinstance(x, PermutationGroup_generic): - if len(x.disjoint_direct_product_decomposition()) > 1: - raise ValueError(f"{x} is not directly indecomposable") - return self.element_class(self, x) - raise ValueError(f"unable to convert {x} to {self}") - - def _repr_(self): - r""" - Return the string representation for ``self``. - - TESTS:: - - sage: from sage.rings.species import ConjugacyClassesOfDirectlyIndecomposableSubgroups - sage: C = ConjugacyClassesOfDirectlyIndecomposableSubgroups(); C - Set of conjugacy classes of directly indecomposable subgroups - """ - return "Set of conjugacy classes of directly indecomposable subgroups" - - def __iter__(self): - r""" - An iterator over all conjugacy classes of directly indecomposable - subgroups. - - EXAMPLES:: - - sage: from sage.rings.species import ConjugacyClassesOfDirectlyIndecomposableSubgroups - sage: C = ConjugacyClassesOfDirectlyIndecomposableSubgroups() - sage: it = iter(C) - sage: for i in range(5): - ....: print(next(it)) - () - ((),) - ((1,2),) - ((1,2,3),) - ((2,3), (1,2,3)) - - TESTS:: - - sage: it = iter(C) - sage: l = [next(it) for _ in range(100)] # long time - sage: len(set(l)) == len(l) # long time - True - """ - n = 0 - while True: - for G in SymmetricGroup(n).conjugacy_classes_subgroups(): - if len(G.disjoint_direct_product_decomposition()) <= 1: - yield self._element_constructor_(G) - n += 1 - - def __contains__(self, G): - r""" - Return if ``G`` is in ``self``. - - TESTS:: - - sage: from sage.rings.species import ConjugacyClassesOfDirectlyIndecomposableSubgroups - sage: C = ConjugacyClassesOfDirectlyIndecomposableSubgroups() - sage: G = PermutationGroup([[(1,2)], [(3,4)]]); G - Permutation Group with generators [(3,4), (1,2)] - sage: G.disjoint_direct_product_decomposition() - {{1, 2}, {3, 4}} - sage: G in C - False - """ - if parent(G) == self: - return True - return len(G.disjoint_direct_product_decomposition()) <= 1 - - @cached_method - def an_element(self): - r""" - Return an element of ``self``. - - EXAMPLES:: - - sage: from sage.rings.species import ConjugacyClassesOfDirectlyIndecomposableSubgroups - sage: C = ConjugacyClassesOfDirectlyIndecomposableSubgroups() - sage: C.an_element() - ((),) - """ - return self._element_constructor_(SymmetricGroup(1)) - - Element = ConjugacyClassOfDirectlyIndecomposableSubgroups - - class AtomicSpeciesElement(Element, WithEqualityById, WithPicklingByInitArgs, metaclass=InheritComparisonClasscallMetaclass): @@ -331,17 +46,27 @@ class AtomicSpeciesElement(Element, WithEqualityById, conjugating element. """ @staticmethod - def __classcall__(cls, parent, dis, domain_partition): + def __classcall__(cls, parent, C, dom_part): r""" Normalize the input for unique representation. TESTS:: sage: from sage.rings.species import AtomicSpecies - sage: A = AtomicSpecies("X, Y") + sage: A = AtomicSpecies("X") + sage: G = PermutationGroup([(2,3), (1,2,3)]) + sage: A(G) + E_3 + sage: G = CyclicPermutationGroup(4) + sage: A(G) + C_4 + sage: G = PermutationGroup([[(1,2), (3,4)], [(1,4), (2,3)]]) + sage: A(G) + Pb_4 Check that the domain is irrelevant:: + sage: A = AtomicSpecies("X, Y") sage: G = PermutationGroup([[("a", "b", "c", "d"), ("e", "f")]]) sage: a = A(G, {0: "abcd", 1: "ef"}); a # random {((1,2,3,4)(5,6),): ({1, 2, 3, 4}, {5, 6})} @@ -374,30 +99,71 @@ def __classcall__(cls, parent, dis, domain_partition): sage: a is c True """ - mc = tuple(len(v) for v in domain_partition) - domain = list(chain(*map(sorted, domain_partition))) - - def is_equal(elm): - # mc and dis match because they are part of the key, we - # construct the mapping between the groups - elm_domain = list(chain(*map(sorted, elm._dompart))) - mapping = libgap.MappingPermListList(elm_domain, domain) - G = PermutationGroup(gap_group=libgap.ConjugateGroup(elm._dis._C, - mapping), - domain=elm._dis._C.domain()) - # The conjugated group must be exactly equal to the other group - return G == dis._C + # a directly indecomposable group has no fixed points, so we + # can use the gap group without worrying about the domain + G = C.gap() + dom_part = [[ZZ(C._domain_to_gap[e]) for e in b] + for b in dom_part] + orbits = sorted(G.Orbits().sage(), key=len, reverse=True) + for orbit in orbits: + if not any(set(orbit).issubset(p) for p in dom_part): + o = [C._domain_from_gap[e] for e in orbit] + raise ValueError(f"All elements of orbit {o} must have the same sort") + n = C.degree() + S = SymmetricGroup(n) + + def new_dis(): + """ + Return a representative ``dis`` in the conjugacy + class of subgroups conjugate to ``C``, together with the + conjugating map ``mp`` + """ + if not n: + return S, PermutationGroupElement([]) + # create a group conjugate to `C` whose orbits + # consist of contiguous sets of numbers, with larger + # orbits having smaller numbers, and compute a small + # generating set + mp = PermutationGroupElement([e for o in orbits for e in o]).inverse().gap() + H = PermutationGroup(G.SmallGeneratingSet().sage()) + return H.conjugate(mp), mp + + key = C.cardinality(), tuple(len(o) for o in orbits) + if key in parent._dis_cache: + lookup_dis = parent._dis_cache[key] + for dis in lookup_dis: + mp = libgap.RepresentativeAction(S, G, dis) + if mp != GAP_FAIL: + break + else: + dis, mp = new_dis() + lookup_dis.append(dis) + else: + dis, mp = new_dis() + lookup_dis = parent._dis_cache[key] = [dis] + dom_part = [[ZZ(e ** mp) for e in b] for b in dom_part] + mc = tuple([len(b) for b in dom_part]) key = mc, dis if key in parent._cache: lookup = parent._cache[key] - for elm in lookup: - if is_equal(elm): - return elm + if parent._arity == 1 and lookup: + assert len(lookup) == 1 + return lookup[0] + else: + domain = list(chain(*map(sorted, dom_part))) + for elm in lookup: + # check whether the assignment to sorts given by + # dom_part and by elm._dompart are the same + elm_domain = list(chain(*map(sorted, elm._dompart))) + mp = libgap.MappingPermListList(elm_domain, domain) + if all(g ** mp in dis for g in dis.gens()): + return elm else: lookup = parent._cache[key] = [] - elm = WithPicklingByInitArgs.__classcall__(cls, parent, dis, domain_partition) + dom_part = tuple([frozenset(b) for b in dom_part]) + elm = WithPicklingByInitArgs.__classcall__(cls, parent, dis, dom_part) lookup.append(elm) return elm @@ -432,6 +198,11 @@ def __hash__(self): """ Return a hash of ``self``. + ..TODO:: + + Why does the hash not come from + :class:`~sage.misc.fast_methods.WithEqualityById`? + EXAMPLES:: sage: from sage.rings.species import AtomicSpecies @@ -442,9 +213,8 @@ def __hash__(self): sage: hash(A(G)) == hash(A(H)) False sage: hash(A(H)) == hash(A(K)) - True - sage: A(H) == A(K) False + """ return hash((self._dis, self._dompart)) @@ -464,10 +234,10 @@ def _repr_(self): {((1,2,3,4)(5,6)(7,8)(9,10),): ({}, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10})} """ if self.parent()._arity == 1: - return "{" + f"{self._dis}" + "}" + return "{" + f"{self._dis.gens()}" + "}" dompart = ', '.join("{" + repr(sorted(b))[1:-1] + "}" for b in self._dompart) - return "{" + f"{self._dis}: ({dompart})" + "}" + return "{" + f"{self._dis.gens()}: ({dompart})" + "}" def grade(self): r""" @@ -546,10 +316,10 @@ def _richcmp_(self, other, op): # conjugate self and other to match S g = list(chain.from_iterable(self._dompart)) conj_self = PermutationGroupElement(g).inverse() - G = libgap.ConjugateGroup(self._dis._C, conj_self) + G = libgap.ConjugateGroup(self._dis, conj_self) h = list(chain.from_iterable(other._dompart)) conj_other = PermutationGroupElement(h).inverse() - H = libgap.ConjugateGroup(other._dis._C, conj_other) + H = libgap.ConjugateGroup(other._dis, conj_other) return GAP_FAIL != libgap.ContainedConjugates(S, G, H, True) @@ -603,6 +373,7 @@ def __init__(self, names): Parent.__init__(self, names=names, category=category) self._arity = len(names) self._cache = dict() + self._dis_cache = dict() self._renamed = set() # the degrees that have been renamed already def _repr_(self): @@ -685,7 +456,7 @@ def _element_constructor_(self, G, pi=None): sage: A(G, {0:[1], 1:[2,3,4,5,6]}) Traceback (most recent call last): ... - ValueError: All elements of orbit (1, 2) must have the same sort + ValueError: All elements of orbit [1, 2] must have the same sort sage: A(0) Traceback (most recent call last): @@ -708,17 +479,8 @@ def _element_constructor_(self, G, pi=None): raise ValueError(f"keys of pi (={pi.keys()}) must be in range({self._arity})") if sum(len(p) for p in pi.values()) != len(G.domain()) or set(chain.from_iterable(pi.values())) != set(G.domain()): raise ValueError(f"values of pi (={pi.values()}) must partition the domain of G (={G.domain()})") - for orbit in G.orbits(): - if not any(set(orbit).issubset(p) for p in pi.values()): - raise ValueError(f"All elements of orbit {orbit} must have the same sort") - # TODO: perhaps move to AtomicSpeciesElement.__classcall__ - dis_elm = ConjugacyClassesOfDirectlyIndecomposableSubgroups()(G) - mapping = {v: i for i, v in enumerate(G.domain(), 1)} - sorted_orbits = sorted(G.orbits(), key=len, reverse=True) - mapping2 = PermutationGroupElement([mapping[e] for o in sorted_orbits for e in o]).inverse() - dompart = [frozenset(mapping2(mapping[x]) for x in pi.get(k, [])) - for k in range(self._arity)] - elm = self.element_class(self, dis_elm, tuple(dompart)) + dom_part = [pi.get(s, []) for s in range(self._arity)] + elm = self.element_class(self, G, dom_part) if elm._tc not in self._renamed: self._rename(elm._tc) return elm @@ -1066,12 +828,14 @@ def _element_constructor_(self, G, pi=None): INPUT: - - ``G`` -- element of ``self`` (in this case ``pi`` must be ``None``) - permutation group, or pair ``(X, a)`` consisting of a - finite set and a transitive action - - ``pi`` -- ``dict`` mapping sorts to iterables whose union is the - domain of ``G`` (if ``G`` is a permutation group) or `X` (if ``G`` - is a pair ``(X, a)``); if `k=1`, ``pi`` can be omitted + - ``G`` -- element of ``self`` (in this case ``pi`` must be + ``None``) permutation group, or pair ``(X, a)`` consisting + of a finite set and a transitive action + + - ``pi`` -- ``dict`` mapping sorts to iterables whose union + is the domain of ``G`` (if ``G`` is a permutation group) or + `X` (if ``G`` is a pair ``(X, a)``); if `k=1` and ``G`` is + a permutation group, ``pi`` can be omitted EXAMPLES: @@ -1101,7 +865,7 @@ def _element_constructor_(self, G, pi=None): sage: M(CyclicPermutationGroup(4), {0: [1,2], 1: [3,4]}) Traceback (most recent call last): ... - ValueError: All elements of orbit (1, 2, 3, 4) must have the same sort + ValueError: All elements of orbit [1, 2, 3, 4] must have the same sort sage: G = PermutationGroup([[(2,3),(4,5)]], domain=[2,3,4,5]) sage: M(G, {0: [2, 3], 1: [4, 5]}) @@ -1149,6 +913,7 @@ def _element_constructor_(self, G, pi=None): ... ValueError: 0 must be a permutation group or a pair specifying a group action on the given domain pi=None + """ if parent(G) == self: # pi cannot be None because of framework @@ -1174,7 +939,8 @@ def _element_constructor_(self, G, pi=None): domain=component) dompart = {k: [e for e in v if e in component] for k, v in pi.items()} - elm *= self.gen(self._indices(H, dompart)) + a = self._indices(H, dompart) + elm *= self.gen(a) return elm try: @@ -1457,13 +1223,13 @@ def shift_gens(gens, n): A, n = factors[0] if n == 1: a = list(A._monomial)[0] # as atomic species - return a._dis._C, a._dompart + return a._dis, a._dompart if n % 2 == 1: # split off a single monomial a = list(A._monomial)[0] # as atomic species b, b_dompart = (A ** (n-1)).group_and_partition() - gens = a._dis._C.gens() + shift_gens(b.gens(), a._tc) + gens = a._dis.gens() + shift_gens(b.gens(), a._tc) new_dompart = tuple([frozenset(list(p_a) + [a._tc + e for e in p_b]) for p_a, p_b in zip(a._dompart, b_dompart)]) domain = range(1, n * a._tc + 1) @@ -1623,7 +1389,9 @@ def __call__(self, *args): if not all(isinstance(arg, MolecularSpecies.Element) for arg in args): raise ValueError("all args must be molecular species") - # TODO: What happens if in F(G), G has a constant part? E(1+X)? + # TODO: the case that G in F(G) has a constant part and F + # is a polynomial species is not yet covered - see + # section 4.3 of [ALL2002]_ Mlist = [None for _ in range(sum(self.grade()))] G, dompart = self.group_and_partition() for i, v in enumerate(dompart): @@ -1817,9 +1585,10 @@ def hadamard_product(self, other): # loop over representatives new = P.zero() for tau, _ in taus: - F = libgap.Intersection(libgap.ConjugateGroup(H, tau), G) - new += P(PermutationGroup(gap_group=F, domain=range(1, tc + 1)), - dompart) + G_H = libgap.Intersection(libgap.ConjugateGroup(H, tau), G) + K = PermutationGroup(gap_group=G_H, domain=range(1, tc + 1)) + F = P(K, dompart) + new += F result += c * d * new return result @@ -1956,14 +1725,14 @@ def _compose_with_weighted_singletons(self, names, multiplicities, degrees): """ P = self.parent() if not self.support(): - return P.zero() + return P.zero() # TODO: testme if not self.is_homogeneous(): - raise ValueError("element is not homogeneous") + raise ValueError("element is not homogeneous") # TODO: testme left = self._compose_with_singletons(names, degrees) Pn = left.parent() - right = Pn.exponential(multiplicities, - list(chain.from_iterable(degrees))) + right = Pn._exponential(multiplicities, + list(chain.from_iterable(degrees))) return left.hadamard_product(right) def __call__(self, *args): @@ -2002,13 +1771,13 @@ def __call__(self, *args): """ P = self.parent() if len(args) != P._arity: - raise ValueError("number of args must match arity of self") + raise ValueError("number of args must match arity of self") # TODO: testme if len(set(arg.parent() for arg in args)) > 1: - raise ValueError("all args must have the same parent") + raise ValueError("all args must have the same parent") # TODO: testme P0 = args[0].parent() if not self.support(): - return P0.zero() + return P0.zero() # TODO: testme args = [sorted(g, key=lambda x: x[0].grade()) for g in args] multiplicities = list(chain.from_iterable([[c for _, c in g] for g in args])) @@ -2055,7 +1824,7 @@ def factor(self): factors = poly.factor() unit = self.base_ring()(factors.unit()) if factors.universe() == self.base_ring(): - return Factorization(factors, unit=unit) + return Factorization(factors, unit=unit) # TODO: testme P = self.parent() M = P._indices @@ -2168,11 +1937,26 @@ def _element_constructor_(self, G, pi=None): ....: return next(K for K in X if K == H) sage: P((X, act), {0: range(1, n+1)}) 4*E_4 + 4*P_4 + E_2^2 + 2*X*E_3 + + TESTS:: + + sage: P = PolynomialSpecies(ZZ, "X, Y") + sage: G = PermutationGroup([(1,2), (3,4)]) + sage: P(G) + Traceback (most recent call last): + ... + ValueError: the assignment of sorts to the domain elements must be provided + sage: f = P(G, {0: [1, 2], 1: [3, 4]}) + sage: P(f) is f + True + sage: P(f, {0: [1,2,3,4]}) + Traceback (most recent call last): + ... + ValueError: cannot reassign sorts to a polynomial species """ if parent(G) == self: - if pi is not None: - raise ValueError("cannot reassign sorts to a polynomial species") - return G + # pi cannot be None because of framework + raise ValueError("cannot reassign sorts to a polynomial species") if isinstance(G, PermutationGroup_generic): if pi is None: if self._arity == 1: @@ -2217,6 +2001,11 @@ def change_ring(self, R): sage: P = PolynomialSpecies(ZZ, ["X", "Y"]) sage: P.change_ring(QQ) Polynomial species in X, Y over Rational Field + + TESTS:: + + sage: P.change_ring(ZZ) is P + True """ if R is self.base_ring(): return self @@ -2300,7 +2089,7 @@ def product_on_basis(self, H, K): return self.element_class(self, {H * K: ZZ.one()}) @cached_method - def powersum(self, s, n): + def _powersum(self, s, n): r""" Return the combinatorial powersum species `P_n(X_s)`. @@ -2308,31 +2097,49 @@ def powersum(self, s, n): coefficient of `t^n/n` in `\log E(tX)`, where `E` is the species of sets. + ..TODO:: + + this is really a univariate species, so it would be better + to have a fast way to change all the variables of a + univariate species into a new sort. + EXAMPLES:: sage: from sage.rings.species import PolynomialSpecies sage: P = PolynomialSpecies(ZZ, "X") - sage: P.powersum(0, 4) + sage: P._powersum(0, 4) 4*E_4 - 4*X*E_3 - 2*E_2^2 + 4*X^2*E_2 - X^4 + + TESTS:: + + sage: P._powersum(0, 0) + Traceback (most recent call last): + ... + ValueError: n must be a positive integer + """ - if not (n in ZZ and n > 0): + if n not in ZZ or n <= 0: raise ValueError("n must be a positive integer") if n == 1: return self(SymmetricGroup(1), {s: [1]}) return (ZZ(n) * self(SymmetricGroup(n), {s: range(1, n+1)}) - sum(self(SymmetricGroup(i), {s: range(1, i+1)}) - * self.powersum(s, n-i) + * self._powersum(s, n-i) for i in range(1, n))) - def exponential(self, multiplicities, degrees): + def _exponential(self, multiplicities, degrees): r""" Return `E(\sum_i m_i X_i)` in the specified degrees. + ..TODO:: + + rethink the signature + EXAMPLES:: sage: from sage.rings.species import PolynomialSpecies sage: P = PolynomialSpecies(QQ, ["X"]) - sage: P.exponential([3/2], [7]) + sage: P._exponential([3/2], [7]) 3/2*E_7 + 3/4*X*E_6 + 3/4*E_2*E_5 - 3/16*X^2*E_5 + 3/4*E_3*E_4 - 3/8*X*E_2*E_4 + 3/32*X^3*E_4 - 3/16*X*E_3^2 - 3/16*E_2^2*E_3 + 9/32*X^2*E_2*E_3 - 15/256*X^4*E_3 + 3/32*X*E_2^3 @@ -2342,23 +2149,23 @@ def exponential(self, multiplicities, degrees): sage: R. = QQ[] sage: P = PolynomialSpecies(R, ["X"]) - sage: P.exponential([1], [2]) + sage: P._exponential([1], [2]) E_2 - sage: P.exponential([1+q], [3]) + sage: P._exponential([1+q], [3]) (q^3+1)*E_3 + (q^2+q)*X*E_2 - sage: P.exponential([1-q], [2]) + sage: P._exponential([1-q], [2]) (-q^2+1)*E_2 + (q^2-q)*X^2 sage: P = PolynomialSpecies(R, ["X", "Y"]) - sage: P.exponential([1, q], [2, 2]) + sage: P._exponential([1, q], [2, 2]) q^2*E_2(X)*E_2(Y) TESTS:: sage: P = PolynomialSpecies(QQ, ["X"]) - sage: P.exponential([1], [0]).parent() + sage: P._exponential([1], [0]).parent() Polynomial species in X over Rational Field """ def stretch(c, k): @@ -2379,7 +2186,7 @@ def factor(s, c, d): """ return self.sum(~ mu.centralizer_size() * self.prod(stretch(c, k) - * self.powersum(s, k) for k in mu) + * self._powersum(s, k) for k in mu) for mu in Partitions(d)) return self.prod(factor(s, multiplicities[s], degrees[s]) From c1f528541cee1d54196a585ba5460335237cb85c Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Sat, 26 Oct 2024 20:53:40 +0200 Subject: [PATCH 345/537] allow to skip checks, make variable names more consistent, avoid unneccessary conversions between gap and sage in AtomicSpeciesElement.__classcall__ for performance --- src/sage/rings/species.py | 263 +++++++++++++++++++++----------------- 1 file changed, 149 insertions(+), 114 deletions(-) diff --git a/src/sage/rings/species.py b/src/sage/rings/species.py index c1b0f67f0a3..6653b9fcf57 100644 --- a/src/sage/rings/species.py +++ b/src/sage/rings/species.py @@ -46,10 +46,22 @@ class AtomicSpeciesElement(Element, WithEqualityById, conjugating element. """ @staticmethod - def __classcall__(cls, parent, C, dom_part): + def __classcall__(cls, parent, C, dompart): r""" Normalize the input for unique representation. + INPUT: + + - ``C`` -- a directly indecomposable permutation group + - ``dompart`` -- a `k`-tuple of iterables, where `k` is the + arity, representing the assignment of each element of the + domain of ``dis`` to a sort + + ..WARNING:: + + we do not check whether ``C`` is indeed directly + indecomposable. + TESTS:: sage: from sage.rings.species import AtomicSpecies @@ -102,15 +114,14 @@ def __classcall__(cls, parent, C, dom_part): # a directly indecomposable group has no fixed points, so we # can use the gap group without worrying about the domain G = C.gap() - dom_part = [[ZZ(C._domain_to_gap[e]) for e in b] - for b in dom_part] + dompart = [[ZZ(C._domain_to_gap[e]) for e in b] for b in dompart] orbits = sorted(G.Orbits().sage(), key=len, reverse=True) for orbit in orbits: - if not any(set(orbit).issubset(p) for p in dom_part): + if not any(set(orbit).issubset(p) for p in dompart): o = [C._domain_from_gap[e] for e in orbit] raise ValueError(f"All elements of orbit {o} must have the same sort") - n = C.degree() - S = SymmetricGroup(n) + + S = SymmetricGroup(C.degree()) def new_dis(): """ @@ -118,8 +129,6 @@ def new_dis(): class of subgroups conjugate to ``C``, together with the conjugating map ``mp`` """ - if not n: - return S, PermutationGroupElement([]) # create a group conjugate to `C` whose orbits # consist of contiguous sets of numbers, with larger # orbits having smaller numbers, and compute a small @@ -128,11 +137,12 @@ class of subgroups conjugate to ``C``, together with the H = PermutationGroup(G.SmallGeneratingSet().sage()) return H.conjugate(mp), mp - key = C.cardinality(), tuple(len(o) for o in orbits) + key = G.Size().sage(), tuple([len(o) for o in orbits]) + S_gap = S.gap() if key in parent._dis_cache: lookup_dis = parent._dis_cache[key] for dis in lookup_dis: - mp = libgap.RepresentativeAction(S, G, dis) + mp = libgap.RepresentativeAction(S_gap, G, dis) if mp != GAP_FAIL: break else: @@ -142,8 +152,8 @@ class of subgroups conjugate to ``C``, together with the dis, mp = new_dis() lookup_dis = parent._dis_cache[key] = [dis] - dom_part = [[ZZ(e ** mp) for e in b] for b in dom_part] - mc = tuple([len(b) for b in dom_part]) + dompart = [[ZZ(e ** mp) for e in b] for b in dompart] + mc = tuple([len(b) for b in dompart]) key = mc, dis if key in parent._cache: lookup = parent._cache[key] @@ -151,19 +161,21 @@ class of subgroups conjugate to ``C``, together with the assert len(lookup) == 1 return lookup[0] else: - domain = list(chain(*map(sorted, dom_part))) + domain = list(chain(*map(sorted, dompart))) + dis_gap = dis.gap() + dis_gens = dis_gap.GeneratorsOfGroup() for elm in lookup: # check whether the assignment to sorts given by - # dom_part and by elm._dompart are the same + # dompart and by elm._dompart are the same elm_domain = list(chain(*map(sorted, elm._dompart))) mp = libgap.MappingPermListList(elm_domain, domain) - if all(g ** mp in dis for g in dis.gens()): + if all(g ** mp in dis_gap for g in dis_gens): return elm else: lookup = parent._cache[key] = [] - dom_part = tuple([frozenset(b) for b in dom_part]) - elm = WithPicklingByInitArgs.__classcall__(cls, parent, dis, dom_part) + dompart = tuple([frozenset(b) for b in dompart]) + elm = WithPicklingByInitArgs.__classcall__(cls, parent, dis, dompart) lookup.append(elm) return elm @@ -173,10 +185,10 @@ def __init__(self, parent, dis, domain_partition): INPUT: - - ``dis`` -- :class:`ConjugacyClassOfDirectlyIndecomposableSubgroups` - - ``domain_partition`` -- ``dict`` representing the - assignment of each element of the domain of ``dis`` to - a "variable" + - ``dis`` -- a directly indecomposable permutation group + - ``domain_partition`` -- a `k`-tuple of ``frozenset``s, + where `k` is the arity, representing the assignment of each + element of the domain of ``dis`` to a sort TESTS:: @@ -191,7 +203,7 @@ def __init__(self, parent, dis, domain_partition): Element.__init__(self, parent) self._dis = dis self._dompart = domain_partition - self._mc = tuple(len(v) for v in self._dompart) + self._mc = tuple([len(v) for v in self._dompart]) self._tc = sum(self._mc) def __hash__(self): @@ -353,8 +365,8 @@ def __init__(self, names): INPUT: - - ``names`` -- an iterable of ``k`` strings for the sorts of - the species + - ``names`` -- an iterable of strings for the sorts of the + species TESTS: @@ -392,17 +404,19 @@ def _repr_(self): return f"Atomic species in {self._names[0]}" return f"Atomic species in {', '.join(self._names)}" - def _element_constructor_(self, G, pi=None): + def _element_constructor_(self, G, pi=None, check=True): r""" Construct the `k`-variate atomic species with the given data. INPUT: - - ``G`` -- element of ``self`` (in this case ``pi`` must be ``None``) - or permutation group + - ``G`` -- element of ``self`` (in this case ``pi`` must be + ``None``) or permutation group - ``pi`` -- `k`-tuple or list of iterables or a dict mapping sorts to iterables whose union is the domain; if `k=1`, ``pi`` can be omitted + - ``check`` -- boolean (default: ``True``); skip input + checking if ``False`` EXAMPLES:: @@ -412,11 +426,15 @@ def _element_constructor_(self, G, pi=None): P_5(X) sage: G = PermutationGroup([[(1,2),(3,4,5,6)]]) - sage: A(G, {0: [1,2], 1: [3,4,5,6]}) # random + sage: pi = {0: [1,2], 1: [3,4,5,6]} + sage: a = A(G, pi) # random {((1,2,3,4)(5,6),): ({5, 6}, {1, 2, 3, 4})} - sage: A(G, ([1,2], [3,4,5,6])) # random - {((1,2,3,4)(5,6),): ({5, 6}, {1, 2, 3, 4})} + The assignment of domain elements to sorts can be given as a + tuple:: + + sage: a is A(G, ([1,2], [3,4,5,6])) + True TESTS:: @@ -426,6 +444,17 @@ def _element_constructor_(self, G, pi=None): Test that errors are raised on some possible misuses:: + sage: G = SymmetricGroup(0) + sage: A(G) + Traceback (most recent call last): + ... + ValueError: Symmetric group of order 0! as a permutation group is not directly indecomposable + + sage: A(PermutationGroup([(1,2), (3,4)])) + Traceback (most recent call last): + ... + ValueError: Permutation Group with generators [(3,4), (1,2)] is not directly indecomposable + sage: A = AtomicSpecies("X, Y") sage: G = PermutationGroup([[(1,2), (3,4,5,6)]]) sage: a = A(G, {0:[1,2], 1:[3,4,5,6]}) @@ -463,11 +492,14 @@ def _element_constructor_(self, G, pi=None): ... ValueError: 0 must be a permutation group """ - if parent(G) == self: - # pi cannot be None because of framework - raise ValueError("cannot reassign sorts to an atomic species") - if not isinstance(G, PermutationGroup_generic): - raise ValueError(f"{G} must be a permutation group") + if check: + if parent(G) == self: + # pi cannot be None because of framework + raise ValueError("cannot reassign sorts to an atomic species") + if not isinstance(G, PermutationGroup_generic): + raise ValueError(f"{G} must be a permutation group") + if len(G.disjoint_direct_product_decomposition()) != 1: + raise ValueError(f"{G} is not directly indecomposable") if pi is None: if self._arity == 1: pi = {0: G.domain()} @@ -475,12 +507,14 @@ def _element_constructor_(self, G, pi=None): raise ValueError("the assignment of sorts to the domain elements must be provided") elif not isinstance(pi, dict): pi = {i: v for i, v in enumerate(pi)} - if not set(pi.keys()).issubset(range(self._arity)): - raise ValueError(f"keys of pi (={pi.keys()}) must be in range({self._arity})") - if sum(len(p) for p in pi.values()) != len(G.domain()) or set(chain.from_iterable(pi.values())) != set(G.domain()): - raise ValueError(f"values of pi (={pi.values()}) must partition the domain of G (={G.domain()})") - dom_part = [pi.get(s, []) for s in range(self._arity)] - elm = self.element_class(self, G, dom_part) + if check: + if not set(pi.keys()).issubset(range(self._arity)): + raise ValueError(f"keys of pi (={pi.keys()}) must be in range({self._arity})") + if (sum(len(p) for p in pi.values()) != len(G.domain()) + or set(chain.from_iterable(pi.values())) != set(G.domain())): + raise ValueError(f"values of pi (={pi.values()}) must partition the domain of G (={G.domain()})") + dompart = [pi.get(s, []) for s in range(self._arity)] + elm = self.element_class(self, G, dompart) if elm._tc not in self._renamed: self._rename(elm._tc) return elm @@ -519,8 +553,9 @@ def _rename(self, n): # prevent infinite recursion in self._element_constructor_ self._renamed.add(n) for i in range(self._arity): + pi = {i: range(1, n+1)} if n == 1: - self(SymmetricGroup(1), {i: [1]}).rename(self._names[i]) + self(SymmetricGroup(1), pi, check=False).rename(self._names[i]) if self._arity == 1: sort = "" @@ -528,26 +563,21 @@ def _rename(self, n): sort = f"({self._names[i]})" if n >= 2: - self(SymmetricGroup(n), - {i: range(1, n+1)}).rename(f"E_{n}" + sort) + self(SymmetricGroup(n), pi, check=False).rename(f"E_{n}" + sort) if n >= 3: - self(CyclicPermutationGroup(n), - {i: range(1, n+1)}).rename(f"C_{n}" + sort) + self(CyclicPermutationGroup(n), pi, check=False).rename(f"C_{n}" + sort) if n >= 4: - self(DihedralGroup(n), - {i: range(1, n+1)}).rename(f"P_{n}" + sort) + self(DihedralGroup(n), pi, check=False).rename(f"P_{n}" + sort) if n >= 4: - self(AlternatingGroup(n), - {i: range(1, n+1)}).rename(f"Eo_{n}" + sort) + self(AlternatingGroup(n), pi, check=False).rename(f"Eo_{n}" + sort) if n >= 4 and not n % 2: gens = [[(i, n-i+1) for i in range(1, n//2 + 1)], [(i, i+1) for i in range(1, n, 2)]] - self(PermutationGroup(gens), - {i: range(1, n+1)}).rename(f"Pb_{n}" + sort) + self(PermutationGroup(gens), pi, check=False).rename(f"Pb_{n}" + sort) def __contains__(self, x): r""" @@ -636,7 +666,7 @@ def subset(self, size): result = result.union(self.graded_component(grade)) return result - def graded_component(self, grade): + def graded_component(self, mc): """ Return the set of atomic species with given multicardinality. @@ -649,12 +679,11 @@ def graded_component(self, grade): sage: A.graded_component([2, 3]) # random {{((2,3)(4,5), (1,2,3)): ({4, 5}, {1, 2, 3})}} """ - assert len(grade) == self._arity - n = sum(grade) - S = SymmetricGroup(n).young_subgroup(grade) - dom = S.domain() - dompart = {i: dom[sum(grade[:i]): sum(grade[:i+1])] for i in range(len(grade))} - return Set([self(G, dompart) for G in S.conjugacy_classes_subgroups() + assert len(mc) == self._arity + S = SymmetricGroup(sum(mc)).young_subgroup(mc) + domain = S.domain() + pi = {i: domain[sum(mc[:i]): sum(mc[:i+1])] for i in range(len(mc))} + return Set([self(G, pi, check=False) for G in S.conjugacy_classes_subgroups() if len(G.disjoint_direct_product_decomposition()) <= 1]) @cached_method @@ -822,7 +851,7 @@ def _repr_(self): return f"Molecular species in {self._indices._names[0]}" return f"Molecular species in {', '.join(self._indices._names)}" - def _element_constructor_(self, G, pi=None): + def _element_constructor_(self, G, pi=None, check=True): r""" Construct the `k`-variate molecular species with the given data. @@ -831,11 +860,12 @@ def _element_constructor_(self, G, pi=None): - ``G`` -- element of ``self`` (in this case ``pi`` must be ``None``) permutation group, or pair ``(X, a)`` consisting of a finite set and a transitive action - - ``pi`` -- ``dict`` mapping sorts to iterables whose union is the domain of ``G`` (if ``G`` is a permutation group) or `X` (if ``G`` is a pair ``(X, a)``); if `k=1` and ``G`` is a permutation group, ``pi`` can be omitted + - ``check`` -- boolean (default: ``True``); skip input + checking if ``False`` EXAMPLES: @@ -847,6 +877,9 @@ def _element_constructor_(self, G, pi=None): sage: M(G, {0: [1,2], 1: [3,4]}) E_2(X)*E_2(Y) + sage: M(SymmetricGroup(0)) + 1 + Create a molecular species given an action:: sage: M = MolecularSpecies("X") @@ -923,12 +956,14 @@ def _element_constructor_(self, G, pi=None): if pi is None: if self._arity == 1: pi = {0: G.domain()} + elif not G.degree(): + pi = {} else: raise ValueError("the assignment of sorts to the domain elements must be provided") elif not isinstance(pi, dict): pi = {i: v for i, v in enumerate(pi)} domain = [e for p in pi.values() for e in p] - if len(domain) != len(set(domain)) or set(G.domain()) != set(domain): + if check and len(domain) != len(set(domain)) or set(G.domain()) != set(domain): raise ValueError(f"values of pi (={pi.values()}) must partition the domain of G (={G.domain()})") components = G.disjoint_direct_product_decomposition() elm = self.one() @@ -937,9 +972,9 @@ def _element_constructor_(self, G, pi=None): for gen in G.gens()] H = PermutationGroup([gen for gen in gens if gen], domain=component) - dompart = {k: [e for e in v if e in component] - for k, v in pi.items()} - a = self._indices(H, dompart) + pi_H = {k: [e for e in v if e in component] + for k, v in pi.items()} + a = self._indices(H, pi_H, check=check) elm *= self.gen(a) return elm @@ -947,12 +982,12 @@ def _element_constructor_(self, G, pi=None): X, a = G except TypeError: raise ValueError(f"{G} must be a permutation group or a pair specifying a group action on the given domain pi={pi}") - L = [len(pi.get(i, [])) for i in range(self._arity)] - S = SymmetricGroup(sum(L)).young_subgroup(L) + mc = [len(pi.get(i, [])) for i in range(self._arity)] + S = SymmetricGroup(sum(mc)).young_subgroup(mc) H = _stabilizer_subgroups(S, X, a) if len(H) > 1: raise ValueError("Action is not transitive") - return self(H[0], pi) + return self(H[0], pi, check=check) def grading_set(self): r""" @@ -984,7 +1019,7 @@ def subset(self, size): result = result.union(self.graded_component(grade)) return result - def graded_component(self, grade): + def graded_component(self, mc): """ Return the set of molecular species with given multicardinality. @@ -998,12 +1033,11 @@ def graded_component(self, grade): X*{((1,2)(3,4),): ({1, 2}, {3, 4})}, X*E_2(X)*Y^2, E_3(X)*E_2(Y), C_3(X)*Y^2, C_3(X)*E_2(Y)} """ - assert len(grade) == self._arity - n = sum(grade) - S = SymmetricGroup(n).young_subgroup(grade) - dom = S.domain() - dompart = {i: dom[sum(grade[:i]): sum(grade[:i+1])] for i in range(len(grade))} - return Set([self(G, dompart) for G in S.conjugacy_classes_subgroups()]) + assert len(mc) == self._arity + S = SymmetricGroup(sum(mc)).young_subgroup(mc) + domain = S.domain() + pi = {i: domain[sum(mc[:i]): sum(mc[:i+1])] for i in range(len(mc))} + return Set([self(G, pi, check=False) for G in S.conjugacy_classes_subgroups()]) class Element(IndexedFreeAbelianMonoidElement): def __init__(self, parent, x): @@ -1303,17 +1337,17 @@ def cycle_index(self, parent=None): raise ValueError("`parent` should be a module with basis indexed by partitions") base_ring = parent.base_ring() G, dompart = self.group_and_partition() - dompart_dict = {} + pi = {} for i, s in enumerate(dompart): - dompart_dict.update({e: i for e in s}) + pi.update({e: i for e in s}) - def cycle_type(pi): - tuples = pi.cycle_tuples(singletons=True) + def cycle_type(g): + tuples = g.cycle_tuples(singletons=True) cycle_type = [[] for _ in range(k)] for c in tuples: - cycle_type[dompart_dict[c[0]]].append(len(c)) - return tuple(_Partitions(sorted(c, reverse=True)) - for c in cycle_type) + cycle_type[pi[c[0]]].append(len(c)) + return tuple([_Partitions(sorted(c, reverse=True)) + for c in cycle_type]) return (parent.sum_of_terms([cycle_type(C.an_element()), base_ring(C.cardinality())] @@ -1406,22 +1440,22 @@ def __call__(self, *args): newgen = [] for cyc in gen.cycle_tuples(): for k in range(1, sum(Mlist[cyc[0] - 1].grade()) + 1): - newgen.append(tuple(k + starts[i - 1] for i in cyc)) + newgen.append(tuple([k + starts[i - 1] for i in cyc])) gens.append(newgen) # gens from M_i and dompart P = args[0].parent() - dompart = {i: [] for i in range(P._arity)} + pi = {i: [] for i in range(P._arity)} for start, M in zip(starts, Mlist): K, K_dompart = M.group_and_partition() for i, v in enumerate(K_dompart): - dompart[i].extend([start + k for k in v]) + pi[i].extend([start + k for k in v]) for gen in K.gens(): - gens.append([tuple(start + k for k in cyc) + gens.append([tuple([start + k for k in cyc]) for cyc in gen.cycle_tuples()]) return P(PermutationGroup(gens, domain=range(1, starts[-1] + 1)), - dompart) + pi, check=False) class PolynomialSpeciesElement(CombinatorialFreeModule.Element): @@ -1572,8 +1606,8 @@ def hadamard_product(self, other): g = list(chain.from_iterable(dompart)) conj_L = PermutationGroupElement(g).inverse() G = libgap.ConjugateGroup(G, conj_L) - dompart = {i: range(x - mc[i] + 1, x + 1) - for i, x in enumerate(accumulate(mc))} + pi = {i: range(x - mc[i] + 1, x + 1) + for i, x in enumerate(accumulate(mc))} for R, d in other: if mc != R.grade(): continue @@ -1587,7 +1621,7 @@ def hadamard_product(self, other): for tau, _ in taus: G_H = libgap.Intersection(libgap.ConjugateGroup(H, tau), G) K = PermutationGroup(gap_group=G_H, domain=range(1, tc + 1)) - F = P(K, dompart) + F = P(K, pi, check=False) new += F result += c * d * new @@ -1603,7 +1637,6 @@ def _compose_with_singletons(self, names, args): INPUT: - ``names``, the (flat) list of names of the result - - ``args``, the sequence of `k` compositions, each of which sums to the corresponding degree of ``self``, where `k` is the arity of ``self``. @@ -1646,12 +1679,12 @@ def _compose_with_singletons(self, names, args): # TODO: possibly check that all args are compositions, # and that sums match cardinalities comp = list(chain.from_iterable(args)) - result_dompart = {i: range(x - comp[i] + 1, x + 1) - for i, x in enumerate(accumulate(comp))} + pi = {i: range(x - comp[i] + 1, x + 1) + for i, x in enumerate(accumulate(comp))} S_down = SymmetricGroup(sum(comp)).young_subgroup(comp) - Pn = PolynomialSpecies(self.parent().base_ring(), names) - result = Pn.zero() + P = PolynomialSpecies(self.parent().base_ring(), names) + result = P.zero() for M, c in self: # Create group of the composition # conjugate self.group() so that [1..k] is sort 1, [k+1,..] is sort 2, so on @@ -1665,13 +1698,13 @@ def _compose_with_singletons(self, names, args): taus = libgap.DoubleCosetRepsAndSizes(S_up, S_down, G) # sum over double coset representatives. - summand = Pn.zero() + summand = P.zero() for tau, _ in taus: H = libgap.Intersection(libgap.ConjugateGroup(G, tau.Inverse()), S_down) K = PermutationGroup(gap_group=H, domain=range(1, tc + 1)) - summand += Pn(K, result_dompart) - result += c*summand + summand += P(K, pi, check=False) + result += c * summand return result def _compose_with_weighted_singletons(self, names, multiplicities, degrees): @@ -1723,16 +1756,15 @@ def _compose_with_weighted_singletons(self, names, multiplicities, degrees): sage: (C4+E2^2)._compose_with_weighted_singletons(["X"], [-1], [[4]]) -C_4 + E_2^2 + {((1,2)(3,4),)} - 2*X^2*E_2 + X^4 """ - P = self.parent() if not self.support(): - return P.zero() # TODO: testme + return self.parent().zero() # TODO: testme if not self.is_homogeneous(): raise ValueError("element is not homogeneous") # TODO: testme left = self._compose_with_singletons(names, degrees) - Pn = left.parent() - right = Pn._exponential(multiplicities, - list(chain.from_iterable(degrees))) + P = left.parent() + right = P._exponential(multiplicities, + list(chain.from_iterable(degrees))) return left.hadamard_product(right) def __call__(self, *args): @@ -1895,7 +1927,7 @@ def _repr_(self): return f"Polynomial species in {names[0]} over {self.base_ring()}" return f"Polynomial species in {', '.join(names)} over {self.base_ring()}" - def _element_constructor_(self, G, pi=None): + def _element_constructor_(self, G, pi=None, check=True): r""" Construct the `k`-variate polynomial species with the given data. @@ -1907,6 +1939,9 @@ def _element_constructor_(self, G, pi=None): - ``pi`` -- ``dict`` mapping sorts to iterables whose union is the domain of ``G`` (if ``G`` is a permutation group) or `X` (if ``G`` is a pair ``(X, a)``); if `k=1`, ``pi`` can be omitted + - ``check`` -- boolean (default: ``True``); skip input + checking if ``False`` + EXAMPLES:: @@ -1960,17 +1995,17 @@ def _element_constructor_(self, G, pi=None): if isinstance(G, PermutationGroup_generic): if pi is None: if self._arity == 1: - return self._from_dict({self._indices(G): ZZ.one()}) + return self._from_dict({self._indices(G, check=check): ZZ.one()}) raise ValueError("the assignment of sorts to the domain elements must be provided") elif not isinstance(pi, dict): pi = {i: v for i, v in enumerate(pi)} - return self._from_dict({self._indices(G, pi): ZZ.one()}) + return self._from_dict({self._indices(G, pi, check=check): ZZ.one()}) X, a = G - L = [len(pi.get(i, [])) for i in range(self._arity)] - S = SymmetricGroup(sum(L)).young_subgroup(L) + mc = [len(pi.get(i, [])) for i in range(self._arity)] + S = SymmetricGroup(sum(mc)).young_subgroup(mc) Hs = _stabilizer_subgroups(S, X, a) - return self.sum_of_terms((self._indices(H, pi), ZZ.one()) for H in Hs) + return self.sum_of_terms((self._indices(H, pi, check=check), ZZ.one()) for H in Hs) def _first_ngens(self, n): r""" @@ -1988,8 +2023,8 @@ def _first_ngens(self, n): X + 2*Y """ B = self.basis() - return tuple(B[i] for grade in IntegerVectors(1, length=self._arity) - for i in self._indices.graded_component(grade)) + return tuple([B[i] for grade in IntegerVectors(1, length=self._arity) + for i in self._indices.graded_component(grade)]) def change_ring(self, R): r""" @@ -2121,9 +2156,9 @@ def _powersum(self, s, n): if n not in ZZ or n <= 0: raise ValueError("n must be a positive integer") if n == 1: - return self(SymmetricGroup(1), {s: [1]}) - return (ZZ(n) * self(SymmetricGroup(n), {s: range(1, n+1)}) - - sum(self(SymmetricGroup(i), {s: range(1, i+1)}) + return self(SymmetricGroup(1), {s: [1]}, check=False) + return (ZZ(n) * self(SymmetricGroup(n), {s: range(1, n+1)}, check=False) + - sum(self(SymmetricGroup(i), {s: range(1, i+1)}, check=False) * self._powersum(s, n-i) for i in range(1, n))) From 070a08ea0d24eeb3a8951c4cd42fed3d2bfbeea7 Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Sat, 26 Oct 2024 22:19:44 +0200 Subject: [PATCH 346/537] test sanity of parameters of _compose_with_weighted_singletons --- src/sage/rings/species.py | 105 +++++++++++++++++++++++++++++++------- 1 file changed, 87 insertions(+), 18 deletions(-) diff --git a/src/sage/rings/species.py b/src/sage/rings/species.py index 6653b9fcf57..2723eb5977c 100644 --- a/src/sage/rings/species.py +++ b/src/sage/rings/species.py @@ -226,7 +226,6 @@ def __hash__(self): False sage: hash(A(H)) == hash(A(K)) False - """ return hash((self._dis, self._dompart)) @@ -379,7 +378,6 @@ def __init__(self, names): sage: A2 = AtomicSpecies(["X", "Y"]) sage: TestSuite(A1).run(skip="_test_graded_components") sage: TestSuite(A2).run(skip="_test_graded_components") - """ category = SetsWithGrading().Infinite() Parent.__init__(self, names=names, category=category) @@ -946,7 +944,6 @@ def _element_constructor_(self, G, pi=None, check=True): ... ValueError: 0 must be a permutation group or a pair specifying a group action on the given domain pi=None - """ if parent(G) == self: # pi cannot be None because of framework @@ -1718,10 +1715,17 @@ def _compose_with_weighted_singletons(self, names, multiplicities, degrees): INPUT: - ``names`` -- the (flat) list of names of the result - - ``multiplicities`` -- a (flat) list of constants - - ``degrees`` -- a `k`-tuple of compositions `c_1, - \ldots, c_k`, such that the size of `c_i` is the - degree of ``self`` in sort `i` + - ``multiplicities`` -- a (flat) list of constants, of the + same length as ``names`` + - ``degrees`` -- a `k`-tuple of compositions `c_1, \ldots, + c_k`, such that the size of `c_i` is the degree of ``self`` + in sort `i`, and the total length of the compositions is + the number of names + + ..TODO:: + + once this is thoroughly tested, there should be an + optional keyword parameter to skip the checks EXAMPLES: @@ -1755,11 +1759,51 @@ def _compose_with_weighted_singletons(self, names, multiplicities, degrees): sage: (C4+E2^2)._compose_with_weighted_singletons(["X"], [-1], [[4]]) -C_4 + E_2^2 + {((1,2)(3,4),)} - 2*X^2*E_2 + X^4 + + sage: C4._compose_with_weighted_singletons(["X"], [-1, 0], [[4]]) + Traceback (most recent call last): + ... + ValueError: the number of names must match the number of multiplicities + + sage: C4._compose_with_weighted_singletons(["X"], [-1], [[2,2]]) + Traceback (most recent call last): + ... + ValueError: the total length of the compositions must match the number of names + + sage: C4._compose_with_weighted_singletons(["X"], [-1], [[4], []]) + Traceback (most recent call last): + ... + ValueError: the number of compositions should be the arity of self + + sage: C4._compose_with_weighted_singletons(["X"], [-1], [[3]]) + Traceback (most recent call last): + ... + ValueError: the size of the i-th composition should be the degree in sort i + + sage: P.zero()._compose_with_weighted_singletons(["X"], [-1], [[1]]) + Traceback (most recent call last): + ... + ValueError: the size of the i-th composition should be the degree in sort i, which is zero + + sage: P.zero()._compose_with_weighted_singletons(["X"], [-1], [[0]]) + 0 """ + if len(names) != len(multiplicities): + raise ValueError("the number of names must match the number of multiplicities") + if sum(len(c) for c in degrees) != len(names): + raise ValueError("the total length of the compositions must match the number of names") + P = self.parent() + if len(degrees) != P._arity: + raise ValueError("the number of compositions should be the arity of self") + mc_s = set(m.grade() for m in self.support()) + if len(mc_s) > 1: + raise ValueError("self should be homogeneous with respect to all sorts") if not self.support(): - return self.parent().zero() # TODO: testme - if not self.is_homogeneous(): - raise ValueError("element is not homogeneous") # TODO: testme + if any(sum(c) for c in degrees): + raise ValueError("the size of the i-th composition should be the degree in sort i, which is zero") + return P.zero() + if not all(sum(c) == d for c, d in zip(degrees, list(mc_s)[0])): + raise ValueError("the size of the i-th composition should be the degree in sort i") left = self._compose_with_singletons(names, degrees) P = left.parent() @@ -1800,16 +1844,42 @@ def __call__(self, *args): sage: E2 = P(SymmetricGroup(2)) sage: E2(q*X) q^2*E_2 + + TESTS:: + + sage: P = PolynomialSpecies(QQ, "X") + sage: P.one()() + Traceback (most recent call last): + ... + ValueError: number of args must match arity of self + + sage: P.one()(2) + Traceback (most recent call last): + ... + ValueError: the args must be PolynomialSpecies + + sage: P = PolynomialSpecies(QQ, "X, Y") + sage: Q. = PolynomialSpecies(QQ) + sage: R. = PolynomialSpecies(QQ) + sage: P.one()(X, Y) + Traceback (most recent call last): + ... + ValueError: all args must have the same parent + + sage: P.zero()(X, X) + 0 """ P = self.parent() if len(args) != P._arity: - raise ValueError("number of args must match arity of self") # TODO: testme + raise ValueError("number of args must match arity of self") if len(set(arg.parent() for arg in args)) > 1: - raise ValueError("all args must have the same parent") # TODO: testme + raise ValueError("all args must have the same parent") P0 = args[0].parent() + if not isinstance(P0, PolynomialSpecies): + raise ValueError("the args must be PolynomialSpecies") if not self.support(): - return P0.zero() # TODO: testme + return P0.zero() args = [sorted(g, key=lambda x: x[0].grade()) for g in args] multiplicities = list(chain.from_iterable([[c for _, c in g] for g in args])) @@ -1818,10 +1888,10 @@ def __call__(self, *args): names = ["X%s" % i for i in range(sum(len(arg) for arg in args))] result = P0.zero() - for n in F_degrees: - F = P.sum_of_terms((M, c) for M, c in self if M.grade() == n) - for degrees in cartesian_product([IntegerVectors(n_i, length=len(arg)) - for n_i, arg in zip(n, args)]): + for mc in F_degrees: + F = P.sum_of_terms((M, c) for M, c in self if M.grade() == mc) + for degrees in cartesian_product([IntegerVectors(d, length=len(arg)) + for d, arg in zip(mc, args)]): # each degree is a weak composition of the degree of F in sort i FX = F._compose_with_weighted_singletons(names, multiplicities, @@ -2151,7 +2221,6 @@ def _powersum(self, s, n): Traceback (most recent call last): ... ValueError: n must be a positive integer - """ if n not in ZZ or n <= 0: raise ValueError("n must be a positive integer") From 96a5aa02be3f66c4f4a8997ce1088511f2eea28c Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Sat, 26 Oct 2024 22:26:06 +0200 Subject: [PATCH 347/537] add doctest, remove dead code discovered by codecov --- src/sage/rings/species.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/sage/rings/species.py b/src/sage/rings/species.py index 2723eb5977c..adf01c222ff 100644 --- a/src/sage/rings/species.py +++ b/src/sage/rings/species.py @@ -1914,6 +1914,11 @@ def factor(self): sage: f = (3*E2*X + C3)*(2*E2 + C3) sage: factor(f) (2*E_2 + C_3) * (3*X*E_2 + C_3) + + TESTS:: + + sage: P(6).factor() + 2 * 3 """ # find the set of atoms and fix an order atoms = list(set(a for m in self.monomial_coefficients() @@ -1925,8 +1930,6 @@ def factor(self): for m, c in self) factors = poly.factor() unit = self.base_ring()(factors.unit()) - if factors.universe() == self.base_ring(): - return Factorization(factors, unit=unit) # TODO: testme P = self.parent() M = P._indices From 7721794232a3f5ba542018a225e28dc71d959cba Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Sat, 26 Oct 2024 22:28:13 +0200 Subject: [PATCH 348/537] rename group_and_partition to permutation_group --- src/sage/rings/species.py | 42 +++++++++++++++++++-------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/src/sage/rings/species.py b/src/sage/rings/species.py index adf01c222ff..a7933089b77 100644 --- a/src/sage/rings/species.py +++ b/src/sage/rings/species.py @@ -1160,18 +1160,18 @@ def _richcmp_(self, other, op): S = SymmetricGroup(sum(self.grade())).young_subgroup(self.grade()) # conjugate self and other to match S - G, G_dompart = self.group_and_partition() + G, G_dompart = self.permutation_group() g = list(chain.from_iterable(G_dompart)) conj_self = PermutationGroupElement(g).inverse() G = libgap.ConjugateGroup(G, conj_self) - H, H_dompart = other.group_and_partition() + H, H_dompart = other.permutation_group() h = list(chain.from_iterable(H_dompart)) conj_other = PermutationGroupElement(h).inverse() H = libgap.ConjugateGroup(H, conj_other) return GAP_FAIL != libgap.ContainedConjugates(S, G, H, True) @cached_method - def group_and_partition(self): + def permutation_group(self): r""" Return the (transitive) permutation group corresponding to ``self``, together with the partition of @@ -1184,7 +1184,7 @@ def group_and_partition(self): sage: G = PermutationGroup([[(1,2),(3,4)], [(5,6)]]) sage: A = M(G, {0: [5,6], 1: [1,2,3,4]}); A E_2(X)*{((1,2)(3,4),): ({}, {1, 2, 3, 4})} - sage: A.group_and_partition() + sage: A.permutation_group() (Permutation Group with generators [(3,4)(5,6), (1,2)], (frozenset({1, 2}), frozenset({3, 4, 5, 6}))) @@ -1194,14 +1194,14 @@ def group_and_partition(self): sage: A = M(PermutationGroup([(3,4)]), {0:[1,3,4], 1:[2]}) sage: A X*Y*E_2(X) - sage: A.group_and_partition()[1] + sage: A.permutation_group()[1] (frozenset({1, 3, 4}), frozenset({2})) TESTS:: sage: B = M(PermutationGroup([(1,2,3)]), {0: [1,2,3]}); B C_3(X) - sage: B.group_and_partition() + sage: B.permutation_group() (Permutation Group with generators [(1,2,3)], (frozenset({1, 2, 3}), frozenset())) @@ -1209,31 +1209,31 @@ def group_and_partition(self): sage: A = M(G, {0: [5,6], 1: [1,2,3,4]}) sage: A * B E_2(X)*C_3(X)*{((1,2)(3,4),): ({}, {1, 2, 3, 4})} - sage: (A*B).group_and_partition() + sage: (A*B).permutation_group() (Permutation Group with generators [(6,7)(8,9), (3,4,5), (1,2)], (frozenset({1, 2, 3, 4, 5}), frozenset({6, 7, 8, 9}))) sage: C = M(PermutationGroup([(2,3)]), {0: [1], 1: [2,3]}); C X*E_2(Y) - sage: C.group_and_partition() + sage: C.permutation_group() (Permutation Group with generators [(2,3)], (frozenset({1}), frozenset({2, 3}))) - sage: (C^3).group_and_partition() + sage: (C^3).permutation_group() (Permutation Group with generators [(8,9), (6,7), (4,5)], (frozenset({1, 2, 3}), frozenset({4, 5, 6, 7, 8, 9}))) sage: M = MolecularSpecies("X") sage: F = M(SymmetricGroup(1)) * M(SymmetricGroup(2)) - sage: F.group_and_partition() + sage: F.permutation_group() (Permutation Group with generators [(2,3)], (frozenset({1, 2, 3}),)) sage: F = M(PermutationGroup([(1,2),(3,)])) - sage: F.group_and_partition()[0].domain() + sage: F.permutation_group()[0].domain() {1, 2, 3} sage: F = M(AlternatingGroup(2)) - sage: F.group_and_partition()[0].domain() + sage: F.permutation_group()[0].domain() {1, 2} """ def shift_gens(gens, n): @@ -1259,13 +1259,13 @@ def shift_gens(gens, n): if n % 2 == 1: # split off a single monomial a = list(A._monomial)[0] # as atomic species - b, b_dompart = (A ** (n-1)).group_and_partition() + b, b_dompart = (A ** (n-1)).permutation_group() gens = a._dis.gens() + shift_gens(b.gens(), a._tc) new_dompart = tuple([frozenset(list(p_a) + [a._tc + e for e in p_b]) for p_a, p_b in zip(a._dompart, b_dompart)]) domain = range(1, n * a._tc + 1) else: - f, f_dompart = (A ** (n // 2)).group_and_partition() + f, f_dompart = (A ** (n // 2)).permutation_group() tc = sum(len(p) for p in f_dompart) gens = f.gens() + shift_gens(f.gens(), tc) new_dompart = tuple([frozenset(list(p) + [tc + e for e in p]) @@ -1275,7 +1275,7 @@ def shift_gens(gens, n): G = PermutationGroup(gens, domain=domain) return G, new_dompart - f_dompart_list = [(A ** n).group_and_partition() for A, n in factors] + f_dompart_list = [(A ** n).permutation_group() for A, n in factors] f_list = [f for f, _ in f_dompart_list] dompart_list = [f_dompart for _, f_dompart in f_dompart_list] tc_list = list(accumulate([sum(len(p) for p in f_dompart) @@ -1333,7 +1333,7 @@ def cycle_index(self, parent=None): elif parent not in Modules.WithBasis: raise ValueError("`parent` should be a module with basis indexed by partitions") base_ring = parent.base_ring() - G, dompart = self.group_and_partition() + G, dompart = self.permutation_group() pi = {} for i, s in enumerate(dompart): pi.update({e: i for e in s}) @@ -1424,7 +1424,7 @@ def __call__(self, *args): # is a polynomial species is not yet covered - see # section 4.3 of [ALL2002]_ Mlist = [None for _ in range(sum(self.grade()))] - G, dompart = self.group_and_partition() + G, dompart = self.permutation_group() for i, v in enumerate(dompart): for k in v: Mlist[k - 1] = args[i] @@ -1444,7 +1444,7 @@ def __call__(self, *args): P = args[0].parent() pi = {i: [] for i in range(P._arity)} for start, M in zip(starts, Mlist): - K, K_dompart = M.group_and_partition() + K, K_dompart = M.permutation_group() for i, v in enumerate(K_dompart): pi[i].extend([start + k for k in v]) for gen in K.gens(): @@ -1599,7 +1599,7 @@ def hadamard_product(self, other): tc = sum(mc) S = SymmetricGroup(tc).young_subgroup(mc) # conjugate L and R to match S - G, dompart = L.group_and_partition() + G, dompart = L.permutation_group() g = list(chain.from_iterable(dompart)) conj_L = PermutationGroupElement(g).inverse() G = libgap.ConjugateGroup(G, conj_L) @@ -1608,7 +1608,7 @@ def hadamard_product(self, other): for R, d in other: if mc != R.grade(): continue - G_R, dompart_R = R.group_and_partition() + G_R, dompart_R = R.permutation_group() g = list(chain.from_iterable(dompart_R)) conj_R = PermutationGroupElement(g).inverse() H = libgap.ConjugateGroup(G_R, conj_R) @@ -1685,7 +1685,7 @@ def _compose_with_singletons(self, names, args): for M, c in self: # Create group of the composition # conjugate self.group() so that [1..k] is sort 1, [k+1,..] is sort 2, so on - G, dompart = M.group_and_partition() + G, dompart = M.permutation_group() conj = PermutationGroupElement(list(chain.from_iterable(dompart))).inverse() G = libgap.ConjugateGroup(G, conj) From 0c49f2b43770aef87acbde35c53ae0aa23e98771 Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Sun, 27 Oct 2024 09:20:48 +0100 Subject: [PATCH 349/537] add example and test for _compose_with_weighted_singletons for 100% coverage --- src/sage/rings/species.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/sage/rings/species.py b/src/sage/rings/species.py index a7933089b77..669aba74a34 100644 --- a/src/sage/rings/species.py +++ b/src/sage/rings/species.py @@ -1755,6 +1755,17 @@ def _compose_with_weighted_singletons(self, names, multiplicities, degrees): sage: C4._compose_with_weighted_singletons(["X", "Y"], [1, -1], [[2, 2]]) -E_2(XY) + 2*X^2*Y^2 + A bivariate example:: + + sage: P. = PolynomialSpecies(QQ) + sage: F = E2(X)*E2(Y) + X^2*Y^2 + sage: F._compose_with_weighted_singletons(["X0", "X1", "Y0"], [1, 1, 1], [[1, 1], [2]]) + X0*X1*E_2(Y0) + 2*X0*X1*Y0^2 + + sage: Q. = PolynomialSpecies(QQ) + sage: F(X0 + X1, Y0) + E_2(X0)*E_2(Y0) + X0^2*Y0^2 + X0*X1*E_2(Y0) + 2*X0*X1*Y0^2 + E_2(X1)*E_2(Y0) + X1^2*Y0^2 + TESTS:: sage: (C4+E2^2)._compose_with_weighted_singletons(["X"], [-1], [[4]]) @@ -1780,6 +1791,7 @@ def _compose_with_weighted_singletons(self, names, multiplicities, degrees): ... ValueError: the size of the i-th composition should be the degree in sort i + sage: P = PolynomialSpecies(QQ, "X") sage: P.zero()._compose_with_weighted_singletons(["X"], [-1], [[1]]) Traceback (most recent call last): ... @@ -1787,6 +1799,12 @@ def _compose_with_weighted_singletons(self, names, multiplicities, degrees): sage: P.zero()._compose_with_weighted_singletons(["X"], [-1], [[0]]) 0 + + sage: P. = PolynomialSpecies(QQ) + sage: (X^2*Y + X*Y^2)._compose_with_weighted_singletons(["X0", "X1"], [1, 1], [[2], [1]]) + Traceback (most recent call last): + ... + ValueError: self should be homogeneous with respect to all sorts """ if len(names) != len(multiplicities): raise ValueError("the number of names must match the number of multiplicities") From 6755330f4c95c0908c42876a7846b00773e60944 Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Sun, 27 Oct 2024 09:40:33 +0100 Subject: [PATCH 350/537] show construction of table of marks --- src/sage/rings/species.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/sage/rings/species.py b/src/sage/rings/species.py index 669aba74a34..e653e149fde 100644 --- a/src/sage/rings/species.py +++ b/src/sage/rings/species.py @@ -1577,6 +1577,16 @@ def hadamard_product(self, other): sage: C3.hadamard_product(E2^2) 0 + We can create the table of marks for the symmetric group:: + + sage: E3 = P(SymmetricGroup(3)) + sage: C = [X^3, X*E2, C3, E3] + sage: table([(b, [(a.hadamard_product(b)).coefficient(b.support()[0]) for a in C]) for b in C]) + X^3 [6, 3, 2, 1] + X*E_2 [0, 1, 0, 1] + C_3 [0, 0, 2, 1] + E_3 [0, 0, 0, 1] + TESTS:: sage: C3.hadamard_product(-C3) From 905079c1180ebb0b1dcbf215514de906c8e6d8bb Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Sun, 27 Oct 2024 11:59:17 +0100 Subject: [PATCH 351/537] remove hash by switching inheritance order, replace richcmp with lt and le --- src/sage/rings/species.py | 85 +++++++++++++++------------------------ 1 file changed, 32 insertions(+), 53 deletions(-) diff --git a/src/sage/rings/species.py b/src/sage/rings/species.py index e653e149fde..13a1b6e70fd 100644 --- a/src/sage/rings/species.py +++ b/src/sage/rings/species.py @@ -35,7 +35,8 @@ GAP_FAIL = libgap.eval('fail') -class AtomicSpeciesElement(Element, WithEqualityById, +class AtomicSpeciesElement(WithEqualityById, + Element, WithPicklingByInitArgs, metaclass=InheritComparisonClasscallMetaclass): r""" @@ -206,29 +207,6 @@ def __init__(self, parent, dis, domain_partition): self._mc = tuple([len(v) for v in self._dompart]) self._tc = sum(self._mc) - def __hash__(self): - """ - Return a hash of ``self``. - - ..TODO:: - - Why does the hash not come from - :class:`~sage.misc.fast_methods.WithEqualityById`? - - EXAMPLES:: - - sage: from sage.rings.species import AtomicSpecies - sage: A = AtomicSpecies("X") - sage: G = PermutationGroup([[(1,2),(3,4)]]) - sage: H = PermutationGroup([[(1,3),(2,4)], [(1,2),(3,4)]]) - sage: K = PermutationGroup([[(1,2,3,4)]]) - sage: hash(A(G)) == hash(A(H)) - False - sage: hash(A(H)) == hash(A(K)) - False - """ - return hash((self._dis, self._dompart)) - def _repr_(self): r""" Return a string representation of ``self``. @@ -266,10 +244,9 @@ def grade(self): S = self.parent().grading_set() return S(self._mc) - def _richcmp_(self, other, op): + def __lt__(self, other): r""" - Compare ``self`` with ``other`` with respect to the comparison - operator ``op``. + Return whether ``self`` is less than ``other``. ``self`` is less than or equal to ``other`` if it is conjugate to a subgroup of ``other`` in the parent group. @@ -306,32 +283,34 @@ def _richcmp_(self, other, op): sage: [(a, b) for a, b in Subsets(A.subset(3), 2) if (a < b) != (b > a)] [] """ - if op is op_EQ: - return self is other - if op is op_NE: - return self is not other - if op is op_LE: - return self is other or self < other - if op is op_GE: - return other <= self - if op is op_GT: - return other < self - if op is op_LT: - # the arities match because the parents are equal - if self._mc != other._mc: - # X should come before Y - return (sum(self._mc) < sum(other._mc) - or (sum(self._mc) == sum(other._mc) - and self._mc > other._mc)) - S = SymmetricGroup(sum(self._mc)).young_subgroup(self._mc) - # conjugate self and other to match S - g = list(chain.from_iterable(self._dompart)) - conj_self = PermutationGroupElement(g).inverse() - G = libgap.ConjugateGroup(self._dis, conj_self) - h = list(chain.from_iterable(other._dompart)) - conj_other = PermutationGroupElement(h).inverse() - H = libgap.ConjugateGroup(other._dis, conj_other) - return GAP_FAIL != libgap.ContainedConjugates(S, G, H, True) + # the arities match because the parents are equal + if self._mc != other._mc: + # X should come before Y + return (sum(self._mc) < sum(other._mc) + or (sum(self._mc) == sum(other._mc) + and self._mc > other._mc)) + S = SymmetricGroup(sum(self._mc)).young_subgroup(self._mc) + # conjugate self and other to match S + g = list(chain.from_iterable(self._dompart)) + conj_self = PermutationGroupElement(g).inverse() + G = libgap.ConjugateGroup(self._dis, conj_self) + h = list(chain.from_iterable(other._dompart)) + conj_other = PermutationGroupElement(h).inverse() + H = libgap.ConjugateGroup(other._dis, conj_other) + return GAP_FAIL != libgap.ContainedConjugates(S, G, H, True) + + def __le__(self, other): + r""" + Return whether ``self`` is less than or equal to ``other``. + + EXAMPLES:: + + sage: from sage.rings.species import AtomicSpecies + sage: A = AtomicSpecies("X") + sage: A(SymmetricGroup(3)) <= A(SymmetricGroup(3)) + True + """ + return self is other or self < other class AtomicSpecies(UniqueRepresentation, Parent): From c595f4343d9600b7457f89171840e341bdcf6eda Mon Sep 17 00:00:00 2001 From: janmenjayap Date: Sun, 27 Oct 2024 17:09:07 +0530 Subject: [PATCH 352/537] updated the code and the doc --- src/sage/graphs/matching_covered_graph.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/sage/graphs/matching_covered_graph.py b/src/sage/graphs/matching_covered_graph.py index b2c6822ba0d..f54827cd541 100644 --- a/src/sage/graphs/matching_covered_graph.py +++ b/src/sage/graphs/matching_covered_graph.py @@ -451,7 +451,7 @@ class MatchingCoveredGraph(Graph): sage: G = MatchingCoveredGraph(D) Traceback (most recent call last): ... - ValueError: input data is of unknown type + TypeError: input data is of unknown type """ def __init__(self, data=None, matching=None, algorithm='Edmonds', @@ -522,7 +522,7 @@ def __init__(self, data=None, matching=None, algorithm='Edmonds', self._matching = Graph(self).matching() else: - raise ValueError('input data is of unknown type') + raise TypeError('input data is of unknown type') def __repr__(self): r""" @@ -791,11 +791,12 @@ def add_edge(self, u, v=None, label=None): # TODO: A ligher incremental method to check whether the new graph # is matching covered instead of creating a new graph and checking - G = Graph(self) + G = Graph(self, multiedges=self.allows_multiple_edges()) G.add_edge(u, v, label=label) try: self.__init__(data=G, matching=self.get_matching()) + except Exception: raise ValueError('the graph obtained after the addition of ' 'edge (%s) is not matching covered' @@ -1122,7 +1123,7 @@ def delete_vertices(self, vertices): raise ValueError('vertex (%s) not in the graph' % str(vertex)) try: - G = Graph(self, multiedges=False) + G = Graph(self, multiedges=self.allows_multiple_edges()) G.delete_vertices(vertices) M = Graph(self.get_matching()) From 5b79644b44cd666649129ccc3c97115917baad47 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Sun, 27 Oct 2024 17:14:43 +0530 Subject: [PATCH 353/537] Changed index.rst for matroids --- src/doc/en/reference/matroids/index.rst | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/doc/en/reference/matroids/index.rst b/src/doc/en/reference/matroids/index.rst index 59453ff2fdc..284caabe8d0 100644 --- a/src/doc/en/reference/matroids/index.rst +++ b/src/doc/en/reference/matroids/index.rst @@ -34,6 +34,15 @@ Concrete implementations sage/matroids/rank_matroid sage/matroids/graphic_matroid +Chow rings of matroids +---------------------- + +.. toctree:: + :maxdepth: 1 + + sage/matroids/chow_ring_ideal + sage/matroids/chow_ring + Abstract matroid classes ------------------------ @@ -65,13 +74,4 @@ Internals sage/matroids/set_system sage/matroids/unpickling -Chow rings of matroids ----------------------- - -.. toctree:: - :maxdepth: 1 - - sage/matroids/chow_ring_ideal - sage/matroids/chow_ring - .. include:: ../footer.txt From ef66f81ff09f903723d741e7b7ac9a81a30e2ce1 Mon Sep 17 00:00:00 2001 From: janmenjayap Date: Sun, 27 Oct 2024 17:14:49 +0530 Subject: [PATCH 354/537] added add_edges() --- src/sage/graphs/matching_covered_graph.py | 265 ++++++++++++++++++++++ 1 file changed, 265 insertions(+) diff --git a/src/sage/graphs/matching_covered_graph.py b/src/sage/graphs/matching_covered_graph.py index f54827cd541..e33fb6e656c 100644 --- a/src/sage/graphs/matching_covered_graph.py +++ b/src/sage/graphs/matching_covered_graph.py @@ -810,6 +810,271 @@ def add_edge(self, u, v=None, label=None): '(%s) is not matching covered' % str((u, v, label))) + def add_edges(self, edges, loops=False): + r""" + Add edges from an iterable container. + + .. NOTE:: + + This method overwrites the + :meth:`~sage.graphs.generic_graph.GenericGraph.add_edges` method + to ensure that resultant graph is also matching covered. + + INPUT: + + - ``edges`` -- an iterable of edges, given either as ``(u, v)`` + or ``(u, v, 'label')`` + + - ``loops`` -- boolean (default: ``False``); note that this shall + always be set to either ``False`` or ``None`` (since matching covered + graphs are free of loops), in which case all the loops + ``(v, v, 'label')`` are removed from the iterator. If ``loops`` is + set to ``True``, a :exc:`ValueError` is thrown. + + OUTPUT: + + - If ``loops`` is set to ``True``, a :exc:`ValueError` is returned. + + - If ``edges`` is provided with a valid format, but addition of the + edges leave the resulting graph not being matching covered, a + :exc:`ValueError` is returned without any alteration to the existing + matching covered graph. If the addition of the edges preserves the + property of matching covered, then the graph is updated and nothing + is returned. + + - If ``edges`` is provided with an invalid format, a :exc:`ValueError` + is returned. + + EXAMPLES: + + Adding some edges, the incident vertices of each of which are existent, + such that the resulting graph is matching covered:: + + sage: S = graphs.StaircaseGraph(4) + sage: G = MatchingCoveredGraph(S) + sage: F = [(0, 4), (2, 4), (4, 6), (4, 7)] + sage: G.add_edges(F) + sage: G.edges(sort=True) + [(0, 1, None), (0, 3, None), (0, 4, None), (0, 6, None), + (1, 2, None), (1, 4, None), (2, 4, None), (2, 5, None), + (2, 7, None), (3, 4, None), (3, 6, None), (4, 5, None), + (4, 6, None), (4, 7, None), (5, 7, None), (6, 7, None)] + + Adding some edges, at least one of the incident vertices of some of + which are nonexistent such that the resulting graph is matching + covered:: + + sage: C = graphs.CycleGraph(8) + sage: G = MatchingCoveredGraph(C) + sage: F = [(0, 9), (1, 8), (2, 9), (3, 8), + ....: (4, 9), (5, 8), (6, 9), (7, 8)] + sage: G.add_edges(F) + sage: G.edges(sort=True) + [(0, 1, None), (0, 7, None), (0, 9, None), (1, 2, None), + (1, 8, None), (2, 3, None), (2, 9, None), (3, 4, None), + (3, 8, None), (4, 5, None), (4, 9, None), (5, 6, None), + (5, 8, None), (6, 7, None), (6, 9, None), (7, 8, None)] + sage: G.is_isomorphic(graphs.BiwheelGraph(5)) + True + + Adding a removable double ear to a matching covered graph:: + + sage: H = graphs.HexahedralGraph() + sage: G = MatchingCoveredGraph(H) + sage: F = {(0, 8, None), (1, 10), (4, 11, 'label'), + ....: (5, 9), (8, 9), (10, 11)} + sage: G.add_edges(F) + sage: G.edges(sort=True) + [(0, 1, None), (0, 3, None), (0, 4, None), (0, 8, None), + (1, 2, None), (1, 5, None), (1, 10, None), (2, 3, None), + (2, 6, None), (3, 7, None), (4, 5, None), (4, 7, None), + (4, 11, 'label'), (5, 6, None), (5, 9, None), (6, 7, None), + (8, 9, None), (10, 11, None)] + + Adding some edges, the incident vertices of each of which are existent, + such that the resulting graph is NOT matching covered:: + + sage: C = graphs.CycleGraph(6) + sage: G = MatchingCoveredGraph(C) + sage: F = [(0, 2), (3, 5)] + sage: G.add_edges(F) + Traceback (most recent call last): + ... + ValueError: the resulting graph after the addition ofthe edges is not matching covered + + Adding some edges, at least one of the incident vertices of some of + which are nonexistent such that the resulting graph is NOT matching + covered:: + + sage: H = graphs.HexahedralGraph() + sage: G = MatchingCoveredGraph(H) + sage: F = {(0, 5), (2, 7)} + sage: G.add_edges(F) + Traceback (most recent call last): + ... + ValueError: the resulting graph after the addition ofthe edges is not matching covered + sage: J = [(u, 8) for u in range(8)] + sage: G.add_edges(J) + Traceback (most recent call last): + ... + ValueError: odd order is not allowed for matching covered graphs + + Setting the parameter ``loops`` to either ``False`` or ``None``:: + + sage: W = graphs.WheelGraph(6) + sage: G = MatchingCoveredGraph(W) + sage: F = [(0, 0), (1, 3), (2, 4)] + sage: G.add_edges(edges=F, loops=False) + sage: G.edges(sort=True) + [(0, 1, None), (0, 2, None), (0, 3, None), (0, 4, None), + (0, 5, None), (1, 2, None), (1, 3, None), (1, 5, None), + (2, 3, None), (2, 4, None), (3, 4, None), (4, 5, None)] + sage: J = [(1, 1), (3, 5)] + sage: G.add_edges(edges=J, loops=True) + Traceback (most recent call last): + ... + ValueError: loops are not allowed in matching covered graphs + sage: G.edges(sort=True) + [(0, 1, None), (0, 2, None), (0, 3, None), (0, 4, None), + (0, 5, None), (1, 2, None), (1, 3, None), (1, 5, None), + (2, 3, None), (2, 4, None), (3, 4, None), (4, 5, None)] + + Setting the parameter ``loops`` to ``True``:: + + sage: P = graphs.PetersenGraph() + sage: G = MatchingCoveredGraph(P) + sage: F = [(0, 0), (0, 2), (0, 3)] + sage: G.add_edges(edges=F, loops=True) + Traceback (most recent call last): + ... + ValueError: loops are not allowed in matching covered graphs + + Adding a multiple edge:: + + sage: S = graphs.StaircaseGraph(4) + sage: G = MatchingCoveredGraph(S) + sage: G.allow_multiple_edges(True) + sage: F = [(0, 1, 'label'), (0, 4), (1, 2)] + sage: G.add_edges(F) + sage: G.edges(sort=False) + [(0, 1, None), (0, 1, 'label'), (0, 3, None), (0, 4, None), + (0, 6, None), (1, 2, None), (1, 2, None), (1, 4, None), + (2, 5, None), (2, 7, None), (3, 4, None), (3, 6, None), + (4, 5, None), (5, 7, None), (6, 7, None)] + + TESTS: + + Providing with an edge in ``edges`` that has 0 values to unpack:: + + sage: W = graphs.WagnerGraph() + sage: G = MatchingCoveredGraph(W) + sage: G.add_edges([()]) + Traceback (most recent call last): + ... + ValueError: need more than 0 values to unpack + + Providing with an edge in ``edges`` that has precisely one value to unpack:: + + sage: T = graphs.TruncatedBiwheelGraph(10) + sage: G = MatchingCoveredGraph(T) + sage: G.add_edges([(0, )]) + Traceback (most recent call last): + ... + ValueError: need more than 1 value to unpack + + Providing with an edge in ``edges`` that has more than 3 values to unpack:: + + sage: B = graphs.BiwheelGraph(5) + sage: G = MatchingCoveredGraph(B) + sage: G.add_edges([(0, 1, 2, 3, 4)]) + Traceback (most recent call last): + ... + ValueError: too many values to unpack (expected 2) + + Providing with an edge of unknown data type:: + + sage: M = graphs.MurtyGraph() + sage: G = MatchingCoveredGraph(M) + sage: F = ['', 'edge', None, 1234] + sage: G.add_edges(F) + Traceback (most recent call last): + ... + TypeError: input edges is of unknown type + """ + if loops: + raise ValueError('loops are not allowed in ' + 'matching covered graphs') + + for edge in edges: + if isinstance(edge, tuple): + if len(edge) == 0: + raise ValueError('need more than 0 values to unpack') + + elif len(edge) == 1: + raise ValueError('need more than 1 value to unpack') + + elif len(edge) > 3: + raise ValueError('too many values to unpack (expected 2)') + + else: + raise TypeError('input edges is of unknown type') + + # Remove potentially duplicated edges + edges = list(set(edges)) + + # Remove all the loops from edges + for edge in edges: + if edge[0] == edge[1]: + edges.remove(edge) + + # Check if all the incident vertices of the input edges are existent + new_vertices = list(set([x for u, v, *_ in edges for x in [u, v]])) + + for vertex in new_vertices[:]: + if vertex in self: + new_vertices.remove(vertex) + + # Throw error if the no. of new vertices is odd + if len(new_vertices)%2: + raise ValueError('odd order is not allowed for ' + 'matching covered graphs') + + try: + G = Graph(self, multiedges=self.allows_multiple_edges()) + G.add_edges(edges=edges, loops=loops) + + # Check if G has a vertex with at most 1 neighbor + if any(len(G.neighbors(v)) <= 1 for v in G): + raise ValueError('the resulting graph after the addition of' + 'the edges is not matching covered') + + # If all the vertices are existent, the existing perfect matching + # can be used. + if not new_vertices: + self.__init__(data=G, matching=self.get_matching()) + + else: + # Check if the existing perfect matching may be extended to a + # perfect matching of the new graph + edges_with_two_new_vertices = [] + + for edge in edges: + if edge[0] in new_vertices and edge[1] in new_vertices: + edges_with_two_new_vertices.append(edge) + + H = Graph(data=edges_with_two_new_vertices, format='list_of_edges') + M = Graph(self.get_matching()).union(Graph(H.matching())) + + # Check if M is a perfect matching of the resulting graph + if (G.order() != 2*M.size()): + M = None + + self.__init__(data=G, matching=M) + + except Exception: + raise ValueError('the resulting graph after the addition of' + 'the edges is not matching covered') + def add_vertex(self, name=None): r""" Add a vertex to the (matching covered) graph. From 2a5f0cabbafac3a1da346060880c12ddafe5d709 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Sun, 27 Oct 2024 17:19:28 +0530 Subject: [PATCH 355/537] Changed Documentation for augmented Chow rings definition --- src/sage/matroids/chow_ring.py | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/sage/matroids/chow_ring.py b/src/sage/matroids/chow_ring.py index ba668f4ad4a..063cf6416ca 100644 --- a/src/sage/matroids/chow_ring.py +++ b/src/sage/matroids/chow_ring.py @@ -26,26 +26,28 @@ class ChowRing(QuotientRing_generic): where `(I_M + J_M)` is the :class:`Chow ring ideal ` of matroid `M`. - The *augmented Chow ring of matroid* `M` in the Feitchner-Yuzvinsky - presentation is the quotient ring + The *augmented Chow ring of matroid* `M` has two different presentations + as quotient rings: + + The *Feitchner-Yuzvinsky presentation* is the quotient ring .. MATH:: A(M)_R := R[y_{e_1}, \ldots, y_{e_n}, x_{F_1}, \ldots, x_{F_k}] / I_{FY}(M), - where `I_{FY}(M)` is the :class:`augmented Chow ring ideal - ` of matroid `M` - in the Feitchner-Yuzvinsky presentation. + where `I_{FY}(M)` is the :class:`Feitchner-Yuzvinsky augmented Chow ring + ideal ` + of matroid `M`. - The *augmented Chow ring of atom-free presentation* is the quotient ring + The *atom-free presentation* is the quotient ring .. MATH:: A(M)_R := R[x_{F_1}, \ldots, x_{F_k}] / I_{af}(M), - where `I_{af}(M)` is the :class:`augmented Chow ring ideal + where `I_{af}(M)` is the :class:`atom-free augmented Chow ring ideal ` - of matroid `M` in the atom-free presentation. + of matroid `M`. .. SEEALSO:: From 02154a7bcde710f8e03b18b7f920801e000270a1 Mon Sep 17 00:00:00 2001 From: janmenjayap Date: Sun, 27 Oct 2024 17:24:44 +0530 Subject: [PATCH 356/537] updated delete_vertices() --- src/sage/graphs/matching_covered_graph.py | 30 +++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/src/sage/graphs/matching_covered_graph.py b/src/sage/graphs/matching_covered_graph.py index e33fb6e656c..50977b07b7f 100644 --- a/src/sage/graphs/matching_covered_graph.py +++ b/src/sage/graphs/matching_covered_graph.py @@ -1335,6 +1335,14 @@ def delete_vertices(self, vertices): EXAMPLES: + Providing with an empty list of vertices:: + + sage: C = graphs.CycleGraph(6) + sage: G = MatchingCoveredGraph(C) + sage: G.delete_vertices([]) + sage: G == C + True + Providing with a list of vertices with at least one non-existent vertex:: @@ -1350,6 +1358,18 @@ def delete_vertices(self, vertices): ... ValueError: vertex (9) not in the graph + Removing an odd no. of distinct vertices from + a matching covered graph:: + + sage: P = graphs.PetersenGraph() + sage: G = MatchingCoveredGraph(P) + sage: S = [0, 1, 2, 10, 10, 100] + sage: G.delete_vertices(S) + Traceback (most recent call last): + ... + ValueError: an odd no. of distinct vertices can not be + removed from a matching covered graph + Providing with a list of existent vertices whose deletion results in a graph which is not matching covered:: @@ -1383,6 +1403,16 @@ def delete_vertices(self, vertices): sage: G # Matching covered graph on 6 vertices Matching covered staircase graph: graph on 6 vertices """ + if not vertices: # do nothing + return + + # Remove potentially duplicated vertices + vertices = set(vertices) + + if len(vertices) % 2: # try to remove an odd number of vertices + raise ValueError('an odd no. of distinct vertices can not be ' + 'removed from a matching covered graph') + for vertex in vertices: if vertex not in self: raise ValueError('vertex (%s) not in the graph' % str(vertex)) From 0cd3db1953718f780fb97a758a09980c77666099 Mon Sep 17 00:00:00 2001 From: janmenjayap Date: Sun, 27 Oct 2024 17:27:22 +0530 Subject: [PATCH 357/537] updated add_edges() --- src/sage/graphs/matching_covered_graph.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/sage/graphs/matching_covered_graph.py b/src/sage/graphs/matching_covered_graph.py index 50977b07b7f..321ac7c668d 100644 --- a/src/sage/graphs/matching_covered_graph.py +++ b/src/sage/graphs/matching_covered_graph.py @@ -847,6 +847,14 @@ def add_edges(self, edges, loops=False): EXAMPLES: + Providing with an empty list of edges:: + + sage: C = graphs.CycleGraph(6) + sage: G = MatchingCoveredGraph(C) + sage: G.add_edges([]) + sage: G == C + True + Adding some edges, the incident vertices of each of which are existent, such that the resulting graph is matching covered:: @@ -1005,6 +1013,9 @@ def add_edges(self, edges, loops=False): raise ValueError('loops are not allowed in ' 'matching covered graphs') + if not edges: # do nothing + return + for edge in edges: if isinstance(edge, tuple): if len(edge) == 0: From 5b7a29fa55679ee1cc96ba9d6a57736ed1271d0b Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Sun, 27 Oct 2024 17:28:06 +0530 Subject: [PATCH 358/537] Edited inputs for Chow ring class --- src/sage/matroids/chow_ring.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/sage/matroids/chow_ring.py b/src/sage/matroids/chow_ring.py index 063cf6416ca..ca61bd97a81 100644 --- a/src/sage/matroids/chow_ring.py +++ b/src/sage/matroids/chow_ring.py @@ -59,7 +59,8 @@ class ChowRing(QuotientRing_generic): - ``R`` -- commutative ring - ``augmented`` -- boolean; when ``True``, this is the augmented Chow ring and if ``False``, this is the non-augmented Chow ring - - ``presentation`` -- string (default: ``None``); one of the following: + - ``presentation`` -- string (default: ``None``); one of the following + (ignored if ``augmented=False``) * ``"fy"`` - the Feitchner-Yuzvinsky presentation * ``"atom-free"`` - the atom-free presentation From 3c6a9e11feddb5ce44e27707ad354744bbf5d234 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Sun, 27 Oct 2024 17:30:05 +0530 Subject: [PATCH 359/537] Edited _latex_() for ChowRing() class --- src/sage/matroids/chow_ring.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/sage/matroids/chow_ring.py b/src/sage/matroids/chow_ring.py index ca61bd97a81..65a6a1e9eea 100644 --- a/src/sage/matroids/chow_ring.py +++ b/src/sage/matroids/chow_ring.py @@ -130,7 +130,10 @@ def _latex_(self): '\\Bold{Q}[A_{0}, A_{1}, A_{2}, A_{3}, A_{4}, A_{01234}] / I_{M} + J_{M} of matroid \\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}' """ from sage.misc.latex import latex - return "{} / {}".format(latex(self._ideal.ring()), latex(self._ideal)) + base = "A({})_{{{}}}" + if self._augmented: + base += "^*" + return base.format(latex(self.matroid()), latex(self.base_ring())) def _coerce_map_from_base_ring(self): r""" From 1eaa5ad6bf9fd4c177ebf93e8b769b90fa8973b3 Mon Sep 17 00:00:00 2001 From: janmenjayap Date: Sun, 27 Oct 2024 17:39:46 +0530 Subject: [PATCH 360/537] updated delete_vertices() --- src/sage/graphs/matching_covered_graph.py | 29 +++++++++++++++++------ 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/src/sage/graphs/matching_covered_graph.py b/src/sage/graphs/matching_covered_graph.py index 321ac7c668d..2ec4093243c 100644 --- a/src/sage/graphs/matching_covered_graph.py +++ b/src/sage/graphs/matching_covered_graph.py @@ -1354,6 +1354,17 @@ def delete_vertices(self, vertices): sage: G == C True + Removing all the existent vertices:: + + sage: M = graphs.MoebiusLadderGraph(10) + sage: G = MatchingCoveredGraph(M) + sage: S = list(G.vertices()) + sage: G.delete_vertices(S) + Traceback (most recent call last): + ... + ValueError: the resulting graph after the removal of the vertices + is trivial, therefore is not matching covered + Providing with a list of vertices with at least one non-existent vertex:: @@ -1428,20 +1439,24 @@ def delete_vertices(self, vertices): if vertex not in self: raise ValueError('vertex (%s) not in the graph' % str(vertex)) + if self.order() == len(vertices): + raise ValueError('the resulting graph after the removal of the ' + 'vertices is trivial, therefore is not ' + 'matching covered') + try: G = Graph(self, multiedges=self.allows_multiple_edges()) G.delete_vertices(vertices) M = Graph(self.get_matching()) - if M: - M.delete_vertices(vertices) - # The resulting matching after the removal of the input vertices - # must be a valid perfect matching of the resulting graph obtained - # after the removal of the vertices + M.delete_vertices(vertices) + # The resulting matching after the removal of the input vertices + # must be a valid perfect matching of the resulting graph obtained + # after the removal of the vertices - if (G.order() != 2*M.size()): - M = None + if (G.order() != 2*M.size()): + M = None self.__init__(data=G, matching=M) From 338f7e93101a5c9075f104f53fa4f8c205d1f9b1 Mon Sep 17 00:00:00 2001 From: janmenjayap Date: Sun, 27 Oct 2024 17:42:02 +0530 Subject: [PATCH 361/537] updated update_matching() --- src/sage/graphs/matching_covered_graph.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/sage/graphs/matching_covered_graph.py b/src/sage/graphs/matching_covered_graph.py index 2ec4093243c..e2afdbe70c8 100644 --- a/src/sage/graphs/matching_covered_graph.py +++ b/src/sage/graphs/matching_covered_graph.py @@ -1576,12 +1576,10 @@ def update_matching(self, matching): if any(d != 1 for d in M.degree()): raise ValueError("the input is not a matching") - G = Graph(self, multiedges=False) - - if any(not G.has_edge(edge) for edge in M.edge_iterator()): + if any(not self.has_edge(edge) for edge in M.edge_iterator()): raise ValueError("the input is not a matching of the graph") - if (G.order() != M.order()): + if (self.order() != M.order()): raise ValueError("the input is not a perfect matching of the graph") self._matching = M.edges() From c0ba0c6bcf71379073f1bb98366416679eb3c595 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Sun, 27 Oct 2024 17:42:32 +0530 Subject: [PATCH 362/537] Edited basis() method --- src/sage/matroids/chow_ring.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/sage/matroids/chow_ring.py b/src/sage/matroids/chow_ring.py index 65a6a1e9eea..7c5615848f5 100644 --- a/src/sage/matroids/chow_ring.py +++ b/src/sage/matroids/chow_ring.py @@ -178,16 +178,17 @@ def basis(self): sage: set(ch.defining_ideal().normal_basis()) == set(ch.basis()) True """ - flats = [X for i in range(1, self._matroid.rank() + 1) - for X in self._matroid.flats(i)] #Non empty flats + F = self._matroid.lattice_of_flats() + H = F.hasse_diagram() + H.delete_vertex(self._ideal.matroid().flats(0)[0]) # remove the empty flat + lattice_flats = Poset(H) + flats = list(lattice_flats) flats_gen = self._ideal.flats_generator() R = self._ideal.ring() - flats = sorted(flats, key=lambda X: (len(X), sorted(X))) + flats.sort(key=lambda X: (len(X), sorted(X))) ranks = {F: self._matroid.rank(F) for F in flats} monomial_basis = [] - reln = lambda x,y: x <= y - lattice_flats = Poset((flats, reln)) - chains = lattice_flats.chains() #Only chains + chains = lattice_flats.chains() #Only chains if self._augmented: if self._presentation == 'fy': for subset in chains: From aa11b066e094c556ae729e403d784f89ba3d6cad Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Sun, 27 Oct 2024 17:54:36 +0530 Subject: [PATCH 363/537] Edited documentation --- src/sage/matroids/chow_ring_ideal.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sage/matroids/chow_ring_ideal.py b/src/sage/matroids/chow_ring_ideal.py index 49f3aa0752c..e33a30b2e23 100644 --- a/src/sage/matroids/chow_ring_ideal.py +++ b/src/sage/matroids/chow_ring_ideal.py @@ -268,7 +268,7 @@ class AugmentedChowRingIdeal_fy(ChowRingIdeal): for all `i \in E`. - The augmented Chow ring ideal in the Feitchner Yuzvinsky presentation + The augmented Chow ring ideal in the Feitchner-Yuzvinsky presentation for a simple matroid `M` is defined as the ideal `I_{FY}(M)` of the following polynomial ring @@ -280,7 +280,7 @@ class AugmentedChowRingIdeal_fy(ChowRingIdeal): - `F_1, \ldots, F_k` are the flats of `M`, - `e_1, \ldots, e_n` are `n` elements of groundset of `M`, - - `I_{FY}(M)` is the ideal generated by all quadratic forms + - `I_{FY}(M)` is the ideal generated by all quadratic forms `y_{F_i \cup e} y_{F_j \cup e}`, where `F_i` and `F_j` are incomparable elements in the lattice of flats, `y_{i} y_{F \cup e}` for every `i \in E` and `i \notin F`, linear forms @@ -289,7 +289,7 @@ class AugmentedChowRingIdeal_fy(ChowRingIdeal): y_i + \sum_{i \in F} y_{F \cup e} - for all `i \in E` and, + for all `i \in E` and .. MATH:: From bddd230971b0856ec83c8ce2709e45a375f0d3fb Mon Sep 17 00:00:00 2001 From: janmenjayap Date: Sun, 27 Oct 2024 17:57:58 +0530 Subject: [PATCH 364/537] added whitespaces around modulo operator --- src/sage/graphs/matching_covered_graph.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/graphs/matching_covered_graph.py b/src/sage/graphs/matching_covered_graph.py index e2afdbe70c8..d367d73fecd 100644 --- a/src/sage/graphs/matching_covered_graph.py +++ b/src/sage/graphs/matching_covered_graph.py @@ -1046,7 +1046,7 @@ def add_edges(self, edges, loops=False): new_vertices.remove(vertex) # Throw error if the no. of new vertices is odd - if len(new_vertices)%2: + if len(new_vertices) % 2: raise ValueError('odd order is not allowed for ' 'matching covered graphs') From 7cf7d92b7b47996a73a815d74d5c50acb7477bed Mon Sep 17 00:00:00 2001 From: Dima Pasechnik Date: Mon, 28 Oct 2024 15:46:56 +0000 Subject: [PATCH 365/537] libsemigroup upgrade to 2.7.3 --- 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 9c93b8497179ce482d0954be8bcfa53306daa26e Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Mon, 28 Oct 2024 22:31:51 +0530 Subject: [PATCH 366/537] Resolved suggested changes --- src/doc/en/reference/references/index.rst | 2 +- src/sage/matroids/chow_ring_ideal.py | 22 +++++++++++----------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/doc/en/reference/references/index.rst b/src/doc/en/reference/references/index.rst index c189bf296f5..5567eaa8bf2 100644 --- a/src/doc/en/reference/references/index.rst +++ b/src/doc/en/reference/references/index.rst @@ -260,7 +260,7 @@ REFERENCES: .. [Ang1997] B. Anglès. 1997. *On some characteristic polynomials attached to finite Drinfeld modules.* manuscripta mathematica 93, 1 (01 Aug 1997), 369–379. https://doi.org/10.1007/BF02677478 - + .. [ANR2023] Robert Angarone, Anastasia Nathanson, and Victor Reiner. *Chow rings of matroids as permutation representations*, 2023. :arxiv:`2309.14312`. diff --git a/src/sage/matroids/chow_ring_ideal.py b/src/sage/matroids/chow_ring_ideal.py index e33a30b2e23..55812198d00 100644 --- a/src/sage/matroids/chow_ring_ideal.py +++ b/src/sage/matroids/chow_ring_ideal.py @@ -192,7 +192,7 @@ def _latex_(self): I_{M} + J_{M} of matroid \text{\texttt{Matroid{ }of{ }rank{ }2{ }on{ }4{ }elements{ }with{ }3{ }bases}} """ from sage.misc.latex import latex - return 'I_{M} + J_{M} of matroid ' + (latex(self._matroid)) + return 'I_{M} + J_{M} of matroid '.format(latex(self._matroid)) def groebner_basis(self, algorithm='', *args, **kwargs): r""" @@ -328,7 +328,7 @@ def __init__(self, M, R): """ self._matroid = M self._flats = [X for i in range(self._matroid.rank() + 1) - for X in self._matroid.flats(i)] + for X in self._matroid.flats(i)] E = list(self._matroid.groundset()) self._flats_generator = dict() try: @@ -337,9 +337,9 @@ def __init__(self, M, R): poly_ring = PolynomialRing(R, names_groundset + names_flats) #self.ring() except ValueError: #variables are not proper names poly_ring = PolynomialRing(R, 'A', len(E) + len(self._flats)) - for i,x in enumerate(E): + for i, x in enumerate(E): self._flats_generator[x] = poly_ring.gens()[i] - for i,F in enumerate(self._flats): + for i, F in enumerate(self._flats): self._flats_generator[F] = poly_ring.gens()[len(E) + i] MPolynomialIdeal.__init__(self, poly_ring, self._gens_constructor(poly_ring)) @@ -396,7 +396,7 @@ def _gens_constructor(self, poly_ring): term += self._flats_generator[F] for G in self._flats: if not (F <= G or G < F): - Q.append(self._flats_generator[F] * self._flats_generator[G]) #Quadratic Generators + Q.append(self._flats_generator[F] * self._flats_generator[G]) # Quadratic generators L.append(term) for x in E: @@ -432,7 +432,7 @@ def _latex_(self): I_{FY} of matroid \text{\texttt{Graphic{ }matroid{ }of{ }rank{ }2{ }on{ }3{ }elements}} """ from sage.misc.latex import latex - return 'I_{FY} of matroid ' + (latex(self._matroid)) + return 'I_{{FY}}({})'.format((latex(self._matroid))) def groebner_basis(self, algorithm='', *args, **kwargs): r""" @@ -562,16 +562,16 @@ def _gens_constructor(self, poly_ring): A0*A2 + A2*A3, A1*A2 + A2*A3] """ E = list(self._matroid.groundset()) - Q = [] #Quadratic Generators + Q = [] # Quadratic generators flats_containing = {x: [] for x in E} for F in self._flats: for x in F: flats_containing[x].append(F) for F in self._flats: for G in self._flats: - if not (G >= F or F > G): #generators for every pair of non-nested flats - Q.append(self._flats_generator[F]*self._flats_generator[G]) - for x in E: #generators for every set of flats containing element + if not (G >= F or F > G): # generators for every pair of non-nested flats + Q.append(self._flats_generator[F] * self._flats_generator[G]) + for x in E: # generators for every set of flats containing element term = poly_ring.zero() for H in flats_containing[x]: term += self._flats_generator[H] @@ -605,7 +605,7 @@ def _latex_(self): I_{af} of matroid \text{\texttt{Graphic{ }matroid{ }of{ }rank{ }2{ }on{ }3{ }elements}} """ from sage.misc.latex import latex - return 'I_{af} of matroid ' + latex(self._matroid) + return 'I_{af} of matroid '.format(latex(self._matroid)) def groebner_basis(self, algorithm='', *args, **kwargs): """ From 99d843f9d0e5b3079ea6337ec6fca90193cffec9 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Mon, 28 Oct 2024 22:40:01 +0530 Subject: [PATCH 367/537] Corrected linting errors in ideal file --- 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 55812198d00..f3075099f87 100644 --- a/src/sage/matroids/chow_ring_ideal.py +++ b/src/sage/matroids/chow_ring_ideal.py @@ -192,7 +192,7 @@ def _latex_(self): I_{M} + J_{M} of matroid \text{\texttt{Matroid{ }of{ }rank{ }2{ }on{ }4{ }elements{ }with{ }3{ }bases}} """ from sage.misc.latex import latex - return 'I_{M} + J_{M} of matroid '.format(latex(self._matroid)) + return 'I_{M} + J_{M} of matroid ' + latex(self._matroid) def groebner_basis(self, algorithm='', *args, **kwargs): r""" @@ -605,7 +605,7 @@ def _latex_(self): I_{af} of matroid \text{\texttt{Graphic{ }matroid{ }of{ }rank{ }2{ }on{ }3{ }elements}} """ from sage.misc.latex import latex - return 'I_{af} of matroid '.format(latex(self._matroid)) + return 'I_{{af}}({}) of matroid '.format(latex(self._matroid)) def groebner_basis(self, algorithm='', *args, **kwargs): """ From f135107c60e69d2e1701ffa7fb4f3b7b93bade10 Mon Sep 17 00:00:00 2001 From: Verrel Rievaldo Wijaya Date: Tue, 29 Oct 2024 10:36:18 +0700 Subject: [PATCH 368/537] Refactor code based on review --- src/sage/rings/semirings/tropical_variety.py | 68 ++++++++++++-------- 1 file changed, 40 insertions(+), 28 deletions(-) diff --git a/src/sage/rings/semirings/tropical_variety.py b/src/sage/rings/semirings/tropical_variety.py index 7ef364d3ec2..281f8e71e98 100644 --- a/src/sage/rings/semirings/tropical_variety.py +++ b/src/sage/rings/semirings/tropical_variety.py @@ -1253,10 +1253,9 @@ def _vertices_components(self): A dictionary where the keys represent the vertices, and the values are lists of tuples. Each tuple consists of the index - of an adjacent edge (component) `e_i` and a string indicating - the directionality of `e_i` relative to the vertex. The string - is either "pos" or "neg", specifying whether it is positive or - negative. + of an adjacent edge (component) `e_i` and a number indicating + the directionality of `e_i` relative to the vertex. The number + is either -1 or 1. EXAMPLES:: @@ -1264,13 +1263,13 @@ def _vertices_components(self): sage: R. = PolynomialRing(T) sage: p1 = R(0) + x + y + x*y + x^2*y + x*y^2 sage: p1.tropical_variety()._vertices_components() - {(0, 0): [(0, 'pos'), (1, 'pos'), (2, 'pos'), (3, 'neg'), (4, 'neg')]} + {(0, 0): [(0, 1), (1, 1), (2, 1), (3, -1), (4, -1)]} sage: p2 = R(2)*x^2 + x*y + R(2)*y^2 + x + R(-1)*y + R(3) sage: p2.tropical_variety()._vertices_components() - {(-2, 0): [(0, 'neg'), (1, 'pos'), (3, 'pos')], - (-1, -3): [(2, 'neg'), (4, 'pos'), (5, 'pos')], - (-1, 0): [(3, 'neg'), (4, 'neg'), (6, 'pos')], - (3, 4): [(6, 'neg'), (7, 'pos'), (8, 'pos')]} + {(-2, 0): [(0, -1), (1, 1), (3, 1)], + (-1, -3): [(2, -1), (4, 1), (5, 1)], + (-1, 0): [(3, -1), (4, -1), (6, 1)], + (3, 4): [(6, -1), (7, 1), (8, 1)]} """ comp_vert = {} if len(self._hypersurface) >= 3: @@ -1284,16 +1283,16 @@ def _vertices_components(self): 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, 'pos')] + comp_vert[(x,y)] = [(i, 1)] else: - comp_vert[(x,y)].append((i, 'pos')) + 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, 'neg')] + comp_vert[(x,y)] = [(i, -1)] else: - comp_vert[(x,y)].append((i, 'neg')) + comp_vert[(x,y)].append((i, -1)) return comp_vert def weight_vectors(self): @@ -1357,10 +1356,7 @@ def weight_vectors(self): vectors = [] for comp in cov[vertex]: weight = self._hypersurface[comp[0]][2] - if comp[1] == 'pos': - vectors.append(weight*temp_vectors[comp[0]]) - else: - vectors.append(weight*(-temp_vectors[comp[0]])) + vectors.append(weight*comp[1]*temp_vectors[comp[0]]) result[vertex] = vectors return result @@ -1385,9 +1381,7 @@ def is_smooth(self): sage: p2.tropical_variety().is_smooth() True """ - if len(self.vertices()) == self._poly.degree()**2: - return True - return False + return len(self.vertices()) == self._poly.degree() ** 2 def is_simple(self): r""" @@ -1413,10 +1407,9 @@ def is_simple(self): for vertex in self.vertices(): if len(vov[vertex]) > 4: return False - elif len(vov[vertex]) == 4: - for v in vov[vertex]: - if -v not in vov[vertex]: - return False + if len(vov[vertex]) == 4: + if any(-v not in vov[vertex] for v in vov[vertex]): + return False return True def genus(self): @@ -1606,10 +1599,29 @@ def plot(self): Another tropical polynomial with numerous components, resulting in a more intricate structure:: - sage: p2 = (R(8) + R(4)*x + R(2)*y + R(1)*x^2 + x*y + R(1)*y^2 + sage: p2 = (x^6 + R(4)*x^4*y^2 + R(2)*x^3*y^3 + R(3)*x^2*y^4 + ....: + x*y^5 + R(7)*x^2 + R(5)*x*y + R(3)*y^2 + R(2)*x + ....: + y + R(10)) + sage: p2.tropical_variety().plot() + Graphics object consisting of 11 graphics primitives + + .. PLOT:: + :width: 300 px + + T = TropicalSemiring(QQ) + R = PolynomialRing(T, ('x,y')) + x, y = R.gen(), R.gen(1) + p2 = (x**6 + R(4)*x**4*y^2 + R(2)*x**3*y**3 + R(3)*x**2*y**4 + + x*y**5 + R(7)*x**2 + R(5)*x*y + R(3)*y**2 + R(2)*x + + y + R(10)) + sphinx_plot(p2.tropical_variety().plot()) + + :: + + sage: p3 = (R(8) + R(4)*x + R(2)*y + R(1)*x^2 + x*y + R(1)*y^2 ....: + R(2)*x^3 + x^2*y + x*y^2 + R(4)*y^3 + R(8)*x^4 ....: + R(4)*x^3*y + x^2*y^2 + R(2)*x*y^3 + y^4) - sage: p2.tropical_variety().plot() + sage: p3.tropical_variety().plot() Graphics object consisting of 23 graphics primitives .. PLOT:: @@ -1618,10 +1630,10 @@ def plot(self): T = TropicalSemiring(QQ) R = PolynomialRing(T, ('x,y')) x, y = R.gen(), R.gen(1) - p2 = (R(8) + R(4)*x + R(2)*y + R(1)*x**2 + x*y + R(1)*y**2 + p3 = (R(8) + R(4)*x + R(2)*y + R(1)*x**2 + x*y + R(1)*y**2 + R(2)*x**3 + x**2*y + x*y**2 + R(4)*y**3 + R(8)*x**4 + R(4)*x**3*y + x**2*y**2 + R(2)*x*y**3 + y**4) - sphinx_plot(p2.tropical_variety().plot()) + sphinx_plot(p3.tropical_variety().plot()) """ from sage.plot.plot import plot from sage.plot.text import text From 6ef419f35b2f712cc09617071e8f20e1f6556269 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Tue, 29 Oct 2024 09:59:03 +0530 Subject: [PATCH 369/537] Corrected doctests --- src/sage/matroids/chow_ring.py | 17 ++++++++--------- src/sage/matroids/chow_ring_ideal.py | 6 +++--- 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/src/sage/matroids/chow_ring.py b/src/sage/matroids/chow_ring.py index 7c5615848f5..35089995aa9 100644 --- a/src/sage/matroids/chow_ring.py +++ b/src/sage/matroids/chow_ring.py @@ -133,7 +133,7 @@ def _latex_(self): base = "A({})_{{{}}}" if self._augmented: base += "^*" - return base.format(latex(self.matroid()), latex(self.base_ring())) + return base.format(latex(self._matroid), latex(self.base_ring())) def _coerce_map_from_base_ring(self): r""" @@ -157,10 +157,9 @@ def basis(self): sage: ch.basis() Family (1, B1, B1*B012345, B0, B0*B012345, B01, B01^2, B2, B2*B012345, B02, B02^2, B12, B12^2, B3, B3*B012345, B03, B03^2, - B13, B13^2, B23, B23^2, B4, B4*B012345, B24, B24^2, B34, B34^2, - B04, B04^2, B14, B14^2, B5, B5*B012345, B25, B25^2, B35, B35^2, - B45, B45^2, B05, B05^2, B15, B15^2, B012345, B012345^2, - B012345^3) + B13, B13^2, B23, B23^2, B4, B4*B012345, B04, B04^2, B14, B14^2, + B24, B24^2, B34, B34^2, B5, B5*B012345, B05, B05^2, B15, B15^2, + B25, B25^2, B35, B35^2, B45, B45^2, B012345, B012345^2, B012345^3) sage: set(ch.defining_ideal().normal_basis()) == set(ch.basis()) True sage: ch = matroids.catalog.Fano().chow_ring(QQ, False) @@ -310,15 +309,15 @@ def degree(self): A03 1 A13 1 A23 1 - A24 1 - A34 1 A04 1 A14 1 + A24 1 + A34 1 + A05 1 + A15 1 A25 1 A35 1 A45 1 - A05 1 - A15 1 A012345 1 A012345^2 2 sage: v = sum(ch.basis()) diff --git a/src/sage/matroids/chow_ring_ideal.py b/src/sage/matroids/chow_ring_ideal.py index f3075099f87..edf90f682ab 100644 --- a/src/sage/matroids/chow_ring_ideal.py +++ b/src/sage/matroids/chow_ring_ideal.py @@ -429,7 +429,7 @@ def _latex_(self): sage: M1 = Matroid(graphs.CycleGraph(3)) sage: ch = M1.chow_ring(QQ, True, 'fy') sage: ch.defining_ideal()._latex_() - I_{FY} of matroid \text{\texttt{Graphic{ }matroid{ }of{ }rank{ }2{ }on{ }3{ }elements}} + 'I_{FY}(\\text{\\texttt{Graphic{ }matroid{ }of{ }rank{ }2{ }on{ }3{ }elements}})' """ from sage.misc.latex import latex return 'I_{{FY}}({})'.format((latex(self._matroid))) @@ -602,10 +602,10 @@ def _latex_(self): sage: M1 = Matroid(graphs.CycleGraph(3)) sage: ch = M1.chow_ring(QQ, True, 'atom-free') sage: ch.defining_ideal()._latex_() - I_{af} of matroid \text{\texttt{Graphic{ }matroid{ }of{ }rank{ }2{ }on{ }3{ }elements}} + 'I_{af}(\\text{\\texttt{Graphic{ }matroid{ }of{ }rank{ }2{ }on{ }3{ }elements}})' """ from sage.misc.latex import latex - return 'I_{{af}}({}) of matroid '.format(latex(self._matroid)) + return 'I_{{af}}({})'.format(latex(self._matroid)) def groebner_basis(self, algorithm='', *args, **kwargs): """ From f4237380c6372ff5e0090938ed7ab6f3f7ba15af Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Tue, 29 Oct 2024 10:21:41 +0530 Subject: [PATCH 370/537] Added normal_basis() method for all 3 classes --- src/sage/matroids/chow_ring.py | 73 +------------------ src/sage/matroids/chow_ring_ideal.py | 103 ++++++++++++++++++++++++++- 2 files changed, 103 insertions(+), 73 deletions(-) diff --git a/src/sage/matroids/chow_ring.py b/src/sage/matroids/chow_ring.py index 35089995aa9..ec556e5d707 100644 --- a/src/sage/matroids/chow_ring.py +++ b/src/sage/matroids/chow_ring.py @@ -177,79 +177,8 @@ def basis(self): sage: set(ch.defining_ideal().normal_basis()) == set(ch.basis()) True """ - F = self._matroid.lattice_of_flats() - H = F.hasse_diagram() - H.delete_vertex(self._ideal.matroid().flats(0)[0]) # remove the empty flat - lattice_flats = Poset(H) - flats = list(lattice_flats) - flats_gen = self._ideal.flats_generator() - R = self._ideal.ring() - flats.sort(key=lambda X: (len(X), sorted(X))) - ranks = {F: self._matroid.rank(F) for F in flats} - monomial_basis = [] - chains = lattice_flats.chains() #Only chains - if self._augmented: - if self._presentation == 'fy': - for subset in chains: - k = len(subset) - if k == 0: - monomial_basis.append(R.one()) - else: - max_powers = [] - max_powers.append(ranks[subset[0]]) - for i in range(1, k): - max_powers.append(ranks[subset[i]] - ranks[subset[i-1]]) - ranges = [range(1, p) for p in max_powers] - ranges[0] = range(1, max_powers[0] + 1) - for combination in product(*(r for r in ranges)): - #Generating combinations for all powers up to max_powers - expression = R.one() - for i in range(k): - expression *= flats_gen[subset[i]]**combination[i] - monomial_basis.append(expression) - - elif self._presentation == 'atom-free': - for subset in chains: - max_powers = [] - k = len(subset) - if subset == []: - monomial_basis.append(R.one()) - else: - for i in range(k): - if i == 0: - max_powers.append(ranks[subset[i]]) - else: - max_powers.append(ranks[subset[i]] - ranks[subset[i-1]]) - ranges = [range(1, p) for p in max_powers] - ranges[0] = range(1, max_powers[0] + 1) - first_rank = ranks[subset[k-1]] + 1 - for combination in product(*(r for r in ranges)): - #Generating combinations for all powers from 1 to max_powers - if sum(combination) <= first_rank: - expression = R.one() - for i in range(k): - expression *= flats_gen[subset[i]]**combination[i] - monomial_basis.append(expression) - - else: - for subset in chains: - max_powers = [] - k = len(subset) - if (k == 0): - monomial_basis.append(R.one()) - elif not ((k == 1) & (ranks[subset[0]] == 1)): - for i in range(k): - if i == 0: - max_powers.append(ranks[subset[i]]) - else: - max_powers.append(ranks[subset[i]] - ranks[subset[i-1]]) - for combination in product(*(range(1, p) for p in max_powers)): - expression = R.one() - for i in range(k): - expression *= flats_gen[subset[i]]**combination[i] - monomial_basis.append(expression) - from sage.sets.family import Family + monomial_basis = list(self._ideal.normal_basis()) return Family([self.element_class(self, mon, reduce=False) for mon in monomial_basis]) class Element(QuotientRing_generic.Element): diff --git a/src/sage/matroids/chow_ring_ideal.py b/src/sage/matroids/chow_ring_ideal.py index edf90f682ab..15a84552743 100644 --- a/src/sage/matroids/chow_ring_ideal.py +++ b/src/sage/matroids/chow_ring_ideal.py @@ -49,6 +49,17 @@ def flats_generator(self): """ return dict(self._flats_generator) + def lattice_flats(self): + F = self._matroid.lattice_of_flats() + H = F.hasse_diagram() + H.delete_vertex(self._ideal.matroid().flats(0)[0]) # remove the empty flat + lattice_flats = Poset(H) + 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 + return (ranks, chains) + class ChowRingIdeal_nonaug(ChowRingIdeal): r""" @@ -240,6 +251,34 @@ def groebner_basis(self, algorithm='', *args, **kwargs): gb.append(flats_gen[G]*(term)**(ranks[F] - ranks[G])) g_basis = PolynomialSequence(R, [gb]) return g_basis + + def normal_basis(self, algorithm='', *args, **kwargs): + if algorithm == '': + algorithm = 'constructed' + if algorithm != 'constructed': + return super().normal_basis(algorithm=algorithm, *args, **kwargs) + R = self.ring() + flats_gen = self._flats_generator + monomial_basis = [] + ranks, chains = self.lattice_flats() + for subset in chains: + max_powers = [] + k = len(subset) + if (k == 0): + monomial_basis.append(R.one()) + elif not ((k == 1) & (ranks[subset[0]] == 1)): + for i in range(k): + if i == 0: + max_powers.append(ranks[subset[i]]) + else: + max_powers.append(ranks[subset[i]] - ranks[subset[i-1]]) + for combination in product(*(range(1, p) for p in max_powers)): + expression = R.one() + for i in range(k): + expression *= flats_gen[subset[i]]**combination[i] + monomial_basis.append(expression) + n_basis = PolynomialSequence(R, [monomial_basis]) + return n_basis class AugmentedChowRingIdeal_fy(ChowRingIdeal): r""" @@ -478,6 +517,35 @@ def groebner_basis(self, algorithm='', *args, **kwargs): g_basis = PolynomialSequence(poly_ring, [gb]) return g_basis + def normal_basis(self, algorithm='', *args, **kwargs): + if algorithm == '': + algorithm = 'constructed' + if algorithm != 'constructed': + return super().normal_basis(algorithm=algorithm, *args, **kwargs) + R = self.ring() + flats_gen = self._flats_generator + monomial_basis = [] + ranks, chains = self.lattice_flats() + for subset in chains: + k = len(subset) + if k == 0: + monomial_basis.append(R.one()) + else: + max_powers = [] + max_powers.append(ranks[subset[0]]) + for i in range(1, k): + max_powers.append(ranks[subset[i]] - ranks[subset[i-1]]) + ranges = [range(1, p) for p in max_powers] + ranges[0] = range(1, max_powers[0] + 1) + for combination in product(*(r for r in ranges)): + #Generating combinations for all powers up to max_powers + expression = R.one() + for i in range(k): + expression *= flats_gen[subset[i]]**combination[i] + monomial_basis.append(expression) + n_basis = PolynomialSequence(R, [monomial_basis]) + return n_basis + class AugmentedChowRingIdeal_atom_free(ChowRingIdeal): r""" The augmented Chow ring ideal for a matroid `M` over ring `R` in the @@ -640,4 +708,37 @@ def groebner_basis(self, algorithm='', *args, **kwargs): gb.append((term**self._matroid.rank(F)) + 1) g_basis = PolynomialSequence(poly_ring, [gb]) - return g_basis \ No newline at end of file + return g_basis + + def normal_basis(self, algorithm='', *args, **kwargs): + if algorithm == '': + algorithm = 'constructed' + if algorithm != 'constructed': + return super().normal_basis(algorithm=algorithm, *args, **kwargs) + R = self.ring() + flats_gen = self._flats_generator + monomial_basis = [] + ranks, chains = self.lattice_flats() + for subset in chains: + max_powers = [] + k = len(subset) + if subset == []: + monomial_basis.append(R.one()) + else: + for i in range(k): + if i == 0: + max_powers.append(ranks[subset[i]]) + else: + max_powers.append(ranks[subset[i]] - ranks[subset[i-1]]) + ranges = [range(1, p) for p in max_powers] + ranges[0] = range(1, max_powers[0] + 1) + first_rank = ranks[subset[k-1]] + 1 + for combination in product(*(r for r in ranges)): + #Generating combinations for all powers from 1 to max_powers + if sum(combination) <= first_rank: + expression = R.one() + for i in range(k): + expression *= flats_gen[subset[i]]**combination[i] + monomial_basis.append(expression) + n_basis = PolynomialSequence(R, [monomial_basis]) + return n_basis \ No newline at end of file From 6da1c3e1be06ac897cb85afdc6c9b87281954bfd Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Tue, 29 Oct 2024 13:15:22 +0800 Subject: [PATCH 371/537] Use new environment files for meson --- .github/workflows/ci-meson.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci-meson.yml b/.github/workflows/ci-meson.yml index 3ecccb4c16c..d2ceb1a1b9b 100644 --- a/.github/workflows/ci-meson.yml +++ b/.github/workflows/ci-meson.yml @@ -39,7 +39,7 @@ jobs: with: path: ~/conda_pkgs_dir key: - ${{ runner.os }}-conda-${{ hashFiles('src/environment-3.11-linux.yml') }} + ${{ runner.os }}-conda-${{ hashFiles('environment-3.11-linux.yml') }} - name: Compiler cache uses: hendrikmuhs/ccache-action@v1.2 @@ -55,7 +55,7 @@ jobs: channels: conda-forge channel-priority: true activate-environment: sage - environment-file: src/environment-${{ matrix.python }}-${{ startsWith(matrix.os, 'macos') && (startsWith(runner.arch, 'ARM') && 'macos' || 'macos-x86_64') || 'linux' }}.yml + environment-file: environment-${{ matrix.python }}-${{ startsWith(matrix.os, 'macos') && (startsWith(runner.arch, 'ARM') && 'macos' || 'macos-x86_64') || 'linux' }}.yml - name: Print Conda environment shell: bash -l {0} From e4031ada3eb40f8e4cbcdc8317b8a1f48c48d749 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Tue, 29 Oct 2024 10:46:41 +0530 Subject: [PATCH 372/537] Added normal_basis() method doctests for all 3 classes --- src/sage/matroids/chow_ring.py | 2 - src/sage/matroids/chow_ring_ideal.py | 57 +++++++++++++++++++++++++++- 2 files changed, 56 insertions(+), 3 deletions(-) diff --git a/src/sage/matroids/chow_ring.py b/src/sage/matroids/chow_ring.py index ec556e5d707..32559e623e3 100644 --- a/src/sage/matroids/chow_ring.py +++ b/src/sage/matroids/chow_ring.py @@ -10,8 +10,6 @@ from sage.rings.quotient_ring import QuotientRing_generic from sage.categories.graded_algebras_with_basis import GradedAlgebrasWithBasis from sage.categories.commutative_rings import CommutativeRings -from itertools import product -from sage.combinat.posets.posets import Poset class ChowRing(QuotientRing_generic): r""" diff --git a/src/sage/matroids/chow_ring_ideal.py b/src/sage/matroids/chow_ring_ideal.py index 15a84552743..0a20747d923 100644 --- a/src/sage/matroids/chow_ring_ideal.py +++ b/src/sage/matroids/chow_ring_ideal.py @@ -11,6 +11,7 @@ from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing from sage.rings.polynomial.multi_polynomial_sequence import PolynomialSequence from sage.combinat.posets.posets import Poset +from itertools import product class ChowRingIdeal(MPolynomialIdeal): def matroid(self): @@ -50,9 +51,26 @@ def flats_generator(self): return dict(self._flats_generator) def lattice_flats(self): + r""" + Return the ranks and chains of lattice of flats of the matroid. + + EXAMPLES:: + + sage: ch = matroids.catalog.NonFano().chow_ring(QQ, True, 'atom-free') + sage: ch.defining_ideal().lattice_flats() + ({frozenset({'b'}): 1, frozenset({'c'}): 1, frozenset({'d'}): 1, + frozenset({'e'}): 1, frozenset({'f'}): 1, frozenset({'g'}): 1, + frozenset({'d', 'e'}): 2, frozenset({'d', 'f'}): 2, + frozenset({'e', 'f'}): 2, frozenset({'a', 'b', 'f'}): 2, + frozenset({'a', 'c', 'e'}): 2, frozenset({'a', 'd', 'g'}): 2, + frozenset({'b', 'c', 'd'}): 2, frozenset({'b', 'e', 'g'}): 2, + frozenset({'c', 'f', 'g'}): 2, + frozenset({'a', 'b', 'c', 'd', 'e', 'f', 'g'}): 3}, + Set of chains of Finite poset containing 17 elements) + """ F = self._matroid.lattice_of_flats() H = F.hasse_diagram() - H.delete_vertex(self._ideal.matroid().flats(0)[0]) # remove the empty flat + H.delete_vertex(self._matroid.flats(0)[0]) # remove the empty flat lattice_flats = Poset(H) flats = list(lattice_flats) flats.sort(key=lambda X: (len(X), sorted(X))) @@ -253,6 +271,19 @@ def groebner_basis(self, algorithm='', *args, **kwargs): return g_basis def normal_basis(self, algorithm='', *args, **kwargs): + r""" + Return the monomial basis of the quotient ring of this ideal. + + EXAMPLES:: + + sage: ch = matroids.catalog.Fano().chow_ring(QQ, False) + sage: ch.defining_ideal().normal_basis() + [1, Abcd, Aace, Aabf, Adef, Aadg, Abeg, Acfg, Aabcdefg, Aabcdefg^2] + sage: ch = matroids.AG(2,3).chow_ring(QQ, False) + sage: ch.defining_ideal().normal_basis() + [1, A012, A236, A046, A156, A345, A247, A057, A137, A258, A678, + A038, A148, A012345678, A012345678^2] + """ if algorithm == '': algorithm = 'constructed' if algorithm != 'constructed': @@ -518,6 +549,18 @@ def groebner_basis(self, algorithm='', *args, **kwargs): return g_basis def normal_basis(self, algorithm='', *args, **kwargs): + r""" + Return the monomial basis of the quotient ring of this ideal. + + EXAMPLES:: + + sage: ch = matroids.catalog.K33().chow_ring(QQ, True, 'fy') + sage: ch.defining_ideal().normal_basis() + Polynomial Sequence with 1758 Polynomials in 127 Variables + sage: ch = matroids.catalog.Wheel4().chow_ring(QQ, True, 'fy') + sage: ch.defining_ideal().normal_basis() + Polynomial Sequence with 200 Polynomials in 42 Variables + """ if algorithm == '': algorithm = 'constructed' if algorithm != 'constructed': @@ -711,6 +754,18 @@ def groebner_basis(self, algorithm='', *args, **kwargs): return g_basis def normal_basis(self, algorithm='', *args, **kwargs): + r""" + Return the monomial basis of the quotient ring of this ideal. + + EXAMPLES:: + + sage: ch = matroids.Whirl(5).chow_ring(QQ, True, 'atom-free') + sage: ch.defining_ideal().normal_basis() + Polynomial Sequence with 1726 Polynomials in 121 Variables + sage: ch = matroids.Z(4).chow_ring(QQ, True, 'atom-free') + sage: ch.defining_ideal().normal_basis() + Polynomial Sequence with 248 Polynomials in 52 Variables + """ if algorithm == '': algorithm = 'constructed' if algorithm != 'constructed': From 744fc9305240a4c4bfa20c66293f81bc47e75c51 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Tue, 29 Oct 2024 10:49:21 +0530 Subject: [PATCH 373/537] Added input parameters for chow_ring() method --- src/sage/matroids/matroid.pyx | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/sage/matroids/matroid.pyx b/src/sage/matroids/matroid.pyx index 2bf1fd8abc3..56135b71821 100644 --- a/src/sage/matroids/matroid.pyx +++ b/src/sage/matroids/matroid.pyx @@ -8037,6 +8037,18 @@ cdef class Matroid(SageObject): - :mod:`sage.matroids.chow_ring_ideal` - :mod:`sage.matroids.chow_ring` + INPUT: + + - ``M`` -- matroid + - ``R`` -- commutative ring + - ``augmented`` -- boolean; when ``True``, this is the augmented + Chow ring and if ``False``, this is the non-augmented Chow ring + - ``presentation`` -- string (default: ``None``); one of the following + (ignored if ``augmented=False``) + + * ``"fy"`` - the Feitchner-Yuzvinsky presentation + * ``"atom-free"`` - the atom-free presentation + EXAMPLES:: sage: M = matroids.Wheel(2) From 8468ff121974b2625036dcfd086a5e421e53bdbc Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Tue, 29 Oct 2024 10:56:08 +0530 Subject: [PATCH 374/537] Edited augmented chow ring ideal definition for atom-free presentation --- src/sage/matroids/chow_ring_ideal.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/sage/matroids/chow_ring_ideal.py b/src/sage/matroids/chow_ring_ideal.py index 0a20747d923..eda866b26e6 100644 --- a/src/sage/matroids/chow_ring_ideal.py +++ b/src/sage/matroids/chow_ring_ideal.py @@ -601,23 +601,23 @@ class AugmentedChowRingIdeal_atom_free(ChowRingIdeal): R[x_{F_1}, \ldots, x_{F_k}], - where - - - `F_1, \ldots, F_k` are the non-empty flats of `M`, - - `I_{af}(M)` is the ideal generated by all quadratic forms `x_{F_i} x_{F_j}` - where `F_i` and `F_j` are incomparable elements in the lattice of flats, + where `F_1, \ldots, F_k` are the non-empty flats of `M` and `I_{af}(M)` is + the ideal generated by + + - all quadratic monomials `x_{F} x_{F'}` for all incomparable elements + `F` and `F'` in the lattice of flats, + + - for all flats `F` and `i \in E \setminus F` .. MATH:: x_F \sum_{i \in F'} x_{F'} - for all `i \in E` and `i \notin F`, and + - and for all `i \in E` .. MATH:: - \sum_{i \in F'} (x_{F'})^2 - - for all `i \in E`. + \sum_{i \in F'} (x_{F'})^2. REFERENCES: From 5070e36805fb1c0e3f49b8b8c20cdf84ef2de839 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Tue, 29 Oct 2024 10:57:51 +0530 Subject: [PATCH 375/537] Corrected linting errors --- 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 eda866b26e6..afa4c6ecfc9 100644 --- a/src/sage/matroids/chow_ring_ideal.py +++ b/src/sage/matroids/chow_ring_ideal.py @@ -269,7 +269,7 @@ def groebner_basis(self, algorithm='', *args, **kwargs): gb.append(flats_gen[G]*(term)**(ranks[F] - ranks[G])) g_basis = PolynomialSequence(R, [gb]) return g_basis - + def normal_basis(self, algorithm='', *args, **kwargs): r""" Return the monomial basis of the quotient ring of this ideal. From 11fc7c84542da04123e15d5701db4c8e4af4fe43 Mon Sep 17 00:00:00 2001 From: janmenjayap Date: Tue, 29 Oct 2024 13:14:25 +0530 Subject: [PATCH 376/537] added TODO methods --- src/sage/graphs/matching_covered_graph.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/sage/graphs/matching_covered_graph.py b/src/sage/graphs/matching_covered_graph.py index d367d73fecd..b20e210ad83 100644 --- a/src/sage/graphs/matching_covered_graph.py +++ b/src/sage/graphs/matching_covered_graph.py @@ -14,6 +14,22 @@ AUTHORS: - Janmenjaya Panda (2024-06-14): initial version + +.. TODO: + + The following methods are to be incorporated in + :class:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph`:: + + - ``delete_edge()`` | Delete the edge from ``u`` to ``v``. + - ``delete_edges()`` | Delete edges from an iterable container. + - ``is_removable_double_ear()`` | Check whether the pair of ears form a removable double ear. + - ``is_removable_doubleton()`` | Check whether the pair of edges constitute a removable doubleton. + - ``is_removable_ear()`` | Check whether the ear is removable. + - ``is_removable_edge()`` | Check whether the edge is removable. + - ``removable_double_ears()`` | Return a list of removable double ears. + - ``removable_doubletons()`` | Return a list of removable doubletons. + - ``removable_ears()`` | Return a list of removable ears. + - ``removable_edges()`` | Return a :class:`~EdgesView` of removable edges. """ # **************************************************************************** # Copyright (C) 2024 Janmenjaya Panda From 3de9015507022f18bb75c1bcbb8d266106c90ed3 Mon Sep 17 00:00:00 2001 From: janmenjayap Date: Tue, 29 Oct 2024 13:22:22 +0530 Subject: [PATCH 377/537] changed the description of get_matching() --- src/sage/graphs/matching_covered_graph.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/graphs/matching_covered_graph.py b/src/sage/graphs/matching_covered_graph.py index b20e210ad83..91a1943c2b9 100644 --- a/src/sage/graphs/matching_covered_graph.py +++ b/src/sage/graphs/matching_covered_graph.py @@ -1482,8 +1482,8 @@ def delete_vertices(self, vertices): def get_matching(self): r""" - Return ``self._matching``, which is a perfect matching of the (matching - covered) graph computed at the initialization. + Return a :class:`~EdgesView` of ``self._matching`` (a perfect matching + of the (matching covered) graph computed at the initialization). OUTPUT: From a022f89a3689e0e4e4eb1effee7d2091861cf8ec Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Tue, 29 Oct 2024 14:17:23 +0530 Subject: [PATCH 378/537] Changed augmented chow ring ideal definition --- src/sage/matroids/chow_ring_ideal.py | 55 ++++++++++++++-------------- 1 file changed, 28 insertions(+), 27 deletions(-) diff --git a/src/sage/matroids/chow_ring_ideal.py b/src/sage/matroids/chow_ring_ideal.py index afa4c6ecfc9..d24c5f422e4 100644 --- a/src/sage/matroids/chow_ring_ideal.py +++ b/src/sage/matroids/chow_ring_ideal.py @@ -327,9 +327,9 @@ class AugmentedChowRingIdeal_fy(ChowRingIdeal): - `F_1, \ldots, F_k` are the proper flats of `M`, - `e_1, \ldots, e_n` are `n` elements of groundset of `M`, - - `J_M` is the ideal generated by all quadratic forms `x_{F_i} x_{F_j}`, - where `F_i` and `F_j` are incomparable elements in the lattice of - flats and `y_{i} x_F` for every `i \in E` and `i \notin F`, and + - `J_M` is the ideal generated by all quadratic monomials `x_{F} x_{F'}`, + where `F` and `F'` are incomparable elements in the lattice of + flats and `y_{i} x_F` for all flats `F` and `i \in E \setminus F` and - `I_M` is the ideal generated by all linear forms .. MATH:: @@ -346,20 +346,21 @@ class AugmentedChowRingIdeal_fy(ChowRingIdeal): R[y_{e_1}, \ldots, y_{e_n}, y_{F_1 \cup e}, \ldots, y_{F_k \cup e}], - where + where `F_1, \ldots, F_k` are the flats of `M`, `e_1, \ldots, e_n` are + `n` elements of groundset of `M`, and `I_{FY}(M)` is the ideal generated by - - `F_1, \ldots, F_k` are the flats of `M`, - - `e_1, \ldots, e_n` are `n` elements of groundset of `M`, - - `I_{FY}(M)` is the ideal generated by all quadratic forms - `y_{F_i \cup e} y_{F_j \cup e}`, where `F_i` and `F_j` - are incomparable elements in the lattice of flats, `y_{i} y_{F \cup e}` - for every `i \in E` and `i \notin F`, linear forms + - all quadratic monomials `y_{F \cup e} y_{F' \cup e}`, for incomparable + elements `F` and `F'` in the lattice of flats, + + - `y_{i} y_{F \cup e}` for all flats `F` and all `i \in E \setminus F` + + - for all `i \in E` .. MATH:: y_i + \sum_{i \in F} y_{F \cup e} - for all `i \in E` and + - and .. MATH:: @@ -520,13 +521,13 @@ def groebner_basis(self, algorithm='', *args, **kwargs): algorithm = 'constructed' if algorithm != 'constructed': return super().groebner_basis(algorithm=algorithm, *args, **kwargs) - gb = [] #Reduced groebner basis with two eliminated cases + gb = [] # reduced groebner basis with two eliminated cases E = list(self._matroid.groundset()) poly_ring = self.ring() for F in self._flats: for G in self._flats: - if not (F <= G or G <= F): #Non-nested flats - gb.append(self._flats_generator[F]*self._flats_generator[G]) + if not (F <= G or G <= F): # non-nested flats + gb.append(self._flats_generator[F]*self._flats_generator[G]) for i in E: term = poly_ring.zero() @@ -537,11 +538,11 @@ def groebner_basis(self, algorithm='', *args, **kwargs): if H >= G: term1 += self._flats_generator[H] if term != poly_ring.zero(): - gb.append(self._flats_generator[i] + term) #5.7 + gb.append(self._flats_generator[i] + term) #5.7 (MM2022) if term1 != poly_ring.zero(): - gb.append(term1**(self._matroid.rank(G) + 1)) #5.6 + gb.append(term1**(self._matroid.rank(G) + 1)) #5.6 (MM2022) - if G > F: #nested flats + if G > F: # nested flats if term1 != poly_ring.zero(): gb.append(self._flats_generator[F]*term1**(self._matroid.rank(G)-self._matroid.rank(F))) @@ -570,10 +571,10 @@ def normal_basis(self, algorithm='', *args, **kwargs): monomial_basis = [] ranks, chains = self.lattice_flats() for subset in chains: - k = len(subset) - if k == 0: + if not subset: monomial_basis.append(R.one()) else: + k = len(subset) max_powers = [] max_powers.append(ranks[subset[0]]) for i in range(1, k): @@ -581,10 +582,10 @@ def normal_basis(self, algorithm='', *args, **kwargs): ranges = [range(1, p) for p in max_powers] ranges[0] = range(1, max_powers[0] + 1) for combination in product(*(r for r in ranges)): - #Generating combinations for all powers up to max_powers + # generating combinations for all powers up to max_powers expression = R.one() - for i in range(k): - expression *= flats_gen[subset[i]]**combination[i] + for val, c in zip(subset, combination): + expression *= flats_gen[val] ** c monomial_basis.append(expression) n_basis = PolynomialSequence(R, [monomial_basis]) return n_basis @@ -603,10 +604,10 @@ class AugmentedChowRingIdeal_atom_free(ChowRingIdeal): where `F_1, \ldots, F_k` are the non-empty flats of `M` and `I_{af}(M)` is the ideal generated by - + - all quadratic monomials `x_{F} x_{F'}` for all incomparable elements `F` and `F'` in the lattice of flats, - + - for all flats `F` and `i \in E \setminus F` .. MATH:: @@ -648,7 +649,7 @@ def __init__(self, M, R): """ self._matroid = M self._flats = [X for i in range(1, self._matroid.rank() + 1) - for X in self._matroid.flats(i)] + 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 self._flats] try: poly_ring = PolynomialRing(R, names) #self.ring @@ -681,7 +682,7 @@ def _gens_constructor(self, poly_ring): for F in self._flats: for G in self._flats: if not (G >= F or F > G): # generators for every pair of non-nested flats - Q.append(self._flats_generator[F] * self._flats_generator[G]) + Q.append(self._flats_generator[F] * self._flats_generator[G]) for x in E: # generators for every set of flats containing element term = poly_ring.zero() for H in flats_containing[x]: @@ -777,7 +778,7 @@ def normal_basis(self, algorithm='', *args, **kwargs): for subset in chains: max_powers = [] k = len(subset) - if subset == []: + if not subset: monomial_basis.append(R.one()) else: for i in range(k): From 3abd40098b6982100861ae75d8f9be09367c0276 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Tue, 29 Oct 2024 14:24:05 +0530 Subject: [PATCH 379/537] Corrected doctests --- src/sage/matroids/chow_ring.py | 2 +- src/sage/matroids/chow_ring_ideal.py | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/sage/matroids/chow_ring.py b/src/sage/matroids/chow_ring.py index 32559e623e3..f69a8ea1462 100644 --- a/src/sage/matroids/chow_ring.py +++ b/src/sage/matroids/chow_ring.py @@ -125,7 +125,7 @@ def _latex_(self): sage: M1 = matroids.Uniform(2,5) sage: ch = M1.chow_ring(QQ, False) sage: ch._latex_() - '\\Bold{Q}[A_{0}, A_{1}, A_{2}, A_{3}, A_{4}, A_{01234}] / I_{M} + J_{M} of matroid \\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}' + '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}}' """ from sage.misc.latex import latex base = "A({})_{{{}}}" diff --git a/src/sage/matroids/chow_ring_ideal.py b/src/sage/matroids/chow_ring_ideal.py index d24c5f422e4..0c0e8140e32 100644 --- a/src/sage/matroids/chow_ring_ideal.py +++ b/src/sage/matroids/chow_ring_ideal.py @@ -58,13 +58,13 @@ def lattice_flats(self): sage: ch = matroids.catalog.NonFano().chow_ring(QQ, True, 'atom-free') sage: ch.defining_ideal().lattice_flats() - ({frozenset({'b'}): 1, frozenset({'c'}): 1, frozenset({'d'}): 1, - frozenset({'e'}): 1, frozenset({'f'}): 1, frozenset({'g'}): 1, - frozenset({'d', 'e'}): 2, frozenset({'d', 'f'}): 2, - frozenset({'e', 'f'}): 2, frozenset({'a', 'b', 'f'}): 2, - frozenset({'a', 'c', 'e'}): 2, frozenset({'a', 'd', 'g'}): 2, - frozenset({'b', 'c', 'd'}): 2, frozenset({'b', 'e', 'g'}): 2, - frozenset({'c', 'f', 'g'}): 2, + ({frozenset({'a'}): 1, frozenset({'b'}): 1, frozenset({'c'}): 1, + frozenset({'d'}): 1, frozenset({'e'}): 1, frozenset({'f'}): 1, + frozenset({'g'}): 1, frozenset({'d', 'e'}): 2, + frozenset({'d', 'f'}): 2, frozenset({'e', 'f'}): 2, + frozenset({'a', 'b', 'f'}): 2, frozenset({'a', 'c', 'e'}): 2, + frozenset({'a', 'd', 'g'}): 2, frozenset({'b', 'c', 'd'}): 2, + frozenset({'b', 'e', 'g'}): 2, frozenset({'c', 'f', 'g'}): 2, frozenset({'a', 'b', 'c', 'd', 'e', 'f', 'g'}): 3}, Set of chains of Finite poset containing 17 elements) """ From a6ecb2d618221adfe6db566eb6fb5a6791dc396b Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Tue, 29 Oct 2024 14:25:42 +0530 Subject: [PATCH 380/537] Removed flats_generator() method --- src/sage/matroids/chow_ring_ideal.py | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/src/sage/matroids/chow_ring_ideal.py b/src/sage/matroids/chow_ring_ideal.py index 0c0e8140e32..6926961f2dc 100644 --- a/src/sage/matroids/chow_ring_ideal.py +++ b/src/sage/matroids/chow_ring_ideal.py @@ -28,28 +28,6 @@ def matroid(self): M = self._matroid return M - def flats_generator(self): - r""" - Return the variables of every corresponding flat/groundset element - of the matroid. - - EXAMPLES:: - - sage: ch = matroids.catalog.Fano().chow_ring(QQ, False) - sage: ch.defining_ideal().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', 'f'}): Adef, - frozenset({'a', 'b', 'c', 'd', 'e', 'f', 'g'}): Aabcdefg} - """ - return dict(self._flats_generator) - def lattice_flats(self): r""" Return the ranks and chains of lattice of flats of the matroid. From ad966f0d8fbbff501f041c1b6421a2774d91a936 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Tue, 29 Oct 2024 14:30:42 +0530 Subject: [PATCH 381/537] Renamed lattice_flats() method --- src/sage/matroids/chow_ring_ideal.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/sage/matroids/chow_ring_ideal.py b/src/sage/matroids/chow_ring_ideal.py index 6926961f2dc..f5cc622e339 100644 --- a/src/sage/matroids/chow_ring_ideal.py +++ b/src/sage/matroids/chow_ring_ideal.py @@ -28,14 +28,14 @@ def matroid(self): M = self._matroid return M - def lattice_flats(self): + def _lattice_flats(self): r""" Return the ranks and chains of lattice of flats of the matroid. EXAMPLES:: sage: ch = matroids.catalog.NonFano().chow_ring(QQ, True, 'atom-free') - sage: ch.defining_ideal().lattice_flats() + sage: ch.defining_ideal()._lattice_flats() ({frozenset({'a'}): 1, frozenset({'b'}): 1, frozenset({'c'}): 1, frozenset({'d'}): 1, frozenset({'e'}): 1, frozenset({'f'}): 1, frozenset({'g'}): 1, frozenset({'d', 'e'}): 2, @@ -269,7 +269,7 @@ def normal_basis(self, algorithm='', *args, **kwargs): R = self.ring() flats_gen = self._flats_generator monomial_basis = [] - ranks, chains = self.lattice_flats() + ranks, chains = self._lattice_flats() for subset in chains: max_powers = [] k = len(subset) @@ -547,7 +547,7 @@ def normal_basis(self, algorithm='', *args, **kwargs): R = self.ring() flats_gen = self._flats_generator monomial_basis = [] - ranks, chains = self.lattice_flats() + ranks, chains = self._lattice_flats() for subset in chains: if not subset: monomial_basis.append(R.one()) @@ -752,7 +752,7 @@ def normal_basis(self, algorithm='', *args, **kwargs): R = self.ring() flats_gen = self._flats_generator monomial_basis = [] - ranks, chains = self.lattice_flats() + ranks, chains = self._lattice_flats() for subset in chains: max_powers = [] k = len(subset) From 564ac20d0c895b0e4a0dbb5347d7f341af26427b Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Tue, 29 Oct 2024 14:46:12 +0530 Subject: [PATCH 382/537] Optimized PolynomialSequence returns --- src/sage/matroids/chow_ring_ideal.py | 35 ++++++++++++++-------------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/src/sage/matroids/chow_ring_ideal.py b/src/sage/matroids/chow_ring_ideal.py index f5cc622e339..300e46770d6 100644 --- a/src/sage/matroids/chow_ring_ideal.py +++ b/src/sage/matroids/chow_ring_ideal.py @@ -56,7 +56,6 @@ def _lattice_flats(self): chains = lattice_flats.chains() #Only chains return (ranks, chains) - class ChowRingIdeal_nonaug(ChowRingIdeal): r""" The Chow ring ideal of a matroid `M`. @@ -212,6 +211,8 @@ def groebner_basis(self, algorithm='', *args, **kwargs): [Aa*Abc, Aa, Abc, Aa*Aabc, Abc*Aabc, Aabc] sage: ch.defining_ideal().groebner_basis().is_groebner() True + sage: ch.defining_ideal().hilbert_series() == ch.defining_ideal().hilbert_series(algorithm='singular') + True Another example would be the Groebner basis of the Chow ring ideal of the matroid of the length 3 cycle graph:: @@ -221,6 +222,8 @@ def groebner_basis(self, algorithm='', *args, **kwargs): [A0*A1, A0*A2, A1*A2, A0, A1, A2, A0*A3, A1*A3, A2*A3, A3] sage: ch.defining_ideal().groebner_basis().is_groebner() True + sage: ch.defining_ideal().hilbert_series() == ch.defining_ideal().hilbert_series(algorithm='singular') + True """ if algorithm == '': algorithm = 'constructed' @@ -245,8 +248,7 @@ def groebner_basis(self, algorithm='', *args, **kwargs): term += flats_gen[G] for G in lattice_flats.order_ideal([F]): gb.append(flats_gen[G]*(term)**(ranks[F] - ranks[G])) - g_basis = PolynomialSequence(R, [gb]) - return g_basis + return PolynomialSequence(R, [gb]) def normal_basis(self, algorithm='', *args, **kwargs): r""" @@ -283,11 +285,10 @@ def normal_basis(self, algorithm='', *args, **kwargs): max_powers.append(ranks[subset[i]] - ranks[subset[i-1]]) for combination in product(*(range(1, p) for p in max_powers)): expression = R.one() - for i in range(k): - expression *= flats_gen[subset[i]]**combination[i] + for val, c in zip(subset, combination): + expression *= flats_gen[val] ** c monomial_basis.append(expression) - n_basis = PolynomialSequence(R, [monomial_basis]) - return n_basis + return PolynomialSequence(R, [monomial_basis]) class AugmentedChowRingIdeal_fy(ChowRingIdeal): r""" @@ -494,6 +495,8 @@ def groebner_basis(self, algorithm='', *args, **kwargs): Polynomial Sequence with 565 Polynomials in 12 Variables sage: ch.defining_ideal().groebner_basis(algorithm='').is_groebner() True + sage: ch.defining_ideal().hilbert_series() == ch.defining_ideal().hilbert_series(algorithm='singular') + True """ if algorithm == '': algorithm = 'constructed' @@ -524,8 +527,7 @@ def groebner_basis(self, algorithm='', *args, **kwargs): if term1 != poly_ring.zero(): gb.append(self._flats_generator[F]*term1**(self._matroid.rank(G)-self._matroid.rank(F))) - g_basis = PolynomialSequence(poly_ring, [gb]) - return g_basis + return PolynomialSequence(poly_ring, [gb]) def normal_basis(self, algorithm='', *args, **kwargs): r""" @@ -565,8 +567,7 @@ def normal_basis(self, algorithm='', *args, **kwargs): for val, c in zip(subset, combination): expression *= flats_gen[val] ** c monomial_basis.append(expression) - n_basis = PolynomialSequence(R, [monomial_basis]) - return n_basis + return PolynomialSequence(R, [monomial_basis]) class AugmentedChowRingIdeal_atom_free(ChowRingIdeal): r""" @@ -709,6 +710,8 @@ def groebner_basis(self, algorithm='', *args, **kwargs): Polynomial Sequence with 22 Polynomials in 3 Variables sage: ch.defining_ideal().groebner_basis(algorithm='').is_groebner() True + sage: ch.defining_ideal().hilbert_series() == ch.defining_ideal().hilbert_series(algorithm='singular') + True """ if algorithm == '': algorithm = 'constructed' @@ -729,8 +732,7 @@ def groebner_basis(self, algorithm='', *args, **kwargs): gb.append(self._flats_generator[F]*(term**(self._matroid.rank(G) - self._matroid.rank(F)))) gb.append((term**self._matroid.rank(F)) + 1) - g_basis = PolynomialSequence(poly_ring, [gb]) - return g_basis + return PolynomialSequence(poly_ring, [gb]) def normal_basis(self, algorithm='', *args, **kwargs): r""" @@ -771,8 +773,7 @@ def normal_basis(self, algorithm='', *args, **kwargs): #Generating combinations for all powers from 1 to max_powers if sum(combination) <= first_rank: expression = R.one() - for i in range(k): - expression *= flats_gen[subset[i]]**combination[i] + for val, c in zip(subset, combination): + expression *= flats_gen[val] ** c monomial_basis.append(expression) - n_basis = PolynomialSequence(R, [monomial_basis]) - return n_basis \ No newline at end of file + return PolynomialSequence(R, [monomial_basis]) \ No newline at end of file From 084ea136d831aa1da51dd204b8dc072b3df9a815 Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Tue, 29 Oct 2024 11:58:45 +0100 Subject: [PATCH 383/537] fix a bug in creating multisort species given an action and fix INPUT description --- src/sage/rings/species.py | 59 ++++++++++++++++++++++++++++----------- 1 file changed, 43 insertions(+), 16 deletions(-) diff --git a/src/sage/rings/species.py b/src/sage/rings/species.py index 13a1b6e70fd..b78e115a130 100644 --- a/src/sage/rings/species.py +++ b/src/sage/rings/species.py @@ -529,15 +529,15 @@ def _rename(self, n): # prevent infinite recursion in self._element_constructor_ self._renamed.add(n) - for i in range(self._arity): - pi = {i: range(1, n+1)} + for s in range(self._arity): + pi = {s: range(1, n+1)} if n == 1: - self(SymmetricGroup(1), pi, check=False).rename(self._names[i]) + self(SymmetricGroup(1), pi, check=False).rename(self._names[s]) if self._arity == 1: sort = "" else: - sort = f"({self._names[i]})" + sort = f"({self._names[s]})" if n >= 2: self(SymmetricGroup(n), pi, check=False).rename(f"E_{n}" + sort) @@ -683,8 +683,8 @@ def an_element(self): sage: a E_2(XY) """ - G = PermutationGroup([[(2 * i + 1, 2 * i + 2) for i in range(self._arity)]]) - m = {i: [2 * i + 1, 2 * i + 2] for i in range(self._arity)} + G = PermutationGroup([[(2 * s + 1, 2 * s + 2) for s in range(self._arity)]]) + m = {s: [2 * s + 1, 2 * s + 2] for s in range(self._arity)} return self._element_constructor_(G, m) Element = AtomicSpeciesElement @@ -748,7 +748,8 @@ def _stabilizer_subgroups(G, X, a): while M: p = M.pop() OS = libgap.OrbitStabilizer(G, p, G.gens(), gens) - result.append(PermutationGroup(gap_group=OS["stabilizer"], domain=G.domain())) + result.append(PermutationGroup(gap_group=OS["stabilizer"], + domain=G.domain())) M.difference_update(OS["orbit"].sage()) return result @@ -839,8 +840,9 @@ def _element_constructor_(self, G, pi=None, check=True): of a finite set and a transitive action - ``pi`` -- ``dict`` mapping sorts to iterables whose union is the domain of ``G`` (if ``G`` is a permutation group) or - `X` (if ``G`` is a pair ``(X, a)``); if `k=1` and ``G`` is - a permutation group, ``pi`` can be omitted + the domain of the acting symmetric group (if ``G`` is a + pair ``(X, a)``); if `k=1` and ``G`` is a permutation + group, ``pi`` can be omitted - ``check`` -- boolean (default: ``True``); skip input checking if ``False`` @@ -923,6 +925,7 @@ def _element_constructor_(self, G, pi=None, check=True): ... ValueError: 0 must be a permutation group or a pair specifying a group action on the given domain pi=None + """ if parent(G) == self: # pi cannot be None because of framework @@ -958,8 +961,10 @@ def _element_constructor_(self, G, pi=None, check=True): X, a = G except TypeError: raise ValueError(f"{G} must be a permutation group or a pair specifying a group action on the given domain pi={pi}") - mc = [len(pi.get(i, [])) for i in range(self._arity)] - S = SymmetricGroup(sum(mc)).young_subgroup(mc) + dompart = [sorted(pi.get(s, [])) for s in range(self._arity)] + S = PermutationGroup([tuple(b) for b in dompart if len(b) > 2] + + [(b[0], b[1]) for b in dompart if len(b) > 1], + domain=list(chain(*dompart))) H = _stabilizer_subgroups(S, X, a) if len(H) > 1: raise ValueError("Action is not transitive") @@ -2016,9 +2021,11 @@ def _element_constructor_(self, G, pi=None, check=True): - ``G`` -- element of ``self`` (in this case ``pi`` must be ``None``) permutation group, or pair ``(X, a)`` consisting of a finite set and an action - - ``pi`` -- ``dict`` mapping sorts to iterables whose union is the - domain of ``G`` (if ``G`` is a permutation group) or `X` (if ``G`` - is a pair ``(X, a)``); if `k=1`, ``pi`` can be omitted + - ``pi`` -- ``dict`` mapping sorts to iterables whose union + is the domain of ``G`` (if ``G`` is a permutation group) or + the domain of the acting symmetric group (if ``G`` is a + pair ``(X, a)``); if `k=1` and ``G`` is a permutation + group, ``pi`` can be omitted - ``check`` -- boolean (default: ``True``); skip input checking if ``False`` @@ -2068,6 +2075,24 @@ def _element_constructor_(self, G, pi=None, check=True): Traceback (most recent call last): ... ValueError: cannot reassign sorts to a polynomial species + + Create a multisort species given an action:: + + sage: P = PolynomialSpecies(QQ, "X,Y") + sage: G = PermutationGroup([(2,3)]) + sage: pi = {0: [2, 3], 1: [1]} + sage: X = [(s, a) for s in libgap.RightCosets(G, G) for a in G if libgap.OnRight(s, a) == s] + sage: def act(s, a, g): + ....: g_dict = g.dict() + ....: g_gap = libgap.PermList([g_dict[i] for i in range(1, max(g_dict)+1)]) + ....: t = libgap.OnRight(s, g_gap) + ....: b = a ** g_gap + ....: for r, c in X: + ....: if r == t and c == b: + ....: return r, c + ....: raise ValueError + sage: P((X, lambda g, x: act(x[0], x[1], g)), pi) + 2*Y*E_2(X) """ if parent(G) == self: # pi cannot be None because of framework @@ -2082,8 +2107,10 @@ def _element_constructor_(self, G, pi=None, check=True): return self._from_dict({self._indices(G, pi, check=check): ZZ.one()}) X, a = G - mc = [len(pi.get(i, [])) for i in range(self._arity)] - S = SymmetricGroup(sum(mc)).young_subgroup(mc) + dompart = [sorted(pi.get(s, [])) for s in range(self._arity)] + S = PermutationGroup([tuple(b) for b in dompart if len(b) > 2] + + [(b[0], b[1]) for b in dompart if len(b) > 1], + domain=list(chain(*dompart))) Hs = _stabilizer_subgroups(S, X, a) return self.sum_of_terms((self._indices(H, pi, check=check), ZZ.one()) for H in Hs) From e91e6008eb95a6072ca37c891b4edf49d9ec32c8 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Tue, 29 Oct 2024 16:36:54 +0530 Subject: [PATCH 384/537] Optimized groebner_basis() and _gens_constructor() for augmented chow ring ideals --- src/sage/matroids/chow_ring.py | 4 +- src/sage/matroids/chow_ring_ideal.py | 158 ++++++++++++++------------- 2 files changed, 82 insertions(+), 80 deletions(-) diff --git a/src/sage/matroids/chow_ring.py b/src/sage/matroids/chow_ring.py index f69a8ea1462..291a8f7db8d 100644 --- a/src/sage/matroids/chow_ring.py +++ b/src/sage/matroids/chow_ring.py @@ -208,9 +208,9 @@ def monomial_coefficients(self, copy=None): sage: ch = matroids.catalog.NonFano().chow_ring(QQ, True, 'atom-free') sage: v = ch.an_element(); v - 0 + Aa sage: v.monomial_coefficients() - {0: 0, 1: 0, 2: 0, 3: 0, 4: 0, 5: 0, 6: 0, 7: 0, 8: 0, 9: 0, + {0: 0, 1: 1, 2: 0, 3: 0, 4: 0, 5: 0, 6: 0, 7: 0, 8: 0, 9: 0, 10: 0, 11: 0, 12: 0, 13: 0, 14: 0, 15: 0, 16: 0, 17: 0, 18: 0, 19: 0, 20: 0, 21: 0, 22: 0, 23: 0, 24: 0, 25: 0, 26: 0, 27: 0, 28: 0, 29: 0, 30: 0, 31: 0, 32: 0, 33: 0, diff --git a/src/sage/matroids/chow_ring_ideal.py b/src/sage/matroids/chow_ring_ideal.py index 300e46770d6..afdafd671ab 100644 --- a/src/sage/matroids/chow_ring_ideal.py +++ b/src/sage/matroids/chow_ring_ideal.py @@ -391,6 +391,10 @@ def __init__(self, M, R): self._flats_generator[x] = poly_ring.gens()[i] for i, F in enumerate(self._flats): self._flats_generator[F] = poly_ring.gens()[len(E) + i] + self._flats_containing = {x: [] for x in E} + for F in self._flats: + for x in F: + self._flats_containing[x].append(F) MPolynomialIdeal.__init__(self, poly_ring, self._gens_constructor(poly_ring)) def _gens_constructor(self, poly_ring): @@ -401,62 +405,54 @@ def _gens_constructor(self, poly_ring): sage: ch = matroids.Wheel(3).chow_ring(QQ, True, 'fy') sage: ch.defining_ideal()._gens_constructor(ch.defining_ideal().ring()) - [B0*B1, B0*B2, B0*B3, B0*B4, B0*B5, B0*B124, B0*B15, B0*B23, - B0*B345, B0*B1, B1*B2, B1*B3, B1*B4, B1*B5, B1*B025, B1*B04, - B1*B23, B1*B345, B0*B2, B1*B2, B2*B3, B2*B4, B2*B5, B2*B013, - B2*B04, B2*B15, B2*B345, B0*B3, B1*B3, B2*B3, B3*B4, B3*B5, - B3*B025, B3*B04, B3*B124, B3*B15, B0*B4, B1*B4, B2*B4, B3*B4, - B4*B5, B4*B013, B4*B025, B4*B15, B4*B23, B0*B5, B1*B5, B2*B5, - B3*B5, B4*B5, B5*B013, B5*B04, B5*B124, B5*B23, B2*B013, B4*B013, - B5*B013, B013*B025, B013*B04, B013*B124, B013*B15, B013*B23, - B013*B345, B1*B025, B3*B025, B4*B025, B013*B025, B025*B04, - B025*B124, B025*B15, B025*B23, B025*B345, B1*B04, B2*B04, B3*B04, - B5*B04, B013*B04, B025*B04, B04*B124, B04*B15, B04*B23, B04*B345, - B0*B124, B3*B124, B5*B124, B013*B124, B025*B124, B04*B124, - B124*B15, B124*B23, B124*B345, B0*B15, B2*B15, B3*B15, B4*B15, - B013*B15, B025*B15, B04*B15, B124*B15, B15*B23, B15*B345, B0*B23, - B1*B23, B4*B23, B5*B23, B013*B23, B025*B23, B04*B23, B124*B23, - B15*B23, B23*B345, B0*B345, B1*B345, B2*B345, B013*B345, - B025*B345, B04*B345, B124*B345, B15*B345, B23*B345, A0*B, A0*B1, - A0*B2, A0*B3, A0*B4, A0*B5, A0*B124, A0*B15, A0*B23, A0*B345, - A1*B, A1*B0, A1*B2, A1*B3, A1*B4, A1*B5, A1*B025, A1*B04, A1*B23, - A1*B345, A2*B, A2*B0, A2*B1, A2*B3, A2*B4, A2*B5, A2*B013, A2*B04, - A2*B15, A2*B345, A3*B, A3*B0, A3*B1, A3*B2, A3*B4, A3*B5, A3*B025, - A3*B04, A3*B124, A3*B15, A4*B, A4*B0, A4*B1, A4*B2, A4*B3, A4*B5, - A4*B013, A4*B025, A4*B15, A4*B23, A5*B, A5*B0, A5*B1, A5*B2, - A5*B3, A5*B4, A5*B013, A5*B04, A5*B124, A5*B23, + [B0*B1, B0*B2, B0*B3, B0*B23, B0*B4, B0*B124, B0*B5, B0*B15, + B0*B345, B1*B2, B1*B3, B1*B23, B1*B4, B1*B04, B1*B5, B1*B025, + B1*B345, B2*B3, B2*B013, B2*B4, B2*B04, B2*B5, B2*B15, B2*B345, + B3*B4, B3*B04, B3*B124, B3*B5, B3*B025, B3*B15, B013*B23, B4*B013, + B013*B04, B013*B124, B5*B013, B013*B025, B013*B15, B013*B345, + B4*B23, B04*B23, B124*B23, B5*B23, B025*B23, B15*B23, B23*B345, + B4*B5, B4*B025, B4*B15, B04*B124, B5*B04, B025*B04, B04*B15, + B04*B345, B5*B124, B025*B124, B124*B15, B124*B345, B025*B15, + B025*B345, B15*B345, A0*B, A0*B1, A0*B2, A0*B3, A0*B4, A0*B5, + A0*B124, A0*B15, A0*B23, A0*B345, A1*B, A1*B0, A1*B2, A1*B3, + A1*B4, A1*B5, A1*B025, A1*B04, A1*B23, A1*B345, A2*B, A2*B0, + A2*B1, A2*B3, A2*B4, A2*B5, A2*B013, A2*B04, A2*B15, A2*B345, + A3*B, A3*B0, A3*B1, A3*B2, A3*B4, A3*B5, A3*B025, A3*B04, A3*B124, + A3*B15, A4*B, A4*B0, A4*B1, A4*B2, A4*B3, A4*B5, A4*B013, A4*B025, + A4*B15, A4*B23, A5*B, A5*B0, A5*B1, A5*B2, A5*B3, A5*B4, A5*B013, + A5*B04, A5*B124, A5*B23, A0 + B0 + B013 + B025 + B04 + B012345, B + B0 + B1 + B2 + B3 + B4 + B5 + B013 + B025 + B04 + B124 + B15 + B23 + B345 + B012345, - A0 + B0 + B013 + B025 + B04 + B012345, A1 + B1 + B013 + B124 + B15 + B012345, + B + B0 + B1 + B2 + B3 + B4 + B5 + B013 + B025 + B04 + B124 + B15 + B23 + B345 + B012345, A2 + B2 + B025 + B124 + B23 + B012345, + B + B0 + B1 + B2 + B3 + B4 + B5 + B013 + B025 + B04 + B124 + B15 + B23 + B345 + B012345, A3 + B3 + B013 + B23 + B345 + B012345, + B + B0 + B1 + B2 + B3 + B4 + B5 + B013 + B025 + B04 + B124 + B15 + B23 + B345 + B012345, A4 + B4 + B04 + B124 + B345 + B012345, - A5 + B5 + B025 + B15 + B345 + B012345] + B + B0 + B1 + B2 + B3 + B4 + B5 + B013 + B025 + B04 + B124 + B15 + B23 + B345 + B012345, + A5 + B5 + B025 + B15 + B345 + B012345, + B + B0 + B1 + B2 + B3 + B4 + B5 + B013 + B025 + B04 + B124 + B15 + B23 + B345 + B012345] """ E = list(self._matroid.groundset()) - flats_containing = {x: [] for x in E} - for F in self._flats: - for x in F: - flats_containing[x].append(F) - Q = list() L = list() - term = poly_ring.zero() - for F in self._flats: - term += self._flats_generator[F] - for G in self._flats: - if not (F <= G or G < F): - Q.append(self._flats_generator[F] * self._flats_generator[G]) # Quadratic generators - L.append(term) + reln = lambda x,y: x <= y + lattice_flats = Poset((self._flats, reln)) + antichains = lattice_flats.antichains().elements_of_depth_iterator(2) + for F, G in antichains: + Q.append(self._flats_generator[F] * self._flats_generator[G]) # Quadratic generators for x in E: term = poly_ring.zero() + term1 = poly_ring.zero() for F in self._flats: - if F not in flats_containing[x]: + term1 += self._flats_generator[F] + if F not in self._flats_containing[x]: Q.append(self._flats_generator[x] * self._flats_generator[F]) else: term += self._flats_generator[F] L.append(self._flats_generator[x] + term) #Linear Generators + L.append(term1) return Q + L def _repr_(self): @@ -492,7 +488,7 @@ def groebner_basis(self, algorithm='', *args, **kwargs): sage: ch = matroids.Uniform(2,5).chow_ring(QQ, True, 'fy') sage: ch.defining_ideal().groebner_basis(algorithm='') - Polynomial Sequence with 565 Polynomials in 12 Variables + Polynomial Sequence with 33 Polynomials in 12 Variables sage: ch.defining_ideal().groebner_basis(algorithm='').is_groebner() True sage: ch.defining_ideal().hilbert_series() == ch.defining_ideal().hilbert_series(algorithm='singular') @@ -505,27 +501,28 @@ def groebner_basis(self, algorithm='', *args, **kwargs): gb = [] # reduced groebner basis with two eliminated cases E = list(self._matroid.groundset()) poly_ring = self.ring() + reln = lambda x,y: x <= y + lattice_flats = Poset((self._flats, reln)) + antichains = lattice_flats.antichains().elements_of_depth_iterator(2) + for F, G in antichains: + gb.append(self._flats_generator[F] * self._flats_generator[G]) # non-nested flats + for i in E: + term = poly_ring.zero() + for H in self._flats_containing[i]: + term += self._flats_generator[H] + if term != poly_ring.zero(): + gb.append(self._flats_generator[i] + term) # 5.7 (MM2022) + for F in self._flats: - for G in self._flats: - if not (F <= G or G <= F): # non-nested flats - gb.append(self._flats_generator[F]*self._flats_generator[G]) - - for i in E: - term = poly_ring.zero() - term1 = poly_ring.zero() - for H in self._flats: - if i in H: - term += self._flats_generator[H] - if H >= G: - term1 += self._flats_generator[H] - if term != poly_ring.zero(): - gb.append(self._flats_generator[i] + term) #5.7 (MM2022) - if term1 != poly_ring.zero(): - gb.append(term1**(self._matroid.rank(G) + 1)) #5.6 (MM2022) - - if G > F: # nested flats - if term1 != poly_ring.zero(): - gb.append(self._flats_generator[F]*term1**(self._matroid.rank(G)-self._matroid.rank(F))) + term1 = poly_ring.zero() + for H in lattice_flats.order_filter([F]): + term1 += self._flats_generator[H] + if term1 != poly_ring.zero(): + gb.append(term1**(self._matroid.rank(G) + 1)) #5.6 (MM2022) + order_ideal_modified = lattice_flats.order_ideal([F]) + order_ideal_modified.remove(F) + for G in order_ideal_modified: # nested flats + gb.append(self._flats_generator[F]*term1**(self._matroid.rank(F) - self._matroid.rank(G))) return PolynomialSequence(poly_ring, [gb]) @@ -647,10 +644,9 @@ def _gens_constructor(self, poly_ring): sage: M1 = Matroid(graphs.CycleGraph(3)) sage: ch = M1.chow_ring(QQ, True, 'atom-free') sage: ch.defining_ideal()._gens_constructor(ch.defining_ideal().ring()) - [A0*A1, A0*A2, A0^2 + 2*A0*A3 + A3^2, A1^2 + 2*A1*A3 + A3^2, + [A0*A1, A0*A2, A1*A2, A0^2 + 2*A0*A3 + A3^2, A1^2 + 2*A1*A3 + A3^2, A0*A1 + A0*A3, A2^2 + 2*A2*A3 + A3^2, A0*A2 + A0*A3, - A0*A1, A1*A2, A0*A1 + A1*A3, A1*A2 + A1*A3, A0*A2, A1*A2, - A0*A2 + A2*A3, A1*A2 + A2*A3] + A0*A1 + A1*A3, A1*A2 + A1*A3, A0*A2 + A2*A3, A1*A2 + A2*A3] """ E = list(self._matroid.groundset()) Q = [] # Quadratic generators @@ -658,10 +654,12 @@ def _gens_constructor(self, poly_ring): for F in self._flats: for x in F: flats_containing[x].append(F) + reln = lambda x,y: x <= y + lattice_flats = Poset((self._flats, reln)) + antichains = lattice_flats.antichains().elements_of_depth_iterator(2) + for F, G in antichains: + Q.append(self._flats_generator[F] * self._flats_generator[G]) for F in self._flats: - for G in self._flats: - if not (G >= F or F > G): # generators for every pair of non-nested flats - Q.append(self._flats_generator[F] * self._flats_generator[G]) for x in E: # generators for every set of flats containing element term = poly_ring.zero() for H in flats_containing[x]: @@ -707,7 +705,8 @@ def groebner_basis(self, algorithm='', *args, **kwargs): sage: M1 = Matroid(graphs.CycleGraph(3)) sage: ch = M1.chow_ring(QQ, True, 'atom-free') sage: ch.defining_ideal().groebner_basis(algorithm='') - Polynomial Sequence with 22 Polynomials in 3 Variables + [A0*A1, A0*A2, A1*A2, A0^2 + 2*A0*A3 + A3^2, A1^2 + 2*A1*A3 + A3^2, + A2^2 + 2*A2*A3 + A3^2, A0*A3, A1*A3, A2*A3, A3^3] sage: ch.defining_ideal().groebner_basis(algorithm='').is_groebner() True sage: ch.defining_ideal().hilbert_series() == ch.defining_ideal().hilbert_series(algorithm='singular') @@ -719,18 +718,21 @@ def groebner_basis(self, algorithm='', *args, **kwargs): return super().groebner_basis(algorithm=algorithm, *args, **kwargs) gb = [] poly_ring = self.ring() + reln = lambda x,y: x <= y + lattice_flats = Poset((self._flats, reln)) + antichains = lattice_flats.antichains().elements_of_depth_iterator(2) + for F, G in antichains: + gb.append(self._flats_generator[F]*self._flats_generator[G]) for F in self._flats: - for G in self._flats: - term = poly_ring.zero() - for H in self._flats: - if H < F: - term += self._flats_generator[H] - if not (F >= G or G > F): #Non nested flats - gb.append(self._flats_generator[F]*self._flats_generator[G]) - elif F < G: #Nested flats - if term != poly_ring.zero(): - gb.append(self._flats_generator[F]*(term**(self._matroid.rank(G) - self._matroid.rank(F)))) - gb.append((term**self._matroid.rank(F)) + 1) + term = poly_ring.zero() + for H in lattice_flats.order_filter([F]): + term += self._flats_generator[H] + if term != poly_ring.zero(): + order_ideal_modified = lattice_flats.order_ideal([F]) + order_ideal_modified.remove(F) + for G in order_ideal_modified: + gb.append(self._flats_generator[G] * (term ** (self._matroid.rank(F) - self._matroid.rank(G)))) + gb.append(term ** (self._matroid.rank(F) + 1)) return PolynomialSequence(poly_ring, [gb]) From f4c4723619fa82548198ada660a5b9ae9dce532d Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Tue, 29 Oct 2024 12:24:27 +0100 Subject: [PATCH 385/537] minor optimization --- src/sage/rings/species.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/sage/rings/species.py b/src/sage/rings/species.py index b78e115a130..7bc55e6ccb5 100644 --- a/src/sage/rings/species.py +++ b/src/sage/rings/species.py @@ -6,6 +6,7 @@ from sage.categories.sets_cat import cartesian_product from sage.categories.sets_with_grading import SetsWithGrading from sage.categories.tensor import tensor +from sage.combinat.cyclic_sieving_phenomenon import orbit_decomposition from sage.combinat.free_module import CombinatorialFreeModule from sage.combinat.integer_vector import IntegerVectors from sage.combinat.partition import Partitions, _Partitions @@ -118,7 +119,7 @@ def __classcall__(cls, parent, C, dompart): dompart = [[ZZ(C._domain_to_gap[e]) for e in b] for b in dompart] orbits = sorted(G.Orbits().sage(), key=len, reverse=True) for orbit in orbits: - if not any(set(orbit).issubset(p) for p in dompart): + if not any(set(orbit).issubset(b) for b in dompart): o = [C._domain_from_gap[e] for e in orbit] raise ValueError(f"All elements of orbit {o} must have the same sort") @@ -734,10 +735,10 @@ def _stabilizer_subgroups(G, X, a): sage: _stabilizer_subgroups(SymmetricGroup(2), [1], lambda pi, H: H) [Permutation Group with generators [(1,2)]] """ - from sage.combinat.cyclic_sieving_phenomenon import orbit_decomposition to_gap = {x: i for i, x in enumerate(X, 1)} - g_orbits = [orbit_decomposition(list(to_gap), lambda x: a(g, x)) + X = set(X) # because orbit_decomposition turns X into a set + g_orbits = [orbit_decomposition(X, lambda x: a(g, x)) for g in G.gens()] gens = [PermutationGroupElement([tuple([to_gap[x] for x in o]) @@ -1262,7 +1263,7 @@ def shift_gens(gens, n): f_dompart_list = [(A ** n).permutation_group() for A, n in factors] f_list = [f for f, _ in f_dompart_list] dompart_list = [f_dompart for _, f_dompart in f_dompart_list] - tc_list = list(accumulate([sum(len(p) for p in f_dompart) + tc_list = list(accumulate([sum(len(b) for b in f_dompart) for f_dompart in dompart_list], initial=0)) gens = [gen @@ -1971,7 +1972,6 @@ def __classcall__(cls, base_ring, names): sage: P1 == P3 False """ - from sage.structure.category_object import normalize_names names = normalize_names(-1, names) return super().__classcall__(cls, base_ring, names) @@ -2112,7 +2112,8 @@ def _element_constructor_(self, G, pi=None, check=True): + [(b[0], b[1]) for b in dompart if len(b) > 1], domain=list(chain(*dompart))) Hs = _stabilizer_subgroups(S, X, a) - return self.sum_of_terms((self._indices(H, pi, check=check), ZZ.one()) for H in Hs) + return self.sum_of_terms((self._indices(H, pi, check=check), ZZ.one()) + for H in Hs) def _first_ngens(self, n): r""" From 0611846f59ae3c13637076ffe8aaa4fb27bdaf78 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Tue, 29 Oct 2024 17:07:45 +0530 Subject: [PATCH 386/537] Edited basis() method --- 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 291a8f7db8d..57c20813edd 100644 --- a/src/sage/matroids/chow_ring.py +++ b/src/sage/matroids/chow_ring.py @@ -176,7 +176,7 @@ def basis(self): True """ from sage.sets.family import Family - monomial_basis = list(self._ideal.normal_basis()) + monomial_basis = self._ideal.normal_basis() return Family([self.element_class(self, mon, reduce=False) for mon in monomial_basis]) class Element(QuotientRing_generic.Element): From adce272f9d8b1f289e18b9455c11153659559f9b Mon Sep 17 00:00:00 2001 From: janmenjayap Date: Tue, 29 Oct 2024 22:28:17 +0530 Subject: [PATCH 387/537] added _subgraph_by_adding() --- src/sage/graphs/generic_graph.py | 2 +- src/sage/graphs/matching_covered_graph.py | 168 ++++++++++++++++++++++ 2 files changed, 169 insertions(+), 1 deletion(-) diff --git a/src/sage/graphs/generic_graph.py b/src/sage/graphs/generic_graph.py index 9786af20367..042c64acded 100644 --- a/src/sage/graphs/generic_graph.py +++ b/src/sage/graphs/generic_graph.py @@ -14390,7 +14390,7 @@ def _subgraph_by_adding(self, vertices=None, edges=None, edge_property=None, imm or (v, u) in edges_to_keep_unlabeled)): edges_to_keep.append((u, v, l)) else: - s_vertices = set(vertices) + s_vertices = set(G.vertices()) if vertices is None else set(vertices) edges_to_keep = [e for e in self.edges(vertices=vertices, sort=False, sort_vertices=False) if e[0] in s_vertices and e[1] in s_vertices] diff --git a/src/sage/graphs/matching_covered_graph.py b/src/sage/graphs/matching_covered_graph.py index 91a1943c2b9..4a5d8a6dde6 100644 --- a/src/sage/graphs/matching_covered_graph.py +++ b/src/sage/graphs/matching_covered_graph.py @@ -583,6 +583,174 @@ def __repr__(self): return s.capitalize() return "".join(["Matching covered ", s]) + def _subgraph_by_adding(self, vertices=None, edges=None, edge_property=None, immutable=None): + r""" + Return the matching covered subgraph containing the given vertices and edges. + + The edges also satisfy the edge_property, if it is not None. The + subgraph is created by creating a new empty graph and adding the + necessary vertices, edges, and other properties. + + .. NOTE:: + + This method overwrites the + :meth:`~sage.graphs.generic_graph.GenericGraph._subgraph_by_adding` + method to ensure that resultant subgraph is also matching covered. + + INPUT: + + - ``vertices`` -- (default: ``None``) an iterable container of + vertices, e.g. a list, set, graph, file or numeric array. If not + passed (i.e., ``None``), defaults to the entire graph. + + - ``edges`` -- a single edge or an iterable container of edges (e.g., a + list, set, file, numeric array, etc.). By default (``edges=None``), + all edges are assumed and the returned graph is an induced + subgraph. In the case of multiple edges, specifying an edge as `(u,v)` + means to keep all edges `(u,v)`, regardless of the label. + + - ``edge_property`` -- function (default: ``None``); a function that + inputs an edge and outputs a boolean value, i.e., a edge ``e`` in + ``edges`` is kept if ``edge_property(e) == True`` + + - ``immutable`` -- boolean (default: ``None``); whether to create a + mutable/immutable subgraph. ``immutable=None`` (default) means that + the graph and its subgraph will behave the same way. + + OUTPUT: + + - An instance of :class:`~MatchingCoveredGraph` is returned if the + subgraph obtained is matching covered, otherwise a :exc:`ValueError` + is thrown. + + EXAMPLES: + + Ladder graphs are subgraphs of a staircase graph, that is + matching covered:: + + sage: G = MatchingCoveredGraph(graphs.StaircaseGraph(4)) + sage: H = G._subgraph_by_adding(vertices=[0..5]) + sage: H.order(), H.size() + (6, 7) + sage: H + Matching covered subgraph of (staircase graph): graph on 6 vertices + sage: H.is_isomorphic(graphs.LadderGraph(3)) + True + + Cycle graphs are subgraphs of a biwheel graph, that is + matching covered:: + + sage: G = MatchingCoveredGraph(graphs.BiwheelGraph(5)) + sage: H = G._subgraph_by_adding(vertices=[0..7], + ....: edges=[(u, (u+1) % 8) for u in range(8)]) + sage: H.order(), H.size() + (8, 8) + sage: H + Matching covered subgraph of (biwheel graph): graph on 8 vertices + sage: H.is_isomorphic(graphs.CycleGraph(8)) + True + + One may use the ``edge_property`` argument:: + + sage: G = Graph(multiedges=True) + sage: G.add_edges([ + ....: (0, 1, 'label'), (0, 2), (0, 3), (0, 4), + ....: (0, 5), (1, 2, 'label'), (1, 2), (1, 5), + ....: (2, 5), (3, 4), (3, 5), (4, 5) + ....: ]) + sage: H = MatchingCoveredGraph(G) + sage: J = H._subgraph_by_adding(vertices=[0, 1, 2, 5], edge_property= + ....: (lambda edge: + ....: (edge[0] in [1, 2]) != (edge[1] in [1, 2])) + ....: ) + sage: J.order(), J.size() + (4, 4) + sage: J + Matching covered subgraph of (): multi-graph on 4 vertices + sage: J.is_isomorphic(graphs.CompleteBipartiteGraph(2, 2)) + True + + We may specify the subgraph to be immutable:: + + sage: M = graphs.MoebiusLadderGraph(4) + sage: G = MatchingCoveredGraph(M) + sage: H = G._subgraph_by_adding(edge_property= + ....: (lambda edge: abs(edge[0] - edge[1]) != 4), + ....: immutable=True) + sage: H.order(), H.size() + (8, 8) + sage: H + Matching covered subgraph of (moebius ladder graph): graph on 8 vertices + sage: H.is_isomorphic(graphs.CycleGraph(8)) + True + sage: H.is_immutable() + True + + An error is thrown if the subgraph is not matching covered:: + + sage: P = graphs.PetersenGraph() + sage: G = MatchingCoveredGraph(P) + sage: H = G._subgraph_by_adding(vertices=[]) + Traceback (most recent call last): + ... + ValueError: the graph is trivial + sage: H = G._subgraph_by_adding(edge_property= + ....: (lambda edge: edge[0] == 0) + ....: ) + Traceback (most recent call last): + ... + ValueError: the graph is not connected + sage: H = G._subgraph_by_adding(vertices=[1, 2, 3]) + Traceback (most recent call last): + ... + ValueError: input graph is not matching covered + """ + if immutable is None: + immutable = self.is_immutable() + + if edges is None and edge_property is None: + if vertices is None: + G = self.copy() + G.name('Matching covered subgraph of ({})'.format(self.name())) + if immutable: + G = G.copy(immutable=True) + + return G + + else: + # Check if all existent vertices are there + all_existent_vertices = True + for vertex in self: + if vertex not in vertices: + all_existent_vertices = False + break + + if all_existent_vertices: + G = self.copy() + G.name('Matching covered subgraph of ({})'.format(self.name())) + if immutable: + G = G.copy(immutable=True) + + return G + + G = Graph(self, weighted=self._weighted, loops=self.allows_loops(), + multiedges=self.allows_multiple_edges()) + + H = G._subgraph_by_adding(vertices=vertices, edges=edges, + edge_property=edge_property, + immutable=False) + + try: + H = MatchingCoveredGraph(H) + H.name('Matching covered subgraph of ({})'.format(self.name())) + if immutable: + H = H.copy(immutable=True) + + return H + + except Exception as exception: + raise exception + def add_edge(self, u, v=None, label=None): r""" Add an edge from vertex ``u`` to vertex ``v``. From 273a44d70d6a914250e043f0be276de430ee51aa Mon Sep 17 00:00:00 2001 From: Sebastian Date: Tue, 29 Oct 2024 18:37:06 +0100 Subject: [PATCH 388/537] follow_up_38822 initial --- build/pkgs/database_knotinfo/checksums.ini | 4 ++-- build/pkgs/database_knotinfo/package-version.txt | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/build/pkgs/database_knotinfo/checksums.ini b/build/pkgs/database_knotinfo/checksums.ini index d6116d6d0d3..dc038308d45 100644 --- a/build/pkgs/database_knotinfo/checksums.ini +++ b/build/pkgs/database_knotinfo/checksums.ini @@ -1,4 +1,4 @@ tarball=database_knotinfo-VERSION.tar.gz -sha1=8bc72e561c009cc6a7c15eceedee522281fbf763 -sha256=805868c8f3c30888e5866d833aec4f9ab07ad92b7b7caeb09bfec4634b28b0fd +sha1=d94335a4839946e73458064d6ad1def9595101c7 +sha256=9065ec00e22bd1e43716b3e0c2d1bb9e2c32e504a24f11d81ab556428bb4aa7f upstream_url=https://pypi.io/packages/source/d/database_knotinfo/database_knotinfo-VERSION.tar.gz diff --git a/build/pkgs/database_knotinfo/package-version.txt b/build/pkgs/database_knotinfo/package-version.txt index b150c162f6e..142bb53d9d5 100644 --- a/build/pkgs/database_knotinfo/package-version.txt +++ b/build/pkgs/database_knotinfo/package-version.txt @@ -1 +1 @@ -2024.5.1 +2024.10.1 From a4e8851b8dff01f6cfac0fd99eccdc402f52f8b3 Mon Sep 17 00:00:00 2001 From: janmenjayap Date: Tue, 29 Oct 2024 23:07:32 +0530 Subject: [PATCH 389/537] corrected a class name --- src/sage/graphs/matching_covered_graph.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/graphs/matching_covered_graph.py b/src/sage/graphs/matching_covered_graph.py index 4a5d8a6dde6..b1ff6e9672d 100644 --- a/src/sage/graphs/matching_covered_graph.py +++ b/src/sage/graphs/matching_covered_graph.py @@ -18,7 +18,7 @@ .. TODO: The following methods are to be incorporated in - :class:`~sage.graphs.matching_covered_graph.MatchingCoveredGraph`:: + :class:`~MatchingCoveredGraph`:: - ``delete_edge()`` | Delete the edge from ``u`` to ``v``. - ``delete_edges()`` | Delete edges from an iterable container. From 37c18345323b5cb87b6792f9930c12e6c08d4e70 Mon Sep 17 00:00:00 2001 From: janmenjayap Date: Wed, 30 Oct 2024 10:36:12 +0530 Subject: [PATCH 390/537] added allows_loops() --- src/sage/graphs/matching_covered_graph.py | 28 +++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/src/sage/graphs/matching_covered_graph.py b/src/sage/graphs/matching_covered_graph.py index b1ff6e9672d..7e3ab4c3dda 100644 --- a/src/sage/graphs/matching_covered_graph.py +++ b/src/sage/graphs/matching_covered_graph.py @@ -1439,6 +1439,34 @@ def allow_loops(self, new, check=True): raise ValueError('loops are not allowed in ' 'matching covered graphs') + def allows_loops(self): + r""" + Return whether loops are permitted in (matching covered) graphs. + + .. NOTE:: + + This method overwrites the + :meth:`~sage.graphs.generic_graph.GenericGraph.allows_loops` method + to show that loops are forbidden in :class:`~MatchingCoveredGraph`. + + OUTPUT: + + - A boolean value ``False`` is returned, since matching covered graphs, + by definition, are free of loops. + + EXAMPLES: + + Petersen graph is matching covered:: + + sage: P = graphs.PetersenGraph() + sage: P.is_matching_covered() + True + sage: G = MatchingCoveredGraph(P) + sage: G.allows_loops() + False + """ + return False + def delete_vertex(self, vertex, in_order=False): r""" Delete a vertex, removing all incident edges. From 77938e8e051f308c9bc4c0ddde1aaa518eb91121 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Wed, 30 Oct 2024 11:18:11 +0530 Subject: [PATCH 391/537] Corrected groebner_basis() for FY presentation --- src/sage/matroids/chow_ring_ideal.py | 63 ++++++++++++++++++---------- 1 file changed, 40 insertions(+), 23 deletions(-) diff --git a/src/sage/matroids/chow_ring_ideal.py b/src/sage/matroids/chow_ring_ideal.py index afdafd671ab..760d35341d4 100644 --- a/src/sage/matroids/chow_ring_ideal.py +++ b/src/sage/matroids/chow_ring_ideal.py @@ -256,13 +256,19 @@ def normal_basis(self, algorithm='', *args, **kwargs): EXAMPLES:: - sage: ch = matroids.catalog.Fano().chow_ring(QQ, False) - sage: ch.defining_ideal().normal_basis() - [1, Abcd, Aace, Aabf, Adef, Aadg, Abeg, Acfg, Aabcdefg, Aabcdefg^2] + sage: ch = matroids.Z(3).chow_ring(QQ, False) + sage: I = ch.defining_ideal() + sage: I.normal_basis() + [1, Ax2x3y1, Ax1x3y2, Ax1x2y3, Ay1y2y3, Atx1y1, Atx2y2, Atx3y3, Atx1x2x3y1y2y3, Atx1x2x3y1y2y3^2] + sage: set(I.gens().ideal().normal_basis()) == set(I.normal_basis()) + True sage: ch = matroids.AG(2,3).chow_ring(QQ, False) - sage: ch.defining_ideal().normal_basis() + sage: I = ch.defining_ideal() + sage: I.normal_basis() [1, A012, A236, A046, A156, A345, A247, A057, A137, A258, A678, A038, A148, A012345678, A012345678^2] + sage: set(I.gens().ideal().normal_basis()) == set(I.normal_basis()) + True """ if algorithm == '': algorithm = 'constructed' @@ -486,9 +492,9 @@ def groebner_basis(self, algorithm='', *args, **kwargs): EXAMPLES:: - sage: ch = matroids.Uniform(2,5).chow_ring(QQ, True, 'fy') + sage: ch = matroids.catalog.NonFano().chow_ring(QQ, True, 'fy') sage: ch.defining_ideal().groebner_basis(algorithm='') - Polynomial Sequence with 33 Polynomials in 12 Variables + Polynomial Sequence with 178 Polynomials in 25 Variables sage: ch.defining_ideal().groebner_basis(algorithm='').is_groebner() True sage: ch.defining_ideal().hilbert_series() == ch.defining_ideal().hilbert_series(algorithm='singular') @@ -518,11 +524,11 @@ def groebner_basis(self, algorithm='', *args, **kwargs): for H in lattice_flats.order_filter([F]): term1 += self._flats_generator[H] if term1 != poly_ring.zero(): - gb.append(term1**(self._matroid.rank(G) + 1)) #5.6 (MM2022) + gb.append(term1**(self._matroid.rank(F) + 1)) #5.6 (MM2022) order_ideal_modified = lattice_flats.order_ideal([F]) order_ideal_modified.remove(F) for G in order_ideal_modified: # nested flats - gb.append(self._flats_generator[F]*term1**(self._matroid.rank(F) - self._matroid.rank(G))) + gb.append(self._flats_generator[G]*term1**(self._matroid.rank(F) - self._matroid.rank(G))) return PolynomialSequence(poly_ring, [gb]) @@ -532,12 +538,18 @@ def normal_basis(self, algorithm='', *args, **kwargs): EXAMPLES:: - sage: ch = matroids.catalog.K33().chow_ring(QQ, True, 'fy') - sage: ch.defining_ideal().normal_basis() - Polynomial Sequence with 1758 Polynomials in 127 Variables - sage: ch = matroids.catalog.Wheel4().chow_ring(QQ, True, 'fy') - sage: ch.defining_ideal().normal_basis() - Polynomial Sequence with 200 Polynomials in 42 Variables + 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] + sage: set(I.gens().ideal().normal_basis()) == set(I.normal_basis()) + True + sage: ch = matroids.catalog.Fano().chow_ring(QQ, True, 'fy') + sage: I = ch.defining_ideal() + sage: I.normal_basis() + Polynomial Sequence with 32 Polynomials in 15 Variables + sage: set(I.gens().ideal().normal_basis()) == set(I.normal_basis()) + True """ if algorithm == '': algorithm = 'constructed' @@ -702,11 +714,10 @@ def groebner_basis(self, algorithm='', *args, **kwargs): EXAMPLES:: - sage: M1 = Matroid(graphs.CycleGraph(3)) + sage: M1 = matroids.Uniform(3,6) sage: ch = M1.chow_ring(QQ, True, 'atom-free') sage: ch.defining_ideal().groebner_basis(algorithm='') - [A0*A1, A0*A2, A1*A2, A0^2 + 2*A0*A3 + A3^2, A1^2 + 2*A1*A3 + A3^2, - A2^2 + 2*A2*A3 + A3^2, A0*A3, A1*A3, A2*A3, A3^3] + Polynomial Sequence with 253 Polynomials in 22 Variables sage: ch.defining_ideal().groebner_basis(algorithm='').is_groebner() True sage: ch.defining_ideal().hilbert_series() == ch.defining_ideal().hilbert_series(algorithm='singular') @@ -742,12 +753,18 @@ def normal_basis(self, algorithm='', *args, **kwargs): EXAMPLES:: - sage: ch = matroids.Whirl(5).chow_ring(QQ, True, 'atom-free') - sage: ch.defining_ideal().normal_basis() - Polynomial Sequence with 1726 Polynomials in 121 Variables - sage: ch = matroids.Z(4).chow_ring(QQ, True, 'atom-free') - sage: ch.defining_ideal().normal_basis() - Polynomial Sequence with 248 Polynomials in 52 Variables + sage: ch = Matroid(graphs.CycleGraph(3)).chow_ring(QQ, True, 'atom-free') + sage: I = ch.defining_ideal() + sage: I.normal_basis() + [1, A0, A1, A2, A3, A3^2] + sage: set(I.gens().ideal().normal_basis()) == set(I.normal_basis()) + True + sage: ch = matroids.Wheel(3).chow_ring(QQ, True, 'atom-free') + sage: I = ch.defining_ideal() + sage: I.normal_basis() + Polynomial Sequence with 30 Polynomials in 14 Variables + sage: set(I.gens().ideal().normal_basis()) == set(I.normal_basis()) + True """ if algorithm == '': algorithm = 'constructed' From 509cfd0afb07df505a7d0d1d783f611bfc80aaec Mon Sep 17 00:00:00 2001 From: janmenjayap Date: Wed, 30 Oct 2024 14:22:12 +0530 Subject: [PATCH 392/537] added REFERENCES --- src/sage/graphs/matching_covered_graph.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/sage/graphs/matching_covered_graph.py b/src/sage/graphs/matching_covered_graph.py index 7e3ab4c3dda..8d0d64edc6d 100644 --- a/src/sage/graphs/matching_covered_graph.py +++ b/src/sage/graphs/matching_covered_graph.py @@ -11,6 +11,11 @@ edge set of an 1-regular spanning subgraph. A connected nontrivial graph is called *matching* *covered* if each edge participates in some perfect matching. +REFERENCES: + +- This methods of this module has been adopted and inspired by the book of + Lucchesi and Murty [LM2024]_. + AUTHORS: - Janmenjaya Panda (2024-06-14): initial version From 2b49ba0d023611d710e5e5cd433d81618c945e05 Mon Sep 17 00:00:00 2001 From: janmenjayap Date: Wed, 30 Oct 2024 14:28:37 +0530 Subject: [PATCH 393/537] updated the TODO list --- src/sage/graphs/matching_covered_graph.py | 54 ++++++++++++++++++++--- 1 file changed, 49 insertions(+), 5 deletions(-) diff --git a/src/sage/graphs/matching_covered_graph.py b/src/sage/graphs/matching_covered_graph.py index 8d0d64edc6d..360e7872754 100644 --- a/src/sage/graphs/matching_covered_graph.py +++ b/src/sage/graphs/matching_covered_graph.py @@ -15,27 +15,71 @@ - This methods of this module has been adopted and inspired by the book of Lucchesi and Murty [LM2024]_. - + AUTHORS: - Janmenjaya Panda (2024-06-14): initial version -.. TODO: +.. TODO:: The following methods are to be incorporated in - :class:`~MatchingCoveredGraph`:: + :class:`~MatchingCoveredGraph`: + + Overwritten Methods: - ``delete_edge()`` | Delete the edge from ``u`` to ``v``. - ``delete_edges()`` | Delete edges from an iterable container. - - ``is_removable_double_ear()`` | Check whether the pair of ears form a removable double ear. - - ``is_removable_doubleton()`` | Check whether the pair of edges constitute a removable doubleton. + + Barriers and canonical partition: + + - ``canonical_partition()`` | Return the canonical partition of the + (matching covered) graph. + - ``maximal_barrier()`` | Return the (unique) maximal barrier of the + (matching covered) graph containing the (provided) vertex. + + Bricks, braces and tight cut decomposition: + + - ``bricks_and_braces()`` | Return the list of (underlying simple graph of) + the bricks and braces of the (matching covered) graph. + - ``is_brace()`` | Check if the (matching covered) graph is a brace. + - ``is_brick()`` | Check if the (matching covered) graph is a brick. + - ``number_of_braces()`` | Return the number of braces. + - ``number_of_bricks()`` | Return the number of bricks. + - ``number_of_petersen_bricks()`` | Return the number of Petersen bricks. + - ``tight_cut_decomposition()`` | Return a tight cut decomposition. + + Removability and ear decomposition: + + - ``efficient_ear_decomposition()`` | Return a matching covered ear + decomposition computed at the fastest possible time. + - ``is_removable_double_ear()`` | Check whether the pair of ears form a + removable double ear. + - ``is_removable_doubleton()`` | Check whether the pair of edges constitute + a removable doubleton. - ``is_removable_ear()`` | Check whether the ear is removable. - ``is_removable_edge()`` | Check whether the edge is removable. + - ``optimal_ear_decomposition()`` | Return an optimal ear decomposition. - ``removable_double_ears()`` | Return a list of removable double ears. - ``removable_doubletons()`` | Return a list of removable doubletons. - ``removable_ears()`` | Return a list of removable ears. - ``removable_edges()`` | Return a :class:`~EdgesView` of removable edges. + - ``retract()`` | Compute the retract of the (matching covered) graph. + + Generating bricks and braces: + + - ``brace_generation_sequence()`` | Return a McCuaig brace generation + sequence of the (given) brace. + - ``brick_generation_sequence()`` | Return a Norine-Thomas brick generation + sequence of the (given) brick. + - ``is_mccuaig_brace()`` | Check if the brace is a McCuaig brace. + - ``is_norine_thomas_brick()`` | Check if the brick is a Norine-Thomas + brick. + + +Methods +------- """ + # **************************************************************************** # Copyright (C) 2024 Janmenjaya Panda # From 021ef7c2b3de629464aa0eef2670a27442d3d949 Mon Sep 17 00:00:00 2001 From: janmenjayap Date: Wed, 30 Oct 2024 14:31:32 +0530 Subject: [PATCH 394/537] added doc_index --- src/sage/graphs/matching_covered_graph.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/sage/graphs/matching_covered_graph.py b/src/sage/graphs/matching_covered_graph.py index 360e7872754..e4cb77ad43f 100644 --- a/src/sage/graphs/matching_covered_graph.py +++ b/src/sage/graphs/matching_covered_graph.py @@ -11,6 +11,8 @@ edge set of an 1-regular spanning subgraph. A connected nontrivial graph is called *matching* *covered* if each edge participates in some perfect matching. +{INDEX_OF_METHODS} + REFERENCES: - This methods of this module has been adopted and inspired by the book of @@ -90,6 +92,7 @@ # https://www.gnu.org/licenses/ # **************************************************************************** from .graph import Graph +from sage.misc.rest_index_of_methods import doc_index class MatchingCoveredGraph(Graph): r""" @@ -632,6 +635,7 @@ def __repr__(self): return s.capitalize() return "".join(["Matching covered ", s]) + @doc_index('Overwritten methods') def _subgraph_by_adding(self, vertices=None, edges=None, edge_property=None, immutable=None): r""" Return the matching covered subgraph containing the given vertices and edges. @@ -800,6 +804,7 @@ def _subgraph_by_adding(self, vertices=None, edges=None, edge_property=None, imm except Exception as exception: raise exception + @doc_index('Overwritten methods') def add_edge(self, u, v=None, label=None): r""" Add an edge from vertex ``u`` to vertex ``v``. @@ -1043,6 +1048,7 @@ def add_edge(self, u, v=None, label=None): '(%s) is not matching covered' % str((u, v, label))) + @doc_index('Overwritten methods') def add_edges(self, edges, loops=False): r""" Add edges from an iterable container. @@ -1319,6 +1325,7 @@ def add_edges(self, edges, loops=False): raise ValueError('the resulting graph after the addition of' 'the edges is not matching covered') + @doc_index('Overwritten methods') def add_vertex(self, name=None): r""" Add a vertex to the (matching covered) graph. @@ -1375,6 +1382,7 @@ def add_vertex(self, name=None): raise ValueError('isolated vertices are not allowed in ' 'matching covered graphs') + @doc_index('Overwritten methods') def add_vertices(self, vertices): r""" Add vertices to the (matching covered) graph from an iterable container @@ -1444,6 +1452,7 @@ def add_vertices(self, vertices): raise ValueError('isolated vertices are not allowed in ' 'matching covered graphs') + @doc_index('Overwritten methods') def allow_loops(self, new, check=True): r""" Change whether loops are allowed in (matching covered) graphs. @@ -1488,6 +1497,7 @@ def allow_loops(self, new, check=True): raise ValueError('loops are not allowed in ' 'matching covered graphs') + @doc_index('Overwritten methods') def allows_loops(self): r""" Return whether loops are permitted in (matching covered) graphs. @@ -1516,6 +1526,7 @@ def allows_loops(self): """ return False + @doc_index('Overwritten methods') def delete_vertex(self, vertex, in_order=False): r""" Delete a vertex, removing all incident edges. @@ -1574,6 +1585,7 @@ def delete_vertex(self, vertex, in_order=False): raise ValueError('odd order is not allowed for ' 'matching covered graphs') + @doc_index('Overwritten methods') def delete_vertices(self, vertices): r""" Delete specified vertices form ``self``. @@ -1725,6 +1737,7 @@ def delete_vertices(self, vertices): raise ValueError('the resulting graph after the removal of ' 'the vertices is not matching covered') + @doc_index('Overwritten methods') def get_matching(self): r""" Return a :class:`~EdgesView` of ``self._matching`` (a perfect matching @@ -1763,6 +1776,7 @@ def get_matching(self): """ return self._matching + @doc_index('Miscellaneous methods') def update_matching(self, matching): r""" Update the perfect matching captured in ``self._matching``. From 58739eff1e248dafe0519fc69b30390d677f325f Mon Sep 17 00:00:00 2001 From: janmenjayap Date: Wed, 30 Oct 2024 15:04:23 +0530 Subject: [PATCH 395/537] added _upgrade_from_graph() --- src/sage/graphs/matching_covered_graph.py | 40 ++++++++++++++++------- 1 file changed, 29 insertions(+), 11 deletions(-) diff --git a/src/sage/graphs/matching_covered_graph.py b/src/sage/graphs/matching_covered_graph.py index e4cb77ad43f..12bcfc59d4d 100644 --- a/src/sage/graphs/matching_covered_graph.py +++ b/src/sage/graphs/matching_covered_graph.py @@ -554,17 +554,12 @@ def __init__(self, data=None, matching=None, algorithm='Edmonds', elif isinstance(data, Graph): try: - check = Graph.is_matching_covered(G=data, matching=matching, - algorithm=algorithm, - coNP_certificate=False, - solver=solver, verbose=verbose, - integrality_tolerance=integrality_tolerance) - - if check: - Graph.__init__(self, data, *args, **kwds) - success = True - else: - raise ValueError("input graph is not matching covered") + self._upgrade_from_graph(data=data, matching=matching, + algorithm=algorithm, + solver=solver, verbose=verbose, + integrality_tolerance=integrality_tolerance, + *args, **kwds) + success = True except Exception as exception: raise exception @@ -804,6 +799,29 @@ def _subgraph_by_adding(self, vertices=None, edges=None, edge_property=None, imm except Exception as exception: raise exception + def _upgrade_from_graph(self, data=None, matching=None, algorithm='Edmonds', + solver=None, verbose=0, integrality_tolerance=0.001, + *args, **kwds): + r""" + Upgrade the given graph to a matching covered graph if eligible. + + See documentation ``MatchingCoveredGraph?`` for detailed information. + """ + try: + check = Graph.is_matching_covered(G=data, matching=matching, + algorithm=algorithm, + coNP_certificate=False, + solver=solver, verbose=verbose, + integrality_tolerance=integrality_tolerance) + + if check: + Graph.__init__(self, data, *args, **kwds) + else: + raise ValueError("input graph is not matching covered") + + except Exception as exception: + raise exception + @doc_index('Overwritten methods') def add_edge(self, u, v=None, label=None): r""" From f6c188b3645c904fc4b85165a1e10c6b97ca618c Mon Sep 17 00:00:00 2001 From: janmenjayap Date: Wed, 30 Oct 2024 15:51:48 +0530 Subject: [PATCH 396/537] added the file to sage/graphs/meson.build --- src/sage/graphs/meson.build | 1 + 1 file changed, 1 insertion(+) diff --git a/src/sage/graphs/meson.build b/src/sage/graphs/meson.build index dbc1808f107..d88f1942daf 100644 --- a/src/sage/graphs/meson.build +++ b/src/sage/graphs/meson.build @@ -36,6 +36,7 @@ py.install_sources( 'isgci.py', 'lovasz_theta.py', 'matching.py', + 'matching_covered_graph.py', 'mcqd.pxd', 'orientations.py', 'partial_cube.py', From aa5d41dea25faefbdf416c342be6d6d3d1729169 Mon Sep 17 00:00:00 2001 From: janmenjayap Date: Thu, 31 Oct 2024 12:16:02 +0530 Subject: [PATCH 397/537] added the book name --- src/sage/graphs/matching_covered_graph.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/sage/graphs/matching_covered_graph.py b/src/sage/graphs/matching_covered_graph.py index 12bcfc59d4d..08444b90cf9 100644 --- a/src/sage/graphs/matching_covered_graph.py +++ b/src/sage/graphs/matching_covered_graph.py @@ -16,7 +16,8 @@ REFERENCES: - This methods of this module has been adopted and inspired by the book of - Lucchesi and Murty [LM2024]_. + Lucchesi and Murty --- *Perfect Matchings: a theory of matching covered + graphs* [LM2024]_. AUTHORS: From b8b9b6c32f891965faa279df2282ea8911d06495 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Fri, 1 Nov 2024 11:33:41 +0100 Subject: [PATCH 398/537] a few details in combinat, following ruff and pycodestyle --- .../rigged_configurations/kleber_tree.py | 62 +++++++++---------- src/sage/combinat/tableau.py | 32 ++++------ src/sage/combinat/words/finite_word.py | 31 +++++----- src/sage/combinat/words/morphism.py | 9 ++- 4 files changed, 63 insertions(+), 71 deletions(-) diff --git a/src/sage/combinat/rigged_configurations/kleber_tree.py b/src/sage/combinat/rigged_configurations/kleber_tree.py index e82b6c28035..6ee130bb789 100644 --- a/src/sage/combinat/rigged_configurations/kleber_tree.py +++ b/src/sage/combinat/rigged_configurations/kleber_tree.py @@ -122,7 +122,10 @@ def _draw_tree(tree_node, node_label=True, style_point=None, style_node='fill=wh start = [0., 0.] if rpos is None: rpos = [0., 0.] - draw_point = lambda point: '(%.3f, %.3f)' % (point[0],point[1]) + + def draw_point(point): + return '(%.3f, %.3f)' % (point[0], point[1]) + if not tree_node.children: r = '' node_name = node_prefix + str(node_id) @@ -149,7 +152,7 @@ def _draw_tree(tree_node, node_label=True, style_point=None, style_node='fill=wh nb_children = len(tree_node.children) half = nb_children // 2 children_str = '' - pos = [start[0],start[1]] + pos = [start[0], start[1]] start[1] += vspace lines_str = '' @@ -269,7 +272,7 @@ def depth(self): sage: n2.depth 1 """ - depth = -1 # Offset + depth = -1 # Offset cur = self while cur is not None: depth += 1 @@ -337,7 +340,7 @@ def multiplicity(self): mult = Integer(1) for a, m in self.up_root: p = self.weight[a] - for r,s in self.parent().B: + for r, s in self.parent().B: if r == a and s > self.depth: p -= s - self.depth mult *= binomial(m + p, m) @@ -346,7 +349,7 @@ def multiplicity(self): cur = self.parent_node while cur.parent_node is not None: root_diff = cur.up_root - prev_up_root - for a,m in root_diff: + for a, m in root_diff: p = cur.weight[a] for r, s in self.parent().B: if r == a and s > cur.depth: @@ -636,7 +639,8 @@ def __init__(self, cartan_type, B, classical_ct): self._CM = self._classical_ct.cartan_matrix().dense_matrix() self._build_tree() self._latex_options = dict(edge_labels=True, use_vector_notation=False, - hspace=2.5, vspace=min(-2.5, -0.75*self._classical_ct.rank())) + hspace=2.5, + vspace=min(-2.5, -0.75*self._classical_ct.rank())) def latex_options(self, **options): """ @@ -705,21 +709,19 @@ def _build_tree(self): # Create an empty node at first step self.root = KleberTreeNode(self, P.zero(), self._classical_ct.root_system().root_lattice().zero()) - full_list = [self.root] # The list of tree nodes + full_list = [self.root] # The list of tree nodes n = self._classical_ct.rank() # Convert the B values into an L matrix - L = [] I = self._classical_ct.index_set() - for i in range(n): - L.append([0]) + L = [[0] for _ in range(n)] - for r,s in self.B: - while len(L[0]) < s: # Add more columns if needed + for r, s in self.B: + while len(L[0]) < s: # Add more columns if needed for row in L: row.append(0) - L[I.index(r)][s - 1] += 1 # The -1 is for indexing + L[I.index(r)][s - 1] += 1 # The -1 is for indexing # Perform a special case of the algorithm for the root node weight_basis = P.basis() @@ -751,7 +753,7 @@ def _build_tree(self): for x in full_list: growth = True for a in range(n): - for i in range(depth - 1, len(L[a])): # Subtract 1 for indexing + for i in range(depth - 1, len(L[a])): # Subtract 1 for indexing x.weight += L[a][i] * weight_basis[I[a]] new_children = [new_child @@ -824,16 +826,16 @@ def _children_iter(self, node): # Construct the shifted weight cone root_weight = node.weight.to_vector() ieqs = [[root_weight[i]] + list(col) - for i,col in enumerate(self._CM.columns())] + for i, col in enumerate(self._CM.columns())] # Construct the negative weight cone for i in range(n): v = [0] * (n+1) v[i+1] = -1 ieqs.append(v) - ieqs.append([-1]*(n+1)) # For avoiding the origin + ieqs.append([-1]*(n+1)) # For avoiding the origin # Construct the bounds for the non-root nodes if node != self.root: - for i,c in enumerate(node.up_root.to_vector()): + for i, c in enumerate(node.up_root.to_vector()): v = [0] * (n+1) v[0] = c v[i+1] = 1 @@ -849,9 +851,9 @@ def _children_iter(self, node): # Build the nodes from the polytope # Sort for a consistent ordering (it is typically a small list) for pt in sorted(poly.integral_points(), reverse=True): - up_root = Q._from_dict({I[i]: -val for i,val in enumerate(pt) if val != 0}, + up_root = Q._from_dict({I[i]: -val for i, val in enumerate(pt) if val != 0}, remove_zeros=False) - wt = node.weight + sum(val * P.simple_root(I[i]) for i,val in enumerate(pt)) + wt = node.weight + sum(val * P.simple_root(I[i]) for i, val in enumerate(pt)) yield KleberTreeNode(self, wt, up_root, node) def _children_iter_vector(self, node): @@ -895,9 +897,9 @@ def _children_iter_vector(self, node): converted_root = sum(cols[i] * c for i, c in enumerate(root) if c != 0) - if all(wt[i] >= val for i,val in enumerate(converted_root)): - wd = {I[i]: wt[i] - val for i,val in enumerate(converted_root)} - rd = {I[i]: val for i,val in enumerate(root) if val != 0} + if all(wt[i] >= val for i, val in enumerate(converted_root)): + wd = {I[i]: wt[i] - val for i, val in enumerate(converted_root)} + rd = {I[i]: val for i, val in enumerate(root) if val != 0} yield KleberTreeNode(self, P._from_dict(wd), Q._from_dict(rd, remove_zeros=False), @@ -1171,14 +1173,12 @@ def __init__(self, cartan_type, B): sage: TestSuite(KT).run(skip='_test_elements') """ self._folded_ct = cartan_type.as_folding() - virtual_dims = [] self.base_dims = B sigma = self._folded_ct.folding_orbit() gamma = self._folded_ct.scaling_factors() classical_ct = self._folded_ct.folding_of().classical() - for r,s in B: - for i in sigma[r]: - virtual_dims.append([i, s * gamma[r]]) + virtual_dims = [[i, s * gamma[r]] + for r, s in B for i in sigma[r]] KleberTree.__init__(self, cartan_type, virtual_dims, classical_ct) @@ -1229,8 +1229,9 @@ def _prune(self, new_child, depth): return True gamma = self._folded_ct.scaling_factors() for a in range(1, len(gamma)): - if (depth - 1) % gamma[a] != 0 and new_child.up_root[sigma[a][0]] \ - != new_child.parent_node.up_root[sigma[a][0]]: + s = sigma[a][0] + if ((depth - 1) % gamma[a] != 0 and + new_child.up_root[s] != new_child.parent_node.up_root[s]): return True return False @@ -1371,12 +1372,11 @@ def __init__(self, cartan_type, B): self.base_dims = B sigma = self._folded_ct.folding_orbit() classical_ct = self._folded_ct.folding_of().classical() - for r,s in B: + for r, s in B: if r == n: virtual_dims.extend([[n, s], [n, s]]) else: - for i in sigma[r]: - virtual_dims.append([i, s]) + virtual_dims.extend([i, s] for i in sigma[r]) KleberTree.__init__(self, cartan_type, virtual_dims, classical_ct) diff --git a/src/sage/combinat/tableau.py b/src/sage/combinat/tableau.py index 80e3391b279..aace1ba5a2c 100644 --- a/src/sage/combinat/tableau.py +++ b/src/sage/combinat/tableau.py @@ -2055,14 +2055,14 @@ def k_weight(self, k): w = self.weight() s = self.cells() - for l in range(1, len(w)+1): + for l in range(1, len(w) + 1): new_s = [(i, j) for i, j in s if self[i][j] == l] # If there are no elements that meet the condition - if new_s == []: + if not new_s: res.append(0) continue - x = set((i-j) % (k+1) for i, j in new_s) + x = {(i - j) % (k + 1) for i, j in new_s} res.append(len(x)) return res @@ -2955,9 +2955,8 @@ def row_stabilizer(self): # tableau, by including the identity permutation on the set [1..k]. k = self.size() gens = [list(range(1, k + 1))] - for row in self: - for j in range(len(row) - 1): - gens.append((row[j], row[j + 1])) + gens.extend((row[j], row[j + 1]) + for row in self for j in range(len(row) - 1)) return PermutationGroup(gens) def column_stabilizer(self): @@ -7675,9 +7674,9 @@ def __contains__(self, x): """ if isinstance(x, StandardTableau): return True - elif Tableaux.__contains__(self, x): + if Tableaux.__contains__(self, x): flatx = sorted(c for row in x for c in row) - return flatx == list(range(1, len(flatx)+1)) and (len(x) == 0 or + return all(i == fi for i, fi in enumerate(flatx, start=1)) and (len(x) == 0 or (all(row[i] < row[i+1] for row in x for i in range(len(row)-1)) and all(x[r][c] < x[r+1][c] for r in range(len(x)-1) for c in range(len(x[r+1]))) @@ -8183,25 +8182,20 @@ def random_element(self): t = [[None] * n for n in p] # Get the cells in the Young diagram - cells = [] - for i in range(len(p)): - for j in range(p[i]): - cells.append((i, j)) + cells = [(i, j) for i in range(len(p)) for j in range(p[i])] m = sum(p) - while m > 0: + while m: # Choose a cell at random cell = random.choice(cells) # Find a corner inner_corners = p.corners() while cell not in inner_corners: - hooks = [] - for k in range(cell[1] + 1, p[cell[0]]): - hooks.append((cell[0], k)) - for k in range(cell[0] + 1, len(p)): - if p[k] > cell[1]: - hooks.append((k, cell[1])) + c0, c1 = cell + hooks = [(c0, k) for k in range(c1 + 1, p[c0])] + hooks.extend((k, c1) + for k in range(c0 + 1, len(p)) if p[k] > c1) cell = random.choice(hooks) # Assign m to cell diff --git a/src/sage/combinat/words/finite_word.py b/src/sage/combinat/words/finite_word.py index 23e02ad61fb..ba9bf3f2157 100644 --- a/src/sage/combinat/words/finite_word.py +++ b/src/sage/combinat/words/finite_word.py @@ -511,10 +511,10 @@ def fcn(n): length = exp * self.length() if length in ZZ and length >= 0: return self._parent(fcn, length=length) - else: - raise ValueError("Power of the word is not defined on the exponent {}:" - " the length of the word ({}) times the exponent ({}) must" - " be a positive integer".format(exp, self.length(), exp)) + + raise ValueError("Power of the word is not defined on the exponent {}: " + "the length of the word ({}) times the exponent ({}) must " + "be a positive integer".format(exp, self.length(), exp)) def length(self): r""" @@ -4153,8 +4153,7 @@ def last_position_dict(self): {'1': 3, '2': 6, '3': 5} """ d = {} - for i, letter in enumerate(self): - d[letter] = i + d.update((letter, i) for i, letter in enumerate(self)) return d def _pos_in(self, other, p): @@ -4191,7 +4190,7 @@ def _pos_in(self, other, p): """ from sage.misc.superseded import deprecation deprecation(30187, 'f._pos_in(w, start) is deprecated.' - ' Use w.first_occurrence(f, start) instead.') + ' Use w.first_occurrence(f, start) instead.') return other.first_occurrence(self, p) def first_pos_in(self, other): @@ -4219,7 +4218,7 @@ def first_pos_in(self, other): """ from sage.misc.superseded import deprecation deprecation(30187, 'f.first_pos_in(w) is deprecated.' - ' Use w.first_occurrence(f) instead.') + ' Use w.first_occurrence(f) instead.') return other.first_occurrence(self) def find(self, sub, start=0, end=None): @@ -4440,7 +4439,7 @@ def factor_occurrences_in(self, other): """ from sage.misc.superseded import deprecation deprecation(30187, 'f.factor_occurrences_in(w) is deprecated.' - ' Use w.factor_occurrences_iterator(f) instead.') + ' Use w.factor_occurrences_iterator(f) instead.') return other.factor_occurrences_iterator(self) def nb_factor_occurrences_in(self, other): @@ -4475,7 +4474,7 @@ def nb_factor_occurrences_in(self, other): """ from sage.misc.superseded import deprecation deprecation(30187, 'f.nb_factor_occurrences_in(w) is deprecated.' - ' Use w.number_of_factor_occurrences(f) instead.') + ' Use w.number_of_factor_occurrences(f) instead.') return other.number_of_factor_occurrences(self) def nb_subword_occurrences_in(self, other): @@ -4544,7 +4543,7 @@ def nb_subword_occurrences_in(self, other): """ from sage.misc.superseded import deprecation deprecation(30187, 'f.nb_subword_occurrences_in(w) is deprecated.' - ' Use w.number_of_subword_occurrences(f) instead.') + ' Use w.number_of_subword_occurrences(f) instead.') return other.number_of_subword_occurrences(self) def number_of_factor_occurrences(self, other): @@ -5675,7 +5674,7 @@ def abelian_vectors(self, n): size = alphabet.cardinality() if size == float('inf'): raise TypeError("The alphabet of the parent is infinite; define" - " the word with a parent on a finite alphabet") + " the word with a parent on a finite alphabet") S = set() if n > self.length(): return S @@ -6105,8 +6104,8 @@ def abelian_vector(self): alphabet = self.parent().alphabet() if alphabet.cardinality() is Infinity: raise TypeError("The alphabet of the parent is infinite; define " - "the word with a parent on a finite alphabet or use " - "evaluation_dict() instead") + "the word with a parent on a finite alphabet " + "or use evaluation_dict() instead") ev_dict = self.evaluation_dict() return [ev_dict.get(a, 0) for a in alphabet] @@ -6803,8 +6802,8 @@ def colored_vector(self, x=0, y=0, width='default', height=1, cmap='hsv', thickn else: ordered_alphabet = self.parent().alphabet() dim = float(self.parent().alphabet().cardinality()) - letter_to_integer_dict = {a: i for i, a in - enumerate(ordered_alphabet)} + letter_to_integer_dict = {a: i + for i, a in enumerate(ordered_alphabet)} xp = x for a in self: i = letter_to_integer_dict[a] diff --git a/src/sage/combinat/words/morphism.py b/src/sage/combinat/words/morphism.py index 7ff3b53451c..343fe8af9eb 100644 --- a/src/sage/combinat/words/morphism.py +++ b/src/sage/combinat/words/morphism.py @@ -1048,8 +1048,7 @@ def extend_by(self, other): raise TypeError("other (=%s) is not a WordMorphism" % other) nv = dict(other._morph) - for k, v in self._morph.items(): - nv[k] = v + nv.update(self._morph) return WordMorphism(nv) def restrict_domain(self, alphabet): @@ -2467,9 +2466,9 @@ def dual_map(self, k=1): if k == 1: from sage.combinat.e_one_star import E1Star return E1Star(self) - else: - raise NotImplementedError("the dual map E_k^*" + - " is implemented only for k = 1 (not %s)" % k) + + raise NotImplementedError("the dual map E_k^* is implemented only " + "for k = 1 (not %s)" % k) @cached_method def rauzy_fractal_projection(self, eig=None, prec=53): From 826f34fad001d4cf285bd08393c4d35dfe11d622 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Fri, 1 Nov 2024 19:52:07 +0100 Subject: [PATCH 399/537] avoid one function --- src/sage/combinat/rigged_configurations/kleber_tree.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/sage/combinat/rigged_configurations/kleber_tree.py b/src/sage/combinat/rigged_configurations/kleber_tree.py index 6ee130bb789..551c975ce76 100644 --- a/src/sage/combinat/rigged_configurations/kleber_tree.py +++ b/src/sage/combinat/rigged_configurations/kleber_tree.py @@ -123,13 +123,10 @@ def _draw_tree(tree_node, node_label=True, style_point=None, style_node='fill=wh if rpos is None: rpos = [0., 0.] - def draw_point(point): - return '(%.3f, %.3f)' % (point[0], point[1]) - if not tree_node.children: r = '' node_name = node_prefix + str(node_id) - r = "\\node (%s) at %s" % (node_name, draw_point(start)) + r = "\\node (%s) at (%.3f, %.3f)" % (node_name, *start) if node_label: r += "{$%s$};\n" % tree_node._latex_() else: @@ -187,7 +184,7 @@ def draw_point(point): rpos[0] = pos[0] rpos[1] = pos[1] point_str = '' - node_str = "\\node%s (%s) at %s" % (style_node, node_name, draw_point(pos)) + node_str = "\\node%s (%s) at (%.3f, %.3f)" % (style_node, node_name, *pos) if node_label: node_str += "{$%s$};\n" % tree_node._latex_() else: From d649f31896ec8c3baca32943aba9c762199a5df5 Mon Sep 17 00:00:00 2001 From: Marc Culler Date: Fri, 1 Nov 2024 14:34:26 -0500 Subject: [PATCH 400/537] Update gcc spkg to 14.2.0 using iains/gcc-14-branch --- build/pkgs/gcc/checksums.ini | 8 +- build/pkgs/gcc/package-version.txt | 2 +- build/pkgs/gcc/patches/gcc-13_3_0.patch | 14497 ---------------- build/pkgs/gcc/patches/gcc-multiarch.patch | 235 - .../gcc/patches/gcc-multilib-multiarch.patch | 126 - 5 files changed, 5 insertions(+), 14863 deletions(-) delete mode 100644 build/pkgs/gcc/patches/gcc-13_3_0.patch delete mode 100644 build/pkgs/gcc/patches/gcc-multiarch.patch delete mode 100644 build/pkgs/gcc/patches/gcc-multilib-multiarch.patch diff --git a/build/pkgs/gcc/checksums.ini b/build/pkgs/gcc/checksums.ini index f9c9ba9f3a8..2145abdf067 100644 --- a/build/pkgs/gcc/checksums.ini +++ b/build/pkgs/gcc/checksums.ini @@ -1,4 +1,4 @@ -tarball=gcc-VERSION.tar.xz -sha1=6501872415823c95d48be28853ce3ebd6c1040c4 -sha256=0845e9621c9543a13f484e94584a49ffc0129970e9914624235fc1d061a0c083 -upstream_url=https://mirrors.kernel.org/gnu/gcc/gcc-VERSION/gcc-VERSION.tar.xz +tarball=gcc-VERSION.tar.gz +sha1=c25c11e209fbfa795e80e354f8f48f181decd83b +sha256=23c2a1b2ce01e9d51948339869453229173c6889758137e7e517b545ae8bfc02 +upstream_url=https://github.com/iains/gcc-14-branch/archive/refs/tags/gcc-14.2-darwin-r2.tar.gz diff --git a/build/pkgs/gcc/package-version.txt b/build/pkgs/gcc/package-version.txt index ac565bc1cab..07ea9fa4381 100644 --- a/build/pkgs/gcc/package-version.txt +++ b/build/pkgs/gcc/package-version.txt @@ -1 +1 @@ -13.3.0 +14.2.0 diff --git a/build/pkgs/gcc/patches/gcc-13_3_0.patch b/build/pkgs/gcc/patches/gcc-13_3_0.patch deleted file mode 100644 index f121fdb6461..00000000000 --- a/build/pkgs/gcc/patches/gcc-13_3_0.patch +++ /dev/null @@ -1,14497 +0,0 @@ -diff --git a/Makefile.def b/Makefile.def -index 35e994e..9b4a8a2 100644 ---- a/Makefile.def -+++ b/Makefile.def -@@ -47,7 +47,8 @@ host_modules= { module= fixincludes; bootstrap=true; - host_modules= { module= flex; no_check_cross= true; }; - host_modules= { module= gas; bootstrap=true; }; - host_modules= { module= gcc; bootstrap=true; -- extra_make_flags="$(EXTRA_GCC_FLAGS)"; }; -+ extra_make_flags="$(EXTRA_GCC_FLAGS)"; -+ extra_configure_flags='@gcc_host_pie@'; }; - host_modules= { module= gmp; lib_path=.libs; bootstrap=true; - // Work around in-tree gmp configure bug with missing flex. - extra_configure_flags='--disable-shared LEX="touch lex.yy.c" @host_libs_picflag@'; -diff --git a/Makefile.in b/Makefile.in -index 205d3c3..fdfd3d7 100644 ---- a/Makefile.in -+++ b/Makefile.in -@@ -12016,7 +12016,7 @@ configure-gcc: - $$s/$$module_srcdir/configure \ - --srcdir=$${topdir}/$$module_srcdir \ - $(HOST_CONFIGARGS) --build=${build_alias} --host=${host_alias} \ -- --target=${target_alias} \ -+ --target=${target_alias} @gcc_host_pie@ \ - || exit 1 - @endif gcc - -@@ -12051,7 +12051,8 @@ configure-stage1-gcc: - $(HOST_CONFIGARGS) --build=${build_alias} --host=${host_alias} \ - --target=${target_alias} \ - \ -- $(STAGE1_CONFIGURE_FLAGS) -+ $(STAGE1_CONFIGURE_FLAGS) \ -+ @gcc_host_pie@ - @endif gcc-bootstrap - - .PHONY: configure-stage2-gcc maybe-configure-stage2-gcc -@@ -12084,7 +12085,8 @@ configure-stage2-gcc: - $(HOST_CONFIGARGS) --build=${build_alias} --host=${host_alias} \ - --target=${target_alias} \ - --with-build-libsubdir=$(HOST_SUBDIR) \ -- $(STAGE2_CONFIGURE_FLAGS) -+ $(STAGE2_CONFIGURE_FLAGS) \ -+ @gcc_host_pie@ - @endif gcc-bootstrap - - .PHONY: configure-stage3-gcc maybe-configure-stage3-gcc -@@ -12117,7 +12119,8 @@ configure-stage3-gcc: - $(HOST_CONFIGARGS) --build=${build_alias} --host=${host_alias} \ - --target=${target_alias} \ - --with-build-libsubdir=$(HOST_SUBDIR) \ -- $(STAGE3_CONFIGURE_FLAGS) -+ $(STAGE3_CONFIGURE_FLAGS) \ -+ @gcc_host_pie@ - @endif gcc-bootstrap - - .PHONY: configure-stage4-gcc maybe-configure-stage4-gcc -@@ -12150,7 +12153,8 @@ configure-stage4-gcc: - $(HOST_CONFIGARGS) --build=${build_alias} --host=${host_alias} \ - --target=${target_alias} \ - --with-build-libsubdir=$(HOST_SUBDIR) \ -- $(STAGE4_CONFIGURE_FLAGS) -+ $(STAGE4_CONFIGURE_FLAGS) \ -+ @gcc_host_pie@ - @endif gcc-bootstrap - - .PHONY: configure-stageprofile-gcc maybe-configure-stageprofile-gcc -@@ -12183,7 +12187,8 @@ configure-stageprofile-gcc: - $(HOST_CONFIGARGS) --build=${build_alias} --host=${host_alias} \ - --target=${target_alias} \ - --with-build-libsubdir=$(HOST_SUBDIR) \ -- $(STAGEprofile_CONFIGURE_FLAGS) -+ $(STAGEprofile_CONFIGURE_FLAGS) \ -+ @gcc_host_pie@ - @endif gcc-bootstrap - - .PHONY: configure-stagetrain-gcc maybe-configure-stagetrain-gcc -@@ -12216,7 +12221,8 @@ configure-stagetrain-gcc: - $(HOST_CONFIGARGS) --build=${build_alias} --host=${host_alias} \ - --target=${target_alias} \ - --with-build-libsubdir=$(HOST_SUBDIR) \ -- $(STAGEtrain_CONFIGURE_FLAGS) -+ $(STAGEtrain_CONFIGURE_FLAGS) \ -+ @gcc_host_pie@ - @endif gcc-bootstrap - - .PHONY: configure-stagefeedback-gcc maybe-configure-stagefeedback-gcc -@@ -12249,7 +12255,8 @@ configure-stagefeedback-gcc: - $(HOST_CONFIGARGS) --build=${build_alias} --host=${host_alias} \ - --target=${target_alias} \ - --with-build-libsubdir=$(HOST_SUBDIR) \ -- $(STAGEfeedback_CONFIGURE_FLAGS) -+ $(STAGEfeedback_CONFIGURE_FLAGS) \ -+ @gcc_host_pie@ - @endif gcc-bootstrap - - .PHONY: configure-stageautoprofile-gcc maybe-configure-stageautoprofile-gcc -@@ -12282,7 +12289,8 @@ configure-stageautoprofile-gcc: - $(HOST_CONFIGARGS) --build=${build_alias} --host=${host_alias} \ - --target=${target_alias} \ - --with-build-libsubdir=$(HOST_SUBDIR) \ -- $(STAGEautoprofile_CONFIGURE_FLAGS) -+ $(STAGEautoprofile_CONFIGURE_FLAGS) \ -+ @gcc_host_pie@ - @endif gcc-bootstrap - - .PHONY: configure-stageautofeedback-gcc maybe-configure-stageautofeedback-gcc -@@ -12315,7 +12323,8 @@ configure-stageautofeedback-gcc: - $(HOST_CONFIGARGS) --build=${build_alias} --host=${host_alias} \ - --target=${target_alias} \ - --with-build-libsubdir=$(HOST_SUBDIR) \ -- $(STAGEautofeedback_CONFIGURE_FLAGS) -+ $(STAGEautofeedback_CONFIGURE_FLAGS) \ -+ @gcc_host_pie@ - @endif gcc-bootstrap - - -diff --git a/c++tools/Makefile.in b/c++tools/Makefile.in -index 77bda3d..dcb1029 100644 ---- a/c++tools/Makefile.in -+++ b/c++tools/Makefile.in -@@ -29,8 +29,9 @@ AUTOCONF := @AUTOCONF@ - AUTOHEADER := @AUTOHEADER@ - CXX := @CXX@ - CXXFLAGS := @CXXFLAGS@ --PIEFLAG := @PIEFLAG@ --CXXOPTS := $(CXXFLAGS) $(PIEFLAG) -fno-exceptions -fno-rtti -+PICFLAG := @PICFLAG@ -+LD_PICFLAG := @LD_PICFLAG@ -+CXXOPTS := $(CXXFLAGS) $(PICFLAG) -fno-exceptions -fno-rtti - LDFLAGS := @LDFLAGS@ - exeext := @EXEEXT@ - LIBIBERTY := ../libiberty/libiberty.a -@@ -90,11 +91,15 @@ ifeq (@CXX_AUX_TOOLS@,yes) - - all::g++-mapper-server$(exeext) - -+ifneq ($(PICFLAG),) -+override LIBIBERTY := ../libiberty/pic/libiberty.a -+endif -+ - MAPPER.O := server.o resolver.o - CODYLIB = ../libcody/libcody.a - CXXINC += -I$(srcdir)/../libcody -I$(srcdir)/../include -I$(srcdir)/../gcc -I. -I../gcc - g++-mapper-server$(exeext): $(MAPPER.O) $(CODYLIB) -- +$(CXX) $(LDFLAGS) $(PIEFLAG) -o $@ $^ $(LIBIBERTY) $(NETLIBS) -+ +$(CXX) $(LDFLAGS) $(PICFLAG) $(LD_PICFLAG) -o $@ $^ $(LIBIBERTY) $(NETLIBS) - - # copy to gcc dir so tests there can run - all::../gcc/g++-mapper-server$(exeext) -diff --git a/c++tools/configure b/c++tools/configure -index 742816e..8808700 100755 ---- a/c++tools/configure -+++ b/c++tools/configure -@@ -627,7 +627,8 @@ get_gcc_base_ver - EGREP - GREP - CXXCPP --PIEFLAG -+LD_PICFLAG -+PICFLAG - MAINTAINER - CXX_AUX_TOOLS - AUTOHEADER -@@ -700,6 +701,7 @@ enable_c___tools - enable_maintainer_mode - enable_checking - enable_default_pie -+enable_host_pie - with_gcc_major_version_only - ' - ac_precious_vars='build_alias -@@ -1333,6 +1335,7 @@ Optional Features: - only specific categories of checks. Categories are: - yes,no,all,none,release. - --enable-default-pie enable Position Independent Executable as default -+ --enable-host-pie build host code as PIE - - Optional Packages: - --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] -@@ -2990,12 +2993,20 @@ fi - # Check whether --enable-default-pie was given. - # Check whether --enable-default-pie was given. - if test "${enable_default_pie+set}" = set; then : -- enableval=$enable_default_pie; PIEFLAG=-fPIE -+ enableval=$enable_default_pie; PICFLAG=-fPIE - else -- PIEFLAG= -+ PICFLAG= - fi - - -+# Enable --enable-host-pie -+# Check whether --enable-host-pie was given. -+if test "${enable_host_pie+set}" = set; then : -+ enableval=$enable_host_pie; PICFLAG=-fPIE; LD_PICFLAG=-pie -+fi -+ -+ -+ - - # Check if O_CLOEXEC is defined by fcntl - -diff --git a/c++tools/configure.ac b/c++tools/configure.ac -index 23e98c8..44dfacc 100644 ---- a/c++tools/configure.ac -+++ b/c++tools/configure.ac -@@ -102,8 +102,15 @@ fi - AC_ARG_ENABLE(default-pie, - [AS_HELP_STRING([--enable-default-pie], - [enable Position Independent Executable as default])], --[PIEFLAG=-fPIE], [PIEFLAG=]) --AC_SUBST([PIEFLAG]) -+[PICFLAG=-fPIE], [PICFLAG=]) -+ -+# Enable --enable-host-pie -+AC_ARG_ENABLE(host-pie, -+[AS_HELP_STRING([--enable-host-pie], -+ [build host code as PIE])], -+[PICFLAG=-fPIE; LD_PICFLAG=-pie], []) -+AC_SUBST(PICFLAG) -+AC_SUBST(LD_PICFLAG) - - # Check if O_CLOEXEC is defined by fcntl - AC_CACHE_CHECK(for O_CLOEXEC, ac_cv_o_cloexec, [ -diff --git a/configure b/configure -index 117a7ef..c721ee4 100755 ---- a/configure -+++ b/configure -@@ -687,7 +687,10 @@ extra_host_zlib_configure_flags - extra_host_libiberty_configure_flags - stage1_languages - host_libs_picflag -+PICFLAG - host_shared -+gcc_host_pie -+host_pie - extra_linker_plugin_flags - extra_linker_plugin_configure_flags - islinc -@@ -830,6 +833,7 @@ enable_isl_version_check - enable_lto - enable_linker_plugin_configure_flags - enable_linker_plugin_flags -+enable_host_pie - enable_host_shared - enable_stage1_languages - enable_objc_gc -@@ -1558,6 +1562,7 @@ Optional Features: - --enable-linker-plugin-flags=FLAGS - additional flags for configuring and building linker - plugins [none] -+ --enable-host-pie build position independent host executables - --enable-host-shared build host code as shared libraries - --enable-stage1-languages[=all] - choose additional languages to build during stage1. -@@ -3451,6 +3456,8 @@ esac - - # Disable libffi for some systems. - case "${target}" in -+ aarch64*-*-darwin2*) -+ ;; - powerpc-*-darwin*) - ;; - i[3456789]86-*-darwin*) -@@ -8414,6 +8421,20 @@ else - fi - fi - -+case $target in -+ *-darwin2* | *-darwin1[56789]*) -+ # For these versions, we default to using embedded rpaths. -+ if test "x$enable_darwin_at_rpath" != "xno"; then -+ poststage1_ldflags="$poststage1_ldflags -nodefaultrpaths" -+ fi -+ ;; -+ *-darwin*) -+ # For these versions, we only use embedded rpaths on demand. -+ if test "x$enable_darwin_at_rpath" = "xyes"; then -+ poststage1_ldflags="$poststage1_ldflags -nodefaultrpaths" -+ fi -+ ;; -+esac - - - # GCC GRAPHITE dependency isl. -@@ -8645,6 +8666,39 @@ fi - - - -+# Handle --enable-host-pie -+# If host PIE executables are the default (or must be forced on) for some host, -+# we must pass that configuration to the gcc directory. -+gcc_host_pie= -+# Check whether --enable-host-pie was given. -+if test "${enable_host_pie+set}" = set; then : -+ enableval=$enable_host_pie; host_pie=$enableval -+ case $host in -+ *-*-darwin2*) -+ if test x$host_pie != xyes ; then -+ # for Darwin20+ this is required. -+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: PIE executables are required for the configured host, host-pie setting ignored." >&5 -+$as_echo "$as_me: WARNING: PIE executables are required for the configured host, host-pie setting ignored." >&2;} -+ host_pie=yes -+ gcc_host_pie=--enable-host-pie -+ fi ;; -+ *) ;; -+ esac -+else -+ case $host in -+ *-*-darwin2*) -+ # Default to PIE (mandatory for aarch64). -+ host_pie=yes -+ gcc_host_pie=--enable-host-pie -+ ;; -+ *) host_pie=no ;; -+ esac -+fi -+ -+ -+ -+ -+ - # Enable --enable-host-shared. - # Checked early to determine whether jit is an 'all' language - # Check whether --enable-host-shared was given. -@@ -8654,26 +8708,57 @@ if test "${enable_host_shared+set}" = set; then : - x86_64-*-darwin* | aarch64-*-darwin*) - if test x$host_shared != xyes ; then - # PIC is the default, and actually cannot be switched off. -- echo configure.ac: warning: PIC code is required for the configured target, host-shared setting ignored. 1>&2 -+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: PIC code is required for the configured host; host-shared setting ignored." >&5 -+$as_echo "$as_me: WARNING: PIC code is required for the configured host; host-shared setting ignored." >&2;} -+ host_shared=yes -+ fi ;; -+ *-*-darwin*) -+ if test x$host_pie = xyes -a x$host_shared != xyes ; then -+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: PIC code is required for PIE host executables host-shared setting ignored." >&5 -+$as_echo "$as_me: WARNING: PIC code is required for PIE host executables host-shared setting ignored." >&2;} - host_shared=yes - fi ;; - *) ;; - esac - else - case $host in -+ # 64B x86_64 and Aarch64 Darwin default to PIC. - x86_64-*-darwin* | aarch64-*-darwin*) host_shared=yes ;; -- *) host_shared=no ;; -+ # 32B and powerpc64 Darwin must use PIC to link PIE exes. -+ *-*-darwin*) host_shared=$host_pie ;; -+ *) host_shared=no;; - esac - fi - - - - -+if test x$host_shared = xyes; then -+ case $host in -+ *-*-darwin*) -+ # Since host shared is the default for 64b Darwin, and also enabled for -+ # host_pie, ensure that we present the PIE flag when host_pie is active. -+ if test x$host_pie = xyes; then -+ PICFLAG=-fPIE -+ fi -+ ;; -+ *) -+ PICFLAG=-fPIC -+ ;; -+ esac -+elif test x$host_pie = xyes; then -+ PICFLAG=-fPIE -+else -+ PICFLAG= -+fi -+ -+ -+ - # If we are building PIC/PIE host executables, and we are building dependent - # libs (e.g. GMP) in-tree those libs need to be configured to generate PIC - # code. - host_libs_picflag= --if test "$host_shared" = "yes";then -+if test "$host_shared" = "yes" -o "$host_pie" = "yes"; then - host_libs_picflag='--with-pic' - fi - -diff --git a/configure.ac b/configure.ac -index b3e9bbd..a75c9e8 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -710,6 +710,8 @@ esac - - # Disable libffi for some systems. - case "${target}" in -+ aarch64*-*-darwin2*) -+ ;; - powerpc-*-darwin*) - ;; - i[[3456789]]86-*-darwin*) -@@ -1806,6 +1808,20 @@ AC_ARG_WITH(boot-ldflags, - if test "$poststage1_libs" = ""; then - poststage1_ldflags="-static-libstdc++ -static-libgcc" - fi]) -+case $target in -+ *-darwin2* | *-darwin1[[56789]]*) -+ # For these versions, we default to using embedded rpaths. -+ if test "x$enable_darwin_at_rpath" != "xno"; then -+ poststage1_ldflags="$poststage1_ldflags -nodefaultrpaths" -+ fi -+ ;; -+ *-darwin*) -+ # For these versions, we only use embedded rpaths on demand. -+ if test "x$enable_darwin_at_rpath" = "xyes"; then -+ poststage1_ldflags="$poststage1_ldflags -nodefaultrpaths" -+ fi -+ ;; -+esac - AC_SUBST(poststage1_ldflags) - - # GCC GRAPHITE dependency isl. -@@ -1891,6 +1907,36 @@ AC_ARG_ENABLE(linker-plugin-flags, - extra_linker_plugin_flags=) - AC_SUBST(extra_linker_plugin_flags) - -+# Handle --enable-host-pie -+# If host PIE executables are the default (or must be forced on) for some host, -+# we must pass that configuration to the gcc directory. -+gcc_host_pie= -+AC_ARG_ENABLE(host-pie, -+[AS_HELP_STRING([--enable-host-pie], -+ [build position independent host executables])], -+[host_pie=$enableval -+ case $host in -+ *-*-darwin2*) -+ if test x$host_pie != xyes ; then -+ # for Darwin20+ this is required. -+ AC_MSG_WARN([PIE executables are required for the configured host, host-pie setting ignored.]) -+ host_pie=yes -+ gcc_host_pie=--enable-host-pie -+ fi ;; -+ *) ;; -+ esac], -+[case $host in -+ *-*-darwin2*) -+ # Default to PIE (mandatory for aarch64). -+ host_pie=yes -+ gcc_host_pie=--enable-host-pie -+ ;; -+ *) host_pie=no ;; -+ esac]) -+ -+AC_SUBST(host_pie) -+AC_SUBST(gcc_host_pie) -+ - # Enable --enable-host-shared. - # Checked early to determine whether jit is an 'all' language - AC_ARG_ENABLE(host-shared, -@@ -1901,23 +1947,52 @@ AC_ARG_ENABLE(host-shared, - x86_64-*-darwin* | aarch64-*-darwin*) - if test x$host_shared != xyes ; then - # PIC is the default, and actually cannot be switched off. -- echo configure.ac: warning: PIC code is required for the configured target, host-shared setting ignored. 1>&2 -+ AC_MSG_WARN([PIC code is required for the configured host; host-shared setting ignored.]) -+ host_shared=yes -+ fi ;; -+ *-*-darwin*) -+ if test x$host_pie = xyes -a x$host_shared != xyes ; then -+ AC_MSG_WARN([PIC code is required for PIE host executables host-shared setting ignored.]) - host_shared=yes - fi ;; - *) ;; - esac], - [case $host in -+ # 64B x86_64 and Aarch64 Darwin default to PIC. - x86_64-*-darwin* | aarch64-*-darwin*) host_shared=yes ;; -- *) host_shared=no ;; -+ # 32B and powerpc64 Darwin must use PIC to link PIE exes. -+ *-*-darwin*) host_shared=$host_pie ;; -+ *) host_shared=no;; - esac]) - - AC_SUBST(host_shared) - -+if test x$host_shared = xyes; then -+ case $host in -+ *-*-darwin*) -+ # Since host shared is the default for 64b Darwin, and also enabled for -+ # host_pie, ensure that we present the PIE flag when host_pie is active. -+ if test x$host_pie = xyes; then -+ PICFLAG=-fPIE -+ fi -+ ;; -+ *) -+ PICFLAG=-fPIC -+ ;; -+ esac -+elif test x$host_pie = xyes; then -+ PICFLAG=-fPIE -+else -+ PICFLAG= -+fi -+ -+AC_SUBST(PICFLAG) -+ - # If we are building PIC/PIE host executables, and we are building dependent - # libs (e.g. GMP) in-tree those libs need to be configured to generate PIC - # code. - host_libs_picflag= --if test "$host_shared" = "yes";then -+if test "$host_shared" = "yes" -o "$host_pie" = "yes"; then - host_libs_picflag='--with-pic' - fi - AC_SUBST(host_libs_picflag) -diff --git a/fixincludes/Makefile.in b/fixincludes/Makefile.in -index 1937dca..e6ce41d 100644 ---- a/fixincludes/Makefile.in -+++ b/fixincludes/Makefile.in -@@ -73,7 +73,7 @@ default : all - # Now figure out from those variables how to compile and link. - - .c.o: -- $(CC) -c $(CFLAGS) $(WARN_CFLAGS) $(CPPFLAGS) $(FIXINC_CFLAGS) $< -+ $(CC) -c $(CFLAGS) $(PICFLAG) $(WARN_CFLAGS) $(CPPFLAGS) $(FIXINC_CFLAGS) $< - - # The only suffixes we want for implicit rules are .c and .o. - .SUFFIXES: -@@ -87,7 +87,11 @@ default : all - ## - ## # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # - -+ifeq ($(PICFLAG),) - LIBIBERTY=../libiberty/libiberty.a -+else -+LIBIBERTY=../libiberty/pic/libiberty.a -+endif - - ALLOBJ = fixincl.o fixtests.o fixfixes.o server.o procopen.o \ - fixlib.o fixopts.o -@@ -107,15 +111,15 @@ oneprocess : full-stamp - twoprocess : test-stamp $(AF) - - full-stamp : $(ALLOBJ) $(LIBIBERTY) -- $(CC) $(CFLAGS) $(LDFLAGS) -o $(FI) $(ALLOBJ) $(LIBIBERTY) -+ $(CC) $(CFLAGS) $(PICFLAG) $(LDFLAGS) $(LD_PICFLAG) -o $(FI) $(ALLOBJ) $(LIBIBERTY) - $(STAMP) $@ - - test-stamp : $(TESTOBJ) $(LIBIBERTY) -- $(CC) $(CFLAGS) $(LDFLAGS) -o $(FI) $(TESTOBJ) $(LIBIBERTY) -+ $(CC) $(CFLAGS) $(PICFLAG) $(LDFLAGS) $(LD_PICFLAG) -o $(FI) $(TESTOBJ) $(LIBIBERTY) - $(STAMP) $@ - - $(AF): $(FIXOBJ) $(LIBIBERTY) -- $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(FIXOBJ) $(LIBIBERTY) -+ $(CC) $(CFLAGS) $(PICFLAG) $(LDFLAGS) $(LD_PICFLAG) -o $@ $(FIXOBJ) $(LIBIBERTY) - - $(ALLOBJ) : $(HDR) - fixincl.o : fixincl.c $(srcdir)/fixincl.x -diff --git a/fixincludes/configure b/fixincludes/configure -index bdcc41f..b2759ee 100755 ---- a/fixincludes/configure -+++ b/fixincludes/configure -@@ -623,6 +623,8 @@ ac_subst_vars='LTLIBOBJS - LIBOBJS - get_gcc_base_ver - MAINT -+LD_PICFLAG -+PICFLAG - TARGET - target_noncanonical - WERROR -@@ -695,6 +697,7 @@ enable_option_checking - enable_werror_always - with_local_prefix - enable_twoprocess -+enable_host_pie - enable_maintainer_mode - with_gcc_major_version_only - ' -@@ -1323,6 +1326,7 @@ Optional Features: - --enable-FEATURE[=ARG] include FEATURE [ARG=yes] - --enable-werror-always enable -Werror despite compiler version - --enable-twoprocess Use a separate process to apply the fixes -+ --enable-host-pie build host code as PIE - --enable-maintainer-mode enable make rules and dependencies not useful - (and sometimes confusing) to the casual installer - -@@ -3044,7 +3048,6 @@ ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. - # the compiler configuration to `libtool'. - # _LT_LANG_CXX_CONFIG - -- - # _LT_SYS_HIDDEN_LIBDEPS([TAGNAME]) - # --------------------------------- - # Figure out "hidden" library dependencies from verbose -@@ -4835,6 +4838,15 @@ $as_echo "#define SEPARATE_FIX_PROC 1" >>confdefs.h - - fi - -+# Enable --enable-host-pie. -+# Check whether --enable-host-pie was given. -+if test "${enable_host_pie+set}" = set; then : -+ enableval=$enable_host_pie; PICFLAG=-fPIE; LD_PICFLAG=-pie -+fi -+ -+ -+ -+ - case $host in - vax-dec-bsd* ) - -diff --git a/fixincludes/configure.ac b/fixincludes/configure.ac -index ef2227e..4e78511 100644 ---- a/fixincludes/configure.ac -+++ b/fixincludes/configure.ac -@@ -68,6 +68,14 @@ if test $TARGET = twoprocess; then - [Define if testing and fixing are done by separate process]) - fi - -+# Enable --enable-host-pie. -+AC_ARG_ENABLE(host-pie, -+[AS_HELP_STRING([--enable-host-pie], -+ [build host code as PIE])], -+[PICFLAG=-fPIE; LD_PICFLAG=-pie], []) -+AC_SUBST(PICFLAG) -+AC_SUBST(LD_PICFLAG) -+ - case $host in - vax-dec-bsd* ) - AC_DEFINE(exit, xexit, [Define to xexit if the host system does not support atexit]) -diff --git a/gcc/Makefile.in b/gcc/Makefile.in -index 775aaa1..740199c 100644 ---- a/gcc/Makefile.in -+++ b/gcc/Makefile.in -@@ -158,6 +158,9 @@ LDFLAGS = @LDFLAGS@ - # Should we build position-independent host code? - PICFLAG = @PICFLAG@ - -+# The linker flag for the above. -+LD_PICFLAG = @LD_PICFLAG@ -+ - # Flags to determine code coverage. When coverage is disabled, this will - # contain the optimization flags, as you normally want code coverage - # without optimization. -@@ -266,19 +269,19 @@ LINKER = $(CC) - LINKER_FLAGS = $(CFLAGS) - endif - -+enable_host_pie = @enable_host_pie@ -+ - # Enable Intel CET on Intel CET enabled host if needed. - CET_HOST_FLAGS = @CET_HOST_FLAGS@ - COMPILER += $(CET_HOST_FLAGS) - --NO_PIE_CFLAGS = @NO_PIE_CFLAGS@ --NO_PIE_FLAG = @NO_PIE_FLAG@ - DO_LINK_MUTEX = @DO_LINK_MUTEX@ - --# We don't want to compile the compilers with -fPIE, it make PCH fail. --COMPILER += $(NO_PIE_CFLAGS) -+# Maybe compile the compilers with -fPIE or -fPIC. -+COMPILER += $(PICFLAG) - --# Link with -no-pie since we compile the compiler with -fno-PIE. --LINKER += $(NO_PIE_FLAG) -+# Link with -pie, or -no-pie, depending on the above. -+LINKER += $(LD_PICFLAG) - - # Like LINKER, but use a mutex for serializing front end links. - ifeq (@DO_LINK_MUTEX@,true) -@@ -1050,7 +1053,7 @@ RTL_SSA_H = $(PRETTY_PRINT_H) insn-config.h splay-tree-utils.h \ - # programs built during a bootstrap. - # autoconf inserts -DCROSS_DIRECTORY_STRUCTURE if we are building a - # cross compiler which does not use the native headers and libraries. --INTERNAL_CFLAGS = -DIN_GCC $(PICFLAG) @CROSS@ -+INTERNAL_CFLAGS = -DIN_GCC @CROSS@ - - # This is the variable actually used when we compile. If you change this, - # you probably want to update BUILD_CFLAGS in configure.ac -@@ -1068,21 +1071,24 @@ ALL_CXXFLAGS = $(T_CFLAGS) $(CFLAGS-$@) $(CXXFLAGS) $(INTERNAL_CFLAGS) \ - ALL_CPPFLAGS = $(INCLUDES) $(CPPFLAGS) - - # This is the variable to use when using $(COMPILER). --ALL_COMPILERFLAGS = $(ALL_CXXFLAGS) -+ALL_COMPILERFLAGS = $(ALL_CXXFLAGS) $(PICFLAG) - - # This is the variable to use when using $(LINKER). --ALL_LINKERFLAGS = $(ALL_CXXFLAGS) -+ALL_LINKERFLAGS = $(ALL_CXXFLAGS) $(LD_PICFLAG) - - # Build and host support libraries. - --# Use the "pic" build of libiberty if --enable-host-shared, unless we are --# building for mingw. -+# Use the "pic" build of libiberty if --enable-host-shared or --enable-host-pie, -+# unless we are building for mingw. - LIBIBERTY_PICDIR=$(if $(findstring mingw,$(target)),,pic) --ifeq ($(enable_host_shared),yes) -+ifneq ($(enable_host_shared)$(enable_host_pie),) - LIBIBERTY = ../libiberty/$(LIBIBERTY_PICDIR)/libiberty.a --BUILD_LIBIBERTY = $(build_libobjdir)/libiberty/$(LIBIBERTY_PICDIR)/libiberty.a - else - LIBIBERTY = ../libiberty/libiberty.a -+endif -+ifeq ($(enable_host_shared),yes) -+BUILD_LIBIBERTY = $(build_libobjdir)/libiberty/$(LIBIBERTY_PICDIR)/libiberty.a -+else - BUILD_LIBIBERTY = $(build_libobjdir)/libiberty/libiberty.a - endif - -@@ -1167,6 +1173,8 @@ LANG_MAKEFRAGS = @all_lang_makefrags@ - # Used by gcc/jit/Make-lang.in - LD_VERSION_SCRIPT_OPTION = @ld_version_script_option@ - LD_SONAME_OPTION = @ld_soname_option@ -+@ENABLE_DARWIN_AT_RPATH_TRUE@DARWIN_RPATH = @rpath -+@ENABLE_DARWIN_AT_RPATH_FALSE@DARWIN_RPATH = ${libdir} - - # Flags to pass to recursive makes. - # CC is set by configure. -@@ -1973,9 +1981,12 @@ cs-tconfig.h: Makefile - $(SHELL) $(srcdir)/mkconfig.sh tconfig.h - - cs-tm.h: Makefile -- TARGET_CPU_DEFAULT="$(target_cpu_default)" \ -- HEADERS="$(tm_include_list)" DEFINES="$(tm_defines)" \ -- $(SHELL) $(srcdir)/mkconfig.sh tm.h -+@ENABLE_DARWIN_AT_RPATH_FALSE@ TARGET_CPU_DEFAULT="$(target_cpu_default)" \ -+@ENABLE_DARWIN_AT_RPATH_FALSE@ HEADERS="$(tm_include_list)" DEFINES="$(tm_defines)" \ -+@ENABLE_DARWIN_AT_RPATH_FALSE@ $(SHELL) $(srcdir)/mkconfig.sh tm.h -+@ENABLE_DARWIN_AT_RPATH_TRUE@ TARGET_CPU_DEFAULT="$(target_cpu_default)" \ -+@ENABLE_DARWIN_AT_RPATH_TRUE@ HEADERS="$(tm_include_list)" DEFINES="$(tm_defines) DARWIN_AT_RPATH=1" \ -+@ENABLE_DARWIN_AT_RPATH_TRUE@ $(SHELL) $(srcdir)/mkconfig.sh tm.h - - cs-tm_p.h: Makefile - TARGET_CPU_DEFAULT="" \ -@@ -4141,6 +4152,9 @@ site.exp: ./config.status Makefile - echo "set COMPAT_OPTIONS \"$(COMPAT_OPTIONS)\"" >> ./site.tmp; \ - else true; \ - fi -+ @if test "X@ENABLE_DARWIN_AT_RPATH_TRUE@" != "X#" ; then \ -+ echo "set ENABLE_DARWIN_AT_RPATH 1" >> ./site.tmp; \ -+ fi - @echo "## All variables above are generated by configure. Do Not Edit ##" >> ./site.tmp - @cat ./site.tmp > site.exp - @cat site.bak | sed \ -diff --git a/gcc/aclocal.m4 b/gcc/aclocal.m4 -index 6be36df..126e09b 100644 ---- a/gcc/aclocal.m4 -+++ b/gcc/aclocal.m4 -@@ -12,6 +12,56 @@ - # PARTICULAR PURPOSE. - - m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])]) -+# AM_CONDITIONAL -*- Autoconf -*- -+ -+# Copyright (C) 1997-2017 Free Software Foundation, Inc. -+# -+# This file is free software; the Free Software Foundation -+# gives unlimited permission to copy and/or distribute it, -+# with or without modifications, as long as this notice is preserved. -+ -+# AM_CONDITIONAL(NAME, SHELL-CONDITION) -+# ------------------------------------- -+# Define a conditional. -+AC_DEFUN([AM_CONDITIONAL], -+[AC_PREREQ([2.52])dnl -+ m4_if([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], -+ [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl -+AC_SUBST([$1_TRUE])dnl -+AC_SUBST([$1_FALSE])dnl -+_AM_SUBST_NOTMAKE([$1_TRUE])dnl -+_AM_SUBST_NOTMAKE([$1_FALSE])dnl -+m4_define([_AM_COND_VALUE_$1], [$2])dnl -+if $2; then -+ $1_TRUE= -+ $1_FALSE='#' -+else -+ $1_TRUE='#' -+ $1_FALSE= -+fi -+AC_CONFIG_COMMANDS_PRE( -+[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then -+ AC_MSG_ERROR([[conditional "$1" was never defined. -+Usually this means the macro was only invoked conditionally.]]) -+fi])]) -+ -+# Copyright (C) 2006-2017 Free Software Foundation, Inc. -+# -+# This file is free software; the Free Software Foundation -+# gives unlimited permission to copy and/or distribute it, -+# with or without modifications, as long as this notice is preserved. -+ -+# _AM_SUBST_NOTMAKE(VARIABLE) -+# --------------------------- -+# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. -+# This macro is traced by Automake. -+AC_DEFUN([_AM_SUBST_NOTMAKE]) -+ -+# AM_SUBST_NOTMAKE(VARIABLE) -+# -------------------------- -+# Public sister of _AM_SUBST_NOTMAKE. -+AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) -+ - m4_include([../libtool.m4]) - m4_include([../ltoptions.m4]) - m4_include([../ltsugar.m4]) -diff --git a/gcc/ada/gcc-interface/Make-lang.in b/gcc/ada/gcc-interface/Make-lang.in -index 9507f2f..2b9b0de 100644 ---- a/gcc/ada/gcc-interface/Make-lang.in -+++ b/gcc/ada/gcc-interface/Make-lang.in -@@ -72,7 +72,8 @@ else - endif - - ALL_ADAFLAGS = \ -- $(CFLAGS) $(ADA_CFLAGS) $(ADAFLAGS) $(CHECKING_ADAFLAGS) $(WARN_ADAFLAGS) -+ $(CFLAGS) $(ADA_CFLAGS) $(ADAFLAGS) $(CHECKING_ADAFLAGS) \ -+ $(WARN_ADAFLAGS) $(PICFLAG) - FORCE_DEBUG_ADAFLAGS = -g - ADA_CFLAGS = - COMMON_ADA_INCLUDES = -I- -I. -Iada/generated -Iada -I$(srcdir)/ada -@@ -1109,7 +1110,7 @@ ada/b_gnat1.adb : $(GNAT1_ADA_OBJS) - ada/b_gnat1.o : ada/b_gnat1.adb - # Do not use ADAFLAGS to get rid of -gnatg which generates a lot - # of style messages. -- $(CC) -c $(CFLAGS) $(ADA_CFLAGS) -gnatp -gnatws $(ADA_INCLUDES) \ -+ $(CC) -c $(CFLAGS) $(ADA_CFLAGS) $(PICFLAG) -gnatp -gnatws $(ADA_INCLUDES) \ - $< $(ADA_OUTPUT_OPTION) - - ada/b_gnatb.adb : $(GNATBIND_OBJS) ada/gnatbind.o -@@ -1118,7 +1119,7 @@ ada/b_gnatb.adb : $(GNATBIND_OBJS) ada/gnatbind.o - $(MV) b_gnatb.adb b_gnatb.ads ada/ - - ada/b_gnatb.o : ada/b_gnatb.adb -- $(CC) -c $(CFLAGS) $(ADA_CFLAGS) -gnatp -gnatws $(ADA_INCLUDES) \ -+ $(CC) -c $(CFLAGS) $(ADA_CFLAGS) $(PICFLAG) -gnatp -gnatws $(ADA_INCLUDES) \ - $< $(ADA_OUTPUT_OPTION) - - include $(srcdir)/ada/Make-generated.in -diff --git a/gcc/ada/gcc-interface/Makefile.in b/gcc/ada/gcc-interface/Makefile.in -index da6a56f..51a4bf1 100644 ---- a/gcc/ada/gcc-interface/Makefile.in -+++ b/gcc/ada/gcc-interface/Makefile.in -@@ -91,6 +91,7 @@ LS = ls - RANLIB = @RANLIB@ - RANLIB_FLAGS = @ranlib_flags@ - AWK = @AWK@ -+PICFLAG = @PICFLAG@ - - COMPILER = $(CC) - COMPILER_FLAGS = $(CFLAGS) -@@ -239,7 +240,11 @@ ALL_CPPFLAGS = $(CPPFLAGS) - ALL_COMPILERFLAGS = $(ALL_CFLAGS) - - # This is where we get libiberty.a from. -+ifeq ($(PICFLAG),) - LIBIBERTY = ../../libiberty/libiberty.a -+else -+LIBIBERTY = ../../libiberty/pic/libiberty.a -+endif - - # We need to link against libbacktrace because diagnostic.c in - # libcommon.a uses it. -@@ -256,9 +261,6 @@ TOOLS_LIBS = ../version.o ../link.o ../targext.o ../../ggc-none.o \ - $(LIBGNAT) $(LIBINTL) $(LIBICONV) ../$(LIBBACKTRACE) ../$(LIBIBERTY) \ - $(SYSLIBS) $(TGT_LIB) - --# Add -no-pie to TOOLS_LIBS since some of them are compiled with -fno-PIE. --TOOLS_LIBS += @NO_PIE_FLAG@ -- - # Specify the directories to be searched for header files. - # Both . and srcdir are used, in that order, - # so that tm.h and config.h will be found in the compilation -@@ -789,12 +791,15 @@ gnatlib-shared-darwin: - $(GNATRTL_NONTASKING_OBJS) $(LIBGNAT_OBJS) \ - $(SO_OPTS) \ - -Wl,-install_name,@rpath/libgnat$(hyphen)$(LIBRARY_VERSION)$(soext) \ -- $(MISCLIB) -+ -nodefaultrpaths -Wl,-rpath,@loader_path/,-rpath,@loader_path/.. \ -+ -Wl,-rpath,@loader_path/../../../../ $(MISCLIB) - cd $(RTSDIR); $(GCC_FOR_ADA_RTS) -dynamiclib $(PICFLAG_FOR_TARGET) \ - -o libgnarl$(hyphen)$(LIBRARY_VERSION)$(soext) \ - $(GNATRTL_TASKING_OBJS) \ - $(SO_OPTS) \ - -Wl,-install_name,@rpath/libgnarl$(hyphen)$(LIBRARY_VERSION)$(soext) \ -+ -nodefaultrpaths -Wl,-rpath,@loader_path/,-rpath,@loader_path/.. \ -+ -Wl,-rpath,@loader_path/../../../../ \ - $(THREADSLIB) -Wl,libgnat$(hyphen)$(LIBRARY_VERSION)$(soext) - cd $(RTSDIR); $(LN_S) libgnat$(hyphen)$(LIBRARY_VERSION)$(soext) \ - libgnat$(soext) -diff --git a/gcc/analyzer/kf.cc b/gcc/analyzer/kf.cc -index 4389ff9..0fe5d2a 100644 ---- a/gcc/analyzer/kf.cc -+++ b/gcc/analyzer/kf.cc -@@ -1081,7 +1081,7 @@ register_known_functions (known_function_manager &kfm) - like this: - extern int *___errno(void) __attribute__((__const__)); - #define errno (*(___errno())) -- and OS X like this: -+ and macOS like this: - extern int * __error(void); - #define errno (*__error()) - and similarly __errno for newlib. -diff --git a/gcc/builtins.cc b/gcc/builtins.cc -index 1bfdc59..1122527 100644 ---- a/gcc/builtins.cc -+++ b/gcc/builtins.cc -@@ -5501,6 +5501,13 @@ expand_builtin_trap (void) - static void - expand_builtin_unreachable (void) - { -+ /* If the target wants a trap in place of the fall-through, use that. */ -+ if (targetm.unreachable_should_trap ()) -+ { -+ expand_builtin_trap (); -+ return; -+ } -+ - /* Use gimple_build_builtin_unreachable or builtin_decl_unreachable - to avoid this. */ - gcc_checking_assert (!sanitize_flags_p (SANITIZE_UNREACHABLE)); -@@ -7958,6 +7965,10 @@ expand_builtin (tree exp, rtx target, rtx subtarget, machine_mode mode, - case BUILT_IN_ADJUST_DESCRIPTOR: - return expand_builtin_adjust_descriptor (exp); - -+ case BUILT_IN_GCC_NESTED_PTR_CREATED: -+ case BUILT_IN_GCC_NESTED_PTR_DELETED: -+ break; /* At present, no expansion, just call the function. */ -+ - case BUILT_IN_FORK: - case BUILT_IN_EXECL: - case BUILT_IN_EXECV: -diff --git a/gcc/builtins.def b/gcc/builtins.def -index 4ad95a1..448cf83 100644 ---- a/gcc/builtins.def -+++ b/gcc/builtins.def -@@ -1067,6 +1067,8 @@ DEF_BUILTIN_STUB (BUILT_IN_ADJUST_TRAMPOLINE, "__builtin_adjust_trampoline") - DEF_BUILTIN_STUB (BUILT_IN_INIT_DESCRIPTOR, "__builtin_init_descriptor") - DEF_BUILTIN_STUB (BUILT_IN_ADJUST_DESCRIPTOR, "__builtin_adjust_descriptor") - DEF_BUILTIN_STUB (BUILT_IN_NONLOCAL_GOTO, "__builtin_nonlocal_goto") -+DEF_EXT_LIB_BUILTIN (BUILT_IN_GCC_NESTED_PTR_CREATED, "__gcc_nested_func_ptr_created", BT_FN_VOID_PTR_PTR_PTR, ATTR_NOTHROW_LIST) -+DEF_EXT_LIB_BUILTIN (BUILT_IN_GCC_NESTED_PTR_DELETED, "__gcc_nested_func_ptr_deleted", BT_FN_VOID, ATTR_NOTHROW_LIST) - - /* Implementing __builtin_setjmp. */ - DEF_BUILTIN_STUB (BUILT_IN_SETJMP_SETUP, "__builtin_setjmp_setup") -diff --git a/gcc/c/c-lang.cc b/gcc/c/c-lang.cc -index b4e0c8c..11e7aaa 100644 ---- a/gcc/c/c-lang.cc -+++ b/gcc/c/c-lang.cc -@@ -61,6 +61,15 @@ c_get_sarif_source_language (const char *) - return "c"; - } - -+/* Implement c-family hook to register language-specific features for -+ __has_{feature,extension}. */ -+ -+void -+c_family_register_lang_features () -+{ -+ c_register_features (); -+} -+ - #if CHECKING_P - - namespace selftest { -diff --git a/gcc/c/c-objc-common.cc b/gcc/c/c-objc-common.cc -index e4aed61..fad4662 100644 ---- a/gcc/c/c-objc-common.cc -+++ b/gcc/c/c-objc-common.cc -@@ -34,6 +34,38 @@ along with GCC; see the file COPYING3. If not see - static bool c_tree_printer (pretty_printer *, text_info *, const char *, - int, bool, bool, bool, bool *, const char **); - -+/* Info for C language features which can be queried through -+ __has_{feature,extension}. */ -+ -+struct c_feature_info -+{ -+ const char *ident; -+ const int *enable_flag; -+}; -+ -+static const c_feature_info c_feature_table[] = -+{ -+ { "c_alignas", &flag_isoc11 }, -+ { "c_alignof", &flag_isoc11 }, -+ { "c_atomic", &flag_isoc11 }, -+ { "c_generic_selections", &flag_isoc11 }, -+ { "c_static_assert", &flag_isoc11 }, -+ { "c_thread_local", &flag_isoc11 } -+}; -+ -+/* Register features specific to the C language. */ -+ -+void -+c_register_features () -+{ -+ for (unsigned i = 0; i < ARRAY_SIZE (c_feature_table); i++) -+ { -+ const c_feature_info *info = c_feature_table + i; -+ const bool feat_p = !info->enable_flag || *info->enable_flag; -+ c_common_register_feature (info->ident, feat_p); -+ } -+} -+ - bool - c_missing_noreturn_ok_p (tree decl) - { -diff --git a/gcc/c/c-objc-common.h b/gcc/c/c-objc-common.h -index d31dacb..34dc23a 100644 ---- a/gcc/c/c-objc-common.h -+++ b/gcc/c/c-objc-common.h -@@ -21,6 +21,9 @@ along with GCC; see the file COPYING3. If not see - #ifndef GCC_C_OBJC_COMMON - #define GCC_C_OBJC_COMMON - -+/* Implemented in c-objc-common.cc. */ -+extern void c_register_features (); -+ - /* Lang hooks that are shared between C and ObjC are defined here. Hooks - specific to C or ObjC go in c-lang.cc and objc/objc-lang.cc, respectively. */ - -diff --git a/gcc/c/c-parser.cc b/gcc/c/c-parser.cc -index 3627a3f..5abc6e8 100644 ---- a/gcc/c/c-parser.cc -+++ b/gcc/c/c-parser.cc -@@ -217,6 +217,9 @@ struct GTY(()) c_parser { - should translate them to the execution character set (false - inside attributes). */ - BOOL_BITFIELD translate_strings_p : 1; -+ /* True if we want to lex arbitrary number-like sequences as their -+ string representation. */ -+ BOOL_BITFIELD lex_number_as_string : 1; - - /* Objective-C specific parser/lexer information. */ - -@@ -291,10 +294,10 @@ c_lex_one_token (c_parser *parser, c_token *token, bool raw = false) - - if (raw || vec_safe_length (parser->raw_tokens) == 0) - { -+ int lex_flags = parser->lex_joined_string ? 0 : C_LEX_STRING_NO_JOIN; -+ lex_flags |= parser->lex_number_as_string ? C_LEX_NUMBER_AS_STRING : 0; - token->type = c_lex_with_flags (&token->value, &token->location, -- &token->flags, -- (parser->lex_joined_string -- ? 0 : C_LEX_STRING_NO_JOIN)); -+ &token->flags, lex_flags); - token->id_kind = C_ID_NONE; - token->keyword = RID_MAX; - token->pragma_kind = PRAGMA_NONE; -@@ -4993,6 +4996,88 @@ c_parser_gnu_attribute_any_word (c_parser *parser) - return attr_name; - } - -+/* Handle parsing clang-form attribute arguments, where we need to adjust -+ the parsing rules to relate to a specific attribute. */ -+ -+static tree -+c_parser_clang_attribute_arguments (c_parser *parser, tree /*attr_id*/) -+{ -+ /* We can, if required, alter the parsing on the basis of the attribute. -+ At present, we handle the availability attr, where ach entry can be : -+ identifier -+ identifier=N.MM.Z -+ identifier="string" -+ followed by ',' or ) for the last entry*/ -+ -+ tree attr_args = NULL_TREE; -+ do -+ { -+ tree name = NULL_TREE; -+ tree value = NULL_TREE; -+ -+ if (c_parser_next_token_is (parser, CPP_NAME) -+ && c_parser_peek_token (parser)->id_kind == C_ID_ID) -+ { -+ name = c_parser_peek_token (parser)->value; -+ c_parser_consume_token (parser); -+ } -+ else if (c_parser_next_token_is (parser, CPP_COMMA)) -+ name = error_mark_node; /* Comma handled below. */ -+ else -+ { -+ bool saved_join_state = parser->lex_joined_string; -+ parser->lex_number_as_string = 1; -+ parser->lex_joined_string = 1; -+ c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, -+ "expected an attribute keyword"); -+ parser->lex_number_as_string = 0; -+ parser->lex_joined_string = saved_join_state; -+ return error_mark_node; -+ } -+ if (c_parser_next_token_is (parser, CPP_EQ)) -+ { -+ c_parser_consume_token (parser); /* eat the '=' */ -+ /* We need to bludgeon the lexer into not trying to interpret the -+ xx.yy.zz form, since that just looks like a malformed float. -+ Also, as a result of macro processing, we can have strig literals -+ that are in multiple pieces so, for this specific part of the -+ parse, we need to join strings. */ -+ bool saved_join_state = parser->lex_joined_string; -+ parser->lex_number_as_string = 1; -+ parser->lex_joined_string = 1; -+ /* So look at the next token, expecting a string, or something that -+ looks initially like a number, but might be a version number. */ -+ c_parser_peek_token (parser); -+ /* Done with the funky number parsing. */ -+ parser->lex_number_as_string = 0; -+ parser->lex_joined_string = saved_join_state; -+ if (c_parser_next_token_is_not (parser, CPP_CLOSE_PAREN) -+ && c_parser_next_token_is_not (parser, CPP_COMMA)) -+ { -+ value = c_parser_peek_token (parser)->value; -+ /* ???: check for error mark and early-return? */ -+ c_parser_consume_token (parser); -+ } -+ /* else value is absent. */ -+ } -+ else if (c_parser_next_token_is_not (parser, CPP_CLOSE_PAREN) -+ && c_parser_next_token_is_not (parser, CPP_COMMA)) -+ { -+ c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, -+ "expected %<,%> or %<=%>"); -+ return error_mark_node; -+ } -+ if (c_parser_next_token_is (parser, CPP_COMMA)) -+ c_parser_consume_token (parser); /* Just skip the comma. */ -+ tree t = tree_cons (value, name, NULL); -+ if (!attr_args) -+ attr_args = t; -+ else -+ chainon (attr_args, t); -+ } while (c_parser_next_token_is_not (parser, CPP_CLOSE_PAREN)); -+ return attr_args; -+} -+ - /* Parse attribute arguments. This is a common form of syntax - covering all currently valid GNU and standard attributes. - -@@ -5158,9 +5243,13 @@ c_parser_gnu_attribute (c_parser *parser, tree attrs, - attrs = chainon (attrs, attr); - return attrs; - } -- c_parser_consume_token (parser); -+ c_parser_consume_token (parser); /* The '('. */ - -- tree attr_args -+ tree attr_args; -+ if (attribute_clang_form_p (attr_name)) -+ attr_args = c_parser_clang_attribute_arguments (parser, attr_name); -+ else -+ attr_args - = c_parser_attribute_arguments (parser, - attribute_takes_identifier_p (attr_name), - false, -diff --git a/gcc/c-family/c-attribs.cc b/gcc/c-family/c-attribs.cc -index 6770991..a0adac1 100644 ---- a/gcc/c-family/c-attribs.cc -+++ b/gcc/c-family/c-attribs.cc -@@ -607,6 +607,18 @@ attribute_takes_identifier_p (const_tree attr_id) - return targetm.attribute_takes_identifier_p (attr_id); - } - -+/* Returns TRUE iff the attribute indicated by ATTR_ID needs its -+ arguments converted to string constants. */ -+ -+bool -+attribute_clang_form_p (const_tree attr_id) -+{ -+ const struct attribute_spec *spec = lookup_attribute_spec (attr_id); -+ if (spec && !strcmp ("availability", spec->name)) -+ return true; -+ return false; -+} -+ - /* Verify that argument value POS at position ARGNO to attribute NAME - applied to function FN (which is either a function declaration or function - type) refers to a function parameter at position POS and the expected type -diff --git a/gcc/c-family/c-common.cc b/gcc/c-family/c-common.cc -index 303d7f1..e3c3fae 100644 ---- a/gcc/c-family/c-common.cc -+++ b/gcc/c-family/c-common.cc -@@ -311,6 +311,44 @@ const struct fname_var_t fname_vars[] = - {NULL, 0, 0}, - }; - -+/* Flags to restrict availability of generic features that -+ are known to __has_{feature,extension}. */ -+ -+enum -+{ -+ HF_FLAG_NONE = 0, -+ HF_FLAG_EXT = 1, /* Available only as an extension. */ -+ HF_FLAG_SANITIZE = 2, /* Availability depends on sanitizer flags. */ -+}; -+ -+/* Info for generic features which can be queried through -+ __has_{feature,extension}. */ -+ -+struct hf_feature_info -+{ -+ const char *ident; -+ unsigned flags; -+ unsigned mask; -+}; -+ -+/* Table of generic features which can be queried through -+ __has_{feature,extension}. */ -+ -+static constexpr hf_feature_info has_feature_table[] = -+{ -+ { "address_sanitizer", HF_FLAG_SANITIZE, SANITIZE_ADDRESS }, -+ { "thread_sanitizer", HF_FLAG_SANITIZE, SANITIZE_THREAD }, -+ { "leak_sanitizer", HF_FLAG_SANITIZE, SANITIZE_LEAK }, -+ { "hwaddress_sanitizer", HF_FLAG_SANITIZE, SANITIZE_HWADDRESS }, -+ { "undefined_behavior_sanitizer", HF_FLAG_SANITIZE, SANITIZE_UNDEFINED }, -+ { "attribute_deprecated_with_message", HF_FLAG_NONE, 0 }, -+ { "attribute_unavailable_with_message", HF_FLAG_NONE, 0 }, -+ { "enumerator_attributes", HF_FLAG_NONE, 0 }, -+ { "tls", HF_FLAG_NONE, 0 }, -+ { "gnu_asm_goto_with_outputs", HF_FLAG_EXT, 0 }, -+ { "gnu_asm_goto_with_outputs_full", HF_FLAG_EXT, 0 } -+}; -+ - /* Global visibility options. */ - struct visibility_flags visibility_options; - -@@ -9552,4 +9590,63 @@ c_strict_flex_array_level_of (tree array_field) - return strict_flex_array_level; - } - -+/* Map from identifiers to booleans. Value is true for features, and -+ false for extensions. Used to implement __has_{feature,extension}. */ -+ -+using feature_map_t = hash_map ; -+static feature_map_t *feature_map; -+ -+/* Register a feature for __has_{feature,extension}. FEATURE_P is true -+ if the feature identified by NAME is a feature (as opposed to an -+ extension). */ -+ -+void -+c_common_register_feature (const char *name, bool feature_p) -+{ -+ bool dup = feature_map->put (get_identifier (name), feature_p); -+ gcc_checking_assert (!dup); -+} -+ -+/* Lazily initialize hash table for __has_{feature,extension}, -+ dispatching to the appropriate front end to register language-specific -+ features. */ -+ -+static void -+init_has_feature () -+{ -+ gcc_checking_assert (!feature_map); -+ feature_map = new feature_map_t; -+ -+ for (unsigned i = 0; i < ARRAY_SIZE (has_feature_table); i++) -+ { -+ const hf_feature_info *info = has_feature_table + i; -+ -+ if ((info->flags & HF_FLAG_SANITIZE) && !(flag_sanitize & info->mask)) -+ continue; -+ -+ const bool feature_p = !(info->flags & HF_FLAG_EXT); -+ c_common_register_feature (info->ident, feature_p); -+ } -+ -+ /* Register language-specific features. */ -+ c_family_register_lang_features (); -+} -+ -+/* If STRICT_P is true, evaluate __has_feature (IDENT). -+ Otherwise, evaluate __has_extension (IDENT). */ -+ -+bool -+has_feature_p (const char *ident, bool strict_p) -+{ -+ if (!feature_map) -+ init_has_feature (); -+ -+ tree name = canonicalize_attr_name (get_identifier (ident)); -+ bool *feat_p = feature_map->get (name); -+ if (!feat_p) -+ return false; -+ -+ return !strict_p || *feat_p; -+} -+ - #include "gt-c-family-c-common.h" -diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h -index f96350b..41d69d4 100644 ---- a/gcc/c-family/c-common.h -+++ b/gcc/c-family/c-common.h -@@ -1121,6 +1121,14 @@ extern bool c_cpp_diagnostic (cpp_reader *, enum cpp_diagnostic_level, - ATTRIBUTE_GCC_DIAG(5,0); - extern int c_common_has_attribute (cpp_reader *, bool); - extern int c_common_has_builtin (cpp_reader *); -+extern int c_common_has_feature (cpp_reader *, bool); -+ -+/* Implemented by each front end in *-lang.cc. */ -+extern void c_family_register_lang_features (); -+ -+/* Implemented in c-family/c-common.cc. */ -+extern void c_common_register_feature (const char *, bool); -+extern bool has_feature_p (const char *, bool); - - extern bool parse_optimize_options (tree, bool); - -@@ -1529,6 +1537,7 @@ extern void check_for_xor_used_as_pow (location_t lhs_loc, tree lhs_val, - /* In c-attribs.cc. */ - extern bool attribute_takes_identifier_p (const_tree); - extern tree handle_deprecated_attribute (tree *, tree, tree, int, bool *); -+extern bool attribute_clang_form_p (const_tree); - extern tree handle_unused_attribute (tree *, tree, tree, int, bool *); - extern tree handle_fallthrough_attribute (tree *, tree, tree, int, bool *); - extern int parse_tm_stmt_attr (tree, int); -diff --git a/gcc/c-family/c-lex.cc b/gcc/c-family/c-lex.cc -index 0acfdaa..2a504a9 100644 ---- a/gcc/c-family/c-lex.cc -+++ b/gcc/c-family/c-lex.cc -@@ -82,6 +82,7 @@ init_c_lex (void) - cb->read_pch = c_common_read_pch; - cb->has_attribute = c_common_has_attribute; - cb->has_builtin = c_common_has_builtin; -+ cb->has_feature = c_common_has_feature; - cb->get_source_date_epoch = cb_get_source_date_epoch; - cb->get_suggestion = cb_get_suggestion; - cb->remap_filename = remap_macro_filename; -@@ -457,16 +458,16 @@ c_common_has_attribute (cpp_reader *pfile, bool std_syntax) - return result; - } - --/* Callback for has_builtin. */ -+/* Helper for __has_{builtin,feature,extension}. */ - --int --c_common_has_builtin (cpp_reader *pfile) -+static const char * -+c_common_lex_availability_macro (cpp_reader *pfile, const char *builtin) - { - const cpp_token *token = get_token_no_padding (pfile); - if (token->type != CPP_OPEN_PAREN) - { - cpp_error (pfile, CPP_DL_ERROR, -- "missing '(' after \"__has_builtin\""); -+ "missing '(' after \"__has_%s\"", builtin); - return 0; - } - -@@ -486,7 +487,7 @@ c_common_has_builtin (cpp_reader *pfile) - else - { - cpp_error (pfile, CPP_DL_ERROR, -- "macro \"__has_builtin\" requires an identifier"); -+ "macro \"__has_%s\" requires an identifier", builtin); - if (token->type == CPP_CLOSE_PAREN) - return 0; - } -@@ -505,9 +506,38 @@ c_common_has_builtin (cpp_reader *pfile) - break; - } - -+ return name; -+} -+ -+/* Callback for has_builtin. */ -+ -+int -+c_common_has_builtin (cpp_reader *pfile) -+{ -+ const char *name = c_common_lex_availability_macro (pfile, "builtin"); -+ if (!name) -+ return 0; -+ - return names_builtin_p (name); - } - -+/* Callback for has_feature. STRICT_P is true for has_feature and false -+ for has_extension. */ -+ -+int -+c_common_has_feature (cpp_reader *pfile, bool strict_p) -+{ -+ const char *builtin = strict_p ? "feature" : "extension"; -+ const char *name = c_common_lex_availability_macro (pfile, builtin); -+ if (!name) -+ return 0; -+ -+ /* If -pedantic-errors is given, __has_extension is equivalent to -+ __has_feature. */ -+ strict_p |= flag_pedantic_errors; -+ return has_feature_p (name, strict_p); -+} -+ - - /* Read a token and return its type. Fill *VALUE with its value, if - applicable. Fill *CPP_FLAGS with the token's flags, if it is -@@ -539,6 +569,21 @@ c_lex_with_flags (tree *value, location_t *loc, unsigned char *cpp_flags, - - case CPP_NUMBER: - { -+ /* If the user wants number-like entities to be returned as a raw -+ string, then don't try to classify them, which emits unwanted -+ diagnostics. */ -+ if (lex_flags & C_LEX_NUMBER_AS_STRING) -+ { -+ /* build_string adds a trailing NUL at [len]. */ -+ tree num_string = build_string (tok->val.str.len + 1, -+ (const char *) tok->val.str.text); -+ TREE_TYPE (num_string) = char_array_type_node; -+ *value = num_string; -+ /* We will effectively note this as CPP_N_INVALID, because we -+ made no checks here. */ -+ break; -+ } -+ - const char *suffix = NULL; - unsigned int flags = cpp_classify_number (parse_in, tok, &suffix, *loc); - -diff --git a/gcc/c-family/c-opts.cc b/gcc/c-family/c-opts.cc -index c68a2a2..a600d40 100644 ---- a/gcc/c-family/c-opts.cc -+++ b/gcc/c-family/c-opts.cc -@@ -1070,7 +1070,7 @@ c_common_post_options (const char **pfilename) - - if (flag_extern_tls_init) - { -- if (!TARGET_SUPPORTS_ALIASES || !SUPPORTS_WEAK) -+ if (!SUPPORTS_WEAK) - { - /* Lazy TLS initialization for a variable in another TU requires - alias and weak reference support. */ -diff --git a/gcc/c-family/c-ppoutput.cc b/gcc/c-family/c-ppoutput.cc -index 4aa2bef..a1488c6 100644 ---- a/gcc/c-family/c-ppoutput.cc -+++ b/gcc/c-family/c-ppoutput.cc -@@ -162,6 +162,7 @@ init_pp_output (FILE *out_stream) - - cb->has_attribute = c_common_has_attribute; - cb->has_builtin = c_common_has_builtin; -+ cb->has_feature = c_common_has_feature; - cb->get_source_date_epoch = cb_get_source_date_epoch; - cb->remap_filename = remap_macro_filename; - -diff --git a/gcc/c-family/c-pragma.h b/gcc/c-family/c-pragma.h -index 9cc95ab..3e86a16 100644 ---- a/gcc/c-family/c-pragma.h -+++ b/gcc/c-family/c-pragma.h -@@ -272,6 +272,9 @@ extern enum cpp_ttype pragma_lex (tree *, location_t *loc = NULL); - #define C_LEX_STRING_NO_JOIN 2 /* Do not concatenate strings - nor translate them into execution - character set. */ -+#define C_LEX_NUMBER_AS_STRING 4 /* Do not classify a number, but -+ instead return it as a raw -+ string. */ - - /* This is not actually available to pragma parsers. It's merely a - convenient location to declare this function for c-lex, after -diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt -index a750389..c7e6620 100644 ---- a/gcc/c-family/c.opt -+++ b/gcc/c-family/c.opt -@@ -1484,6 +1484,10 @@ Wsubobject-linkage - C++ ObjC++ Var(warn_subobject_linkage) Warning Init(1) - Warn if a class type has a base or a field whose type uses the anonymous namespace or depends on a type with no linkage. - -+Welaborated-enum-base -+C++ ObjC++ Var(warn_elaborated_enum_base) Warning Init(1) -+Warn if an additional enum-base is used in an elaborated-type-specifier. -+ - Wduplicate-decl-specifier - C ObjC Var(warn_duplicate_decl_specifier) Warning LangEnabledBy(C ObjC,Wall) - Warn when a declaration has duplicate const, volatile, restrict or _Atomic specifier. -@@ -1967,7 +1971,7 @@ Implement resolution of DR 150 for matching of template template arguments. - - fnext-runtime - ObjC ObjC++ LTO RejectNegative Var(flag_next_runtime) --Generate code for NeXT (Apple Mac OS X) runtime environment. -+Generate code for NeXT (Apple macOS) runtime environment. - - fnil-receivers - ObjC ObjC++ Var(flag_nil_receivers) Init(1) -diff --git a/gcc/calls.cc b/gcc/calls.cc -index 53b0f58..b58990f 100644 ---- a/gcc/calls.cc -+++ b/gcc/calls.cc -@@ -1367,7 +1367,8 @@ initialize_argument_information (int num_actuals ATTRIBUTE_UNUSED, - with those made by function.cc. */ - - /* See if this argument should be passed by invisible reference. */ -- function_arg_info arg (type, argpos < n_named_args); -+ function_arg_info arg (type, argpos < n_named_args, -+ argpos == n_named_args - 1); - if (pass_by_reference (args_so_far_pnt, arg)) - { - const bool callee_copies -@@ -1487,10 +1488,13 @@ initialize_argument_information (int num_actuals ATTRIBUTE_UNUSED, - - unsignedp = TYPE_UNSIGNED (type); - arg.type = type; -- arg.mode -- = promote_function_mode (type, TYPE_MODE (type), &unsignedp, -- fndecl ? TREE_TYPE (fndecl) : fntype, 0); -- -+ arg.mode = TYPE_MODE (type); -+// arg.mode -+// = promote_function_mode (type, TYPE_MODE (type), &unsignedp, -+// fndecl ? TREE_TYPE (fndecl) : fntype, 0); -+ arg.mode = promote_function_mode (args_so_far, arg, -+ fndecl ? TREE_TYPE (fndecl) : fntype, -+ &unsignedp, 0); - args[i].unsignedp = unsignedp; - args[i].mode = arg.mode; - -@@ -1540,6 +1544,7 @@ initialize_argument_information (int num_actuals ATTRIBUTE_UNUSED, - #endif - reg_parm_stack_space, - args[i].pass_on_stack ? 0 : args[i].partial, -+ args_so_far, - fndecl, args_size, &args[i].locate); - #ifdef BLOCK_REG_PADDING - else -@@ -4076,6 +4081,7 @@ split_complex_types (tree types) - return types; - } - -+extern void debug_tree (tree); - /* Output a library call to function ORGFUN (a SYMBOL_REF rtx) - for a value of mode OUTMODE, - with NARGS different arguments, passed as ARGS. -@@ -4261,6 +4267,7 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx value, - argvec[count].reg != 0, - #endif - reg_parm_stack_space, 0, -+ args_so_far, - NULL_TREE, &args_size, &argvec[count].locate); - - if (argvec[count].reg == 0 || argvec[count].partial != 0 -@@ -4331,8 +4338,16 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx value, - val = force_operand (XEXP (slot, 0), NULL_RTX); - } - -- arg.mode = promote_function_mode (NULL_TREE, arg.mode, &unsigned_p, -- NULL_TREE, 0); -+// arg.mode = promote_function_mode (NULL_TREE, arg.mode, &unsigned_p, -+// NULL_TREE, 0); -+ tree t = arg.type; -+if (t) -+ debug_tree (t); -+gcc_assert (!t); -+ arg.type = NULL_TREE; -+ arg.mode = promote_function_mode (args_so_far, arg, NULL_TREE, -+ &unsigned_p, 0); -+ arg.type = t; - argvec[count].mode = arg.mode; - argvec[count].value = convert_modes (arg.mode, GET_MODE (val), val, - unsigned_p); -@@ -4352,6 +4367,7 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx value, - argvec[count].reg != 0, - #endif - reg_parm_stack_space, argvec[count].partial, -+ args_so_far, - NULL_TREE, &args_size, &argvec[count].locate); - args_size.constant += argvec[count].locate.size.constant; - gcc_assert (!argvec[count].locate.size.var); -diff --git a/gcc/calls.h b/gcc/calls.h -index c7f8c5e..42a1774 100644 ---- a/gcc/calls.h -+++ b/gcc/calls.h -@@ -35,24 +35,43 @@ class function_arg_info - { - public: - function_arg_info () -- : type (NULL_TREE), mode (VOIDmode), named (false), -+ : type (NULL_TREE), mode (VOIDmode), named (false), last_named (false), - pass_by_reference (false) - {} - - /* Initialize an argument of mode MODE, either before or after promotion. */ - function_arg_info (machine_mode mode, bool named) -- : type (NULL_TREE), mode (mode), named (named), pass_by_reference (false) -+ : type (NULL_TREE), mode (mode), named (named), last_named (false), -+ pass_by_reference (false) -+ {} -+ -+ function_arg_info (machine_mode mode, bool named, bool last_named) -+ : type (NULL_TREE), mode (mode), named (named), last_named (last_named), -+ pass_by_reference (false) - {} - - /* Initialize an unpromoted argument of type TYPE. */ - function_arg_info (tree type, bool named) -- : type (type), mode (TYPE_MODE (type)), named (named), -+ : type (type), mode (TYPE_MODE (type)), named (named), last_named (false), - pass_by_reference (false) - {} - -+ /* Initialize an unpromoted argument of type TYPE. */ -+ function_arg_info (tree type, bool named, bool last_named) -+ : type (type), mode (TYPE_MODE (type)), named (named), -+ last_named (last_named), pass_by_reference (false) -+ {} -+ - /* Initialize an argument with explicit properties. */ - function_arg_info (tree type, machine_mode mode, bool named) -- : type (type), mode (mode), named (named), pass_by_reference (false) -+ : type (type), mode (mode), named (named), last_named (false), -+ pass_by_reference (false) -+ {} -+ -+ /* Initialize an argument with explicit properties. */ -+ function_arg_info (tree type, machine_mode mode, bool named, bool last_named) -+ : type (type), mode (mode), named (named), last_named (last_named), -+ pass_by_reference (false) - {} - - /* Return true if the gimple-level type is an aggregate. */ -@@ -105,6 +124,9 @@ public: - "..."). See also TARGET_STRICT_ARGUMENT_NAMING. */ - unsigned int named : 1; - -+ /* True if this is the last named argument. */ -+ unsigned int last_named : 1; -+ - /* True if we have decided to pass the argument by reference, in which case - the function_arg_info describes a pointer to the original argument. */ - unsigned int pass_by_reference : 1; -diff --git a/gcc/collect2.cc b/gcc/collect2.cc -index 63b9a0c..1d7d9a4 100644 ---- a/gcc/collect2.cc -+++ b/gcc/collect2.cc -@@ -73,7 +73,7 @@ along with GCC; see the file COPYING3. If not see - In a cross-compiler, this means you need a cross nm, - but that is not quite as unpleasant as special headers. */ - --#if !defined (OBJECT_FORMAT_COFF) -+#if !defined (OBJECT_FORMAT_COFF) && !defined (OBJECT_FORMAT_MACHO) - #define OBJECT_FORMAT_NONE - #endif - -@@ -107,7 +107,7 @@ along with GCC; see the file COPYING3. If not see - - #endif /* OBJECT_FORMAT_COFF */ - --#ifdef OBJECT_FORMAT_NONE -+#if defined (OBJECT_FORMAT_NONE) || defined (OBJECT_FORMAT_MACHO) - - /* Default flags to pass to nm. */ - #ifndef NM_FLAGS -@@ -525,7 +525,7 @@ static const char *const target_machine = TARGET_MACHINE; - - Return 0 if not found, otherwise return its name, allocated with malloc. */ - --#ifdef OBJECT_FORMAT_NONE -+#if defined (OBJECT_FORMAT_NONE) || defined (OBJECT_FORMAT_MACHO) - - /* Add an entry for the object file NAME to object file list LIST. - New entries are added at the end of the list. The original pointer -@@ -764,6 +764,12 @@ do_link (char **ld_argv, const char *atsuffix) - } - } - -+#if defined (OBJECT_FORMAT_MACHO) -+# define LLD_NAME "ld64.lld" -+#else -+# define LLD_NAME "ld.lld" -+#endif -+ - /* Main program. */ - - int -@@ -777,16 +783,19 @@ main (int argc, char **argv) - USE_BFD_LD, - USE_LLD_LD, - USE_MOLD_LD, -+ USE_CLASSIC_LD, - USE_LD_MAX - } selected_linker = USE_DEFAULT_LD; -+ - static const char *const ld_suffixes[USE_LD_MAX] = - { - "ld", - PLUGIN_LD_SUFFIX, - "ld.gold", - "ld.bfd", -- "ld.lld", -- "ld.mold" -+ LLD_NAME, -+ "ld.mold", -+ "ld-classic" - }; - static const char *const real_ld_suffix = "real-ld"; - static const char *const collect_ld_suffix = "collect-ld"; -@@ -953,14 +962,22 @@ main (int argc, char **argv) - if (selected_linker == USE_DEFAULT_LD) - selected_linker = USE_PLUGIN_LD; - } -+#if !defined (OBJECT_FORMAT_MACHO) - else if (strcmp (argv[i], "-fuse-ld=bfd") == 0) - selected_linker = USE_BFD_LD; - else if (strcmp (argv[i], "-fuse-ld=gold") == 0) - selected_linker = USE_GOLD_LD; -+#endif - else if (strcmp (argv[i], "-fuse-ld=lld") == 0) - selected_linker = USE_LLD_LD; - else if (strcmp (argv[i], "-fuse-ld=mold") == 0) - selected_linker = USE_MOLD_LD; -+#if defined (OBJECT_FORMAT_MACHO) -+ else if (strcmp (argv[i], "-fuse-ld=classic") == 0) -+ selected_linker = USE_CLASSIC_LD; -+#endif -+ else if (strcmp (argv[i], "-fuse-ld=") == 0) -+ selected_linker = USE_DEFAULT_LD; - else if (startswith (argv[i], "-o")) - { - /* Parse the output filename if it's given so that we can make -@@ -1052,7 +1069,8 @@ main (int argc, char **argv) - ld_file_name = 0; - #ifdef DEFAULT_LINKER - if (selected_linker == USE_BFD_LD || selected_linker == USE_GOLD_LD || -- selected_linker == USE_LLD_LD || selected_linker == USE_MOLD_LD) -+ selected_linker == USE_LLD_LD || selected_linker == USE_MOLD_LD || -+ selected_linker == USE_CLASSIC_LD) - { - char *linker_name; - # ifdef HOST_EXECUTABLE_SUFFIX -@@ -2266,7 +2284,7 @@ write_aix_file (FILE *stream, struct id *list) - } - #endif - --#ifdef OBJECT_FORMAT_NONE -+#if defined (OBJECT_FORMAT_NONE) || defined (OBJECT_FORMAT_MACHO) - - /* Check to make sure the file is an LTO object file. */ - -diff --git a/gcc/common/config/aarch64/aarch64-common.cc b/gcc/common/config/aarch64/aarch64-common.cc -index 20bc4e1..5058d2f 100644 ---- a/gcc/common/config/aarch64/aarch64-common.cc -+++ b/gcc/common/config/aarch64/aarch64-common.cc -@@ -301,8 +301,12 @@ aarch64_get_extension_string_for_isa_flags - - However, assemblers with Armv8-R AArch64 support should not have this - issue, so we don't need this fix when targeting Armv8-R. */ -- auto explicit_flags = (!(current_flags & AARCH64_FL_V8R) -- ? AARCH64_FL_CRC : 0); -+ aarch64_feature_flags explicit_flags = -+#ifndef DISABLE_AARCH64_AS_CRC_BUGFIX -+ (!(current_flags & AARCH64_ISA_V8R) ? AARCH64_FL_CRC : 0); -+#else -+ 0; -+#endif - - /* Add the features in isa_flags & ~current_flags using the smallest - possible number of extensions. We can do this by iterating over the -@@ -331,7 +335,10 @@ aarch64_get_extension_string_for_isa_flags - if (added & opt.flag_canonical) - { - outstr += "+"; -- outstr += opt.name; -+ if (startswith (opt.name, "rdm")) -+ outstr += "rdm"; -+ else -+ outstr += opt.name; - } - - /* Remove the features in current_flags & ~isa_flags. If the feature does -@@ -344,7 +351,10 @@ aarch64_get_extension_string_for_isa_flags - { - current_flags &= ~opt.flags_off; - outstr += "+no"; -- outstr += opt.name; -+ if (startswith (opt.name, "rdm")) -+ outstr += "rdm"; -+ else -+ outstr += opt.name; - } - - return outstr; -diff --git a/gcc/common.opt b/gcc/common.opt -index b055c7b..cf32af4 100644 ---- a/gcc/common.opt -+++ b/gcc/common.opt -@@ -2794,6 +2794,10 @@ fstack-usage - Common RejectNegative Var(flag_stack_usage) - Output stack usage information on a per-function basis. - -+fstack-use-cumulative-args -+Common RejectNegative Var(flag_stack_use_cumulative_args) Init(STACK_USE_CUMULATIVE_ARGS_INIT) -+Use cumulative args-based stack layout hooks. -+ - fstrength-reduce - Common Ignore - Does nothing. Preserved for backward compatibility. -@@ -2862,10 +2866,25 @@ Common Var(flag_tracer) Optimization - Perform superblock formation via tail duplication. - - ftrampolines --Common Var(flag_trampolines) Init(0) -+Common Var(flag_trampolines) Init(HEAP_TRAMPOLINES_INIT) - For targets that normally need trampolines for nested functions, always - generate them instead of using descriptors. - -+ftrampoline-impl= -+Common Joined RejectNegative Enum(trampoline_impl) Var(flag_trampoline_impl) Init(HEAP_TRAMPOLINES_INIT ? TRAMPOLINE_IMPL_HEAP : TRAMPOLINE_IMPL_STACK) -+Whether trampolines are generated in executable memory rather than -+executable stack. -+ -+Enum -+Name(trampoline_impl) Type(enum trampoline_impl) UnknownError(unknown trampoline implementation %qs) -+ -+EnumValue -+Enum(trampoline_impl) String(stack) Value(TRAMPOLINE_IMPL_STACK) -+ -+EnumValue -+Enum(trampoline_impl) String(heap) Value(TRAMPOLINE_IMPL_HEAP) -+ -+ - ; Zero means that floating-point math operations cannot generate a - ; (user-visible) trap. This is the case, for example, in nonstop - ; IEEE 754 arithmetic. -@@ -3123,6 +3142,10 @@ fuse-ld=mold - Common Driver Negative(fuse-ld=mold) - Use the Modern linker (MOLD) linker instead of the default linker. - -+fuse-ld=classic -+Common Driver Negative(fuse-ld=classic) -+Use the ld-classic linker instead of the default linker. -+ - fuse-linker-plugin - Common Undocumented Var(flag_use_linker_plugin) - -diff --git a/gcc/config/aarch64/aarch64-builtins.cc b/gcc/config/aarch64/aarch64-builtins.cc -index 8ad8284..567fb10 100644 ---- a/gcc/config/aarch64/aarch64-builtins.cc -+++ b/gcc/config/aarch64/aarch64-builtins.cc -@@ -785,6 +785,8 @@ enum aarch64_builtins - AARCH64_RBIT, - AARCH64_RBITL, - AARCH64_RBITLL, -+ /* OS-specific */ -+ AARCH64_BUILTIN_CFSTRING, - AARCH64_BUILTIN_MAX - }; - -@@ -920,6 +922,9 @@ tree aarch64_fp16_ptr_type_node = NULL_TREE; - /* Back-end node type for brain float (bfloat) types. */ - tree aarch64_bf16_ptr_type_node = NULL_TREE; - -+/* Pointer to __float128 on Mach-O, where the 128b float is not long double. */ -+tree aarch64_float128_ptr_type_node = NULL_TREE; -+ - /* Wrapper around add_builtin_function. NAME is the name of the built-in - function, TYPE is the function type, CODE is the function subcode - (relative to AARCH64_BUILTIN_GENERAL), and ATTRS is the function -@@ -1695,6 +1700,29 @@ aarch64_init_bf16_types (void) - aarch64_bf16_ptr_type_node = build_pointer_type (bfloat16_type_node); - } - -+/* Initialize the backend REAL_TYPE type supporting __float128 on Mach-O, -+ as well as the related built-ins. */ -+static void -+aarch64_init_float128_types (void) -+{ -+ /* The __float128 type. The node has already been created as -+ _Float128, so for C we only need to register the __float128 name for -+ it. For C++, we create a distinct type which will mangle differently -+ (g) vs. _Float128 (DF128_) and behave backwards compatibly. */ -+ if (float128t_type_node == NULL_TREE) -+ { -+ float128t_type_node = make_node (REAL_TYPE); -+ TYPE_PRECISION (float128t_type_node) -+ = TYPE_PRECISION (float128_type_node); -+ SET_TYPE_MODE (float128t_type_node, TYPE_MODE (float128_type_node)); -+ layout_type (float128t_type_node); -+ } -+ lang_hooks.types.register_builtin_type (float128t_type_node, "__float128"); -+ -+ aarch64_float128_ptr_type_node = build_pointer_type (float128t_type_node); -+} -+ -+ - /* Pointer authentication builtins that will become NOP on legacy platform. - Currently, these builtins are for internal use only (libgcc EH unwinder). */ - -@@ -1983,8 +2011,9 @@ aarch64_general_init_builtins (void) - aarch64_init_fpsr_fpcr_builtins (); - - aarch64_init_fp16_types (); -- - aarch64_init_bf16_types (); -+ if (TARGET_MACHO) -+ aarch64_init_float128_types (); - - { - aarch64_simd_switcher simd; -@@ -2021,6 +2050,14 @@ aarch64_general_init_builtins (void) - handle_arm_acle_h (); - } - -+void -+aarch64_init_subtarget_builtins (void) -+{ -+#ifdef SUBTARGET_INIT_BUILTINS -+ SUBTARGET_INIT_BUILTINS; -+#endif -+} -+ - /* Implement TARGET_BUILTIN_DECL for the AARCH64_BUILTIN_GENERAL group. */ - tree - aarch64_general_builtin_decl (unsigned code, bool) -diff --git a/gcc/config/aarch64/aarch64-c.cc b/gcc/config/aarch64/aarch64-c.cc -index 578ec6f..56c83ac 100644 ---- a/gcc/config/aarch64/aarch64-c.cc -+++ b/gcc/config/aarch64/aarch64-c.cc -@@ -224,6 +224,16 @@ aarch64_cpu_cpp_builtins (cpp_reader *pfile) - { - aarch64_define_unconditional_macros (pfile); - aarch64_update_cpp_builtins (pfile); -+ -+ if (TARGET_MACHO) -+ { -+ builtin_define ("__builtin_copysignq=__builtin_copysignf128"); -+ builtin_define ("__builtin_fabsq=__builtin_fabsf128"); -+ builtin_define ("__builtin_huge_valq=__builtin_huge_valf128"); -+ builtin_define ("__builtin_infq=__builtin_inff128"); -+ builtin_define ("__builtin_nanq=__builtin_nanf128"); -+ builtin_define ("__builtin_nansq=__builtin_nansf128"); -+ } - } - - /* Hook to validate the current #pragma GCC target and set the state, and -@@ -359,4 +369,8 @@ aarch64_register_pragmas (void) - targetm.check_builtin_call = aarch64_check_builtin_call; - - c_register_pragma ("GCC", "aarch64", aarch64_pragma_aarch64); -+ -+#ifdef REGISTER_SUBTARGET_PRAGMAS -+ REGISTER_SUBTARGET_PRAGMAS (); -+#endif - } -diff --git a/gcc/config/aarch64/aarch64-cores.def b/gcc/config/aarch64/aarch64-cores.def -index fdda069..2dc4ae6 100644 ---- a/gcc/config/aarch64/aarch64-cores.def -+++ b/gcc/config/aarch64/aarch64-cores.def -@@ -165,6 +165,18 @@ AARCH64_CORE("cortex-a76.cortex-a55", cortexa76cortexa55, cortexa53, V8_2A, (F - /* Armv8-R Architecture Processors. */ - AARCH64_CORE("cortex-r82", cortexr82, cortexa53, V8R, (), cortexa53, 0x41, 0xd15, -1) - -+/* Apple (A12 and M) cores. -+ Apple implementer ID from xnu, -+ guesses for part #, guesses for scheduler ident, generic_armv8_a for costs. -+ A12 seems mostly 8.3, -+ M1 seems to be 8.4 + extras (see comments in option-extensions about f16fml), -+ M2 mostly 8.5 but with missing mandatory features. -+ M3 is pretty much the same as M2. */ -+AARCH64_CORE("apple-a12", applea12, cortexa53, V8_3A, (), cortexa53, 0x61, 0x12, -1) -+AARCH64_CORE("apple-m1", applem1, cortexa57, V8_4A, (F16, SB, SSBS), cortexa73, 0x61, 0x23, -1) -+AARCH64_CORE("apple-m2", applem2, cortexa57, V8_4A, (I8MM, BF16, F16, SB, SSBS), cortexa73, 0x61, 0x23, -1) -+AARCH64_CORE("apple-m3", applem3, cortexa57, V8_4A, (I8MM, BF16, F16, SB, SSBS), cortexa73, 0x61, 0x23, -1) -+ - /* Armv9.0-A Architecture Processors. */ - - /* Arm ('A') cores. */ -diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h -index 32716f6..a107f9e 100644 ---- a/gcc/config/aarch64/aarch64-protos.h -+++ b/gcc/config/aarch64/aarch64-protos.h -@@ -109,6 +109,14 @@ enum aarch64_symbol_type - SYMBOL_TLSLE24, - SYMBOL_TLSLE32, - SYMBOL_TLSLE48, -+ SYMBOL_MO_SMALL_ABS, -+ SYMBOL_MO_SMALL_PCR, -+ SYMBOL_MO_SMALL_GOT, -+ SYMBOL_MO_SMALL_TLS, -+ SYMBOL_MO_LARGE_ABS, -+ SYMBOL_MO_LARGE_PCR, -+ SYMBOL_MO_LARGE_GOT, -+ SYMBOL_MO_LARGE_TLS, - SYMBOL_FORCE_TO_MEM - }; - -@@ -745,6 +753,7 @@ void aarch64_post_cfi_startproc (void); - poly_int64 aarch64_initial_elimination_offset (unsigned, unsigned); - int aarch64_get_condition_code (rtx); - bool aarch64_address_valid_for_prefetch_p (rtx, bool); -+bool aarch64_address_valid_for_unscaled_prefetch_p (rtx, bool); - bool aarch64_bitmask_imm (unsigned HOST_WIDE_INT val, machine_mode); - unsigned HOST_WIDE_INT aarch64_and_split_imm1 (HOST_WIDE_INT val_in); - unsigned HOST_WIDE_INT aarch64_and_split_imm2 (HOST_WIDE_INT val_in); -@@ -775,7 +784,11 @@ bool aarch64_is_extend_from_extract (scalar_int_mode, rtx, rtx); - bool aarch64_is_long_call_p (rtx); - bool aarch64_is_noplt_call_p (rtx); - bool aarch64_label_mentioned_p (rtx); -+#if TARGET_MACHO -+void aarch64_darwin_declare_function_name (FILE *, const char*, tree ); -+#else - void aarch64_declare_function_name (FILE *, const char*, tree); -+#endif - void aarch64_asm_output_alias (FILE *, const tree, const tree); - void aarch64_asm_output_external (FILE *, tree, const char*); - bool aarch64_legitimate_pic_operand_p (rtx); -@@ -971,6 +984,7 @@ void aarch64_override_options_internal (struct gcc_options *); - - const char *aarch64_general_mangle_builtin_type (const_tree); - void aarch64_general_init_builtins (void); -+void aarch64_init_subtarget_builtins (void); - tree aarch64_general_fold_builtin (unsigned int, tree, unsigned int, tree *); - gimple *aarch64_general_gimple_fold_builtin (unsigned int, gcall *, - gimple_stmt_iterator *); -diff --git a/gcc/config/aarch64/aarch64-tune.md b/gcc/config/aarch64/aarch64-tune.md -index 9d46d38..3c3aa72 100644 ---- a/gcc/config/aarch64/aarch64-tune.md -+++ b/gcc/config/aarch64/aarch64-tune.md -@@ -1,5 +1,5 @@ - ;; -*- buffer-read-only: t -*- - ;; Generated automatically by gentune.sh from aarch64-cores.def - (define_attr "tune" -- "cortexa34,cortexa35,cortexa53,cortexa57,cortexa72,cortexa73,thunderx,thunderxt88p1,thunderxt88,octeontx,octeontxt81,octeontxt83,thunderxt81,thunderxt83,ampere1,ampere1a,emag,xgene1,falkor,qdf24xx,exynosm1,phecda,thunderx2t99p1,vulcan,thunderx2t99,cortexa55,cortexa75,cortexa76,cortexa76ae,cortexa77,cortexa78,cortexa78ae,cortexa78c,cortexa65,cortexa65ae,cortexx1,cortexx1c,neoversen1,ares,neoversee1,octeontx2,octeontx2t98,octeontx2t96,octeontx2t93,octeontx2f95,octeontx2f95n,octeontx2f95mm,a64fx,tsv110,thunderx3t110,neoversev1,zeus,neoverse512tvb,saphira,cortexa57cortexa53,cortexa72cortexa53,cortexa73cortexa35,cortexa73cortexa53,cortexa75cortexa55,cortexa76cortexa55,cortexr82,cortexa510,cortexa710,cortexa715,cortexx2,cortexx3,neoversen2,cobalt100,neoversev2,demeter" -+ "cortexa34,cortexa35,cortexa53,cortexa57,cortexa72,cortexa73,thunderx,thunderxt88p1,thunderxt88,octeontx,octeontxt81,octeontxt83,thunderxt81,thunderxt83,ampere1,ampere1a,emag,xgene1,falkor,qdf24xx,exynosm1,phecda,thunderx2t99p1,vulcan,thunderx2t99,cortexa55,cortexa75,cortexa76,cortexa76ae,cortexa77,cortexa78,cortexa78ae,cortexa78c,cortexa65,cortexa65ae,cortexx1,cortexx1c,neoversen1,ares,neoversee1,octeontx2,octeontx2t98,octeontx2t96,octeontx2t93,octeontx2f95,octeontx2f95n,octeontx2f95mm,a64fx,tsv110,thunderx3t110,neoversev1,zeus,neoverse512tvb,saphira,cortexa57cortexa53,cortexa72cortexa53,cortexa73cortexa35,cortexa73cortexa53,cortexa75cortexa55,cortexa76cortexa55,cortexr82,applea12,applem1,applem2,applem3,cortexa510,cortexa710,cortexa715,cortexx2,cortexx3,neoversen2,cobalt100,neoversev2,demeter" - (const (symbol_ref "((enum attr_tune) aarch64_tune)"))) -diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc -index b8a4ab1..d2f5034 100644 ---- a/gcc/config/aarch64/aarch64.cc -+++ b/gcc/config/aarch64/aarch64.cc -@@ -295,8 +295,10 @@ static bool aarch64_vfp_is_call_or_return_candidate (machine_mode, - const_tree, - machine_mode *, int *, - bool *, bool); -+#if !TARGET_MACHO - static void aarch64_elf_asm_constructor (rtx, int) ATTRIBUTE_UNUSED; - static void aarch64_elf_asm_destructor (rtx, int) ATTRIBUTE_UNUSED; -+#endif - static void aarch64_override_options_after_change (void); - static bool aarch64_vector_mode_supported_p (machine_mode); - static int aarch64_address_cost (rtx, machine_mode, addr_space_t, bool); -@@ -2795,6 +2797,9 @@ static const struct attribute_spec aarch64_attribute_table[] = - { - /* { name, min_len, max_len, decl_req, type_req, fn_type_req, - affects_type_identity, handler, exclude } */ -+#ifdef SUBTARGET_ATTRIBUTE_TABLE -+ SUBTARGET_ATTRIBUTE_TABLE, -+#endif - { "aarch64_vector_pcs", 0, 0, false, true, true, true, - handle_aarch64_vector_pcs_attribute, NULL }, - { "arm_sve_vector_bits", 1, 1, false, true, false, true, -@@ -3949,7 +3954,7 @@ aarch64_hard_regno_mode_ok (unsigned regno, machine_mode mode) - if (known_le (GET_MODE_SIZE (mode), 8)) - return true; - if (known_le (GET_MODE_SIZE (mode), 16)) -- return (regno & 1) == 0; -+ return (regno & 1) == 0 || TARGET_MACHO; /* darwinpcs D.4 */ - } - else if (FP_REGNUM_P (regno)) - { -@@ -3995,8 +4000,10 @@ static bool - aarch64_takes_arguments_in_sve_regs_p (const_tree fntype) - { - CUMULATIVE_ARGS args_so_far_v; -+ /* This does not apply to variadic functions, so all the (currently -+ uncounted) arguments must be named. */ - aarch64_init_cumulative_args (&args_so_far_v, NULL_TREE, NULL_RTX, -- NULL_TREE, 0, true); -+ NULL_TREE, -1, true); - cumulative_args_t args_so_far = pack_cumulative_args (&args_so_far_v); - - for (tree chain = TYPE_ARG_TYPES (fntype); -@@ -4481,6 +4488,7 @@ aarch64_load_symref_appropriately (rtx dest, rtx imm, - switch (type) - { - case SYMBOL_SMALL_ABSOLUTE: -+ case SYMBOL_MO_SMALL_PCR: - { - /* In ILP32, the mode of dest can be either SImode or DImode. */ - rtx tmp_reg = dest; -@@ -4491,6 +4499,21 @@ aarch64_load_symref_appropriately (rtx dest, rtx imm, - if (can_create_pseudo_p ()) - tmp_reg = gen_reg_rtx (mode); - -+ if (TARGET_MACHO) -+ { -+ rtx sym, off; -+ split_const (imm, &sym, &off); -+ /* Negative offsets don't work, whether by intention is TBD. */ -+ if (INTVAL (off) < 0 || INTVAL (off) > 8 * 1024 * 1024) -+ { -+ emit_move_insn (tmp_reg, gen_rtx_HIGH (mode, sym)); -+ emit_insn (gen_add_losym (dest, tmp_reg, sym)); -+ /* FIXME: add the SI option if/when we support ilp32. */ -+ emit_insn (gen_adddi3 (dest, dest, off)); -+ return; -+ } -+ /* else small enough positive offset is OK. */ -+ } - emit_move_insn (tmp_reg, gen_rtx_HIGH (mode, copy_rtx (imm))); - emit_insn (gen_add_losym (dest, tmp_reg, imm)); - return; -@@ -4574,6 +4597,7 @@ aarch64_load_symref_appropriately (rtx dest, rtx imm, - return; - } - -+ case SYMBOL_MO_SMALL_GOT: - case SYMBOL_SMALL_GOT_4G: - emit_insn (gen_rtx_SET (dest, imm)); - return; -@@ -6855,6 +6879,7 @@ aarch64_expand_mov_immediate (rtx dest, rtx imm) - case SYMBOL_SMALL_TLSIE: - case SYMBOL_SMALL_GOT_28K: - case SYMBOL_SMALL_GOT_4G: -+ case SYMBOL_MO_SMALL_GOT: - case SYMBOL_TINY_GOT: - case SYMBOL_TINY_TLSIE: - if (const_offset != 0) -@@ -6868,6 +6893,7 @@ aarch64_expand_mov_immediate (rtx dest, rtx imm) - /* FALLTHRU */ - - case SYMBOL_SMALL_ABSOLUTE: -+ case SYMBOL_MO_SMALL_PCR: - case SYMBOL_TINY_ABSOLUTE: - case SYMBOL_TLSLE12: - case SYMBOL_TLSLE24: -@@ -7449,6 +7475,7 @@ aarch64_return_in_memory (const_tree type, const_tree fndecl ATTRIBUTE_UNUSED) - gcc_unreachable (); - } - -+#if !TARGET_MACHO - static bool - aarch64_vfp_is_call_candidate (cumulative_args_t pcum_v, machine_mode mode, - const_tree type, int *nregs) -@@ -7458,6 +7485,7 @@ aarch64_vfp_is_call_candidate (cumulative_args_t pcum_v, machine_mode mode, - &pcum->aapcs_vfp_rmode, - nregs, NULL, pcum->silent_p); - } -+#endif - - /* Given MODE and TYPE of a function argument, return the alignment in - bits. The idea is to suppress any stronger alignment requested by -@@ -7481,7 +7509,7 @@ aarch64_function_arg_alignment (machine_mode mode, const_tree type, - if (integer_zerop (TYPE_SIZE (type))) - return 0; - -- gcc_assert (TYPE_MODE (type) == mode); -+ gcc_assert (TARGET_MACHO || TYPE_MODE (type) == mode); - - if (!AGGREGATE_TYPE_P (type)) - { -@@ -7641,6 +7669,14 @@ aarch64_layout_arg (cumulative_args_t pcum_v, const function_arg_info &arg) - Both behaviors were wrong, but in different cases. */ - - pcum->aapcs_arg_processed = true; -+ if (TARGET_MACHO) -+ { -+ /* Set suitable defaults for queries. */ -+ pcum->darwinpcs_arg_boundary -+ = aarch64_function_arg_alignment (mode, type, &abi_break, -+ &abi_break_packed); -+ pcum->darwinpcs_arg_padding = BITS_PER_UNIT; -+ } - - pure_scalable_type_info pst_info; - if (type && pst_info.analyze_registers (type)) -@@ -7700,13 +7736,29 @@ aarch64_layout_arg (cumulative_args_t pcum_v, const function_arg_info &arg) - /* No frontends can create types with variable-sized modes, so we - shouldn't be asked to pass or return them. */ - size = GET_MODE_SIZE (mode).to_constant (); -+ -+ if (TARGET_MACHO) -+ /* Since we can pack things on the stack, we need the unrounded size. */ -+ pcum->darwinpcs_stack_bytes = size; -+ - size = ROUND_UP (size, UNITS_PER_WORD); - - allocate_ncrn = (type) ? !(FLOAT_TYPE_P (type)) : !FLOAT_MODE_P (mode); -+ bool is_ha = false; -+#if !TARGET_MACHO - allocate_nvrn = aarch64_vfp_is_call_candidate (pcum_v, - mode, - type, - &nregs); -+#else -+ /* We care if the value is a homogenous aggregate when laying out the stack, -+ so use this call directly. */ -+ allocate_nvrn -+ = aarch64_vfp_is_call_or_return_candidate (mode, type, -+ &pcum->aapcs_vfp_rmode, -+ &nregs, &is_ha, -+ pcum->silent_p); -+#endif - gcc_assert (!sve_p || !allocate_nvrn); - - unsigned int alignment -@@ -7727,7 +7779,13 @@ aarch64_layout_arg (cumulative_args_t pcum_v, const function_arg_info &arg) - if (!pcum->silent_p && !TARGET_FLOAT) - aarch64_err_no_fpadvsimd (mode); - -- if (nvrn + nregs <= NUM_FP_ARG_REGS) -+ if (TARGET_MACHO -+ && !arg.named) -+ { -+ pcum->aapcs_nextnvrn = NUM_FP_ARG_REGS; -+ goto on_stack; -+ } -+ else if (nvrn + nregs <= NUM_FP_ARG_REGS) - { - pcum->aapcs_nextnvrn = nvrn + nregs; - if (!aarch64_composite_type_p (type, mode)) -@@ -7757,6 +7815,7 @@ aarch64_layout_arg (cumulative_args_t pcum_v, const function_arg_info &arg) - } - pcum->aapcs_reg = par; - } -+ pcum->darwinpcs_stack_bytes = 0; - return; - } - else -@@ -7773,14 +7832,24 @@ aarch64_layout_arg (cumulative_args_t pcum_v, const function_arg_info &arg) - /* C6 - C9. though the sign and zero extension semantics are - handled elsewhere. This is the case where the argument fits - entirely general registers. */ -+ - if (allocate_ncrn && (ncrn + nregs <= NUM_ARG_REGS)) - { - gcc_assert (nregs == 0 || nregs == 1 || nregs == 2); - -+ if (TARGET_MACHO -+ && !arg.named) -+ { -+ pcum->aapcs_nextncrn = NUM_ARG_REGS; -+ goto on_stack; -+ } -+ - /* C.8 if the argument has an alignment of 16 then the NGRN is - rounded up to the next even number. */ - if (nregs == 2 -- && ncrn % 2) -+ && ncrn % 2 -+ /* Darwin PCS deletes rule C.8. */ -+ && !TARGET_MACHO) - { - /* Emit a warning if the alignment changed when taking the - 'packed' attribute into account. */ -@@ -7842,8 +7911,8 @@ aarch64_layout_arg (cumulative_args_t pcum_v, const function_arg_info &arg) - } - pcum->aapcs_reg = par; - } -- - pcum->aapcs_nextncrn = ncrn + nregs; -+ pcum->darwinpcs_stack_bytes = 0; - return; - } - -@@ -7853,7 +7922,81 @@ aarch64_layout_arg (cumulative_args_t pcum_v, const function_arg_info &arg) - /* The argument is passed on stack; record the needed number of words for - this argument and align the total size if necessary. */ - on_stack: -- pcum->aapcs_stack_words = size / UNITS_PER_WORD; -+ -+ if (TARGET_MACHO) -+ { -+ /* Darwin does not round up the allocation for smaller entities to 8 -+ bytes. It only requires the natural alignment for these. -+ -+ but we don't do this for: -+ * unnamed parms in variadic functions -+ * complex types -+ * unions -+ * aggregates (except for homogeneous ones which are handles as the -+ enclosed type). -+ each entry starts a new slot. -+ -+ 16 byte entities are naturally aligned on the stack. -+ There was no darwinpcs for GCC 9, so neither the implementation -+ change nor the warning should fire here (i.e. we do not need to check -+ if 16byte entities alter the stack size). */ -+ -+ gcc_checking_assert (arg.named == pcum->named_p); -+ pcum->darwinpcs_arg_padding = BITS_PER_UNIT; -+ if (!pcum->named_p -+ || TREE_CODE (type) == COMPLEX_TYPE -+ || (TREE_CODE (type) == RECORD_TYPE -+ && !is_ha && !SCALAR_FLOAT_MODE_P (pcum->aapcs_vfp_rmode)) -+ || TREE_CODE (type) == UNION_TYPE) -+ { -+ pcum->aapcs_stack_words = size / UNITS_PER_WORD; -+ pcum->darwinpcs_sub_word_offset = 0; -+ pcum->darwinpcs_sub_word_pos = 0; -+ pcum->darwinpcs_arg_boundary = MAX (alignment, PARM_BOUNDARY); -+ if (!pcum->named_p) -+ pcum->darwinpcs_arg_padding = PARM_BOUNDARY; -+ return; -+ } -+ -+ /* Updated sub-word offset aligned for the new object. -+ We are looking for the case that the new object will fit after some -+ existing object(s) in the same stack slot. In that case, we do not -+ need to add any more stack space for it. */ -+ int new_off -+ = ROUND_UP (pcum->darwinpcs_sub_word_pos, alignment / BITS_PER_UNIT); -+ -+ if (new_off >= UNITS_PER_WORD) -+ { -+ /* That exceeds a stack slot, start a new one. */ -+ pcum->darwinpcs_sub_word_offset = 0; -+ pcum->darwinpcs_sub_word_pos = 0; -+ new_off = 0; -+ } -+ /* This is the end of the new object. */ -+ int new_pos = new_off + pcum->darwinpcs_stack_bytes; -+ -+ if (pcum->darwinpcs_sub_word_pos == 0) -+ /* New stack slot, just allocate one or more words, and note where -+ the next arg will start. */ -+ pcum->aapcs_stack_words = size / UNITS_PER_WORD; -+ else if (new_pos <= UNITS_PER_WORD) -+ /* Old stack slot, object starts at new_off and goes to new_pos, we do -+ not add any stack space. */ -+ pcum->darwinpcs_sub_word_offset = new_off; -+ pcum->darwinpcs_sub_word_pos = new_pos; -+ pcum->darwinpcs_arg_boundary = alignment ; -+ if (pcum->last_named_p && new_pos > 0) -+ { -+ /* Round the last named arg to the start of the next stack slot. */ -+ if (new_pos <= 4) -+ pcum->darwinpcs_arg_padding = PARM_BOUNDARY; -+ else if (new_pos <= 6) -+ pcum->darwinpcs_arg_padding = 4 * BITS_PER_UNIT; -+ else if (pcum->darwinpcs_sub_word_pos <= 7) -+ pcum->darwinpcs_arg_padding = 2 * BITS_PER_UNIT; -+ } -+ return; -+ } - - if (warn_pcs_change - && abi_break_packed -@@ -7862,6 +8005,8 @@ on_stack: - inform (input_location, "parameter passing for argument of type " - "%qT changed in GCC 13.1", type); - -+ /* size was already rounded up to PARM_BOUNDARY. */ -+ pcum->aapcs_stack_words = size / UNITS_PER_WORD; - if (alignment == 16 * BITS_PER_UNIT) - { - int new_size = ROUND_UP (pcum->aapcs_stack_size, 16 / UNITS_PER_WORD); -@@ -7915,7 +8060,28 @@ aarch64_init_cumulative_args (CUMULATIVE_ARGS *pcum, - pcum->aapcs_arg_processed = false; - pcum->aapcs_stack_words = 0; - pcum->aapcs_stack_size = 0; -+ pcum->darwinpcs_stack_bytes = 0; -+ pcum->darwinpcs_sub_word_offset = 0; -+ pcum->darwinpcs_sub_word_pos = 0; -+ pcum->darwinpcs_arg_boundary = BITS_PER_UNIT; -+ pcum->darwinpcs_arg_padding = BITS_PER_UNIT; -+ /* If we have been invoked for incoming args, then n_named will have been -+ set to -1, but we should have a function decl - so pick up the named -+ count from that. If that fails, and we end up with -1, this effectively -+ corresponds to assuming that there is an arbitrary number of named -+ args. */ -+ pcum->darwinpcs_n_named = n_named; -+ if (n_named == (unsigned)-1 && fndecl) -+ { -+ tree fnt = TREE_TYPE (fndecl); -+ if (fnt && TYPE_ARG_TYPES (fnt)) -+ pcum->darwinpcs_n_named = list_length (TYPE_ARG_TYPES (fnt)); -+ } -+ pcum->darwinpcs_n_args_processed = 0; -+ pcum->named_p = pcum->darwinpcs_n_named != 0; -+ pcum->last_named_p = pcum->darwinpcs_n_named == 1; - pcum->silent_p = silent_p; -+ pcum->aapcs_vfp_rmode = VOIDmode; - - if (!silent_p - && !TARGET_FLOAT -@@ -7954,8 +8120,10 @@ aarch64_function_arg_advance (cumulative_args_t pcum_v, - || pcum->pcs_variant == ARM_PCS_SVE) - { - aarch64_layout_arg (pcum_v, arg); -- gcc_assert ((pcum->aapcs_reg != NULL_RTX) -- != (pcum->aapcs_stack_words != 0)); -+ pcum->darwinpcs_n_args_processed++; -+ gcc_assert (TARGET_MACHO -+ || (pcum->aapcs_reg != NULL_RTX) -+ != (pcum->aapcs_stack_words != 0)); - pcum->aapcs_arg_processed = false; - pcum->aapcs_ncrn = pcum->aapcs_nextncrn; - pcum->aapcs_nvrn = pcum->aapcs_nextnvrn; -@@ -7963,6 +8131,12 @@ aarch64_function_arg_advance (cumulative_args_t pcum_v, - pcum->aapcs_stack_size += pcum->aapcs_stack_words; - pcum->aapcs_stack_words = 0; - pcum->aapcs_reg = NULL_RTX; -+ pcum->darwinpcs_arg_boundary = BITS_PER_UNIT; -+ pcum->darwinpcs_arg_padding = BITS_PER_UNIT; -+ pcum->named_p -+ = pcum->darwinpcs_n_args_processed < pcum->darwinpcs_n_named; -+ pcum->last_named_p -+ = pcum->darwinpcs_n_args_processed + 1 == pcum->darwinpcs_n_named; - } - } - -@@ -7974,12 +8148,15 @@ aarch64_function_arg_regno_p (unsigned regno) - || (PR_REGNUM_P (regno) && regno < P0_REGNUM + NUM_PR_ARG_REGS)); - } - --/* Implement FUNCTION_ARG_BOUNDARY. Every parameter gets at least -- PARM_BOUNDARY bits of alignment, but will be given anything up -- to STACK_BOUNDARY bits if the type requires it. This makes sure -- that both before and after the layout of each argument, the Next -- Stacked Argument Address (NSAA) will have a minimum alignment of -- 8 bytes. */ -+/* Implement FUNCTION_ARG_BOUNDARY. -+ For AAPCS64, Every parameter gets at least PARM_BOUNDARY bits of -+ alignment, but will be given anything up to STACK_BOUNDARY bits -+ if the type requires it. This makes sure that both before and after -+ the layout of each argument, the Next Stacked Argument Address (NSAA) -+ will have a minimum alignment of 8 bytes. -+ -+ For darwinpcs, this is only called to lower va_arg entries which are -+ always aligned as for AAPCS64. */ - - static unsigned int - aarch64_function_arg_boundary (machine_mode mode, const_tree type) -@@ -7991,8 +8168,107 @@ aarch64_function_arg_boundary (machine_mode mode, const_tree type) - &abi_break_packed); - /* We rely on aarch64_layout_arg and aarch64_gimplify_va_arg_expr - to emit warnings about ABI incompatibility. */ -+#if TARGET_MACHO -+ /* This can only work for unnamed args. */ -+ machine_mode comp_mode = VOIDmode; -+ int nregs; -+ bool is_ha; -+ aarch64_vfp_is_call_or_return_candidate (mode, type, &comp_mode, &nregs, -+ &is_ha, /*silent*/true); -+ if (TREE_CODE (type) == COMPLEX_TYPE -+ || (TREE_CODE (type) == RECORD_TYPE -+ && !is_ha && !SCALAR_FLOAT_MODE_P (comp_mode)) -+ || TREE_CODE (type) == UNION_TYPE) -+ return MIN (MAX (alignment, PARM_BOUNDARY), STACK_BOUNDARY); -+ return MIN (alignment, STACK_BOUNDARY); -+#else -+ alignment = MIN (MAX (alignment, PARM_BOUNDARY), STACK_BOUNDARY); -+ return alignment; -+#endif -+} -+ -+/* For Darwin, we want to use the arg boundary computed when laying out the -+ function arg, to cope with items packed on the stack and the different -+ rules applied to unnamed parms. */ -+ -+static unsigned int -+aarch64_function_arg_boundary_ca (machine_mode mode ATTRIBUTE_UNUSED, -+ const_tree type ATTRIBUTE_UNUSED, -+ cumulative_args_t ca ATTRIBUTE_UNUSED) -+{ -+ unsigned int abi_break; -+ unsigned int abi_break_packed; -+ unsigned int alignment = aarch64_function_arg_alignment (mode, type, -+ &abi_break, -+ &abi_break_packed); -+ /* We rely on aarch64_layout_arg and aarch64_gimplify_va_arg_expr -+ to emit warnings about ABI incompatibility. */ -+#if TARGET_MACHO -+ CUMULATIVE_ARGS *pcum = get_cumulative_args (ca); -+gcc_checking_assert (pcum->aapcs_arg_processed); -+ -+ bool named_p = pcum->darwinpcs_n_args_processed < pcum->darwinpcs_n_named; -+gcc_checking_assert (named_p == pcum->named_p); -+ machine_mode comp_mode = VOIDmode; -+ int nregs; -+ bool is_ha; -+ aarch64_vfp_is_call_or_return_candidate (mode, type, &comp_mode, &nregs, -+ &is_ha, /*silent*/true); -+ bool no_pack = (TREE_CODE (type) == COMPLEX_TYPE -+ || (TREE_CODE (type) == RECORD_TYPE -+ && !is_ha && !SCALAR_FLOAT_MODE_P (comp_mode)) -+ || TREE_CODE (type) == UNION_TYPE); -+ -+ bool in_regs = (pcum->aapcs_reg != NULL_RTX); -+ -+ if ((named_p && !no_pack) || in_regs) -+ ; /* Leave the alignment as natural. */ -+ else -+ alignment = MAX (alignment, PARM_BOUNDARY); -+gcc_checking_assert (alignment == pcum->darwinpcs_arg_boundary); -+ return MIN (alignment, STACK_BOUNDARY); -+ -+#else - alignment = MIN (MAX (alignment, PARM_BOUNDARY), STACK_BOUNDARY); - return alignment; -+#endif -+} -+ -+/* Implement TARGET_FUNCTION_ARG_ROUND_BOUNDARY_CA for darwinpcs which allows -+ non-standard passing of byte-aligned items [D.2]. This is done by pulling -+ the values out of the cumulative args struct. */ -+ -+static unsigned int -+aarch64_function_arg_round_boundary_ca (machine_mode mode ATTRIBUTE_UNUSED, -+ const_tree type ATTRIBUTE_UNUSED, -+ cumulative_args_t ca) -+{ -+ CUMULATIVE_ARGS *pcum = get_cumulative_args (ca); -+gcc_checking_assert (pcum->aapcs_arg_processed); -+ bool named_p = pcum->darwinpcs_n_args_processed < pcum->darwinpcs_n_named; -+gcc_checking_assert (named_p == pcum->named_p); -+ bool last_named_p = pcum->darwinpcs_n_args_processed + 1 == pcum->darwinpcs_n_named; -+gcc_checking_assert (last_named_p == pcum->last_named_p); -+ -+ unsigned boundary = BITS_PER_UNIT; -+ if (last_named_p && pcum->darwinpcs_sub_word_pos > 0) -+ { -+ /* Round the last named arg to the start of the next stack slot. */ -+ if (pcum->darwinpcs_sub_word_pos <= 4) -+ boundary = PARM_BOUNDARY; -+ else if (pcum->darwinpcs_sub_word_pos <= 6) -+ boundary = 4 * BITS_PER_UNIT; -+ else if (pcum->darwinpcs_sub_word_pos <= 7) -+ boundary = 2 * BITS_PER_UNIT; -+ } -+ else if (named_p) -+ /* Named args are naturally aligned, but with no rounding. */ -+ ; -+ else -+ /* un-named args are rounded to fill slots. */ -+ boundary = PARM_BOUNDARY; -+gcc_checking_assert (boundary == pcum->darwinpcs_arg_padding); -+ return boundary; - } - - /* Implement TARGET_GET_RAW_RESULT_MODE and TARGET_GET_RAW_ARG_MODE. */ -@@ -11091,6 +11367,7 @@ aarch64_classify_address (struct aarch64_address_info *info, - /* load literal: pc-relative constant pool entry. Only supported - for SI mode or larger. */ - info->type = ADDRESS_SYMBOLIC; -+ info->offset = NULL_RTX; - - if (!load_store_pair_p - && GET_MODE_SIZE (mode).is_constant (&const_size) -@@ -11098,6 +11375,7 @@ aarch64_classify_address (struct aarch64_address_info *info, - { - poly_int64 offset; - rtx sym = strip_offset_and_salt (x, &offset); -+ - return ((LABEL_REF_P (sym) - || (SYMBOL_REF_P (sym) - && CONSTANT_POOL_ADDRESS_P (sym) -@@ -11115,10 +11393,13 @@ aarch64_classify_address (struct aarch64_address_info *info, - poly_int64 offset; - HOST_WIDE_INT const_offset; - rtx sym = strip_offset_and_salt (info->offset, &offset); -+ - if (SYMBOL_REF_P (sym) - && offset.is_constant (&const_offset) - && (aarch64_classify_symbol (sym, const_offset) -- == SYMBOL_SMALL_ABSOLUTE)) -+ == SYMBOL_SMALL_ABSOLUTE -+ || aarch64_classify_symbol (sym, const_offset) -+ == SYMBOL_MO_SMALL_PCR)) - { - /* The symbol and offset must be aligned to the access size. */ - unsigned int align; -@@ -11168,6 +11449,55 @@ aarch64_address_valid_for_prefetch_p (rtx x, bool strict_p) - if (!res) - return false; - -+ /* For ELF targets using GAS, we emit prfm unconditionally; GAS will alter -+ the instruction to pick the prfum form where possible (i.e. when the -+ offset is in the range -256..255) and fall back to prfm otherwise. -+ We can reject cases where the offset exceeds the range usable by both -+ insns [-256..32760], or for offsets > 255 when the value is not divisible -+ by 8. -+ For Mach-O (Darwin) where the assembler uses the LLVM back end, that does -+ not yet do the substitution, so we must reject all prfum cases. */ -+ if (addr.offset) -+ { -+ HOST_WIDE_INT offs = INTVAL (addr.offset); -+ if (offs < -256) /* Out of range for both prfum and prfm. */ -+ return false; -+ if (offs > 32760) /* Out of range for prfm. */ -+ return false; -+ if (offs & 0x07) /* We cannot use prfm. */ -+ { -+ if (offs > 255) /* Out of range for prfum. */ -+ return false; -+ if (TARGET_MACHO) -+ return false; -+ } -+ if (TARGET_MACHO && offs < 0) -+ return false; -+ } -+ -+ /* ... except writeback forms. */ -+ return addr.type != ADDRESS_REG_WB; -+} -+ -+/* Return true if the address X is valid for a PRFUM instruction. -+ STRICT_P is true if we should do strict checking with -+ aarch64_classify_address. */ -+ -+bool -+aarch64_address_valid_for_unscaled_prefetch_p (rtx x, bool strict_p) -+{ -+ struct aarch64_address_info addr; -+ -+ /* PRFUM accepts the same addresses as DImode, but constrained to a range -+ -256..255. */ -+ bool res = aarch64_classify_address (&addr, x, DImode, strict_p); -+ if (!res) -+ return false; -+ -+ if (addr.offset && ((INTVAL (addr.offset) > 255) -+ || (INTVAL (addr.offset) < -256))) -+ return false; -+ - /* ... except writeback forms. */ - return addr.type != ADDRESS_REG_WB; - } -@@ -11881,6 +12211,144 @@ sizetochar (int size) - } - } - -+static void -+output_macho_postfix_expr (FILE *file, rtx x, const char *postfix) -+{ -+ char buf[256]; -+ -+ restart: -+ switch (GET_CODE (x)) -+ { -+ case PC: -+ putc ('.', file); -+ break; -+ -+ case SYMBOL_REF: -+ if (SYMBOL_REF_DECL (x)) -+ assemble_external (SYMBOL_REF_DECL (x)); -+ assemble_name (file, XSTR (x, 0)); -+ fprintf (file, "@%s", postfix); -+ break; -+ -+ case LABEL_REF: -+ x = label_ref_label (x); -+ /* Fall through. */ -+ case CODE_LABEL: -+ ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (x)); -+ assemble_name (file, buf); -+ fprintf (file, "@%s", postfix); -+ break; -+ -+ case CONST_INT: -+ fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x)); -+ break; -+ -+ case CONST: -+ /* This used to output parentheses around the expression, -+ but that does not work on the 386 (either ATT or BSD assembler). */ -+ output_macho_postfix_expr (file, XEXP (x, 0), postfix); -+ break; -+ -+ case CONST_WIDE_INT: -+ /* We do not know the mode here so we have to use a round about -+ way to build a wide-int to get it printed properly. */ -+ { -+ wide_int w = wide_int::from_array (&CONST_WIDE_INT_ELT (x, 0), -+ CONST_WIDE_INT_NUNITS (x), -+ CONST_WIDE_INT_NUNITS (x) -+ * HOST_BITS_PER_WIDE_INT, -+ false); -+ print_decs (w, file); -+ } -+ break; -+ -+ case CONST_DOUBLE: -+ if (CONST_DOUBLE_AS_INT_P (x)) -+ { -+ /* We can use %d if the number is one word and positive. */ -+ if (CONST_DOUBLE_HIGH (x)) -+ fprintf (file, HOST_WIDE_INT_PRINT_DOUBLE_HEX, -+ (unsigned HOST_WIDE_INT) CONST_DOUBLE_HIGH (x), -+ (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (x)); -+ else if (CONST_DOUBLE_LOW (x) < 0) -+ fprintf (file, HOST_WIDE_INT_PRINT_HEX, -+ (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (x)); -+ else -+ fprintf (file, HOST_WIDE_INT_PRINT_DEC, CONST_DOUBLE_LOW (x)); -+ } -+ else -+ /* We can't handle floating point constants; -+ PRINT_OPERAND must handle them. */ -+ output_operand_lossage ("floating constant misused"); -+ break; -+ -+ case CONST_FIXED: -+ fprintf (file, HOST_WIDE_INT_PRINT_DEC, CONST_FIXED_VALUE_LOW (x)); -+ break; -+ -+ case PLUS: -+ /* Some assemblers need integer constants to appear last (eg masm). */ -+ if (CONST_INT_P (XEXP (x, 0))) -+ { -+ output_macho_postfix_expr (file, XEXP (x, 1), postfix); -+ if (INTVAL (XEXP (x, 0)) >= 0) -+ fprintf (file, "+"); -+ output_addr_const (file, XEXP (x, 0)); -+ } -+ else -+ { -+ output_macho_postfix_expr (file, XEXP (x, 0), postfix); -+ if (!CONST_INT_P (XEXP (x, 1)) -+ || INTVAL (XEXP (x, 1)) >= 0) -+ fprintf (file, "+"); -+ output_addr_const (file, XEXP (x, 1)); -+ } -+ break; -+ -+ case MINUS: -+ /* Avoid outputting things like x-x or x+5-x, -+ since some assemblers can't handle that. */ -+ x = simplify_subtraction (x); -+ if (GET_CODE (x) != MINUS) -+ goto restart; -+ -+ output_macho_postfix_expr (file, XEXP (x, 0), postfix); -+ fprintf (file, "-"); -+ if ((CONST_INT_P (XEXP (x, 1)) && INTVAL (XEXP (x, 1)) >= 0) -+ || GET_CODE (XEXP (x, 1)) == PC -+ || GET_CODE (XEXP (x, 1)) == SYMBOL_REF) -+ output_addr_const (file, XEXP (x, 1)); -+ else -+ { -+ fputs (targetm.asm_out.open_paren, file); -+ output_addr_const (file, XEXP (x, 1)); -+ fputs (targetm.asm_out.close_paren, file); -+ } -+ break; -+ -+ case ZERO_EXTEND: -+ case SIGN_EXTEND: -+ case SUBREG: -+ case TRUNCATE: -+ output_addr_const (file, XEXP (x, 0)); -+ break; -+ -+ case UNSPEC: -+ if (XINT (x, 1) == UNSPEC_SALT_ADDR) -+ { -+ output_macho_postfix_expr (file, XVECEXP (x, 0, 0), postfix); -+ break; -+ } -+ /* FALLTHROUGH */ -+ default: -+ if (targetm.asm_out.output_addr_const_extra (file, x)) -+ break; -+ -+ output_operand_lossage ("invalid expression as operand"); -+ } -+ -+} -+ - /* Print operand X to file F in a target specific manner according to CODE. - The acceptable formatting commands given by CODE are: - 'c': An integer or symbol address without a preceding # -@@ -11949,6 +12417,12 @@ aarch64_print_operand (FILE *f, rtx x, int code) - } - break; - -+ case 'J': -+ output_macho_postfix_expr (f, x, "PAGEOFF"); -+ break; -+ case 'O': -+ output_macho_postfix_expr (f, x, "GOTPAGEOFF"); -+ break; - case 'e': - { - x = unwrap_const_vec_duplicate (x); -@@ -12272,7 +12746,7 @@ aarch64_print_operand (FILE *f, rtx x, int code) - case 'A': - if (GET_CODE (x) == HIGH) - x = XEXP (x, 0); -- -+#if !TARGET_MACHO - switch (aarch64_classify_symbolic_expression (x)) - { - case SYMBOL_SMALL_GOT_4G: -@@ -12303,9 +12777,26 @@ aarch64_print_operand (FILE *f, rtx x, int code) - break; - } - output_addr_const (asm_out_file, x); -+#endif -+#if TARGET_MACHO -+ switch (aarch64_classify_symbolic_expression (x)) -+ { -+ case SYMBOL_MO_SMALL_PCR: -+ output_macho_postfix_expr (asm_out_file, x, "PAGE"); -+ break; -+ case SYMBOL_MO_SMALL_GOT: -+ output_macho_postfix_expr (asm_out_file, x, "GOTPAGE"); -+ break; -+ default: -+ /* large code model unimplemented. */ -+ gcc_unreachable (); -+ break; -+ } -+#endif - break; - - case 'L': -+#if !TARGET_MACHO - switch (aarch64_classify_symbolic_expression (x)) - { - case SYMBOL_SMALL_GOT_4G: -@@ -12343,10 +12834,12 @@ aarch64_print_operand (FILE *f, rtx x, int code) - default: - break; - } -+#endif - output_addr_const (asm_out_file, x); - break; - - case 'G': -+#if !TARGET_MACHO - switch (aarch64_classify_symbolic_expression (x)) - { - case SYMBOL_TLSLE24: -@@ -12355,6 +12848,7 @@ aarch64_print_operand (FILE *f, rtx x, int code) - default: - break; - } -+#endif - output_addr_const (asm_out_file, x); - break; - -@@ -12504,8 +12998,13 @@ aarch64_print_address_internal (FILE *f, machine_mode mode, rtx x, - break; - - case ADDRESS_LO_SUM: -+#if TARGET_MACHO -+ asm_fprintf (f, "[%s, #", reg_names [REGNO (addr.base)]); -+ output_macho_postfix_expr (f, addr.offset, "PAGEOFF"); -+#else - asm_fprintf (f, "[%s, #:lo12:", reg_names [REGNO (addr.base)]); - output_addr_const (f, addr.offset); -+#endif - asm_fprintf (f, "]"); - return true; - -@@ -12786,6 +13285,26 @@ aarch64_secondary_memory_needed (machine_mode mode, reg_class_t class1, - return false; - } - -+#if TARGET_MACHO -+/* Implement TARGET_FRAME_POINTER_REQUIRED. */ -+ -+static bool -+aarch64_darwin_frame_pointer_required () -+{ -+ if (crtl->calls_eh_return) -+ return true; -+ -+ /* Not used in leaf functions (unless forced). */ -+ if (flag_omit_leaf_frame_pointer && leaf_function_p ()) -+ return false; -+ -+ /* NOTE: We are allowing the user to force omission of the frame -+ pointer, (despite that it is not ABI-compliant). */ -+ -+ return flag_omit_frame_pointer != 1; -+} -+#endif -+ - static bool - aarch64_can_eliminate (const int from ATTRIBUTE_UNUSED, const int to) - { -@@ -13003,6 +13522,8 @@ aarch64_asm_output_labelref (FILE* f, const char *name) - asm_fprintf (f, "%U%s", name); - } - -+#if !TARGET_MACHO -+ - static void - aarch64_elf_asm_constructor (rtx symbol, int priority) - { -@@ -13042,6 +13563,7 @@ aarch64_elf_asm_destructor (rtx symbol, int priority) - assemble_aligned_integer (POINTER_BYTES, symbol); - } - } -+#endif - - const char* - aarch64_output_casesi (rtx *operands) -@@ -13145,7 +13667,11 @@ aarch64_select_rtx_section (machine_mode mode, - if (aarch64_can_use_per_function_literal_pools_p ()) - return function_section (current_function_decl); - -+#if TARGET_MACHO -+ return machopic_select_rtx_section (mode, x, align); -+#else - return default_elf_select_rtx_section (mode, x, align); -+#endif - } - - /* Implement ASM_OUTPUT_POOL_EPILOGUE. */ -@@ -15369,15 +15895,17 @@ aarch64_init_builtins () - { - aarch64_general_init_builtins (); - aarch64_sve::init_builtins (); --#ifdef SUBTARGET_INIT_BUILTINS -- SUBTARGET_INIT_BUILTINS; --#endif -+ aarch64_init_subtarget_builtins (); - } - - /* Implement TARGET_FOLD_BUILTIN. */ - static tree - aarch64_fold_builtin (tree fndecl, int nargs, tree *args, bool) - { -+#ifdef SUBTARGET_FOLD_BUILTIN -+ if (tree res = SUBTARGET_FOLD_BUILTIN (fndecl, nargs, args, false)) -+ return res; -+#endif - unsigned int code = DECL_MD_FUNCTION_CODE (fndecl); - unsigned int subcode = code >> AARCH64_BUILTIN_SHIFT; - tree type = TREE_TYPE (TREE_TYPE (fndecl)); -@@ -18561,10 +19089,14 @@ initialize_aarch64_code_model (struct gcc_options *opts) - } - break; - case AARCH64_CMODEL_LARGE: -- if (opts->x_flag_pic) -+ if (TARGET_MACHO) -+ /* We need to implement fPIC here (arm64_32 also accepts the large -+ model). */ -+ sorry ("code model %qs not supported yet", "large"); -+ else if (opts->x_flag_pic) - sorry ("code model %qs with %<-f%s%>", "large", - opts->x_flag_pic > 1 ? "PIC" : "pic"); -- if (opts->x_aarch64_abi == AARCH64_ABI_ILP32) -+ else if (opts->x_aarch64_abi == AARCH64_ABI_ILP32) - sorry ("code model %qs not supported in ilp32 mode", "large"); - break; - case AARCH64_CMODEL_TINY_PIC: -@@ -19450,7 +19982,9 @@ aarch64_classify_symbol (rtx x, HOST_WIDE_INT offset) - case AARCH64_CMODEL_SMALL_SPIC: - case AARCH64_CMODEL_SMALL_PIC: - case AARCH64_CMODEL_SMALL: -- return SYMBOL_SMALL_ABSOLUTE; -+ return TARGET_MACHO -+ ? SYMBOL_MO_SMALL_PCR -+ : SYMBOL_SMALL_ABSOLUTE; - - default: - gcc_unreachable (); -@@ -19486,10 +20020,22 @@ aarch64_classify_symbol (rtx x, HOST_WIDE_INT offset) - - return SYMBOL_TINY_ABSOLUTE; - -- - case AARCH64_CMODEL_SMALL_SPIC: - case AARCH64_CMODEL_SMALL_PIC: - case AARCH64_CMODEL_SMALL: -+#if TARGET_MACHO -+ if (TARGET_MACHO) -+ { -+ /* Constant pool addresses are always TU-local and PC- -+ relative. We indirect common, external and weak -+ symbols (but weak only if not hidden). */ -+ if (!CONSTANT_POOL_ADDRESS_P (x) -+ && (MACHO_SYMBOL_MUST_INDIRECT_P (x) -+ || !aarch64_symbol_binds_local_p (x))) -+ return SYMBOL_MO_SMALL_GOT; -+ } -+ else -+#endif - if ((flag_pic || SYMBOL_REF_WEAK (x)) - && !aarch64_symbol_binds_local_p (x)) - return aarch64_cmodel == AARCH64_CMODEL_SMALL_SPIC -@@ -19501,7 +20047,8 @@ aarch64_classify_symbol (rtx x, HOST_WIDE_INT offset) - || offset_within_block_p (x, offset))) - return SYMBOL_FORCE_TO_MEM; - -- return SYMBOL_SMALL_ABSOLUTE; -+ return TARGET_MACHO ? SYMBOL_MO_SMALL_PCR -+ : SYMBOL_SMALL_ABSOLUTE; - - case AARCH64_CMODEL_LARGE: - /* This is alright even in PIC code as the constant -@@ -19631,7 +20178,10 @@ static GTY(()) tree va_list_type; - void *__vr_top; - int __gr_offs; - int __vr_offs; -- }; */ -+ }; -+ -+ darwinpcs uses 'char *' for the va_list (in common with other platform -+ ports). */ - - static tree - aarch64_build_builtin_va_list (void) -@@ -19639,6 +20189,13 @@ aarch64_build_builtin_va_list (void) - tree va_list_name; - tree f_stack, f_grtop, f_vrtop, f_groff, f_vroff; - -+ /* darwinpcs uses a simple char * for this. */ -+ if (TARGET_MACHO) -+ { -+ va_list_type = build_pointer_type (char_type_node); -+ return va_list_type; -+ } -+ - /* Create the type. */ - va_list_type = lang_hooks.types.make_type (RECORD_TYPE); - /* Give it the required name. */ -@@ -19710,6 +20267,13 @@ aarch64_expand_builtin_va_start (tree valist, rtx nextarg ATTRIBUTE_UNUSED) - int vr_save_area_size = cfun->va_list_fpr_size; - int vr_offset; - -+ /* darwinpcs uses the default, char * va_list impl. */ -+ if (TARGET_MACHO) -+ { -+ std_expand_builtin_va_start (valist, nextarg); -+ return; -+ } -+ - cum = &crtl->args.info; - if (cfun->va_list_gpr_size) - gr_save_area_size = MIN ((NUM_ARG_REGS - cum->aapcs_ncrn) * UNITS_PER_WORD, -@@ -19800,6 +20364,9 @@ aarch64_gimplify_va_arg_expr (tree valist, tree type, gimple_seq *pre_p, - HOST_WIDE_INT size, rsize, adjust, align; - tree t, u, cond1, cond2; - -+ if (TARGET_MACHO) -+ return std_gimplify_va_arg_expr (valist, type, pre_p, post_p); -+ - indirect_p = pass_va_arg_by_reference (type); - if (indirect_p) - type = build_pointer_type (type); -@@ -19990,8 +20557,18 @@ aarch64_gimplify_va_arg_expr (tree valist, tree type, gimple_seq *pre_p, - field_ptr_t = double_ptr_type_node; - break; - case E_TFmode: -- field_t = long_double_type_node; -- field_ptr_t = long_double_ptr_type_node; -+ if (TARGET_MACHO) -+ { -+ /* Darwin has __float128, and long double is the same as -+ double. */ -+ field_t = float128_type_node; -+ field_ptr_t = aarch64_float128_ptr_type_node; -+ } -+ else -+ { -+ field_t = long_double_type_node; -+ field_ptr_t = long_double_ptr_type_node; -+ } - break; - case E_SDmode: - field_t = dfloat32_type_node; -@@ -20074,6 +20651,9 @@ aarch64_setup_incoming_varargs (cumulative_args_t cum_v, - int gr_saved = cfun->va_list_gpr_size; - int vr_saved = cfun->va_list_fpr_size; - -+ if (TARGET_MACHO) -+ return default_setup_incoming_varargs (cum_v, arg, pretend_size, no_rtl); -+ - /* The caller has advanced CUM up to, but not beyond, the last named - argument. Advance a local copy of CUM past the last "real" named - argument, to find out how many registers are left over. */ -@@ -20906,6 +21486,12 @@ aarch64_autovectorize_vector_modes (vector_modes *modes, bool) - static const char * - aarch64_mangle_type (const_tree type) - { -+ /* The darwinpcs ABI documents say that "__va_list" has to be -+ mangled as char *. */ -+ if (TARGET_MACHO -+ && lang_hooks.types_compatible_p (CONST_CAST_TREE (type), va_list_type)) -+ return "Pc"; -+ - /* The AArch64 ABI documents say that "__va_list" has to be - mangled as if it is in the "std" namespace. */ - if (lang_hooks.types_compatible_p (CONST_CAST_TREE (type), va_list_type)) -@@ -20922,6 +21508,12 @@ aarch64_mangle_type (const_tree type) - return "Dh"; - } - -+ /* __float128 is mangled as "g" on darwin. _Float128 is not mangled here, -+ but handled in common code (as "DF128_"). */ -+ if (TARGET_MACHO && TYPE_MODE (type) == TFmode -+ && TYPE_MAIN_VARIANT (type) == float128t_type_node) -+ return "g"; -+ - /* Mangle AArch64-specific internal types. TYPE_NAME is non-NULL_TREE for - builtin types. */ - if (TYPE_NAME (type) != NULL) -@@ -21615,7 +22207,8 @@ aarch64_mov_operand_p (rtx x, machine_mode mode) - - /* GOT accesses are valid moves. */ - if (SYMBOL_REF_P (x) -- && aarch64_classify_symbolic_expression (x) == SYMBOL_SMALL_GOT_4G) -+ && (aarch64_classify_symbolic_expression (x) == SYMBOL_SMALL_GOT_4G -+ || aarch64_classify_symbolic_expression (x) == SYMBOL_MO_SMALL_GOT)) - return true; - - if (SYMBOL_REF_P (x) && mode == DImode && CONSTANT_ADDRESS_P (x)) -@@ -22759,12 +23352,8 @@ aarch64_asm_output_variant_pcs (FILE *stream, const tree decl, const char* name) - static std::string aarch64_last_printed_arch_string; - static std::string aarch64_last_printed_tune_string; - --/* Implement ASM_DECLARE_FUNCTION_NAME. Output the ISA features used -- by the function fndecl. */ -- --void --aarch64_declare_function_name (FILE *stream, const char* name, -- tree fndecl) -+static void -+aarch64_function_options_preamble (tree fndecl) - { - tree target_parts = DECL_FUNCTION_SPECIFIC_TARGET (fndecl); - -@@ -22803,15 +23392,60 @@ aarch64_declare_function_name (FILE *stream, const char* name, - this_tune->name); - aarch64_last_printed_tune_string = this_tune->name; - } -+} -+ -+/* Implement ASM_DECLARE_FUNCTION_NAME. Output the ISA features used -+ by the function fndecl. */ - -+#if TARGET_MACHO -+void -+aarch64_darwin_declare_function_name (FILE *stream, const char* name, -+ tree fndecl) -+{ -+ gcc_checking_assert (TREE_CODE (fndecl) == FUNCTION_DECL); -+ gcc_checking_assert (!DECL_COMMON (fndecl)); -+ -+ /* Update .arch and .tune as needed. */ -+ aarch64_function_options_preamble (fndecl); -+ -+ /* Darwin does not emit pcs variant info. */ -+ -+ rtx decl_rtx = XEXP (DECL_RTL (fndecl), 0); -+ if (GET_CODE (decl_rtx) != SYMBOL_REF) -+ name = IDENTIFIER_POINTER (DECL_NAME (fndecl)); -+ -+ if (! DECL_WEAK (fndecl) -+ && ((TREE_STATIC (fndecl) && !TREE_PUBLIC (fndecl)) -+ || DECL_INITIAL (fndecl))) -+ machopic_define_symbol (DECL_RTL (fndecl)); -+ if ((TREE_STATIC (fndecl) && !TREE_PUBLIC (fndecl)) -+ || DECL_INITIAL (fndecl)) -+ (* targetm.encode_section_info) (fndecl, DECL_RTL (fndecl), false); -+ ASM_OUTPUT_FUNCTION_LABEL (stream, name, fndecl); -+ -+ cfun->machine->label_is_assembled = true; -+} -+ -+#else -+ -+void -+aarch64_declare_function_name (FILE *stream, const char* name, -+ tree fndecl) -+{ -+ /* Update .arch and .tune as needed. */ -+ aarch64_function_options_preamble (fndecl); -+ /* Emit any necessary pcs information. */ - aarch64_asm_output_variant_pcs (stream, fndecl, name); - - /* Don't forget the type directive for ELF. */ -+#ifdef ASM_OUTPUT_TYPE_DIRECTIVE - ASM_OUTPUT_TYPE_DIRECTIVE (stream, name, "function"); -- ASM_OUTPUT_LABEL (stream, name); -+#endif -+ ASM_OUTPUT_FUNCTION_LABEL (stream, name, fndecl); - - cfun->machine->label_is_assembled = true; - } -+#endif - - /* Implement PRINT_PATCHABLE_FUNCTION_ENTRY. */ - -@@ -22868,12 +23502,17 @@ aarch64_output_patchable_area (unsigned int patch_area_size, bool record_p) - /* Implement ASM_OUTPUT_DEF_FROM_DECLS. Output .variant_pcs for aliases. */ - - void --aarch64_asm_output_alias (FILE *stream, const tree decl, const tree target) -+aarch64_asm_output_alias (FILE *stream, const tree decl, -+ const tree target ATTRIBUTE_UNUSED) - { - const char *name = XSTR (XEXP (DECL_RTL (decl), 0), 0); -+#ifdef ASM_OUTPUT_DEF - const char *value = IDENTIFIER_POINTER (target); -+#endif - aarch64_asm_output_variant_pcs (stream, decl, name); -+#ifdef ASM_OUTPUT_DEF - ASM_OUTPUT_DEF (stream, name, value); -+#endif - } - - /* Implement ASM_OUTPUT_EXTERNAL. Output .variant_pcs for undefined -@@ -22919,6 +23558,9 @@ aarch64_start_file (void) - aarch64_last_printed_arch_string.c_str ()); - - default_file_start (); -+#if TARGET_MACHO -+ darwin_file_start (); -+#endif - } - - /* Emit load exclusive. */ -@@ -23396,6 +24038,10 @@ aarch64_float_const_representable_p (rtx x) - || REAL_VALUE_MINUS_ZERO (r)) - return false; - -+ /* For BFmode, only handle 0.0. */ -+ if (GET_MODE (x) == BFmode) -+ return real_iszero (&r, false); -+ - /* Extract exponent. */ - r = real_value_abs (&r); - exponent = REAL_EXP (&r); -@@ -23499,6 +24145,16 @@ aarch64_output_simd_mov_immediate (rtx const_vector, unsigned width, - } - - gcc_assert (CONST_INT_P (info.u.mov.value)); -+ unsigned HOST_WIDE_INT value = UINTVAL (info.u.mov.value); -+ -+ /* We have signed chars which can result in a sign-extended 8bit value -+ which is then emitted as an unsigned hex value, and the LLVM back end -+ assembler rejects that as being too big. */ -+ if (TARGET_MACHO && (known_eq (GET_MODE_BITSIZE (info.elt_mode), 8))) -+ { -+ unsigned HOST_WIDE_INT mask = (1U << GET_MODE_BITSIZE (info.elt_mode))-1; -+ value &= mask; -+ } - - if (which == AARCH64_CHECK_MOV) - { -@@ -23507,16 +24163,16 @@ aarch64_output_simd_mov_immediate (rtx const_vector, unsigned width, - ? "msl" : "lsl"); - if (lane_count == 1) - snprintf (templ, sizeof (templ), "%s\t%%d0, " HOST_WIDE_INT_PRINT_HEX, -- mnemonic, UINTVAL (info.u.mov.value)); -+ mnemonic, value); - else if (info.u.mov.shift) - snprintf (templ, sizeof (templ), "%s\t%%0.%d%c, " - HOST_WIDE_INT_PRINT_HEX ", %s %d", mnemonic, lane_count, -- element_char, UINTVAL (info.u.mov.value), shift_op, -+ element_char, value, shift_op, - info.u.mov.shift); - else - snprintf (templ, sizeof (templ), "%s\t%%0.%d%c, " - HOST_WIDE_INT_PRINT_HEX, mnemonic, lane_count, -- element_char, UINTVAL (info.u.mov.value)); -+ element_char, value); - } - else - { -@@ -23525,12 +24181,12 @@ aarch64_output_simd_mov_immediate (rtx const_vector, unsigned width, - if (info.u.mov.shift) - snprintf (templ, sizeof (templ), "%s\t%%0.%d%c, #" - HOST_WIDE_INT_PRINT_DEC ", %s #%d", mnemonic, lane_count, -- element_char, UINTVAL (info.u.mov.value), "lsl", -+ element_char, value, "lsl", - info.u.mov.shift); - else - snprintf (templ, sizeof (templ), "%s\t%%0.%d%c, #" - HOST_WIDE_INT_PRINT_DEC, mnemonic, lane_count, -- element_char, UINTVAL (info.u.mov.value)); -+ element_char, value); - } - return templ; - } -@@ -26728,7 +27384,8 @@ aarch64_libgcc_floating_mode_supported_p (scalar_float_mode mode) - } - - /* Implement TARGET_SCALAR_MODE_SUPPORTED_P - return TRUE -- if MODE is [BH]Fmode, and punt to the generic implementation otherwise. */ -+ if MODE is [BH]Fmode, or TFmode on Mach-O, and punt to the generic -+ implementation otherwise. */ - - static bool - aarch64_scalar_mode_supported_p (scalar_mode mode) -@@ -26736,7 +27393,7 @@ aarch64_scalar_mode_supported_p (scalar_mode mode) - if (DECIMAL_FLOAT_MODE_P (mode)) - return default_decimal_float_supported_p (); - -- return ((mode == HFmode || mode == BFmode) -+ return ((mode == HFmode || mode == BFmode || (mode == TFmode && TARGET_MACHO)) - ? true - : default_scalar_mode_supported_p (mode)); - } -@@ -27476,19 +28133,37 @@ aarch64_sls_emit_shared_blr_thunks (FILE *out_file) - continue; - - const char *name = indirect_symbol_names[regnum]; -- switch_to_section (get_named_section (decl, NULL, 0)); -+ /* If the target uses a unique section for this switch to it. */ -+ if (DECL_SECTION_NAME (decl)) -+ switch_to_section (get_named_section (decl, NULL, 0)); -+ else -+ switch_to_section (text_section); - ASM_OUTPUT_ALIGN (out_file, 2); -- targetm.asm_out.globalize_label (out_file, name); -+ if (!TARGET_MACHO) -+ targetm.asm_out.globalize_label (out_file, name); -+#ifdef ASM_OUTPUT_TYPE_DIRECTIVE -+ ASM_OUTPUT_TYPE_DIRECTIVE (out_file, name, "function"); -+#endif -+ if (TARGET_MACHO) -+ { -+#ifdef ASM_WEAKEN_DECL -+ if (DECL_WEAK (decl)) -+ ASM_WEAKEN_DECL (out_file, decl, name, 0); -+ else -+#endif -+ targetm.asm_out.globalize_decl_name (out_file, decl); -+ } - /* Only emits if the compiler is configured for an assembler that can - handle visibility directives. */ - targetm.asm_out.assemble_visibility (decl, VISIBILITY_HIDDEN); -- ASM_OUTPUT_TYPE_DIRECTIVE (out_file, name, "function"); - ASM_OUTPUT_LABEL (out_file, name); - aarch64_sls_emit_function_stub (out_file, regnum); - /* Use the most conservative target to ensure it can always be used by any - function in the translation unit. */ - asm_fprintf (out_file, "\tdsb\tsy\n\tisb\n"); -+#ifdef ASM_DECLARE_FUNCTION_SIZE - ASM_DECLARE_FUNCTION_SIZE (out_file, name, decl); -+#endif - } - } - -@@ -27519,6 +28194,60 @@ aarch64_indirect_call_asm (rtx addr) - return ""; - } - -+#if TARGET_MACHO -+/* This handles the promotion of function return values. -+ It also handles function args under two specific curcumstances: -+ - called from combine with a register argument -+ - caller for a libcall with type == NULL. -+ The remaining cases for argument promotion are handled with access to -+ cumulative args data, below. */ -+machine_mode -+aarch64_darwin_promote_fn_mode (const_tree type, machine_mode mode, -+ int *punsignedp, -+ const_tree funtype ATTRIBUTE_UNUSED, -+ int for_return ATTRIBUTE_UNUSED) -+{ -+ /* With the amended use of promote using cargs, the only cases that arrive -+ here with for_return == 0 are from combine (where the value is definitely -+ in a register) and for libcalls, where type == NULL. We want to promote -+ function return values in the callee, so this becomes pretty much -+ unconditional now. */ -+ if (type != NULL_TREE) -+ return promote_mode (type, mode, punsignedp); -+ return mode; -+} -+ -+/* Ensure that we only promote the mode of named parms when they are passed in -+ a register. Named values passed on the stack retain their original mode and -+ alignment. */ -+machine_mode -+aarch64_darwin_promote_function_mode_ca (cumulative_args_t ca, -+ function_arg_info arg, -+ const_tree funtype ATTRIBUTE_UNUSED, -+ int *punsignedp, -+ int for_return ATTRIBUTE_UNUSED) -+{ -+ tree type = arg.type; -+ machine_mode mode = arg.mode; -+ machine_mode new_mode = promote_mode (type, mode, punsignedp); -+ if (new_mode == mode || arg.named == false -+ || GET_MODE_CLASS (new_mode) != MODE_INT -+ || known_gt (GET_MODE_SIZE (new_mode), 4)) -+ return new_mode; -+ -+ CUMULATIVE_ARGS *pcum = get_cumulative_args (ca); -+ /* Make sure that changes in assumption do not get missed. */ -+ gcc_checking_assert (for_return == 0 && new_mode == SImode -+ && !pcum->aapcs_arg_processed); -+ /* We have a named integer value that fits in a reg; if there's one available -+ then promote the value. */ -+ if (pcum->aapcs_ncrn < 8) -+ return new_mode; -+ return mode; -+} -+ -+#endif -+ - /* Target-specific selftests. */ - - #if CHECKING_P -@@ -27681,6 +28410,15 @@ aarch64_run_selftests (void) - #undef TARGET_ASM_ALIGNED_SI_OP - #define TARGET_ASM_ALIGNED_SI_OP "\t.word\t" - -+#if TARGET_MACHO -+#undef TARGET_ASM_UNALIGNED_HI_OP -+#define TARGET_ASM_UNALIGNED_HI_OP "\t.short\t" -+#undef TARGET_ASM_UNALIGNED_SI_OP -+#define TARGET_ASM_UNALIGNED_SI_OP "\t.long\t" -+#undef TARGET_ASM_UNALIGNED_DI_OP -+#define TARGET_ASM_UNALIGNED_DI_OP "\t.quad\t" -+#endif -+ - #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK - #define TARGET_ASM_CAN_OUTPUT_MI_THUNK \ - hook_bool_const_tree_hwi_hwi_const_tree_true -@@ -27767,6 +28505,12 @@ aarch64_run_selftests (void) - #undef TARGET_FUNCTION_ARG_BOUNDARY - #define TARGET_FUNCTION_ARG_BOUNDARY aarch64_function_arg_boundary - -+#undef TARGET_FUNCTION_ARG_BOUNDARY_CA -+#define TARGET_FUNCTION_ARG_BOUNDARY_CA aarch64_function_arg_boundary_ca -+ -+#undef TARGET_FUNCTION_ARG_ROUND_BOUNDARY_CA -+#define TARGET_FUNCTION_ARG_ROUND_BOUNDARY_CA aarch64_function_arg_round_boundary_ca -+ - #undef TARGET_FUNCTION_ARG_PADDING - #define TARGET_FUNCTION_ARG_PADDING aarch64_function_arg_padding - -@@ -28091,7 +28835,7 @@ aarch64_libgcc_floating_mode_supported_p - - /* The architecture reserves bits 0 and 1 so use bit 2 for descriptors. */ - #undef TARGET_CUSTOM_FUNCTION_DESCRIPTORS --#define TARGET_CUSTOM_FUNCTION_DESCRIPTORS 4 -+#define TARGET_CUSTOM_FUNCTION_DESCRIPTORS AARCH64_CUSTOM_FUNCTION_TEST - - #undef TARGET_HARD_REGNO_NREGS - #define TARGET_HARD_REGNO_NREGS aarch64_hard_regno_nregs -@@ -28181,6 +28925,11 @@ aarch64_libgcc_floating_mode_supported_p - #undef TARGET_CONST_ANCHOR - #define TARGET_CONST_ANCHOR 0x1000000 - -+#if TARGET_MACHO -+#undef TARGET_FRAME_POINTER_REQUIRED -+#define TARGET_FRAME_POINTER_REQUIRED aarch64_darwin_frame_pointer_required -+#endif -+ - struct gcc_target targetm = TARGET_INITIALIZER; - - #include "gt-aarch64.h" -diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h -index cfeaf46..81d5658 100644 ---- a/gcc/config/aarch64/aarch64.h -+++ b/gcc/config/aarch64/aarch64.h -@@ -65,6 +65,10 @@ - #define TARGET_SIMD (AARCH64_ISA_SIMD) - #define TARGET_FLOAT (AARCH64_ISA_FP) - -+/* If this is non-zero then generated code of the object format, ABI and -+ assembler syntax used by Darwin (Mach-O) platforms. */ -+#define TARGET_MACHO 0 -+ - #define UNITS_PER_WORD 8 - - #define UNITS_PER_VREG 16 -@@ -142,6 +146,12 @@ - /* Heap alignment (same as BIGGEST_ALIGNMENT and STACK_BOUNDARY). */ - #define MALLOC_ABI_ALIGNMENT 128 - -+/* We will and with this value to test if a custom function descriptor needs -+ a static chain. The function boundary must the adjusted so that the bit -+ this represents is no longer part of the address. 0 Disables the custom -+ function descriptors. */ -+#define AARCH64_CUSTOM_FUNCTION_TEST 4 -+ - /* Defined by the ABI */ - #define WCHAR_TYPE "unsigned int" - #define WCHAR_TYPE_SIZE 32 -@@ -944,6 +954,24 @@ typedef struct - aapcs_reg == NULL_RTX. */ - int aapcs_stack_size; /* The total size (in words, per 8 byte) of the - stack arg area so far. */ -+ -+ /* In the darwinpcs, items smaller than one word are packed onto the stack -+ naturally aligned. Unnamed parameters passed in a variadic call are, -+ however, aligned the same way as the AAPCS64. This means that we need to -+ pad the last named arg to the next parm boundary (and hence notice when -+ we are processing that arg). */ -+ int darwinpcs_stack_bytes; /* If the argument is passed on the stack, this -+ the byte-size. */ -+ int darwinpcs_sub_word_offset;/* This is the offset of this arg within a word -+ when placing smaller items for darwinpcs. */ -+ int darwinpcs_sub_word_pos; /* The next byte available within the word for -+ darwinpcs. */ -+ unsigned darwinpcs_arg_boundary; /* The computed argument boundary. */ -+ unsigned darwinpcs_arg_padding; /* The computed argument padding. */ -+ unsigned darwinpcs_n_named; /* Number of named arguments. */ -+ unsigned darwinpcs_n_args_processed; /* Processed so far. */ -+ bool named_p; /* Is this arg named? */ -+ bool last_named_p; /* Is this the last named arg? */ - bool silent_p; /* True if we should act silently, rather than - raise an error for invalid calls. */ - } CUMULATIVE_ARGS; -@@ -1242,8 +1270,13 @@ extern const char *aarch64_rewrite_mcpu (int argc, const char **argv); - #define ASM_CPU_SPEC \ - MCPU_TO_MARCH_SPEC - -+#ifndef SUBTARGET_EXTRA_SPECS -+#define SUBTARGET_EXTRA_SPECS -+#endif -+ - #define EXTRA_SPECS \ -- { "asm_cpu_spec", ASM_CPU_SPEC } -+ { "asm_cpu_spec", ASM_CPU_SPEC }, \ -+ SUBTARGET_EXTRA_SPECS - - #define ASM_OUTPUT_POOL_EPILOGUE aarch64_asm_output_pool_epilogue - -@@ -1256,6 +1289,10 @@ extern GTY(()) tree aarch64_fp16_ptr_type_node; - bfloat16_type_node. Defined in aarch64-builtins.cc. */ - extern GTY(()) tree aarch64_bf16_ptr_type_node; - -+/* A pointer to the user-visible __float128 (on Mach-O). Defined in -+ aarch64-builtins.c. */ -+extern GTY(()) tree aarch64_float128_ptr_type_node; -+ - /* The generic unwind code in libgcc does not initialize the frame pointer. - So in order to unwind a function using a frame pointer, the very first - function that is unwound must save the frame pointer. That way the frame -diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md -index 922cc98..5c7c815 100644 ---- a/gcc/config/aarch64/aarch64.md -+++ b/gcc/config/aarch64/aarch64.md -@@ -304,6 +304,7 @@ - UNSPEC_LD1RO - UNSPEC_SALT_ADDR - UNSPECV_PATCHABLE_AREA -+ UNSPEC_MACHOPIC_OFFSET ; Common to Mach-O ports. - ]) - - (define_c_enum "unspecv" [ -@@ -850,6 +851,37 @@ - [(set_attr "type" "load_4")] - ) - -+(define_insn "prefetch_unscaled" -+ [(prefetch (match_operand:DI 0 "aarch64_unscaled_prefetch_operand" "Du") -+ (match_operand:QI 1 "const_int_operand" "") -+ (match_operand:QI 2 "const_int_operand" ""))] -+ "" -+ { -+ const char * pftype[2][4] = -+ { -+ {"prfum\\tPLDL1STRM, %0", -+ "prfum\\tPLDL3KEEP, %0", -+ "prfum\\tPLDL2KEEP, %0", -+ "prfum\\tPLDL1KEEP, %0"}, -+ {"prfum\\tPSTL1STRM, %0", -+ "prfum\\tPSTL3KEEP, %0", -+ "prfum\\tPSTL2KEEP, %0", -+ "prfum\\tPSTL1KEEP, %0"}, -+ }; -+ -+ int locality = INTVAL (operands[2]); -+ -+ gcc_assert (IN_RANGE (locality, 0, 3)); -+ -+ /* PRFUM accepts the same addresses as a 64-bit LDR so wrap -+ the address into a DImode MEM so that aarch64_print_operand knows -+ how to print it. */ -+ operands[0] = gen_rtx_MEM (DImode, operands[0]); -+ return pftype[INTVAL(operands[1])][locality]; -+ } -+ [(set_attr "type" "load_4")] -+) -+ - (define_insn "trap" - [(trap_if (const_int 1) (const_int 8))] - "" -@@ -1322,7 +1354,7 @@ - ldr\\t%s0, %1 - str\\t%w1, %0 - str\\t%s1, %0 -- adrp\\t%x0, %A1\;ldr\\t%w0, [%x0, %L1] -+ * return TARGET_MACHO ? \"adrp\\t%x0, %A1\;ldr\\t%w0, [%x0, %O1]\" : \"adrp\\t%x0, %A1\;ldr\\t%w0, [%x0, %L1]\"; - adr\\t%x0, %c1 - adrp\\t%x0, %A1 - fmov\\t%s0, %w1 -@@ -1360,7 +1392,7 @@ - ldr\\t%d0, %1 - str\\t%x1, %0 - str\\t%d1, %0 -- * return TARGET_ILP32 ? \"adrp\\t%0, %A1\;ldr\\t%w0, [%0, %L1]\" : \"adrp\\t%0, %A1\;ldr\\t%0, [%0, %L1]\"; -+ * return TARGET_ILP32 ? (TARGET_MACHO ? \"adrp\\t%0, %A1\;ldr\\t%w0, [%0, %O1]\" : \"adrp\\t%0, %A1\;ldr\\t%w0, [%0, %L1]\") : (TARGET_MACHO ? \"adrp\\t%0, %A1\;ldr\\t%0, [%0, %O1]\" : \"adrp\\t%0, %A1\;ldr\\t%0, [%0, %L1]\"); - adr\\t%x0, %c1 - adrp\\t%x0, %A1 - fmov\\t%d0, %x1 -@@ -1799,16 +1831,16 @@ - (set_attr "arch" "*,fp")] - ) - --(define_insn "load_pair_dw_tftf" -- [(set (match_operand:TF 0 "register_operand" "=w") -- (match_operand:TF 1 "aarch64_mem_pair_operand" "Ump")) -- (set (match_operand:TF 2 "register_operand" "=w") -- (match_operand:TF 3 "memory_operand" "m"))] -+(define_insn "load_pair_dw_" -+ [(set (match_operand:TX 0 "register_operand" "=w") -+ (match_operand:TX 1 "aarch64_mem_pair_operand" "Ump")) -+ (set (match_operand:TX2 2 "register_operand" "=w") -+ (match_operand:TX2 3 "memory_operand" "m"))] - "TARGET_SIMD - && rtx_equal_p (XEXP (operands[3], 0), - plus_constant (Pmode, - XEXP (operands[1], 0), -- GET_MODE_SIZE (TFmode)))" -+ GET_MODE_SIZE (mode)))" - "ldp\\t%q0, %q2, %z1" - [(set_attr "type" "neon_ldp_q") - (set_attr "fp" "yes")] -@@ -1849,11 +1881,11 @@ - (set_attr "arch" "*,fp")] - ) - --(define_insn "store_pair_dw_tftf" -- [(set (match_operand:TF 0 "aarch64_mem_pair_operand" "=Ump") -- (match_operand:TF 1 "register_operand" "w")) -- (set (match_operand:TF 2 "memory_operand" "=m") -- (match_operand:TF 3 "register_operand" "w"))] -+(define_insn "store_pair_dw_" -+ [(set (match_operand:TX 0 "aarch64_mem_pair_operand" "=Ump") -+ (match_operand:TX 1 "register_operand" "w")) -+ (set (match_operand:TX2 2 "memory_operand" "=m") -+ (match_operand:TX2 3 "register_operand" "w"))] - "TARGET_SIMD && - rtx_equal_p (XEXP (operands[2], 0), - plus_constant (Pmode, -@@ -7045,7 +7077,10 @@ - (lo_sum:P (match_operand:P 1 "register_operand" "r") - (match_operand 2 "aarch64_valid_symref" "S")))] - "" -- "add\\t%0, %1, :lo12:%c2" -+ { return TARGET_MACHO -+ ? "add\\t%0, %1, %J2;" -+ : "add\\t%0, %1, :lo12:%c2"; -+ } - [(set_attr "type" "alu_imm")] - ) - -diff --git a/gcc/config/aarch64/aarch64.opt b/gcc/config/aarch64/aarch64.opt -index 1d7967d..cc97d72 100644 ---- a/gcc/config/aarch64/aarch64.opt -+++ b/gcc/config/aarch64/aarch64.opt -@@ -158,6 +158,13 @@ Enum(aarch64_abi) String(ilp32) Value(AARCH64_ABI_ILP32) - EnumValue - Enum(aarch64_abi) String(lp64) Value(AARCH64_ABI_LP64) - -+EnumValue -+Enum(aarch64_abi) String(darwinpcs) Value(AARCH64_ABI_LP64) -+ -+m64 -+Target RejectNegative Alias(mabi=, darwinpcs) -+On Darwin for compatibility with other platform variants. -+ - mpc-relative-literal-loads - Target Save Var(pcrelative_literal_loads) Init(2) Save - PC relative literal loads. -diff --git a/gcc/config/aarch64/constraints.md b/gcc/config/aarch64/constraints.md -index 5b20abc..9c6a631 100644 ---- a/gcc/config/aarch64/constraints.md -+++ b/gcc/config/aarch64/constraints.md -@@ -168,7 +168,9 @@ - A constraint that matches a small GOT access." - (and (match_code "const,symbol_ref") - (match_test "aarch64_classify_symbolic_expression (op) -- == SYMBOL_SMALL_GOT_4G"))) -+ == SYMBOL_SMALL_GOT_4G -+ || aarch64_classify_symbolic_expression (op) -+ == SYMBOL_MO_SMALL_GOT"))) - - (define_constraint "Uss" - "@internal -@@ -505,6 +507,11 @@ - An address valid for a prefetch instruction." - (match_test "aarch64_address_valid_for_prefetch_p (op, true)")) - -+(define_address_constraint "Du" -+ "@internal -+ An address valid for a prefetch instruction with an unscaled offset." -+ (match_test "aarch64_address_valid_for_unscaled_prefetch_p (op, true)")) -+ - (define_constraint "vgb" - "@internal - A constraint that matches an immediate offset valid for SVE LD1B -diff --git b/gcc/config/aarch64/darwin.h b/gcc/config/aarch64/darwin.h -new file mode 100644 -index 0000000..08febf1 ---- /dev/null -+++ b/gcc/config/aarch64/darwin.h -@@ -0,0 +1,289 @@ -+/* Target definitions for Arm64/Aarch64 running on macOS/iOS. -+ -+Copyright The GNU Toolchain Authors. -+Contributed by Iain Sandoe. -+ -+This file is part of GCC. -+ -+GCC 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 3, or (at your option) -+any later version. -+ -+GCC 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. -+ -+You should have received a copy of the GNU General Public License -+along with GCC; see the file COPYING3. If not see -+. */ -+ -+/* Enable Mach-O bits in generic Aarch64 code. */ -+#undef TARGET_MACHO -+#define TARGET_MACHO 1 -+ -+#undef DARWIN_ARM64 -+#define DARWIN_ARM64 1 -+ -+/* This is used in generic code in darwin.cc (at present, we have no support -+ for the arm64_32 target). */ -+#undef TARGET_64BIT -+#define TARGET_64BIT 1 -+ -+#undef PTRDIFF_TYPE -+#define PTRDIFF_TYPE "long int" -+ -+#undef TARGET_PROMOTE_FUNCTION_MODE -+#define TARGET_PROMOTE_FUNCTION_MODE aarch64_darwin_promote_fn_mode -+ -+#undef TARGET_PROMOTE_FUNCTION_MODE_CA -+#define TARGET_PROMOTE_FUNCTION_MODE_CA aarch64_darwin_promote_function_mode_ca -+ -+/* NOTE that arm64_32 is a valid thing and corresponds to darwinpcs -+ and TARGET_ILP32, but we are not implementing that for now. */ -+#define TARGET_OS_CPP_BUILTINS() \ -+ do { \ -+ builtin_define ("__LITTLE_ENDIAN__"); \ -+ builtin_define ("__arm64"); \ -+ builtin_define ("__arm64__"); \ -+ darwin_cpp_builtins (pfile); \ -+ } while (0) -+ -+/* In Darwin's Arm64 ABI, chars are signed. */ -+ -+#undef DEFAULT_SIGNED_CHAR -+#define DEFAULT_SIGNED_CHAR 1 -+ -+#undef LONG_DOUBLE_TYPE_SIZE -+#define LONG_DOUBLE_TYPE_SIZE 64 -+ -+/* Disable custom function descriptors on Darwin (we use heap-based -+ trampolines). */ -+#undef AARCH64_CUSTOM_FUNCTION_TEST -+#define AARCH64_CUSTOM_FUNCTION_TEST 0 -+ -+/* Non-PIE executables are forbidden by the Arm64-darwin security model; -+ remove the option from link-lines since they just produce a warning from -+ ld64 and are then ignored anyway. */ -+#undef DARWIN_NOPIE_SPEC -+#define DARWIN_NOPIE_SPEC \ -+" % -+# include -+#endif -+ -+ -+#if TARGET_MACHO -+ -+/* Default architecture to use if -mcpu=native did not detect a known CPU. */ -+#define DEFAULT_ARCH "apple-m1" -+ -+/* macOS does not have /proc/cpuinfo and needs a different approach, -+ based on sysctl. It is much simpler. */ -+ -+const char * -+host_detect_local_cpu (ATTRIBUTE_UNUSED int argc, ATTRIBUTE_UNUSED const char **argv) -+{ -+ bool arch = false; -+ bool tune = false; -+ bool cpu = false; -+ const char *res = NULL; -+ uint32_t family; -+ size_t len = sizeof(family); -+ -+ gcc_assert (argc); -+ if (!argv[0]) -+ return NULL; -+ -+ /* Are we processing -march, mtune or mcpu? */ -+ arch = strcmp (argv[0], "arch") == 0; -+ if (!arch) -+ tune = strcmp (argv[0], "tune") == 0; -+ if (!arch && !tune) -+ cpu = strcmp (argv[0], "cpu") == 0; -+ if (!arch && !tune && !cpu) -+ return NULL; -+ -+ sysctlbyname("hw.cpufamily", &family, &len, NULL, 0); -+ -+ switch (family) -+ { -+ case 0x07d34b9f: // Vortex, Tempest -+ res = "apple-a12"; -+ break; -+ case 0x573b5eec: -+ case 0x1b588bb3: // Firestorm, Icestorm -+ res = "apple-m1"; -+ break; -+ case 0xda33d83d: // Blizzard, Avalanche -+ res = "apple-m2"; -+ break; -+ case 0xfa33415e: // Ibiza (M3) -+ case 0x5f4dea93: // Lobos (M3 Pro) -+ case 0x72015832: // Palma (M3 Max) -+ res = "apple-m3"; -+ break; -+ default: -+ res = DEFAULT_ARCH; -+ } -+ -+ if (res) -+ return concat ("-m", argv[0], "=", res, NULL); -+ else -+ return NULL; -+} -+ -+#else -+ - struct aarch64_arch_extension - { - const char *ext; -@@ -468,3 +536,4 @@ not_found: - } - } - -+#endif -diff --git a/gcc/config/aarch64/falkor-tag-collision-avoidance.cc b/gcc/config/aarch64/falkor-tag-collision-avoidance.cc -index 39e3f5c..9b3357f 100644 ---- a/gcc/config/aarch64/falkor-tag-collision-avoidance.cc -+++ b/gcc/config/aarch64/falkor-tag-collision-avoidance.cc -@@ -740,7 +740,7 @@ dump_insn_list (const rtx &t, const insn_info_list_t &insn_info, - void *unused ATTRIBUTE_UNUSED) - { - gcc_assert (dump_file); -- fprintf (dump_file, "Tag 0x%lx ::\n", INTVAL (t)); -+ fprintf (dump_file, "Tag 0x" HOST_WIDE_INT_PRINT_HEX_PURE " ::\n", INTVAL (t)); - - for (unsigned i = 0; i < insn_info.length (); i++) - dump_insn_slim (dump_file, insn_info[i]->insn); -diff --git a/gcc/config/aarch64/iterators.md b/gcc/config/aarch64/iterators.md -index 86a196d..0708a92 100644 ---- a/gcc/config/aarch64/iterators.md -+++ b/gcc/config/aarch64/iterators.md -@@ -316,6 +316,9 @@ - ;; TX plus V16QImode. - (define_mode_iterator TX_V16QI [TI TF TD V16QI]) - -+;; Duplicate of TX above -+(define_mode_iterator TX2 [TI TF TD]) -+ - (define_mode_iterator VTX [TI TF TD V16QI V8HI V4SI V2DI V8HF V4SF V2DF V8BF]) - - ;; Advanced SIMD opaque structure modes. -diff --git a/gcc/config/aarch64/predicates.md b/gcc/config/aarch64/predicates.md -index 3f5f4df..4c3498d 100644 ---- a/gcc/config/aarch64/predicates.md -+++ b/gcc/config/aarch64/predicates.md -@@ -277,9 +277,24 @@ - (define_predicate "aarch64_prefetch_operand" - (match_test "aarch64_address_valid_for_prefetch_p (op, false)")) - -+(define_predicate "aarch64_unscaled_prefetch_operand" -+ (match_test "aarch64_address_valid_for_unscaled_prefetch_p (op, false)")) -+ - (define_predicate "aarch64_valid_symref" - (match_code "const, symbol_ref, label_ref") - { -+ if (TARGET_MACHO) -+ { -+ rtx x = op; -+ rtx offset; -+ split_const (x, &x, &offset); -+ if (GET_CODE (x) == CONST) -+ x = XEXP (x, 0); -+ if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_SALT_ADDR) -+ x = XVECEXP (x, 0, 0); -+ if (SYMBOL_REF_P (x) && INTVAL (offset) < 0) -+ return false; -+ } - return (aarch64_classify_symbolic_expression (op) - != SYMBOL_FORCE_TO_MEM); - }) -diff --git b/gcc/config/aarch64/t-aarch64-darwin b/gcc/config/aarch64/t-aarch64-darwin -new file mode 100644 -index 0000000..e2b8ad9 ---- /dev/null -+++ b/gcc/config/aarch64/t-aarch64-darwin -@@ -0,0 +1,25 @@ -+# Machine description for AArch64 architecture. -+# Copyright (C) 2020 Free Software Foundation, Inc. -+# -+# This file is part of GCC. -+# -+# GCC 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 3, or (at your option) -+# any later version. -+# -+# GCC 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. -+# -+# You should have received a copy of the GNU General Public License -+# along with GCC; see the file COPYING3. If not see -+# . -+ -+LIB1ASMSRC = aarch64/lib1funcs.asm -+LIB1ASMFUNCS = _aarch64_sync_cache_range -+ -+# TODO - figure out what multilib provisions we should make for -+# a) arm64e -+# b) arm64_32 -diff --git a/gcc/config/darwin-c.cc b/gcc/config/darwin-c.cc -index 579b9fa..10d5fb1 100644 ---- a/gcc/config/darwin-c.cc -+++ b/gcc/config/darwin-c.cc -@@ -555,7 +555,7 @@ find_subframework_header (cpp_reader *pfile, const char *header, cpp_dir **dirp) - return 0; - } - --/* Given an OS X version VERSION_STR, return it as a statically-allocated array -+/* Given an macOS version VERSION_STR, return it as a statically-allocated array - of three integers. If VERSION_STR is invalid, return NULL. - - VERSION_STR must consist of one, two, or three tokens, each separated by -@@ -612,7 +612,7 @@ parse_version (const char *version_str) - return version_array; - } - --/* Given VERSION -- a three-component OS X version represented as an array of -+/* Given VERSION -- a three-component macOS version represented as an array of - non-negative integers -- return a statically-allocated string suitable for - the legacy __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ macro. If VERSION - is invalid and cannot be coerced into a valid form, return NULL. -@@ -645,7 +645,7 @@ version_as_legacy_macro (const unsigned long *version) - return result; - } - --/* Given VERSION -- a three-component OS X version represented as an array of -+/* Given VERSION -- a three-component macOS version represented as an array of - non-negative integers -- return a statically-allocated string suitable for - the modern __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ macro. If VERSION - is invalid, return NULL. -@@ -675,7 +675,7 @@ version_as_modern_macro (const unsigned long *version) - - /* Return the value of darwin_macosx_version_min, suitably formatted for the - __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ macro. Values representing -- OS X 10.9 and earlier are encoded using the legacy four-character format, -+ macOS 10.9 and earlier are encoded using the legacy four-character format, - while 10.10 and later use a modern six-character format. (For example, - "10.9" produces "1090", and "10.10.1" produces "101001".) If - darwin_macosx_version_min is invalid and cannot be coerced into a valid -diff --git a/gcc/config/darwin-driver.cc b/gcc/config/darwin-driver.cc -index 9c1dcc3..b2f39af 100644 ---- a/gcc/config/darwin-driver.cc -+++ b/gcc/config/darwin-driver.cc -@@ -268,10 +268,13 @@ darwin_driver_init (unsigned int *decoded_options_count, - bool seenX86_64 = false; - bool seenPPC = false; - bool seenPPC64 = false; -+#if !DARWIN_ARM64 -+ bool seenArm64 = false; - bool seenM32 = false; - bool seenM64 = false; - bool appendM32 = false; - bool appendM64 = false; -+#endif - const char *vers_string = NULL; - bool seen_version_min = false; - bool seen_sysroot_p = false; -@@ -296,6 +299,12 @@ darwin_driver_init (unsigned int *decoded_options_count, - seenPPC = true; - else if (!strcmp ((*decoded_options)[i].arg, "ppc64")) - seenPPC64 = true; -+ else if (!strcmp ((*decoded_options)[i].arg, "arm64")) -+#if !DARWIN_ARM64 -+ seenArm64 = true; -+#else -+ ; /* We accept the option, but don't need to act on it. */ -+#endif - else - error ("this compiler does not support %qs", - (*decoded_options)[i].arg); -@@ -309,7 +318,7 @@ darwin_driver_init (unsigned int *decoded_options_count, - --i; - --*decoded_options_count; - break; -- -+#if !DARWIN_ARM64 - case OPT_m32: - seenM32 = true; - break; -@@ -317,6 +326,7 @@ darwin_driver_init (unsigned int *decoded_options_count, - case OPT_m64: - seenM64 = true; - break; -+#endif - - case OPT_mmacosx_version_min_: - seen_version_min = true; -@@ -366,6 +376,9 @@ darwin_driver_init (unsigned int *decoded_options_count, - if (seenPPC || seenPPC64) - warning (0, "this compiler does not support PowerPC" - " (%<-arch%> option ignored)"); -+ else if (seenArm64) -+ warning (0, "this compiler does not support Arm64" -+ " (%<-arch%> option ignored)"); - if (seenX86) - { - if (seenX86_64 || seenM64) -@@ -389,6 +402,9 @@ darwin_driver_init (unsigned int *decoded_options_count, - if (seenX86 || seenX86_64) - warning (0, "this compiler does not support x86" - " (%<-arch%> option ignored)"); -+ else if (seenArm64) -+ warning (0, "this compiler does not support Arm64" -+ " (%<-arch%> option ignored)"); - if (seenPPC) - { - if (seenPPC64 || seenM64) -@@ -408,12 +424,20 @@ darwin_driver_init (unsigned int *decoded_options_count, - if (! seenM64) /* Add -m64 if the User didn't. */ - appendM64 = true; - } -+#elif DARWIN_ARM64 -+ if (seenPPC || seenPPC64) -+ warning (0, "this compiler does not support PowerPC" -+ " (%<-arch%> option ignored)"); -+ if (seenX86 || seenX86_64) -+ warning (0, "this compiler does not support x86" -+ " (%<-arch%> option ignored)"); - #endif - - /* If there is nothing else on the command line, do not add sysroot etc. */ - if (*decoded_options_count <= 1) - return; - -+#if !DARWIN_ARM64 - if (appendM32 || appendM64) - { - ++*decoded_options_count; -@@ -423,6 +447,7 @@ darwin_driver_init (unsigned int *decoded_options_count, - generate_option (appendM32 ? OPT_m32 : OPT_m64, NULL, 1, CL_DRIVER, - &(*decoded_options)[*decoded_options_count - 1]); - } -+#endif - - if (!seen_sysroot_p) - { -@@ -440,7 +465,7 @@ darwin_driver_init (unsigned int *decoded_options_count, - } - } - -- /* We will need to know the OS X version we're trying to build for here -+ /* We will need to know the macOS version we're trying to build for here - so that we can figure out the mechanism and source for the sysroot to - be used. */ - if (!seen_version_min) -diff --git a/gcc/config/darwin-protos.h b/gcc/config/darwin-protos.h -index 9df358e..babc888 100644 ---- a/gcc/config/darwin-protos.h -+++ b/gcc/config/darwin-protos.h -@@ -86,9 +86,12 @@ extern void darwin_asm_lto_end (void); - extern void darwin_mark_decl_preserved (const char *); - - extern tree darwin_handle_kext_attribute (tree *, tree, tree, int, bool *); --extern tree darwin_handle_weak_import_attribute (tree *node, tree name, -- tree args, int flags, -- bool * no_add_attrs); -+extern tree darwin_handle_weak_import_attribute (tree *, tree, tree, int, -+ bool *); -+extern tree darwin_handle_availability_attribute (tree *, tree, tree, -+ int, bool *); -+extern bool darwin_attribute_takes_identifier_p (const_tree); -+ - extern void machopic_output_stub (FILE *, const char *, const char *); - extern void darwin_globalize_label (FILE *, const char *); - extern void darwin_assemble_visibility (tree, int); -@@ -124,6 +127,7 @@ extern void darwin_enter_string_into_cfstring_table (tree); - extern void darwin_asm_output_anchor (rtx symbol); - extern bool darwin_use_anchors_for_symbol_p (const_rtx symbol); - extern bool darwin_kextabi_p (void); -+extern bool darwin_unreachable_traps_p (void); - extern void darwin_override_options (void); - extern void darwin_patch_builtins (void); - extern void darwin_rename_builtins (void); -diff --git a/gcc/config/darwin.cc b/gcc/config/darwin.cc -index 1471dbb..e95520f 100644 ---- a/gcc/config/darwin.cc -+++ b/gcc/config/darwin.cc -@@ -29,6 +29,7 @@ along with GCC; see the file COPYING3. If not see - #include "cfghooks.h" - #include "df.h" - #include "memmodel.h" -+#include "c-family/c-common.h" /* enum rid. */ - #include "tm_p.h" - #include "stringpool.h" - #include "attribs.h" -@@ -49,6 +50,7 @@ along with GCC; see the file COPYING3. If not see - #include "optabs.h" - #include "flags.h" - #include "opts.h" -+#include "c-family/c-objc.h" /* for objc_method_decl(). */ - - /* Fix and Continue. - -@@ -102,6 +104,7 @@ int darwin_running_cxx; - - /* Some code-gen now depends on OS major version numbers (at least). */ - int generating_for_darwin_version ; -+unsigned long current_os_version = 0; - - /* For older linkers we need to emit special sections (marked 'coalesced') for - for weak or single-definition items. */ -@@ -131,7 +134,7 @@ struct { - section * darwin_sections[NUM_DARWIN_SECTIONS]; - - /* While we transition to using in-tests instead of ifdef'd code. */ --#if !HAVE_lo_sum -+#if !HAVE_lo_sum || DARWIN_ARM64 - #define gen_macho_high(m,a,b) (a) - #define gen_macho_low(m,a,b,c) (a) - #endif -@@ -1065,6 +1068,7 @@ machopic_legitimize_pic_address (rtx orig, machine_mode mode, rtx reg) - return pic_ref; - } - -+#if !DARWIN_ARM64 - /* Callbacks to output the stub or non-lazy pointers. - Each works on the item in *SLOT,if it has been used. - DATA is the FILE* for assembly output. -@@ -1220,6 +1224,7 @@ machopic_finish (FILE *out_file) - machopic_indirections->traverse_noresize - (out_file); - } -+#endif - - int - machopic_operand_p (rtx op) -@@ -2155,6 +2160,122 @@ darwin_handle_kext_attribute (tree *node, tree name, - return NULL_TREE; - } - -+enum version_components { MAJOR, MINOR, TINY }; -+ -+/* Parse a version number in x.y.z form and validate it as a macOS -+ version. Ideally, we'd put this in a common place usable by the -+ Darwin backend. */ -+ -+static bool -+parse_version (unsigned version_array[3], const char *version_str) -+{ -+ size_t version_len; -+ char *end, last = '\0', delimiter = '.', alt_delim = '_'; -+ -+ if (!version_str) -+ return false; -+ -+ /* Handle the odd situation in which we get STRING_CST which contain the -+ starting and ending quotes. */ -+ if (version_str[0] == '"') -+ { -+ version_str++; -+ version_len = strrchr (&version_str[1], '"') - version_str; -+ last = '"'; -+ } -+ else -+ version_len = strlen (version_str); -+ -+ if (version_len < 1) -+ return false; -+ -+ /* Version string must consist of digits and periods only. */ -+ if (strspn (version_str, "0123456789._") != version_len) -+ return false; -+ -+ if (!ISDIGIT (version_str[0]) || !ISDIGIT (version_str[version_len - 1])) -+ return false; -+ -+ version_array[MAJOR] = strtoul (version_str, &end, 10); -+ if (*end == '_') -+ { -+ delimiter = '_'; -+ alt_delim = '.'; -+ } -+ version_str = end + ((*end == delimiter) ? 1 : 0); -+ if (version_array[MAJOR] == 100000) -+ return true; -+ if (version_array[MAJOR] > 99) -+ return false; -+ -+ /* Version string must not contain adjacent delimiters. */ -+ if (*version_str == delimiter || *version_str == alt_delim) -+ return false; -+ -+ version_array[MINOR] = strtoul (version_str, &end, 10); -+ if (*end == alt_delim) -+ return false; -+ version_str = end + ((*end == delimiter) ? 1 : 0); -+ if (version_array[MINOR] > 99) -+ return false; -+ -+ version_array[TINY] = strtoul (version_str, &end, 10); -+ if (version_array[TINY] > 99) -+ return false; -+ -+ /* Version string must contain no more than three tokens. */ -+ if (*end != last) -+ return false; -+ -+ return true; -+} -+ -+/* Turn a version expressed as maj.min.tiny into an unsigned long -+ integer representing the value used in macOS availability macros. */ -+ -+static unsigned long -+version_from_version_array (unsigned vers[3]) -+{ -+ unsigned long res = 0; -+ /* There seems to be a special "unknown" value. */ -+ if (vers[0] == 100000) -+ return 999999; -+ -+ /* Here, we follow the 'modern' / 'legacy' numbering scheme for versions. */ -+ if (vers[0] > 10 || vers[1] >= 10) -+ res = vers[0] * 10000 + vers[1] * 100 + vers[2]; -+ else -+ { -+ res = vers[0] * 100; -+ if (vers[1] > 9) -+ res += 90; -+ else -+ res += vers[1] * 10; -+ if (vers[2] > 9) -+ res += 9; -+ else -+ res += vers[1]; -+ } -+ return res; -+} -+ -+/* Extract a macOS version from an availability attribute argument. */ -+ -+static unsigned long -+os_version_from_avail_value (tree value) -+{ -+ unsigned long res = 0; -+ unsigned vers[3] = {0,0,0}; -+ if (TREE_CODE (value) == STRING_CST) -+ { -+ if (parse_version (&vers[0], TREE_STRING_POINTER (value))) -+ res = version_from_version_array (&vers[0]); -+ } -+ else -+ gcc_unreachable (); -+ return res; -+} -+ - /* Handle a "weak_import" attribute; arguments as in - struct attribute_spec.handler. */ - -@@ -2176,6 +2297,231 @@ darwin_handle_weak_import_attribute (tree *node, tree name, - return NULL_TREE; - } - -+#define NUM_AV_OSES 13 -+const char *availability_os[NUM_AV_OSES] -+ = { "macos", "macosx", "ios", "tvos", "watchos", "driverkit", "swift", -+ "maccatalyst", "macCatalyst", "xros", "visionos", "android", "zos" }; -+ -+#define NUM_AV_CLAUSES 6 -+const char *availability_clause[NUM_AV_CLAUSES] -+ = { "unavailable", "introduced", "deprecated", "obsoleted", "message", -+ "replacement" }; -+ -+/* Validate and act upon the arguments to an 'availability' attribute. */ -+ -+tree -+darwin_handle_availability_attribute (tree *node, tree name, tree args, -+ int flags, bool * no_add_attrs) -+{ -+ tree decl = *node; -+ *no_add_attrs = true; -+ -+ if (!decl || (!TYPE_P (decl) && !DECL_P (decl))) -+ { -+ warning (OPT_Wattributes, "%qE attribute ignored", name); -+ return NULL_TREE; -+ } -+ else if (decl == error_mark_node) -+ return NULL_TREE; -+ -+ location_t loc = DECL_SOURCE_LOCATION (decl); -+ if (args == NULL_TREE) -+ { -+ error_at (loc, "%qE attribute requires at least one argument", -+ name); -+ return NULL_TREE; -+ } -+ else if (args == error_mark_node) -+ return NULL_TREE; -+ -+ /* The first argument must name a supported OS - although we could choose -+ to ignore any OS we don't recognise. */ -+ gcc_checking_assert (TREE_CODE (args) == TREE_LIST); -+ tree platform = TREE_VALUE (args); -+ if (platform == error_mark_node) -+ return NULL_TREE; -+ -+ gcc_checking_assert (TREE_CODE (platform) == IDENTIFIER_NODE); -+ bool platform_ok = false; -+ unsigned plat_num = 0; -+ for (; plat_num < (unsigned) NUM_AV_OSES; plat_num++) -+ if (strcmp (availability_os[plat_num], IDENTIFIER_POINTER (platform)) == 0) -+ { -+ platform_ok = true; -+ break; -+ } -+ if (!platform_ok) -+ { -+ error_at (input_location, -+ "platform %qE is not recognised for the % " -+ "attribute", platform); -+ return NULL_TREE; -+ } -+ else if (plat_num > 1) /* We only compile for macos so far. */ -+ return NULL_TREE; -+ -+ /* We might be dealing with an object or type. */ -+ tree target_decl = NULL_TREE; -+ tree type = NULL_TREE; -+ bool warn = false; -+ if (DECL_P (*node)) -+ { -+ type = TREE_TYPE (decl); -+ -+ if (TREE_CODE (decl) == TYPE_DECL -+ || TREE_CODE (decl) == PARM_DECL -+ || VAR_OR_FUNCTION_DECL_P (decl) -+ || TREE_CODE (decl) == FIELD_DECL -+ || TREE_CODE (decl) == CONST_DECL -+ /*|| objc_method_decl (TREE_CODE (decl))*/) -+ target_decl = decl; -+ else -+ warn = true; -+ } -+ else if (TYPE_P (*node)) -+ type = target_decl = *node; -+ else -+ warn = true; -+ -+ tree what = NULL_TREE; -+ if (warn) -+ { -+ if (type && TYPE_NAME (type)) -+ { -+ if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE) -+ what = TYPE_NAME (*node); -+ else if (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL -+ && DECL_NAME (TYPE_NAME (type))) -+ what = DECL_NAME (TYPE_NAME (type)); -+ } -+ if (what) -+ warning (OPT_Wattributes, "%qE attribute ignored for %qE", name, what); -+ else -+ warning (OPT_Wattributes, "%qE attribute ignored", name); -+ return NULL_TREE; -+ } -+ -+ /* Now we have to parse the availability clauses. */ -+ tree msg = NULL_TREE; -+ tree replacement = NULL_TREE; -+ bool unavailable = false; -+ unsigned introduced = 1000; -+ unsigned deprecated = current_os_version + 1; -+ unsigned obsoleted = current_os_version + 1; -+ for (tree arg = TREE_CHAIN (args); arg; arg = TREE_CHAIN (arg)) -+ { -+ tree clause_name = TREE_VALUE (arg); -+ tree clause_value = TREE_PURPOSE (arg); -+ if (clause_name == error_mark_node -+ || clause_value == error_mark_node) -+ continue; -+ unsigned clause_num = 0; -+ for (; clause_num < (unsigned) NUM_AV_CLAUSES; clause_num++) -+ if (strcmp (availability_clause[clause_num], -+ IDENTIFIER_POINTER (clause_name)) == 0) -+ break; -+ switch (clause_num) -+ { -+ default: -+ error_at (input_location, -+ "clause %qE is not recognised for the % " -+ "attribute", clause_name); -+ break; -+ case 0: -+ unavailable = true; -+ break; -+ case 1: -+ case 2: -+ case 3: -+ if (!clause_value) -+ error_at (input_location, "%<%E=%> requires a value", clause_name); -+ else -+ { -+ unsigned version = os_version_from_avail_value (clause_value); -+ if (version == 0) -+ error_at (input_location, "the value %qE provided to %qE is " -+ "not a valid OS version", clause_value, clause_name); -+ else if (clause_num == 1) -+ introduced = version; -+ else if (clause_num == 2) -+ deprecated = version; -+ else if (clause_num == 3) -+ obsoleted = version; -+ } -+ break; -+ case 4: -+ case 5: -+ if (!clause_value || TREE_CODE (clause_value) != STRING_CST) -+ error_at (input_location, "%<%E=%> requires a string", clause_name); -+ else if (clause_num == 4) -+ msg = clause_value; -+ else -+ replacement = clause_value; -+ break; -+ } -+ } -+ /* Now figure out what to do. */ -+ tree maybe_text = NULL_TREE; -+ if (replacement) -+ maybe_text = tree_cons (NULL_TREE, replacement, NULL_TREE); -+ else if (msg) -+ maybe_text = tree_cons (NULL_TREE, msg, NULL_TREE); -+ -+ if (unavailable || current_os_version >= obsoleted) -+ { -+ TREE_UNAVAILABLE (*node) = true; -+ /* We do not handle the availability attribute at diagnostics-time, so -+ if we want the informational messages, then attach them to additional -+ attributes for the deprecation or unavailability. TODO; maybe we can -+ fabricate the composite here. */ -+ if (maybe_text) -+ { -+ *no_add_attrs = false; -+ tree new_attr = tree_cons (get_identifier ("unavailable"), -+ maybe_text, NULL_TREE); -+ /* This is the actual consequence of the evaluation. */ -+ if (TYPE_P (target_decl) && !(flags & (int) ATTR_FLAG_TYPE_IN_PLACE)) -+ { -+ *node = build_variant_type_copy (*node); -+ TYPE_ATTRIBUTES (*node) = chainon (TYPE_ATTRIBUTES (*node), -+ new_attr); -+ } -+ else -+ DECL_ATTRIBUTES (*node) = chainon (DECL_ATTRIBUTES (*node), -+ new_attr); -+ } -+ } -+ else if (current_os_version > deprecated) -+ { -+ TREE_DEPRECATED (*node) = true; -+ if (maybe_text) -+ { -+ *no_add_attrs = false; -+ tree new_attr = tree_cons (get_identifier ("deprecated"), -+ maybe_text, NULL_TREE); -+ /* This is the actual consequence of the evaluation. */ -+ if (TYPE_P (target_decl) && !(flags & (int) ATTR_FLAG_TYPE_IN_PLACE)) -+ { -+ *node = build_variant_type_copy (*node); -+ TYPE_ATTRIBUTES (*node) = chainon (TYPE_ATTRIBUTES (*node), -+ new_attr); -+ } -+ else -+ DECL_ATTRIBUTES (*node) = chainon (DECL_ATTRIBUTES (*node), -+ new_attr); -+ } -+ } -+ else if (current_os_version < introduced) -+ *no_add_attrs = false; -+ return NULL_TREE; -+} -+ -+bool -+darwin_attribute_takes_identifier_p (const_tree attr_id) -+{ -+ return is_attribute_p ("availability", attr_id); -+} -+ - /* Emit a label for an FDE, making it global and/or weak if appropriate. - The third parameter is nonzero if this is for exception handling. - The fourth parameter is nonzero if this is just a placeholder for an -@@ -2267,6 +2613,8 @@ darwin_emit_except_table_label (FILE *file) - rtx - darwin_make_eh_symbol_indirect (rtx orig, bool ARG_UNUSED (pubvis)) - { -+ if (DARWIN_ARM64) -+ return orig; - if (DARWIN_PPC == 0 && TARGET_64BIT) - return orig; - -@@ -3115,7 +3463,12 @@ darwin_file_end (void) - fprintf (asm_out_file, "\t.long\t0\n\t.long\t%u\n", flags); - } - -+#if !DARWIN_ARM64 - machopic_finish (asm_out_file); -+#else -+ gcc_checking_assert (!machopic_indirections); -+#endif -+ - if (flag_apple_kext) - { - /* These sections are only used for kernel code. */ -@@ -3291,6 +3644,13 @@ darwin_kextabi_p (void) { - return flag_apple_kext; - } - -+/* True, iff we want to map __builtin_unreachable to a trap. */ -+ -+bool -+darwin_unreachable_traps_p (void) { -+ return darwin_unreachable_traps; -+} -+ - void - darwin_override_options (void) - { -@@ -3311,7 +3671,14 @@ darwin_override_options (void) - generating_for_darwin_version = 8; - - /* Earlier versions are not specifically accounted, until required. */ -+ unsigned vers[3] = {0,0,0}; -+ if (!parse_version (vers, darwin_macosx_version_min)) -+ error_at (UNKNOWN_LOCATION, "how did we get a bad OS version? (%s)", -+ darwin_macosx_version_min); -+ current_os_version = version_from_version_array (vers); - } -+ else -+ current_os_version = 1058; - - /* Some codegen needs to account for the capabilities of the target - linker. */ -diff --git a/gcc/config/darwin.h b/gcc/config/darwin.h -index 5c6c38d..fcf9eff 100644 ---- a/gcc/config/darwin.h -+++ b/gcc/config/darwin.h -@@ -1,4 +1,4 @@ --/* Target definitions for Darwin (Mac OS X) systems. -+/* Target definitions for Darwin (macOS) systems. - Copyright (C) 1989-2023 Free Software Foundation, Inc. - Contributed by Apple Computer Inc. - -@@ -27,7 +27,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see - #define CONFIG_DARWIN_H - - /* The definitions in this file are common to all processor types -- running Darwin, which is the kernel for Mac OS X. Darwin is -+ running Darwin, which is the kernel for macOS. Darwin is - basically a BSD user layer laid over a Mach kernel, then evolved - for many years (at NeXT) in parallel with other Unix systems. So - while the runtime is a somewhat idiosyncratic Mach-based thing, -@@ -42,6 +42,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see - - #define DARWIN_X86 0 - #define DARWIN_PPC 0 -+#define DARWIN_ARM64 0 - - #define OBJECT_FORMAT_MACHO 1 - -@@ -133,10 +134,9 @@ extern GTY(()) int darwin_ms_struct; - cases where these driver opts are used multiple times, or to control - operations on more than one command (e.g. dynamiclib). These are handled - specially and we then add %= 10.7 mmacosx-version-min= -no_pie) }" - - #define DARWIN_CC1_SPEC \ -- "% 10.11 mmacosx-version-min= -lgcc_s.1.1)" -+# define DARWIN_SHARED_WEAK_ADDS \ -+"%{%:version-compare(>= 10.11 mmacosx-version-min= -lemutls_w): \ -+ " DARWIN_HEAP_T_LIB "}" -+#endif -+ -+ -+/* We might elect to add a path even when this compiler does not use embedded -+ run paths, so that we can use libraries from an alternate compiler that is -+ using embedded runpaths. */ -+#if DARWIN_DO_EXTRA_RPATH -+# define DARWIN_EXTRA_RPATH \ -+"%{!r:%{!nostdlib:%{!nodefaultrpaths:\ -+ %:version-compare(>= 10.5 mmacosx-version-min= -rpath) \ -+ %:version-compare(>= 10.5 mmacosx-version-min= " DARWIN_ADD_RPATH ") \ -+ }}}" -+#else -+# define DARWIN_EXTRA_RPATH "" -+#endif - - #define SUBSUBTARGET_OVERRIDE_OPTIONS \ - do { \ -@@ -336,7 +372,8 @@ extern GTY(()) int darwin_ms_struct; - */ - - #define DARWIN_NOCOMPACT_UNWIND \ --" %:version-compare(>= 10.6 mmacosx-version-min= -no_compact_unwind) " -+"%{!fuse-ld=lld: \ -+ %:version-compare(>= 10.6 mmacosx-version-min= -no_compact_unwind)}" - - /* In Darwin linker specs we can put -lcrt0.o and ld will search the library - path for crt0.o or -lcrtx.a and it will search for libcrtx.a. As for -@@ -356,10 +393,12 @@ extern GTY(()) int darwin_ms_struct; - #define LINK_COMMAND_SPEC_A \ - "%{!c:%{!E:%{!S:%{!M:%{!MM:%{!fsyntax-only:%{!fdump=*: \ - %(linker)" \ -+ DARWIN_LD_DEMANGLE \ - LINK_PLUGIN_SPEC \ - "%{flto*:% 10.6 mmacosx-version-min= -lgcc_eh); \ - shared-libgcc|fexceptions|fobjc-exceptions|fgnu-runtime: \ -- %:version-compare(!> 10.11 mmacosx-version-min= -lgcc_s.1.1) \ -+ " DARWIN_SHARED_LIBGCC " \ - %:version-compare(!> 10.3.9 mmacosx-version-min= -lgcc_eh) \ - %:version-compare(>< 10.3.9 10.5 mmacosx-version-min= -lgcc_s.10.4) \ - %:version-compare(>< 10.5 10.6 mmacosx-version-min= -lgcc_s.10.5) \ -@@ -520,18 +561,19 @@ extern GTY(()) int darwin_ms_struct; - - #define DARWIN_WEAK_CRTS \ - "%{static-libgcc|static: \ -- %:version-compare(>= 10.6 mmacosx-version-min= -lemutls_w) ; \ -- shared-libgcc|fexceptions|fobjc-exceptions|fgnu-runtime: \ -- %:version-compare(>= 10.11 mmacosx-version-min= -lemutls_w) ; \ -- : -lemutls_w \ -+ %{%:version-compare(>= 10.6 mmacosx-version-min= -lemutls_w): \ -+ " DARWIN_HEAP_T_LIB "} ; \ -+ shared-libgcc|fexceptions|fobjc-exceptions|fgnu-runtime: " \ -+ DARWIN_SHARED_WEAK_ADDS " ; \ -+ : -lemutls_w " DARWIN_HEAP_T_LIB " \ - }" - - /* We specify crt0.o as -lcrt0.o so that ld will search the library path. */ - - #undef STARTFILE_SPEC - #define STARTFILE_SPEC \ --"%{dynamiclib: %(darwin_dylib1) %{fgnu-tm: -lcrttms.o}} \ -- %{!dynamiclib:%{bundle:%(darwin_bundle1)} \ -+"%{dynamiclib|shared: %(darwin_dylib1) %{fgnu-tm: -lcrttms.o}} \ -+ %{!dynamiclib:%{!shared:%{bundle:%(darwin_bundle1)} \ - %{!bundle:%{pg:%{static:-lgcrt0.o} \ - %{!static:%{object:-lgcrt0.o} \ - %{!object:%{preload:-lgcrt0.o} \ -@@ -542,8 +584,8 @@ extern GTY(()) int darwin_ms_struct; - %{!static:%{object:-lcrt0.o} \ - %{!object:%{preload:-lcrt0.o} \ - %{!preload: %(darwin_crt1) \ -- %(darwin_crt2)}}}}}} \ -- %(darwin_crt3) % 10.5 mmacosx-version-min= -lcrt1.o) \ -@@ -580,6 +623,16 @@ extern GTY(()) int darwin_ms_struct; - "%{!static:%:version-compare(< 10.6 mmacosx-version-min= -lbundle1.o) \ - %{fgnu-tm: -lcrttms.o}}" - -+#if DARWIN_AT_RPATH -+/* A default rpath, that picks up dependent libraries installed in the same -+ director as one being loaded. */ -+#define DARWIN_RPATH_SPEC \ -+ "%:version-compare(>= 10.5 mmacosx-version-min= -rpath) \ -+ %{%:version-compare(>= 10.5 mmacosx-version-min= @loader_path): %P }" -+#else -+#define DARWIN_RPATH_SPEC "" -+#endif -+ - #ifdef HAVE_AS_MMACOSX_VERSION_MIN_OPTION - /* Emit macosx version (but only major). */ - #define ASM_MMACOSX_VERSION_MIN_SPEC \ -@@ -927,7 +980,12 @@ extern GTY(()) section * darwin_sections[NUM_DARWIN_SECTIONS]; - { "apple_kext_compatibility", 0, 0, false, true, false, false, \ - darwin_handle_kext_attribute, NULL }, \ - { "weak_import", 0, 0, true, false, false, false, \ -- darwin_handle_weak_import_attribute, NULL } -+ darwin_handle_weak_import_attribute, NULL }, \ -+ { "availability", 0, -1, true, false, false, false, \ -+ darwin_handle_availability_attribute, NULL } -+ -+#undef TARGET_ATTRIBUTE_TAKES_IDENTIFIER_P -+#define TARGET_ATTRIBUTE_TAKES_IDENTIFIER_P darwin_attribute_takes_identifier_p - - /* Make local constant labels linker-visible, so that if one follows a - weak_global constant, ld64 will be able to separate the atoms. */ -@@ -1175,6 +1233,10 @@ void add_framework_path (char *); - #define TARGET_N_FORMAT_TYPES 1 - #define TARGET_FORMAT_TYPES darwin_additional_format_types - -+/* We want __builtin_unreachable to be expanded as a trap instruction. */ -+#undef TARGET_UNREACHABLE_SHOULD_TRAP -+#define TARGET_UNREACHABLE_SHOULD_TRAP darwin_unreachable_traps_p -+ - #ifndef USED_FOR_TARGET - extern void darwin_driver_init (unsigned int *,struct cl_decoded_option **); - #define GCC_DRIVER_HOST_INITIALIZATION \ -diff --git a/gcc/config/darwin.opt b/gcc/config/darwin.opt -index d655aae..97b1a74 100644 ---- a/gcc/config/darwin.opt -+++ b/gcc/config/darwin.opt -@@ -91,6 +91,10 @@ mtarget-linker - Target RejectNegative Joined Separate Var(darwin_target_linker) Init(LD64_VERSION) - -mtarget-linker Specify that ld64 is the toolchain linker for the current invocation. - -+munreachable-traps -+Target Var(darwin_unreachable_traps) Init(1) -+When set (the default) this makes __builtin_unreachable render as a trap. -+ - ; Driver options. - - all_load -@@ -241,6 +245,10 @@ nodefaultexport - Driver RejectNegative - Do not add a default symbol exports to modules or dynamic libraries. - -+nodefaultrpaths -+Driver RejectNegative -+Do not add default run paths (for the compiler library directories) to executables, modules or dynamic libraries. -+ - nofixprebinding - Driver RejectNegative - (Obsolete after 10.3.9) Set MH_NOPREFIXBINDING, in an executable. -diff --git a/gcc/config/i386/darwin.h b/gcc/config/i386/darwin.h -index 588bd66..657ea47 100644 ---- a/gcc/config/i386/darwin.h -+++ b/gcc/config/i386/darwin.h -@@ -121,6 +121,9 @@ along with GCC; see the file COPYING3. If not see - #define DARWIN_SUBARCH_SPEC DARWIN_ARCH_SPEC - #endif - -+#undef DARWIN_HEAP_T_LIB -+#define DARWIN_HEAP_T_LIB " -lheapt_w " -+ - #undef SUBTARGET_EXTRA_SPECS - #define SUBTARGET_EXTRA_SPECS \ - DARWIN_EXTRA_SPECS \ -@@ -308,3 +311,9 @@ along with GCC; see the file COPYING3. If not see - #define CLEAR_INSN_CACHE(beg, end) \ - extern void sys_icache_invalidate(void *start, size_t len); \ - sys_icache_invalidate ((beg), (size_t)((end)-(beg))) -+ -+/* Disable custom function descriptors for Darwin when we have off-stack -+ trampolines. */ -+#undef X86_CUSTOM_FUNCTION_TEST -+#define X86_CUSTOM_FUNCTION_TEST \ -+ (flag_trampolines && flag_trampoline_impl == TRAMPOLINE_IMPL_HEAP) ? 0 : 1 -diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc -index 4991841..be6d408 100644 ---- a/gcc/config/i386/i386.cc -+++ b/gcc/config/i386/i386.cc -@@ -25245,7 +25245,7 @@ ix86_libgcc_floating_mode_supported_p - #define TARGET_HARD_REGNO_SCRATCH_OK ix86_hard_regno_scratch_ok - - #undef TARGET_CUSTOM_FUNCTION_DESCRIPTORS --#define TARGET_CUSTOM_FUNCTION_DESCRIPTORS 1 -+#define TARGET_CUSTOM_FUNCTION_DESCRIPTORS X86_CUSTOM_FUNCTION_TEST - - #undef TARGET_ADDR_SPACE_ZERO_ADDRESS_VALID - #define TARGET_ADDR_SPACE_ZERO_ADDRESS_VALID ix86_addr_space_zero_address_valid -diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h -index 539083f..77644b0 100644 ---- a/gcc/config/i386/i386.h -+++ b/gcc/config/i386/i386.h -@@ -754,6 +754,12 @@ extern const char *host_detect_local_cpu (int argc, const char **argv); - /* Minimum allocation boundary for the code of a function. */ - #define FUNCTION_BOUNDARY 8 - -+/* We will and with this value to test if a custom function descriptor needs -+ a static chain. The function boundary must the adjusted so that the bit -+ this represents is no longer part of the address. 0 Disables the custom -+ function descriptors. */ -+#define X86_CUSTOM_FUNCTION_TEST 1 -+ - /* C++ stores the virtual bit in the lowest bit of function pointers. */ - #define TARGET_PTRMEMFUNC_VBIT_LOCATION ptrmemfunc_vbit_in_pfn - -diff --git a/gcc/config/rs6000/darwin.h b/gcc/config/rs6000/darwin.h -index 4d5d6f6..3a2e480 100644 ---- a/gcc/config/rs6000/darwin.h -+++ b/gcc/config/rs6000/darwin.h -@@ -98,7 +98,7 @@ - Include libmx when targeting Darwin 7.0 and above, but before libSystem, - since the functions are actually in libSystem but for 7.x compatibility - we want them to be looked for in libmx first. -- Include libSystemStubs when compiling against 10.3 - 10.5 SDKs (we assume -+ Include libSystemStubs when compiling against 10.3 - 10.6 SDKs (we assume - this is the case when targetting these) - but not for 64-bit long double. - Don't do either for m64, the library is either a dummy or non-existent. - */ -@@ -107,12 +107,15 @@ - #define LIB_SPEC \ - "%{!static: \ - %{!m64:%{!mlong-double-64: \ -- %{pg:%:version-compare(>< 10.3 10.5 mmacosx-version-min= -lSystemStubs_profile)} \ -- %{!pg:%:version-compare(>< 10.3 10.5 mmacosx-version-min= -lSystemStubs)} \ -+ %{pg:%:version-compare(>< 10.3 10.7 mmacosx-version-min= -lSystemStubs_profile)} \ -+ %{!pg:%:version-compare(>< 10.3 10.7 mmacosx-version-min= -lSystemStubs)} \ - %:version-compare(>< 10.3 10.4 mmacosx-version-min= -lmx)}} \ - -lSystem \ - }" - -+#undef DARWIN_HEAP_T_LIB -+#define DARWIN_HEAP_T_LIB " " -+ - /* We want -fPIC by default, unless we're using -static to compile for - the kernel or some such. The "-faltivec" option should have been - called "-maltivec" all along. */ -diff --git a/gcc/config.gcc b/gcc/config.gcc -index c3b73d0..1b80761 100644 ---- a/gcc/config.gcc -+++ b/gcc/config.gcc -@@ -1125,6 +1125,26 @@ case ${target} in - ;; - esac - -+# Figure out if we need to enable heap trampolines -+# and variadic functions handling. -+case ${target} in -+aarch64*-*-darwin2*) -+ # This applies to arm64 Darwin variadic funtions. -+ tm_defines="$tm_defines STACK_USE_CUMULATIVE_ARGS_INIT=1" -+ # Executable stack is forbidden. -+ tm_defines="$tm_defines HEAP_TRAMPOLINES_INIT=1" -+ ;; -+*-*-darwin2*) -+ tm_defines="$tm_defines STACK_USE_CUMULATIVE_ARGS_INIT=0" -+ # Currently, we do this for macOS 11 and above. -+ tm_defines="$tm_defines HEAP_TRAMPOLINES_INIT=1" -+ ;; -+*) -+ tm_defines="$tm_defines STACK_USE_CUMULATIVE_ARGS_INIT=0" -+ tm_defines="$tm_defines HEAP_TRAMPOLINES_INIT=0" -+ ;; -+esac -+ - case ${target} in - aarch64*-*-elf | aarch64*-*-fuchsia* | aarch64*-*-rtems*) - tm_file="${tm_file} elfos.h newlib-stdint.h" -@@ -1164,6 +1184,14 @@ aarch64*-*-elf | aarch64*-*-fuchsia* | aarch64*-*-rtems*) - done - TM_MULTILIB_CONFIG=`echo $TM_MULTILIB_CONFIG | sed 's/^,//'` - ;; -+aarch64-*-darwin* ) -+ tm_file="${tm_file} aarch64/aarch64-errata.h" -+ tmake_file="${tmake_file} aarch64/t-aarch64 aarch64/t-aarch64-darwin" -+ tm_defines="${tm_defines} TARGET_DEFAULT_ASYNC_UNWIND_TABLES=1" -+ tm_defines="${tm_defines} DISABLE_AARCH64_AS_CRC_BUGFIX=1" -+ # Choose a default CPU version that will work for all current releases. -+ with_cpu=${with_cpu:-apple-m1} -+ ;; - aarch64*-*-freebsd*) - tm_file="${tm_file} elfos.h ${fbsd_tm_file}" - tm_file="${tm_file} aarch64/aarch64-elf.h aarch64/aarch64-errata.h aarch64/aarch64-freebsd.h" -@@ -4125,8 +4153,8 @@ case "${target}" in - fi - for which in cpu arch tune; do - eval "val=\$with_$which" -- base_val=`echo $val | sed -e 's/\+.*//'` -- ext_val=`echo $val | sed -e 's/[a-z0-9.-]\+//'` -+ base_val=`echo $val | sed -E -e 's/\+.*//'` -+ ext_val=`echo $val | sed -E -e 's/[a-z0-9.-]+//'` - - if [ $which = arch ]; then - def=aarch64-arches.def -@@ -4158,9 +4186,9 @@ case "${target}" in - - while [ x"$ext_val" != x ] - do -- ext_val=`echo $ext_val | sed -e 's/\+//'` -- ext=`echo $ext_val | sed -e 's/\+.*//'` -- base_ext=`echo $ext | sed -e 's/^no//'` -+ ext_val=`echo $ext_val | sed -E -e 's/\+//'` -+ ext=`echo $ext_val | sed -E -e 's/\+.*//'` -+ base_ext=`echo $ext | sed -E -e 's/^no//'` - opt_line=`echo -e "$options_parsed" | \ - grep "^\"$base_ext\""` - -@@ -4171,7 +4199,7 @@ case "${target}" in - echo "Unknown extension used in --with-$which=$val" 1>&2 - exit 1 - fi -- ext_val=`echo $ext_val | sed -e 's/[a-z0-9]\+//'` -+ ext_val=`echo $ext_val | sed -E -e 's/[a-z0-9]+//'` - done - - true -diff --git a/gcc/config.in b/gcc/config.in -index 5281a12..b70b0be 100644 ---- a/gcc/config.in -+++ b/gcc/config.in -@@ -49,6 +49,19 @@ - #endif - - -+/* Specify a runpath directory, additional to those provided by the compiler -+ */ -+#ifndef USED_FOR_TARGET -+#undef DARWIN_ADD_RPATH -+#endif -+ -+ -+/* Should add an extra runpath directory */ -+#ifndef USED_FOR_TARGET -+#undef DARWIN_DO_EXTRA_RPATH -+#endif -+ -+ - /* Define to enable the use of a default assembler. */ - #ifndef USED_FOR_TARGET - #undef DEFAULT_ASSEMBLER -@@ -634,8 +647,7 @@ - #endif - - --/* Define if your Mac OS X assembler supports -mllvm -x86-pad-for-align=false. -- */ -+/* Define if your macOS assembler supports -mllvm -x86-pad-for-align=false. */ - #ifndef USED_FOR_TARGET - #undef HAVE_AS_MLLVM_X86_PAD_FOR_ALIGN - #endif -@@ -2201,6 +2213,12 @@ - #endif - - -+/* Define to 1 if ld64 supports '-demangle'. */ -+#ifndef USED_FOR_TARGET -+#undef LD64_HAS_DEMANGLE -+#endif -+ -+ - /* Define to 1 if ld64 supports '-export_dynamic'. */ - #ifndef USED_FOR_TARGET - #undef LD64_HAS_EXPORT_DYNAMIC -diff --git a/gcc/configure b/gcc/configure -index ade0af2..4af01a0 100755 ---- a/gcc/configure -+++ b/gcc/configure -@@ -632,10 +632,10 @@ ac_includes_default="\ - ac_subst_vars='LTLIBOBJS - LIBOBJS - CET_HOST_FLAGS --NO_PIE_FLAG --NO_PIE_CFLAGS --enable_default_pie -+LD_PICFLAG - PICFLAG -+enable_default_pie -+enable_host_pie - enable_host_shared - enable_plugin - pluginlibs -@@ -735,11 +735,15 @@ ORIGINAL_NM_FOR_TARGET - gcc_cv_nm - ORIGINAL_LD_GOLD_FOR_TARGET - ORIGINAL_LD_BFD_FOR_TARGET -+ORIGINAL_CLASSIC_LD_FOR_TARGET -+ORIGINAL_LLD_FOR_TARGET - ORIGINAL_LD_FOR_TARGET - ORIGINAL_PLUGIN_LD_FOR_TARGET - gcc_cv_ld - ORIGINAL_AS_FOR_TARGET - gcc_cv_as -+ENABLE_DARWIN_AT_RPATH_FALSE -+ENABLE_DARWIN_AT_RPATH_TRUE - enable_fast_install - objdir - OTOOL64 -@@ -1004,6 +1008,8 @@ enable_static - with_pic - enable_fast_install - enable_libtool_lock -+enable_darwin_at_rpath -+with_darwin_extra_rpath - enable_ld - enable_gold - with_plugin_ld -@@ -1029,6 +1035,7 @@ enable_link_serialization - enable_version_specific_runtime_libs - enable_plugin - enable_host_shared -+enable_host_pie - enable_libquadmath_support - with_linker_hash_style - with_diagnostics_color -@@ -1742,6 +1749,9 @@ Optional Features: - --enable-fast-install[=PKGS] - optimize for fast installation [default=yes] - --disable-libtool-lock avoid locking (might break parallel builds) -+ --enable-darwin-at-rpath -+ install libraries with @rpath/library-name, requires -+ rpaths to be added to executables - --enable-ld[=ARG] build ld [ARG={default,yes,no}] - --enable-gold[=ARG] build gold [ARG={default,yes,no}] - --enable-gnu-indirect-function -@@ -1796,6 +1806,7 @@ Optional Features: - in a compiler-specific directory - --enable-plugin enable plugin support - --enable-host-shared build host code as shared libraries -+ --enable-host-pie build host code as PIE - --disable-libquadmath-support - disable libquadmath support for Fortran - --enable-default-pie enable Position Independent Executable as default -@@ -1860,6 +1871,9 @@ Optional Packages: - --with-pic try to use only PIC/non-PIC objects [default=use - both] - --with-gnu-ld assume the C compiler uses GNU ld [default=no] -+ --with-darwin-extra-rpath=[ARG] -+ Specify a runpath directory, additional to those -+ provided by the compiler - --with-plugin-ld=[ARG] specify the plugin linker - --with-glibc-version=M.N - assume GCC used with glibc version M.N or later -@@ -3759,20 +3773,19 @@ gcc_gxx_libcxx_include_dir= - - # Check whether --with-gxx-libcxx-include-dir was given. - if test "${with_gxx_libcxx_include_dir+set}" = set; then : -- withval=$with_gxx_libcxx_include_dir; case "${withval}" in --yes) as_fn_error $? "bad value ${withval} given for libc++ include directory" "$LINENO" 5 ;; --*) gcc_gxx_libcxx_include_dir=$with_gxx_libcxx_include_dir ;; --esac -+ withval=$with_gxx_libcxx_include_dir; gcc_gxx_libcxx_include_dir=$with_gxx_libcxx_include_dir - fi - - - # --with-gxx-libcxx-include-dir controls the enabling of the -stdlib option. - # if --with-gxx-libcxx-include-dir is 'no' we disable the stdlib option. -+# if --with-gxx-libcxx-include-dir is 'yes' we enable the stdlib option and use -+# the default path within the installation. - # if --with-gxx-libcxx-include-dir is unset we enable the stdlib option --# based on the platform (to be available on platform versions where it is the -+# based on the platform (to be available on platform versions where it is the - # default for the system tools). We also use a default path within the compiler --# install tree. --# Otherwise, we use the path provided and enable the stdlib option. -+# install tree. -+# Otherwise, we use the path provided and enable the stdlib option. - # If both --with-sysroot and --with-gxx-libcxx-include-dir are passed, we - # check to see if the latter starts with the former and, upon success, compute - # gcc_gxx_libcxx_include_dir as relative to the sysroot. -@@ -3780,16 +3793,20 @@ gcc_gxx_libcxx_include_dir_add_sysroot=0 - gcc_enable_stdlib_opt=0 - if test x${gcc_gxx_libcxx_include_dir} != x; then - if test x${gcc_gxx_libcxx_include_dir} = xno; then -- # set defaults for the dir, but the option is disabled anyway. -+ # set defaults for the dir, but the option is disabled anyway. - gcc_gxx_libcxx_include_dir= -+ elif test x${gcc_gxx_libcxx_include_dir} = xyes; then -+ # set defaults for the dir, and enable. -+ gcc_gxx_libcxx_include_dir= -+ gcc_enable_stdlib_opt=1 - else - gcc_enable_stdlib_opt=1 - fi - else - case $target in - *-darwin1[1-9]* | *-darwin2*) -- # Default this on for Darwin versions which default to libcxx, -- # and embed the path in the compiler install so that we get a -+ # Default this on for Darwin versions which default to libcxx, -+ # and embed the path in the compiler install so that we get a - # self-contained toolchain. - gcc_enable_stdlib_opt=1 - ;; -@@ -16341,7 +16358,7 @@ $as_echo "$lt_cv_ld_force_load" >&6; } - # darwin 5.x (macOS 10.1) onwards we only need to adjust when the - # deployment target is forced to an earlier version. - case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host in -- UNSET,*-darwin[89]*|UNSET,*-darwin[12][0123456789]*) -+ UNSET,*-darwin[89]*|UNSET,*-darwin[12][0-9]*) - ;; - 10.[012][,.]*) - _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' -@@ -18046,6 +18063,49 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi - darwin* | rhapsody*) - - -+ -+ # Publish an arg to allow the user to select that Darwin host (and target) -+ # libraries should be given install-names like @rpath/libfoo.dylib. This -+ # requires that the user of the library then adds an 'rpath' to the DSO that -+ # needs access. -+ # NOTE: there are defaults below, for systems that support rpaths. The person -+ # configuring can override the defaults for any system version that supports -+ # them - they are, however, forced off for system versions without support. -+ # Check whether --enable-darwin-at-rpath was given. -+if test "${enable_darwin_at_rpath+set}" = set; then : -+ enableval=$enable_darwin_at_rpath; if test "x$enable_darwin_at_rpath" = "xyes"; then -+ # This is not supported before macOS 10.5 / Darwin9. -+ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in -+ UNSET,darwin[4-8]*|UNSET,rhapsody*|10.[0-4][,.]*) -+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Darwin @rpath library names are incompatible with OSX versions earlier than 10.5 (rpaths disabled)" >&5 -+$as_echo "$as_me: WARNING: Darwin @rpath library names are incompatible with OSX versions earlier than 10.5 (rpaths disabled)" >&2;} -+ enable_darwin_at_rpath=no -+ ;; -+ esac -+ fi -+else -+ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in -+ # As above, before 10.5 / Darwin9 this does not work. -+ UNSET,darwin[4-8]*|UNSET,rhapsody*|10.[0-4][,.]*) -+ enable_darwin_at_rpath=no -+ ;; -+ -+ # We cannot build and test reliably on macOS 10.11+ (Darwin15+) without use -+ # of rpaths, since runpaths set via DYLD_LIBRARY_PATH are elided by key -+ # system executables (e.g. /bin/sh). Force rpaths on for these systems. -+ UNSET,darwin1[5-9]*|UNSET,darwin2*|10.1[1-9][,.]*|1[1-9].*[,.]* ) -+ { $as_echo "$as_me:${as_lineno-$LINENO}: @rpath library names are needed on macOS versions later than 10.11 (rpaths have been enabled)" >&5 -+$as_echo "$as_me: @rpath library names are needed on macOS versions later than 10.11 (rpaths have been enabled)" >&6;} -+ enable_darwin_at_rpath=yes -+ ;; -+ # NOTE: we are not (yet) doing anything for 10.5 .. 10.10, since they can -+ # work with either DYLD_LIBRARY_PATH or embedded rpaths. -+ -+ esac -+ -+fi -+ -+ - archive_cmds_need_lc=no - hardcode_direct=no - hardcode_automatic=yes -@@ -18063,9 +18123,13 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi - esac - if test "$_lt_dar_can_shared" = "yes"; then - output_verbose_link_cmd=func_echo_all -- archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" -+ _lt_install_name='\$rpath/\$soname' -+ if test "x$enable_darwin_at_rpath" = "xyes"; then -+ _lt_install_name='@rpath/\$soname' -+ fi -+ archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name ${_lt_install_name} \$verstring ${_lt_dsymutil}" - module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" -- archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" -+ archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name ${_lt_install_name} \$verstring ${_lt_dar_export_syms}${_lt_dsymutil}" - module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" - - else -@@ -19871,7 +19935,7 @@ else - lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 - lt_status=$lt_dlunknown - cat > conftest.$ac_ext <<_LT_EOF --#line 19874 "configure" -+#line 19938 "configure" - #include "confdefs.h" - - #if HAVE_DLFCN_H -@@ -19977,7 +20041,7 @@ else - lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 - lt_status=$lt_dlunknown - cat > conftest.$ac_ext <<_LT_EOF --#line 19980 "configure" -+#line 20044 "configure" - #include "confdefs.h" - - #if HAVE_DLFCN_H -@@ -20853,6 +20917,49 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi - darwin* | rhapsody*) - - -+ -+ # Publish an arg to allow the user to select that Darwin host (and target) -+ # libraries should be given install-names like @rpath/libfoo.dylib. This -+ # requires that the user of the library then adds an 'rpath' to the DSO that -+ # needs access. -+ # NOTE: there are defaults below, for systems that support rpaths. The person -+ # configuring can override the defaults for any system version that supports -+ # them - they are, however, forced off for system versions without support. -+ # Check whether --enable-darwin-at-rpath was given. -+if test "${enable_darwin_at_rpath+set}" = set; then : -+ enableval=$enable_darwin_at_rpath; if test "x$enable_darwin_at_rpath" = "xyes"; then -+ # This is not supported before macOS 10.5 / Darwin9. -+ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in -+ UNSET,darwin[4-8]*|UNSET,rhapsody*|10.[0-4][,.]*) -+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Darwin @rpath library names are incompatible with OSX versions earlier than 10.5 (rpaths disabled)" >&5 -+$as_echo "$as_me: WARNING: Darwin @rpath library names are incompatible with OSX versions earlier than 10.5 (rpaths disabled)" >&2;} -+ enable_darwin_at_rpath=no -+ ;; -+ esac -+ fi -+else -+ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in -+ # As above, before 10.5 / Darwin9 this does not work. -+ UNSET,darwin[4-8]*|UNSET,rhapsody*|10.[0-4][,.]*) -+ enable_darwin_at_rpath=no -+ ;; -+ -+ # We cannot build and test reliably on macOS 10.11+ (Darwin15+) without use -+ # of rpaths, since runpaths set via DYLD_LIBRARY_PATH are elided by key -+ # system executables (e.g. /bin/sh). Force rpaths on for these systems. -+ UNSET,darwin1[5-9]*|UNSET,darwin2*|10.1[1-9][,.]*|1[1-9].*[,.]* ) -+ { $as_echo "$as_me:${as_lineno-$LINENO}: @rpath library names are needed on macOS versions later than 10.11 (rpaths have been enabled)" >&5 -+$as_echo "$as_me: @rpath library names are needed on macOS versions later than 10.11 (rpaths have been enabled)" >&6;} -+ enable_darwin_at_rpath=yes -+ ;; -+ # NOTE: we are not (yet) doing anything for 10.5 .. 10.10, since they can -+ # work with either DYLD_LIBRARY_PATH or embedded rpaths. -+ -+ esac -+ -+fi -+ -+ - archive_cmds_need_lc_CXX=no - hardcode_direct_CXX=no - hardcode_automatic_CXX=yes -@@ -20870,12 +20977,20 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi - esac - if test "$_lt_dar_can_shared" = "yes"; then - output_verbose_link_cmd=func_echo_all -- archive_cmds_CXX="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" -+ _lt_install_name='\$rpath/\$soname' -+ if test "x$enable_darwin_at_rpath" = "xyes"; then -+ _lt_install_name='@rpath/\$soname' -+ fi -+ archive_cmds_CXX="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name ${_lt_install_name} \$verstring ${_lt_dsymutil}" - module_cmds_CXX="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" -- archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" -+ archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name ${_lt_install_name} \$verstring ${_lt_dar_export_syms}${_lt_dsymutil}" - module_expsym_cmds_CXX="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" - if test "$lt_cv_apple_cc_single_mod" != "yes"; then -- archive_cmds_CXX="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}" -+ _lt_install_name='\$rpath/\$soname' -+ if test "x$enable_darwin_at_rpath" = "xyes"; then -+ _lt_install_name='@rpath/\$soname' -+ fi -+ archive_cmds_CXX="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name ${_lt_install_name} \$verstring${_lt_dsymutil}" - archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}" - fi - -@@ -23246,6 +23361,35 @@ ac_compiler_gnu=$ac_cv_cxx_compiler_gnu - - - -+ if test x$enable_darwin_at_rpath = xyes; then -+ ENABLE_DARWIN_AT_RPATH_TRUE= -+ ENABLE_DARWIN_AT_RPATH_FALSE='#' -+else -+ ENABLE_DARWIN_AT_RPATH_TRUE='#' -+ ENABLE_DARWIN_AT_RPATH_FALSE= -+fi -+ -+DARWIN_DO_EXTRA_RPATH=0 -+ -+# Check whether --with-darwin-extra-rpath was given. -+if test "${with_darwin_extra_rpath+set}" = set; then : -+ withval=$with_darwin_extra_rpath; if test x"$withval" != x; then -+ DARWIN_ADD_RPATH="$withval" -+ DARWIN_DO_EXTRA_RPATH=1 -+ fi -+fi -+ -+ -+cat >>confdefs.h <<_ACEOF -+#define DARWIN_DO_EXTRA_RPATH $DARWIN_DO_EXTRA_RPATH -+_ACEOF -+ -+ -+cat >>confdefs.h <<_ACEOF -+#define DARWIN_ADD_RPATH "$DARWIN_ADD_RPATH" -+_ACEOF -+ -+ - # Identify the assembler which will work hand-in-glove with the newly - # built GCC, so that we can examine its features. This is the assembler - # which will be driven by the driver program. -@@ -23522,6 +23666,14 @@ fi - $as_echo "$gold_non_default" >&6; } - - ORIGINAL_LD_FOR_TARGET=$gcc_cv_ld -+if test x"$ld64_flag" = x"yes"; then -+ORIGINAL_LLD_FOR_TARGET=${gcc_cv_ld}64.lld -+else -+ORIGINAL_LLD_FOR_TARGET=$gcc_cv_lld -+fi -+ORIGINAL_CLASSIC_LD_FOR_TARGET=$gcc_cv_ld-classic -+ -+ - - case "$ORIGINAL_LD_FOR_TARGET" in - ./collect-ld | ./collect-ld$build_exeext) ;; -@@ -30638,6 +30790,7 @@ if test x"$ld64_flag" = x"yes"; then - # Set defaults for possibly untestable items. - gcc_cv_ld64_export_dynamic=0 - gcc_cv_ld64_platform_version=0 -+ gcc_cv_ld64_demangle=0 - - if test "$build" = "$host"; then - darwin_try_test=1 -@@ -30661,6 +30814,9 @@ $as_echo_n "checking ld64 specified version... " >&6; } - gcc_cv_ld64_major=`echo "$gcc_cv_ld64_version" | sed -e 's/\..*//'` - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_ld64_major" >&5 - $as_echo "$gcc_cv_ld64_major" >&6; } -+ if test "$gcc_cv_ld64_major" -ge 97; then -+ gcc_cv_ld64_demangle=1 -+ fi - if test "$gcc_cv_ld64_major" -ge 236; then - gcc_cv_ld64_export_dynamic=1 - fi -@@ -30678,6 +30834,15 @@ $as_echo_n "checking linker version... " >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_ld64_version" >&5 - $as_echo "$gcc_cv_ld64_version" >&6; } - -+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking linker for -demangle support" >&5 -+$as_echo_n "checking linker for -demangle support... " >&6; } -+ gcc_cv_ld64_demangle=1 -+ if $gcc_cv_ld -demangle < /dev/null 2>&1 | grep 'unknown option' > /dev/null; then -+ gcc_cv_ld64_demangle=0 -+ fi -+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_ld64_demangle" >&5 -+$as_echo "$gcc_cv_ld64_demangle" >&6; } -+ - { $as_echo "$as_me:${as_lineno-$LINENO}: checking linker for -export_dynamic support" >&5 - $as_echo_n "checking linker for -export_dynamic support... " >&6; } - gcc_cv_ld64_export_dynamic=1 -@@ -30706,6 +30871,12 @@ _ACEOF - fi - - -+cat >>confdefs.h <<_ACEOF -+#define LD64_HAS_DEMANGLE $gcc_cv_ld64_demangle -+_ACEOF -+ -+ -+ - cat >>confdefs.h <<_ACEOF - #define LD64_HAS_EXPORT_DYNAMIC $gcc_cv_ld64_export_dynamic - _ACEOF -@@ -32251,13 +32422,17 @@ fi - # Enable --enable-host-shared - # Check whether --enable-host-shared was given. - if test "${enable_host_shared+set}" = set; then : -- enableval=$enable_host_shared; PICFLAG=-fPIC --else -- PICFLAG= -+ enableval=$enable_host_shared; - fi - - - -+# Enable --enable-host-pie -+# Check whether --enable-host-pie was given. -+if test "${enable_host_pie+set}" = set; then : -+ enableval=$enable_host_pie; -+fi -+ - - - # Check whether --enable-libquadmath-support was given. -@@ -32411,10 +32586,6 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - fi - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_c_no_fpie" >&5 - $as_echo "$gcc_cv_c_no_fpie" >&6; } --if test "$gcc_cv_c_no_fpie" = "yes"; then -- NO_PIE_CFLAGS="-fno-PIE" --fi -- - - # Check if -no-pie works. - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -no-pie option" >&5 -@@ -32439,11 +32610,28 @@ rm -f core conftest.err conftest.$ac_objext \ - fi - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_no_pie" >&5 - $as_echo "$gcc_cv_no_pie" >&6; } --if test "$gcc_cv_no_pie" = "yes"; then -- NO_PIE_FLAG="-no-pie" -+ -+if test x$enable_host_shared = xyes; then -+ PICFLAG=-fPIC -+elif test x$enable_host_pie = xyes; then -+ PICFLAG=-fPIE -+elif test x$gcc_cv_c_no_fpie = xyes; then -+ PICFLAG=-fno-PIE -+else -+ PICFLAG= -+fi -+ -+if test x$enable_host_pie = xyes; then -+ LD_PICFLAG=-pie -+elif test x$gcc_cv_no_pie = xyes; then -+ LD_PICFLAG=-no-pie -+else -+ LD_PICFLAG= - fi - - -+ -+ - # Enable Intel CET on Intel CET enabled host if jit is enabled. - # Check whether --enable-cet was given. - if test "${enable_cet+set}" = set; then : -@@ -32926,6 +33114,10 @@ LTLIBOBJS=$ac_ltlibobjs - - - -+if test -z "${ENABLE_DARWIN_AT_RPATH_TRUE}" && test -z "${ENABLE_DARWIN_AT_RPATH_FALSE}"; then -+ as_fn_error $? "conditional \"ENABLE_DARWIN_AT_RPATH\" was never defined. -+Usually this means the macro was only invoked conditionally." "$LINENO" 5 -+fi - - : "${CONFIG_STATUS=./config.status}" - ac_write_fail=0 -diff --git a/gcc/configure.ac b/gcc/configure.ac -index bf8ff4d..8c2ff47 100644 ---- a/gcc/configure.ac -+++ b/gcc/configure.ac -@@ -235,18 +235,17 @@ gcc_gxx_libcxx_include_dir= - AC_ARG_WITH(gxx-libcxx-include-dir, - [AS_HELP_STRING([--with-gxx-libcxx-include-dir=DIR], - [specifies directory to find libc++ header files])], --[case "${withval}" in --yes) AC_MSG_ERROR(bad value ${withval} given for libc++ include directory) ;; --*) gcc_gxx_libcxx_include_dir=$with_gxx_libcxx_include_dir ;; --esac]) -+[gcc_gxx_libcxx_include_dir=$with_gxx_libcxx_include_dir]) - - # --with-gxx-libcxx-include-dir controls the enabling of the -stdlib option. - # if --with-gxx-libcxx-include-dir is 'no' we disable the stdlib option. -+# if --with-gxx-libcxx-include-dir is 'yes' we enable the stdlib option and use -+# the default path within the installation. - # if --with-gxx-libcxx-include-dir is unset we enable the stdlib option --# based on the platform (to be available on platform versions where it is the -+# based on the platform (to be available on platform versions where it is the - # default for the system tools). We also use a default path within the compiler --# install tree. --# Otherwise, we use the path provided and enable the stdlib option. -+# install tree. -+# Otherwise, we use the path provided and enable the stdlib option. - # If both --with-sysroot and --with-gxx-libcxx-include-dir are passed, we - # check to see if the latter starts with the former and, upon success, compute - # gcc_gxx_libcxx_include_dir as relative to the sysroot. -@@ -254,16 +253,20 @@ gcc_gxx_libcxx_include_dir_add_sysroot=0 - gcc_enable_stdlib_opt=0 - if test x${gcc_gxx_libcxx_include_dir} != x; then - if test x${gcc_gxx_libcxx_include_dir} = xno; then -- # set defaults for the dir, but the option is disabled anyway. -+ # set defaults for the dir, but the option is disabled anyway. -+ gcc_gxx_libcxx_include_dir= -+ elif test x${gcc_gxx_libcxx_include_dir} = xyes; then -+ # set defaults for the dir, and enable. - gcc_gxx_libcxx_include_dir= -+ gcc_enable_stdlib_opt=1 - else - gcc_enable_stdlib_opt=1 - fi - else - case $target in - *-darwin1[[1-9]]* | *-darwin2*) -- # Default this on for Darwin versions which default to libcxx, -- # and embed the path in the compiler install so that we get a -+ # Default this on for Darwin versions which default to libcxx, -+ # and embed the path in the compiler install so that we get a - # self-contained toolchain. - gcc_enable_stdlib_opt=1 - ;; -@@ -2625,6 +2628,21 @@ AC_PROG_LIBTOOL - AC_SUBST(objdir) - AC_SUBST(enable_fast_install) - -+AM_CONDITIONAL([ENABLE_DARWIN_AT_RPATH], [test x$enable_darwin_at_rpath = xyes]) -+DARWIN_DO_EXTRA_RPATH=0 -+AC_ARG_WITH(darwin-extra-rpath, -+[AS_HELP_STRING( -+ [[--with-darwin-extra-rpath=[ARG]]], -+ [Specify a runpath directory, additional to those provided by the compiler])], -+[if test x"$withval" != x; then -+ DARWIN_ADD_RPATH="$withval" -+ DARWIN_DO_EXTRA_RPATH=1 -+ fi]) -+AC_DEFINE_UNQUOTED(DARWIN_DO_EXTRA_RPATH, $DARWIN_DO_EXTRA_RPATH, -+ [Should add an extra runpath directory]) -+AC_DEFINE_UNQUOTED(DARWIN_ADD_RPATH, "$DARWIN_ADD_RPATH", -+ [Specify a runpath directory, additional to those provided by the compiler]) -+ - # Identify the assembler which will work hand-in-glove with the newly - # built GCC, so that we can examine its features. This is the assembler - # which will be driven by the driver program. -@@ -2797,7 +2815,15 @@ fi - AC_MSG_RESULT($gold_non_default) - - ORIGINAL_LD_FOR_TARGET=$gcc_cv_ld -+if test x"$ld64_flag" = x"yes"; then -+ORIGINAL_LLD_FOR_TARGET=${gcc_cv_ld}64.lld -+else -+ORIGINAL_LLD_FOR_TARGET=$gcc_cv_lld -+fi -+ORIGINAL_CLASSIC_LD_FOR_TARGET=$gcc_cv_ld-classic - AC_SUBST(ORIGINAL_LD_FOR_TARGET) -+AC_SUBST(ORIGINAL_LLD_FOR_TARGET) -+AC_SUBST(ORIGINAL_CLASSIC_LD_FOR_TARGET) - case "$ORIGINAL_LD_FOR_TARGET" in - ./collect-ld | ./collect-ld$build_exeext) ;; - *) AC_CONFIG_FILES(collect-ld:exec-tool.in, [chmod +x collect-ld]) ;; -@@ -4793,7 +4819,7 @@ foo: nop - gcc_cv_as_mllvm_x86_pad_for_align, - [-mllvm -x86-pad-for-align=false], [.text],, - [AC_DEFINE(HAVE_AS_MLLVM_X86_PAD_FOR_ALIGN, 1, -- [Define if your Mac OS X assembler supports -mllvm -x86-pad-for-align=false.])]) -+ [Define if your macOS assembler supports -mllvm -x86-pad-for-align=false.])]) - ;; - esac - -@@ -6273,6 +6299,7 @@ if test x"$ld64_flag" = x"yes"; then - # Set defaults for possibly untestable items. - gcc_cv_ld64_export_dynamic=0 - gcc_cv_ld64_platform_version=0 -+ gcc_cv_ld64_demangle=0 - - if test "$build" = "$host"; then - darwin_try_test=1 -@@ -6294,6 +6321,9 @@ if test x"$ld64_flag" = x"yes"; then - AC_MSG_CHECKING(ld64 specified version) - gcc_cv_ld64_major=`echo "$gcc_cv_ld64_version" | sed -e 's/\..*//'` - AC_MSG_RESULT($gcc_cv_ld64_major) -+ if test "$gcc_cv_ld64_major" -ge 97; then -+ gcc_cv_ld64_demangle=1 -+ fi - if test "$gcc_cv_ld64_major" -ge 236; then - gcc_cv_ld64_export_dynamic=1 - fi -@@ -6309,6 +6339,13 @@ if test x"$ld64_flag" = x"yes"; then - fi - AC_MSG_RESULT($gcc_cv_ld64_version) - -+ AC_MSG_CHECKING(linker for -demangle support) -+ gcc_cv_ld64_demangle=1 -+ if $gcc_cv_ld -demangle < /dev/null 2>&1 | grep 'unknown option' > /dev/null; then -+ gcc_cv_ld64_demangle=0 -+ fi -+ AC_MSG_RESULT($gcc_cv_ld64_demangle) -+ - AC_MSG_CHECKING(linker for -export_dynamic support) - gcc_cv_ld64_export_dynamic=1 - if $gcc_cv_ld -export_dynamic < /dev/null 2>&1 | grep 'unknown option' > /dev/null; then -@@ -6329,6 +6366,9 @@ if test x"$ld64_flag" = x"yes"; then - [Define to ld64 version.]) - fi - -+ AC_DEFINE_UNQUOTED(LD64_HAS_DEMANGLE, $gcc_cv_ld64_demangle, -+ [Define to 1 if ld64 supports '-demangle'.]) -+ - AC_DEFINE_UNQUOTED(LD64_HAS_EXPORT_DYNAMIC, $gcc_cv_ld64_export_dynamic, - [Define to 1 if ld64 supports '-export_dynamic'.]) - -@@ -7479,11 +7519,14 @@ fi - # Enable --enable-host-shared - AC_ARG_ENABLE(host-shared, - [AS_HELP_STRING([--enable-host-shared], -- [build host code as shared libraries])], --[PICFLAG=-fPIC], [PICFLAG=]) -+ [build host code as shared libraries])]) - AC_SUBST(enable_host_shared) --AC_SUBST(PICFLAG) - -+# Enable --enable-host-pie -+AC_ARG_ENABLE(host-pie, -+[AS_HELP_STRING([--enable-host-pie], -+ [build host code as PIE])]) -+AC_SUBST(enable_host_pie) - - AC_ARG_ENABLE(libquadmath-support, - [AS_HELP_STRING([--disable-libquadmath-support], -@@ -7605,10 +7648,6 @@ AC_CACHE_CHECK([for -fno-PIE option], - [gcc_cv_c_no_fpie=yes], - [gcc_cv_c_no_fpie=no]) - CXXFLAGS="$saved_CXXFLAGS"]) --if test "$gcc_cv_c_no_fpie" = "yes"; then -- NO_PIE_CFLAGS="-fno-PIE" --fi --AC_SUBST([NO_PIE_CFLAGS]) - - # Check if -no-pie works. - AC_CACHE_CHECK([for -no-pie option], -@@ -7619,10 +7658,27 @@ AC_CACHE_CHECK([for -no-pie option], - [gcc_cv_no_pie=yes], - [gcc_cv_no_pie=no]) - LDFLAGS="$saved_LDFLAGS"]) --if test "$gcc_cv_no_pie" = "yes"; then -- NO_PIE_FLAG="-no-pie" -+ -+if test x$enable_host_shared = xyes; then -+ PICFLAG=-fPIC -+elif test x$enable_host_pie = xyes; then -+ PICFLAG=-fPIE -+elif test x$gcc_cv_c_no_fpie = xyes; then -+ PICFLAG=-fno-PIE -+else -+ PICFLAG= - fi --AC_SUBST([NO_PIE_FLAG]) -+ -+if test x$enable_host_pie = xyes; then -+ LD_PICFLAG=-pie -+elif test x$gcc_cv_no_pie = xyes; then -+ LD_PICFLAG=-no-pie -+else -+ LD_PICFLAG= -+fi -+ -+AC_SUBST([PICFLAG]) -+AC_SUBST([LD_PICFLAG]) - - # Enable Intel CET on Intel CET enabled host if jit is enabled. - GCC_CET_HOST_FLAGS(CET_HOST_FLAGS) -diff --git a/gcc/coretypes.h b/gcc/coretypes.h -index ca8837c..7e022a4 100644 ---- a/gcc/coretypes.h -+++ b/gcc/coretypes.h -@@ -199,6 +199,12 @@ enum tls_model { - TLS_MODEL_LOCAL_EXEC - }; - -+/* Types of trampoline implementation. */ -+enum trampoline_impl { -+ TRAMPOLINE_IMPL_STACK, -+ TRAMPOLINE_IMPL_HEAP -+}; -+ - /* Types of ABI for an offload compiler. */ - enum offload_abi { - OFFLOAD_ABI_UNSET, -diff --git a/gcc/cp/cp-lang.cc b/gcc/cp/cp-lang.cc -index 2f54146..84200a9 100644 ---- a/gcc/cp/cp-lang.cc -+++ b/gcc/cp/cp-lang.cc -@@ -121,6 +121,15 @@ objcp_tsubst_copy_and_build (tree /*t*/, - return NULL_TREE; - } - -+/* Implement c-family hook to add language-specific features -+ for __has_{feature,extension}. */ -+ -+void -+c_family_register_lang_features () -+{ -+ cp_register_features (); -+} -+ - static const char * - cxx_dwarf_name (tree t, int verbosity) - { -diff --git a/gcc/cp/cp-objcp-common.cc b/gcc/cp/cp-objcp-common.cc -index 93b027b..10b9b35 100644 ---- a/gcc/cp/cp-objcp-common.cc -+++ b/gcc/cp/cp-objcp-common.cc -@@ -23,10 +23,153 @@ along with GCC; see the file COPYING3. If not see - #include "coretypes.h" - #include "cp-tree.h" - #include "cp-objcp-common.h" -+#include "c-family/c-common.h" - #include "dwarf2.h" - #include "stringpool.h" - #include "contracts.h" - -+/* Class to determine whether a given C++ language feature is available. -+ Used to implement __has_{feature,extension}. */ -+ -+struct cp_feature_selector -+{ -+ enum -+ { -+ DIALECT, -+ FLAG -+ } kind; -+ -+ enum class result -+ { -+ NONE, -+ EXT, -+ FEAT -+ }; -+ -+ union -+ { -+ const int *enable_flag; -+ struct { -+ enum cxx_dialect feat; -+ enum cxx_dialect ext; -+ } dialect; -+ }; -+ -+ constexpr cp_feature_selector (const int *flag) -+ : kind (FLAG), enable_flag (flag) {} -+ constexpr cp_feature_selector (enum cxx_dialect feat, -+ enum cxx_dialect ext) -+ : kind (DIALECT), dialect{feat, ext} {} -+ constexpr cp_feature_selector (enum cxx_dialect feat) -+ : cp_feature_selector (feat, feat) {} -+ -+ inline result has_feature () const; -+}; -+ -+/* Check whether this language feature is available as a feature, -+ extension, or not at all. */ -+ -+cp_feature_selector::result -+cp_feature_selector::has_feature () const -+{ -+ switch (kind) -+ { -+ case DIALECT: -+ if (cxx_dialect >= dialect.feat) -+ return result::FEAT; -+ else if (cxx_dialect >= dialect.ext) -+ return result::EXT; -+ else -+ return result::NONE; -+ case FLAG: -+ return *enable_flag ? result::FEAT : result::NONE; -+ } -+ -+ gcc_unreachable (); -+} -+ -+/* Information about a C++ language feature which can be queried -+ through __has_{feature,extension}. IDENT is the name of the feature, -+ and SELECTOR encodes how to compute whether the feature is available. */ -+ -+struct cp_feature_info -+{ -+ const char *ident; -+ cp_feature_selector selector; -+}; -+ -+/* Table of features for __has_{feature,extension}. */ -+ -+static constexpr cp_feature_info cp_feature_table[] = -+{ -+ { "cxx_exceptions", &flag_exceptions }, -+ { "cxx_rtti", &flag_rtti }, -+ { "cxx_access_control_sfinae", { cxx11, cxx98 } }, -+ { "cxx_alias_templates", cxx11 }, -+ { "cxx_alignas", cxx11 }, -+ { "cxx_alignof", cxx11 }, -+ { "cxx_attributes", cxx11 }, -+ { "cxx_constexpr", cxx11 }, -+ { "cxx_decltype", cxx11 }, -+ { "cxx_decltype_incomplete_return_types", cxx11 }, -+ { "cxx_default_function_template_args", cxx11 }, -+ { "cxx_defaulted_functions", cxx11 }, -+ { "cxx_delegating_constructors", cxx11 }, -+ { "cxx_deleted_functions", cxx11 }, -+ { "cxx_explicit_conversions", cxx11 }, -+ { "cxx_generalized_initializers", cxx11 }, -+ { "cxx_implicit_moves", cxx11 }, -+ { "cxx_inheriting_constructors", cxx11 }, -+ { "cxx_inline_namespaces", { cxx11, cxx98 } }, -+ { "cxx_lambdas", cxx11 }, -+ { "cxx_local_type_template_args", cxx11 }, -+ { "cxx_noexcept", cxx11 }, -+ { "cxx_nonstatic_member_init", cxx11 }, -+ { "cxx_nullptr", cxx11 }, -+ { "cxx_override_control", cxx11 }, -+ { "cxx_reference_qualified_functions", cxx11 }, -+ { "cxx_range_for", cxx11 }, -+ { "cxx_raw_string_literals", cxx11 }, -+ { "cxx_rvalue_references", cxx11 }, -+ { "cxx_static_assert", cxx11 }, -+ { "cxx_thread_local", cxx11 }, -+ { "cxx_auto_type", cxx11 }, -+ { "cxx_strong_enums", cxx11 }, -+ { "cxx_trailing_return", cxx11 }, -+ { "cxx_unicode_literals", cxx11 }, -+ { "cxx_unrestricted_unions", cxx11 }, -+ { "cxx_user_literals", cxx11 }, -+ { "cxx_variadic_templates", { cxx11, cxx98 } }, -+ { "cxx_binary_literals", { cxx14, cxx98 } }, -+ { "cxx_contextual_conversions", { cxx14, cxx98 } }, -+ { "cxx_decltype_auto", cxx14 }, -+ { "cxx_aggregate_nsdmi", cxx14 }, -+ { "cxx_init_captures", { cxx14, cxx11 } }, -+ { "cxx_generic_lambdas", cxx14 }, -+ { "cxx_relaxed_constexpr", cxx14 }, -+ { "cxx_return_type_deduction", cxx14 }, -+ { "cxx_variable_templates", cxx14 }, -+ { "modules", &flag_modules }, -+}; -+ -+/* Register C++ language features for __has_{feature,extension}. */ -+ -+void -+cp_register_features () -+{ -+ using result = cp_feature_selector::result; -+ -+ for (unsigned i = 0; i < ARRAY_SIZE (cp_feature_table); i++) -+ { -+ const cp_feature_info *info = cp_feature_table + i; -+ const auto res = info->selector.has_feature (); -+ if (res == result::NONE) -+ continue; -+ -+ c_common_register_feature (info->ident, res == result::FEAT); -+ } -+} -+ - /* Special routine to get the alias set for C++. */ - - alias_set_type -diff --git a/gcc/cp/cp-objcp-common.h b/gcc/cp/cp-objcp-common.h -index 80893aa..9d4d873 100644 ---- a/gcc/cp/cp-objcp-common.h -+++ b/gcc/cp/cp-objcp-common.h -@@ -34,6 +34,7 @@ extern tree cp_classtype_as_base (const_tree); - extern tree cp_get_global_decls (); - extern tree cp_pushdecl (tree); - extern void cp_register_dumps (gcc::dump_manager *); -+extern void cp_register_features (); - extern bool cp_handle_option (size_t, const char *, HOST_WIDE_INT, int, - location_t, const struct cl_option_handlers *); - extern tree cxx_make_type_hook (tree_code); -diff --git a/gcc/cp/decl2.cc b/gcc/cp/decl2.cc -index 36e1f2c..213e52c 100644 ---- a/gcc/cp/decl2.cc -+++ b/gcc/cp/decl2.cc -@@ -3712,9 +3712,8 @@ get_tls_init_fn (tree var) - if (!flag_extern_tls_init && DECL_EXTERNAL (var)) - return NULL_TREE; - -- /* If the variable is internal, or if we can't generate aliases, -- call the local init function directly. */ -- if (!TREE_PUBLIC (var) || !TARGET_SUPPORTS_ALIASES) -+ /* If the variable is internal call the local init function directly. */ -+ if (!TREE_PUBLIC (var)) - return get_local_tls_init_fn (DECL_SOURCE_LOCATION (var)); - - tree sname = mangle_tls_init_fn (var); -@@ -3877,6 +3876,25 @@ generate_tls_wrapper (tree fn) - expand_or_defer_fn (finish_function (/*inline_p=*/false)); - } - -+/* A dummy init function to act as a weak placeholder for a (possibly non- -+ existent) dynamic init. */ -+static void -+generate_tls_dummy_init (tree fn) -+{ -+ tree var = DECL_BEFRIENDING_CLASSES (fn); -+ tree init_fn = get_tls_init_fn (var); -+ /* If have no init fn, or it is non-weak, then we do not need to make a -+ dummy. */ -+ if (!init_fn || !lookup_attribute ("weak", DECL_ATTRIBUTES (init_fn))) -+ return; -+ start_preparsed_function (init_fn, NULL_TREE, SF_DEFAULT | SF_PRE_PARSED); -+ tree body = begin_function_body (); -+ declare_weak (init_fn); -+ finish_return_stmt (NULL_TREE); -+ finish_function_body (body); -+ expand_or_defer_fn (finish_function (/*inline_p=*/false)); -+} -+ - /* Start a global constructor or destructor function. */ - - static tree -@@ -4666,22 +4684,24 @@ handle_tls_init (void) - finish_expr_stmt (cp_build_modify_expr (loc, guard, NOP_EXPR, - boolean_true_node, - tf_warning_or_error)); -+ auto_vec direct_calls; - for (; vars; vars = TREE_CHAIN (vars)) - { - tree var = TREE_VALUE (vars); - tree init = TREE_PURPOSE (vars); - one_static_initialization_or_destruction (/*initp=*/true, var, init); - -- /* Output init aliases even with -fno-extern-tls-init. */ -- if (TARGET_SUPPORTS_ALIASES && TREE_PUBLIC (var)) -+ /* Output inits even with -fno-extern-tls-init. -+ We save the list here and output either an alias or a stub function -+ below. */ -+ if (TREE_PUBLIC (var)) - { -- tree single_init_fn = get_tls_init_fn (var); -+ tree single_init_fn = get_tls_init_fn (var); - if (single_init_fn == NULL_TREE) - continue; -- cgraph_node *alias -- = cgraph_node::get_create (fn)->create_same_body_alias -- (single_init_fn, fn); -- gcc_assert (alias != NULL); -+ if (single_init_fn == fn) -+ continue; -+ direct_calls.safe_push (single_init_fn); - } - } - -@@ -4689,6 +4709,30 @@ handle_tls_init (void) - finish_if_stmt (if_stmt); - finish_function_body (body); - expand_or_defer_fn (finish_function (/*inline_p=*/false)); -+ -+ /* For each TLS var that we have an init function, we either emit an alias -+ between that and the tls_init, or a stub function that just calls the -+ tls_init. */ -+ while (!direct_calls.is_empty()) -+ { -+ tree single_init_fn = direct_calls.pop (); -+ if (TARGET_SUPPORTS_ALIASES) -+ { -+ cgraph_node *alias -+ = cgraph_node::get_create (fn)->create_same_body_alias -+ (single_init_fn, fn); -+ gcc_assert (alias != NULL); -+ } -+ else -+ { -+ start_preparsed_function (single_init_fn, NULL_TREE, SF_PRE_PARSED); -+ tree body = begin_function_body (); -+ tree r = build_call_expr (fn, 0); -+ finish_expr_stmt (r); -+ finish_function_body (body); -+ expand_or_defer_fn (finish_function (/*inline_p=*/false)); -+ } -+ } - } - - /* We're at the end of compilation, so generate any mangling aliases that -@@ -5107,7 +5151,14 @@ c_parse_final_cleanups (void) - } - - if (!DECL_INITIAL (decl) && decl_tls_wrapper_p (decl)) -- generate_tls_wrapper (decl); -+ { -+ generate_tls_wrapper (decl); -+ /* The wrapper might have a weak reference to an init, we provide -+ a dummy function to satisfy that here. The linker/dynamic -+ loader will override this with the actual init, if one is -+ required. */ -+ generate_tls_dummy_init (decl); -+ } - - if (!DECL_SAVED_TREE (decl)) - continue; -diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc -index 4e67da6..1f1b762 100644 ---- a/gcc/cp/parser.cc -+++ b/gcc/cp/parser.cc -@@ -694,6 +694,91 @@ cp_lexer_handle_early_pragma (cp_lexer *lexer) - static cp_parser *cp_parser_new (cp_lexer *); - static GTY (()) cp_parser *the_parser; - -+/* Context-sensitive parse-checking for clang-style attributes. */ -+ -+enum clang_attr_state { -+ CA_NONE = 0, -+ CA_ATTR, -+ CA_BR1, CA_BR2, -+ CA_LIST, -+ CA_LIST_ARGS, -+ CA_IS_CA, -+ CA_CA_ARGS, -+ CA_LIST_CONT -+}; -+ -+/* State machine tracking context of attribute lexing. */ -+ -+static enum clang_attr_state -+cp_lexer_attribute_state (cp_token& token, enum clang_attr_state attr_state) -+{ -+ /* Implement a context-sensitive parser for clang attributes. -+ We detect __attribute__((clang_style_attribute (ARGS))) and lex the -+ args ARGS with the following differences from GNU attributes: -+ (a) number-like values are lexed as strings [this allows lexing XX.YY.ZZ -+ version numbers]. -+ (b) we concatenate strings, since clang attributes allow this too. */ -+ switch (attr_state) -+ { -+ case CA_NONE: -+ if (token.type == CPP_KEYWORD -+ && token.keyword == RID_ATTRIBUTE) -+ attr_state = CA_ATTR; -+ break; -+ case CA_ATTR: -+ if (token.type == CPP_OPEN_PAREN) -+ attr_state = CA_BR1; -+ else -+ attr_state = CA_NONE; -+ break; -+ case CA_BR1: -+ if (token.type == CPP_OPEN_PAREN) -+ attr_state = CA_BR2; -+ else -+ attr_state = CA_NONE; -+ break; -+ case CA_BR2: -+ if (token.type == CPP_NAME) -+ { -+ tree identifier = (token.type == CPP_KEYWORD) -+ /* For keywords, use the canonical spelling, not the -+ parsed identifier. */ -+ ? ridpointers[(int) token.keyword] -+ : token.u.value; -+ identifier = canonicalize_attr_name (identifier); -+ if (attribute_clang_form_p (identifier)) -+ attr_state = CA_IS_CA; -+ else -+ attr_state = CA_LIST; -+ } -+ else -+ attr_state = CA_NONE; -+ break; -+ case CA_IS_CA: -+ case CA_LIST: -+ if (token.type == CPP_COMMA) -+ attr_state = CA_BR2; /* Back to the list outer. */ -+ else if (token.type == CPP_OPEN_PAREN) -+ attr_state = attr_state == CA_IS_CA ? CA_CA_ARGS -+ : CA_LIST_ARGS; -+ else -+ attr_state = CA_NONE; -+ break; -+ case CA_CA_ARGS: /* We will special-case args in this state. */ -+ case CA_LIST_ARGS: -+ if (token.type == CPP_CLOSE_PAREN) -+ attr_state = CA_LIST_CONT; -+ break; -+ case CA_LIST_CONT: -+ if (token.type == CPP_COMMA) -+ attr_state = CA_BR2; /* Back to the list outer. */ -+ else -+ attr_state = CA_NONE; -+ break; -+ } -+ return attr_state; -+} -+ - /* Create a new main C++ lexer, the lexer that gets tokens from the - preprocessor, and also create the main parser. */ - -@@ -710,6 +795,8 @@ cp_lexer_new_main (void) - c_common_no_more_pch (); - - cp_lexer *lexer = cp_lexer_alloc (); -+ enum clang_attr_state attr_state = CA_NONE; -+ - /* Put the first token in the buffer. */ - cp_token *tok = lexer->buffer->quick_push (token); - -@@ -733,8 +820,14 @@ cp_lexer_new_main (void) - if (tok->type == CPP_PRAGMA_EOL) - cp_lexer_handle_early_pragma (lexer); - -+ attr_state = cp_lexer_attribute_state (*tok, attr_state); - tok = vec_safe_push (lexer->buffer, cp_token ()); -- cp_lexer_get_preprocessor_token (C_LEX_STRING_NO_JOIN, tok); -+ unsigned int flags = C_LEX_STRING_NO_JOIN; -+ /* If we are processing clang-style attribute args, lex numbers as -+ potential version strings; NN .. NN.MM .. NN.MM.OO */ -+ if (attr_state == CA_CA_ARGS) -+ flags |= C_LEX_NUMBER_AS_STRING; -+ cp_lexer_get_preprocessor_token (flags, tok); - } - - lexer->next_token = lexer->buffer->address (); -@@ -936,7 +1029,7 @@ cp_lexer_get_preprocessor_token (unsigned flags, cp_token *token) - { - static int is_extern_c = 0; - -- /* Get a new token from the preprocessor. */ -+ /* Get a new token from the preprocessor. */ - token->type - = c_lex_with_flags (&token->u.value, &token->location, &token->flags, - flags); -@@ -20992,11 +21085,13 @@ cp_parser_enum_specifier (cp_parser* parser) - - /* Check for the `:' that denotes a specified underlying type in C++0x. - Note that a ':' could also indicate a bitfield width, however. */ -+ location_t colon_loc = UNKNOWN_LOCATION; - if (cp_lexer_next_token_is (parser->lexer, CPP_COLON)) - { - cp_decl_specifier_seq type_specifiers; - - /* Consume the `:'. */ -+ colon_loc = cp_lexer_peek_token (parser->lexer)->location; - cp_lexer_consume_token (parser->lexer); - - auto tdf -@@ -21045,10 +21140,13 @@ cp_parser_enum_specifier (cp_parser* parser) - && cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON)) - { - if (has_underlying_type) -- cp_parser_commit_to_tentative_parse (parser); -- cp_parser_error (parser, "expected %<;%> or %<{%>"); -- if (has_underlying_type) -- return error_mark_node; -+ pedwarn (colon_loc, -+ OPT_Welaborated_enum_base, -+ "declaration of enumeration with " -+ "fixed underlying type and no enumerator list is " -+ "only permitted as a standalone declaration"); -+ else -+ cp_parser_error (parser, "expected %<;%> or %<{%>"); - } - } - -@@ -29051,6 +29149,91 @@ cp_parser_gnu_attributes_opt (cp_parser* parser) - return attributes; - } - -+/* Parse the arguments list for a clang attribute. */ -+static tree -+cp_parser_clang_attribute (cp_parser *parser, tree/*attr_id*/) -+{ -+ /* Each entry can be : -+ identifier -+ identifier=N.MM.Z -+ identifier="string" -+ followed by ',' or ) for the last entry*/ -+ -+ matching_parens parens; -+ if (!parens.require_open (parser)) -+ return NULL; -+ -+ bool save_translate_strings_p = parser->translate_strings_p; -+ parser->translate_strings_p = false; -+ tree attr_args = NULL_TREE; -+ cp_token *token; -+ do -+ { -+ tree name = NULL_TREE; -+ tree value = NULL_TREE; -+ -+ token = cp_lexer_peek_token (parser->lexer); -+ if (token->type == CPP_NAME) -+ name = token->u.value; -+ else if (token->type == CPP_KEYWORD) -+ name = ridpointers[(int) token->keyword]; -+ else if (token->flags & NAMED_OP) -+ name = get_identifier (cpp_type2name (token->type, token->flags)); -+ else -+ { -+ /* FIXME: context-sensitive for that attrib. */ -+ error_at (token->location, "expected an attribute keyword"); -+ cp_parser_skip_to_closing_parenthesis (parser, -+ /*recovering=*/true, -+ /*or_comma=*/false, -+ /*consume_paren=*/false); -+ attr_args = error_mark_node; -+ break; -+ } -+ cp_lexer_consume_token (parser->lexer); -+ -+ if (cp_lexer_next_token_is (parser->lexer, CPP_EQ)) -+ { -+ cp_lexer_consume_token (parser->lexer); /* eat the '=' */ -+ if (cp_lexer_next_token_is_not (parser->lexer, CPP_CLOSE_PAREN) -+ && cp_lexer_next_token_is_not (parser->lexer, CPP_COMMA)) -+ { -+ token = cp_lexer_peek_token (parser->lexer); -+ if (token->type == CPP_STRING) -+ value = cp_parser_string_literal (parser, /*translate=*/false, -+ /*wide_ok=*/false); -+ else -+ { -+ value = token->u.value; -+ cp_lexer_consume_token (parser->lexer); -+ } -+ } -+ /* else value is missing. */ -+ } -+ else if (cp_lexer_next_token_is_not (parser->lexer, CPP_CLOSE_PAREN) -+ && cp_lexer_next_token_is_not (parser->lexer, CPP_COMMA)) -+ { -+ error_at (token->location, "expected %<,%>, %<=%> or %<)%>"); -+ cp_parser_skip_to_closing_parenthesis (parser, -+ /*recovering=*/true, -+ /*or_comma=*/false, -+ /*consume_paren=*/false); -+ attr_args = error_mark_node; -+ break; -+ } -+ if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA)) -+ cp_lexer_consume_token (parser->lexer); -+ tree t = tree_cons (value, name, NULL_TREE); -+ attr_args = chainon (attr_args, t); -+ } while (cp_lexer_next_token_is_not (parser->lexer, CPP_CLOSE_PAREN)); -+ -+ parser->translate_strings_p = save_translate_strings_p; -+ if (!parens.require_close (parser)) -+ return error_mark_node; -+ -+ return attr_args; -+} -+ - /* Parse a GNU attribute-list. - - attribute-list: -@@ -29110,9 +29293,12 @@ cp_parser_gnu_attribute_list (cp_parser* parser, bool exactly_one /* = false */) - - /* Peek at the next token. */ - token = cp_lexer_peek_token (parser->lexer); -- /* If it's an `(', then parse the attribute arguments. */ -- if (token->type == CPP_OPEN_PAREN) -+ if (token->type == CPP_OPEN_PAREN -+ && attribute_clang_form_p (identifier)) -+ arguments = cp_parser_clang_attribute (parser, identifier); -+ else if (token->type == CPP_OPEN_PAREN) - { -+ /* If it's an `(', then parse the attribute arguments. */ - vec *vec; - int attr_flag = (attribute_takes_identifier_p (identifier) - ? id_attr : normal_attr); -@@ -29129,12 +29315,12 @@ cp_parser_gnu_attribute_list (cp_parser* parser, bool exactly_one /* = false */) - arguments = build_tree_list_vec (vec); - release_tree_vector (vec); - } -- /* Save the arguments away. */ -- TREE_VALUE (attribute) = arguments; - } - - if (arguments != error_mark_node) - { -+ /* Save the arguments away. */ -+ TREE_VALUE (attribute) = arguments; - /* Add this attribute to the list. */ - TREE_CHAIN (attribute) = attribute_list; - attribute_list = attribute; -diff --git b/gcc/cumulative-args.h b/gcc/cumulative-args.h -new file mode 100644 -index 0000000..b60928e ---- /dev/null -+++ b/gcc/cumulative-args.h -@@ -0,0 +1,20 @@ -+#ifndef GCC_CUMULATIVE_ARGS_H -+#define GCC_CUMULATIVE_ARGS_H -+ -+#if CHECKING_P -+ -+struct cumulative_args_t { void *magic; void *p; }; -+ -+#else /* !CHECKING_P */ -+ -+/* When using a GCC build compiler, we could use -+ __attribute__((transparent_union)) to get cumulative_args_t function -+ arguments passed like scalars where the ABI would mandate a less -+ efficient way of argument passing otherwise. However, that would come -+ at the cost of less type-safe !CHECKING_P compilation. */ -+ -+union cumulative_args_t { void *p; }; -+ -+#endif /* !CHECKING_P */ -+ -+#endif /* GCC_CUMULATIVE_ARGS_H */ -diff --git a/gcc/d/Make-lang.in b/gcc/d/Make-lang.in -index 1679fb8..4fbf209 100644 ---- a/gcc/d/Make-lang.in -+++ b/gcc/d/Make-lang.in -@@ -64,7 +64,7 @@ ALL_DFLAGS = $(DFLAGS-$@) $(GDCFLAGS) -fversion=IN_GCC $(CHECKING_DFLAGS) \ - $(PICFLAG) $(ALIASING_FLAGS) $(NOEXCEPTION_DFLAGS) $(COVERAGE_FLAGS) \ - $(WARN_DFLAGS) - --DCOMPILE.base = $(GDC) $(NO_PIE_CFLAGS) -c $(ALL_DFLAGS) -o $@ -+DCOMPILE.base = $(GDC) -c $(ALL_DFLAGS) -o $@ - DCOMPILE = $(DCOMPILE.base) -MT $@ -MMD -MP -MF $(@D)/$(DEPDIR)/$(*F).TPo - DPOSTCOMPILE = @mv $(@D)/$(DEPDIR)/$(*F).TPo $(@D)/$(DEPDIR)/$(*F).Po - DLINKER = $(GDC) $(NO_PIE_FLAG) -lstdc++ -diff --git a/gcc/doc/contrib.texi b/gcc/doc/contrib.texi -index 758805d..f8f002c 100644 ---- a/gcc/doc/contrib.texi -+++ b/gcc/doc/contrib.texi -@@ -1515,7 +1515,7 @@ Gael Thomas for @code{VMClassLoader} boot packages support suggestions. - - @item - Andreas Tobler for Darwin and Solaris testing and fixing, @code{Qt4} --support for Darwin/OS X, @code{Graphics2D} support, @code{gtk+} -+support for Darwin / macOS, @code{Graphics2D} support, @code{gtk+} - updates. - - @item -diff --git a/gcc/doc/cpp.texi b/gcc/doc/cpp.texi -index b0a2ce3..f57278d 100644 ---- a/gcc/doc/cpp.texi -+++ b/gcc/doc/cpp.texi -@@ -3198,6 +3198,8 @@ directive}: @samp{#if}, @samp{#ifdef} or @samp{#ifndef}. - * @code{__has_cpp_attribute}:: - * @code{__has_c_attribute}:: - * @code{__has_builtin}:: -+* @code{__has_feature}:: -+* @code{__has_extension}:: - * @code{__has_include}:: - @end menu - -@@ -3560,6 +3562,45 @@ the operator is as follows: - #endif - @end smallexample - -+@node @code{__has_feature} -+@subsection @code{__has_feature} -+@cindex @code{__has_feature} -+ -+The special operator @code{__has_feature (@var{operand})} may be used in -+constant integer contexts and in preprocessor @samp{#if} and @samp{#elif} -+expressions to test whether the identifier given in @var{operand} is recognized -+as a feature supported by GCC given the current options and, in the case of -+standard language features, whether the feature is available in the chosen -+version of the language standard. -+ -+Note that @code{__has_feature} and @code{__has_extension} are not recommended -+for use in new code, and are only provided for compatibility with Clang. For -+details of which identifiers are accepted by these function-like macros, see -+@w{@uref{https://clang.llvm.org/docs/LanguageExtensions.html#has-feature-and-has-extension, -+the Clang documentation}}. -+ -+@node @code{__has_extension} -+@subsection @code{__has_extension} -+@cindex @code{__has_extension} -+ -+The special operator @code{__has_extension (@var{operand})} may be used in -+constant integer contexts and in preprocessor @samp{#if} and @samp{#elif} -+expressions to test whether the identifier given in @var{operand} is recognized -+as an extension supported by GCC given the current options. In any given -+context, the features accepted by @code{__has_extension} are a strict superset -+of those accepted by @code{__has_feature}. Unlike @code{__has_feature}, -+@code{__has_extension} tests whether a given feature is available regardless of -+strict language standards conformance. -+ -+If the @option{-pedantic-errors} flag is given, @code{__has_extension} is -+equivalent to @code{__has_feature}. -+ -+Note that @code{__has_feature} and @code{__has_extension} are not recommended -+for use in new code, and are only provided for compatibility with Clang. For -+details of which identifiers are accepted by these function-like macros, see -+@w{@uref{https://clang.llvm.org/docs/LanguageExtensions.html#has-feature-and-has-extension, -+the Clang documentation}}. -+ - @node @code{__has_include} - @subsection @code{__has_include} - @cindex @code{__has_include} -diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi -index d6fcd61..a163750 100644 ---- a/gcc/doc/extend.texi -+++ b/gcc/doc/extend.texi -@@ -23797,7 +23797,7 @@ attribute, do change the value of preprocessor macros like - - The following pragmas are available for all architectures running the - Darwin operating system. These are useful for compatibility with other --Mac OS compilers. -+macOS compilers. - - @table @code - @cindex pragma, mark -@@ -24976,7 +24976,7 @@ compiled separately. - @end table - - G++ implements the Borland model on targets where the linker supports it, --including ELF targets (such as GNU/Linux), Mac OS X and Microsoft Windows. -+including ELF targets (such as GNU/Linux), macOS and Microsoft Windows. - Otherwise G++ implements neither automatic model. - - You have the following options for dealing with template instantiations: -diff --git a/gcc/doc/install.texi b/gcc/doc/install.texi -index b30d369..de05d1c 100644 ---- a/gcc/doc/install.texi -+++ b/gcc/doc/install.texi -@@ -1075,14 +1075,26 @@ code. - - @item --enable-host-shared - Specify that the @emph{host} code should be built into position-independent --machine code (with -fPIC), allowing it to be used within shared libraries, --but yielding a slightly slower compiler. -+machine code (with @option{-fPIC}), allowing it to be used within shared -+libraries, but yielding a slightly slower compiler. - - This option is required when building the libgccjit.so library. - - Contrast with @option{--enable-shared}, which affects @emph{target} - libraries. - -+@item --enable-host-pie -+Specify that the @emph{host} executables should be built into -+position-independent executables (with @option{-fPIE} and @option{-pie}), -+yielding a slightly slower compiler (but faster than -+@option{--enable-host-shared}). Position-independent executables are loaded -+at random addresses each time they are executed, therefore provide additional -+protection against Return Oriented Programming (ROP) attacks. -+ -+@option{--enable-host-pie}) may be used with @option{--enable-host-shared}), -+in which case @option{-fPIC} is used when compiling, and @option{-pie} when -+linking. -+ - @item @anchor{with-gnu-as}--with-gnu-as - Specify that the compiler should assume that the - assembler it finds is the GNU assembler. However, this does not modify -@@ -1790,6 +1802,12 @@ particularly useful if you intend to use several versions of GCC in - parallel. The default is @samp{yes} for @samp{libada}, and @samp{no} for - the remaining libraries. - -+@item --with-darwin-extra-rpath -+This is provided to allow distributions to add a single additional -+runpath on Darwin / macOS systems. This allows for cases where the -+installed GCC library directories are then symlinked to a common -+directory outside of the GCC installation. -+ - @item @anchor{WithAixSoname}--with-aix-soname=@samp{aix}, @samp{svr4} or @samp{both} - Traditional AIX shared library versioning (versioned @code{Shared Object} - files as members of unversioned @code{Archive Library} files named -diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi -index 792ce28..cedffc5 100644 ---- a/gcc/doc/invoke.texi -+++ b/gcc/doc/invoke.texi -@@ -254,7 +254,8 @@ in the following sections. - -Wdelete-non-virtual-dtor -Wno-deprecated-array-compare - -Wdeprecated-copy -Wdeprecated-copy-dtor - -Wno-deprecated-enum-enum-conversion -Wno-deprecated-enum-float-conversion ---Weffc++ -Wno-exceptions -Wextra-semi -Wno-inaccessible-base -+-Weffc++ -Wno-elaborated-enum-base -+-Wno-exceptions -Wextra-semi -Wno-inaccessible-base - -Wno-inherited-variadic-ctor -Wno-init-list-lifetime - -Winvalid-constexpr -Winvalid-imported-macros - -Wno-invalid-offsetof -Wno-literal-suffix -@@ -706,8 +707,9 @@ Objective-C and Objective-C++ Dialects}. - -freg-struct-return -fshort-enums -fshort-wchar - -fverbose-asm -fpack-struct[=@var{n}] - -fleading-underscore -ftls-model=@var{model} ---fstack-reuse=@var{reuse_level} ---ftrampolines -ftrapv -fwrapv -+-fstack-reuse=@var{reuse_level} -fstack-use-cumulative-args -+-ftrampolines -ftrampoline-impl=@r{[}stack@r{|}heap@r{]} -+-ftrapv -fwrapv - -fvisibility=@r{[}default@r{|}internal@r{|}hidden@r{|}protected@r{]} - -fstrict-volatile-bitfields -fsync-libcalls} - -@@ -914,7 +916,7 @@ Objective-C and Objective-C++ Dialects}. - -iframework - -image_base -init -install_name -keep_private_externs - -multi_module -multiply_defined -multiply_defined_unused ---noall_load -no_dead_strip_inits_and_terms -+-noall_load -no_dead_strip_inits_and_terms -nodefaultrpaths - -nofixprebinding -nomultidefs -noprebind -noseglinkedit - -pagezero_size -prebind -prebind_all_twolevel_modules - -private_bundle -read_only_relocs -sectalign -@@ -927,7 +929,7 @@ Objective-C and Objective-C++ Dialects}. - -twolevel_namespace -umbrella -undefined - -unexported_symbols_list -weak_reference_mismatches - -whatsloaded -F -gused -gfull -mmacosx-version-min=@var{version} ---mkernel -mone-byte-bool} -+-mkernel -mone-byte-bool -munreachable-traps} - - @emph{DEC Alpha Options} - @gccoptlist{-mno-fp-regs -msoft-float -@@ -3839,6 +3841,15 @@ bool b = e <= 3.7; - @option{-std=c++20}. In pre-C++20 dialects, this warning can be enabled - by @option{-Wenum-conversion}. - -+@opindex Welaborated-enum-base -+@opindex Wno-elaborated-enum-base -+@item -Wno-elaborated-enum-base -+For C++11 and above, warn if an (invalid) additional enum-base is used -+in an elaborated-type-specifier. That is, if an enum with given -+underlying type and no enumerator list is used in a declaration other -+than just a standalone declaration of the enum. Enabled by default. This -+warning is upgraded to an error with -pedantic-errors. -+ - @opindex Winit-list-lifetime - @opindex Wno-init-list-lifetime - @item -Wno-init-list-lifetime @r{(C++ and Objective-C++ only)} -@@ -4802,7 +4813,7 @@ Use @var{class-name} as the name of the class to instantiate for each - literal string specified with the syntax @code{@@"@dots{}"}. The default - class name is @code{NXConstantString} if the GNU runtime is being used, and - @code{NSConstantString} if the NeXT runtime is being used (see below). On --Darwin (macOS, MacOS X) platforms, the @option{-fconstant-cfstrings} option, if -+Darwin / macOS platforms, the @option{-fconstant-cfstrings} option, if - also present, overrides the @option{-fconstant-string-class} setting and cause - @code{@@"@dots{}"} literals to be laid out as constant CoreFoundation strings. - Note that @option{-fconstant-cfstrings} is an alias for the target-specific -@@ -4816,7 +4827,7 @@ runtime. This is the default for most types of systems. - @opindex fnext-runtime - @item -fnext-runtime - Generate output compatible with the NeXT runtime. This is the default --for NeXT-based systems, including Darwin and Mac OS X@. The macro -+for NeXT-based systems, including Darwin / macOS. The macro - @code{__NEXT_RUNTIME__} is predefined if (and only if) this option is - used. - -@@ -6031,8 +6042,45 @@ Give an error whenever the @dfn{base standard} (see @option{-Wpedantic}) - requires a diagnostic, in some cases where there is undefined behavior - at compile-time and in some other cases that do not prevent compilation - of programs that are valid according to the standard. This is not --equivalent to @option{-Werror=pedantic}, since there are errors enabled --by this option and not enabled by the latter and vice versa. -+equivalent to @option{-Werror=pedantic}: the latter option is unlikely to be -+useful, as it only makes errors of the diagnostics that are controlled by -+@option{-Wpedantic}, whereas this option also affects required diagnostics that -+are always enabled or controlled by options other than @option{-Wpedantic}. -+ -+If you want the required diagnostics that are warnings by default to -+be errors instead, but don't also want to enable the @option{-Wpedantic} -+diagnostics, you can specify @option{-pedantic-errors -Wno-pedantic} -+(or @option{-pedantic-errors -Wno-error=pedantic} to enable them but -+only as warnings). -+ -+Some required diagnostics are errors by default, but can be reduced to -+warnings using @option{-fpermissive} or their specific warning option, -+e.g. @option{-Wno-error=narrowing}. -+ -+Some diagnostics for non-ISO practices are controlled by specific -+warning options other than @option{-Wpedantic}, but are also made -+errors by @option{-pedantic-errors}. For instance: -+ -+@gccoptlist{ -+-Wattributes @r{(for standard attributes)} -+-Wchanges-meaning @r{(C++)} -+-Wcomma-subscript @r{(C++23 or later)} -+-Wdeclaration-after-statement @r{(C90 or earlier)} -+-Welaborated-enum-base @r{(C++11 or later)} -+-Wimplicit-int @r{(C99 or later)} -+-Wimplicit-function-declaration @r{(C99 or later)} -+-Wincompatible-pointer-types -+-Wint-conversion -+-Wlong-long @r{(C90 or earlier)} -+-Wmain -+-Wnarrowing @r{(C++11 or later)} -+-Wpointer-arith -+-Wpointer-sign -+-Wincompatible-pointer-types -+-Wregister @r{(C++17 or later)} -+-Wvla @r{(C90 or earlier)} -+-Wwrite-strings @r{(C++11 or later)} -+} - - @opindex Wall - @opindex Wno-all -@@ -11285,7 +11333,7 @@ possible. - Produce debugging information in DWARF format (if that is supported). - The value of @var{version} may be either 2, 3, 4 or 5; the default - version for most targets is 5 (with the exception of VxWorks, TPF and --Darwin/Mac OS X, which default to version 2, and AIX, which defaults -+Darwin / macOS, which default to version 2, and AIX, which defaults - to version 4). - - Note that with DWARF Version 2, some ports require and always -@@ -18167,6 +18215,17 @@ the behavior of older compilers in which temporaries' stack space is - not reused, the aggressive stack reuse can lead to runtime errors. This - option is used to control the temporary stack reuse optimization. - -+@opindex fstack_use_cumulative_args -+@item -fstack-use-cumulative-args -+This option instructs the compiler to use the -+@code{cumulative_args_t}-based stack layout target hooks, -+@code{TARGET_FUNCTION_ARG_BOUNDARY_CA} and -+@code{TARGET_FUNCTION_ARG_ROUND_BOUNDARY_CA}. If a given target does -+not define these hooks, the default behaviour is to fallback to using -+the standard non-@code{_CA} variants instead. Certain targets (such as -+AArch64 Darwin) require using the more advanced @code{_CA}-based -+hooks: For these targets this option should be enabled by default. -+ - @opindex ftrapv - @item -ftrapv - This option generates traps for signed overflow on addition, subtraction, -@@ -18652,6 +18711,20 @@ For languages other than Ada, the @code{-ftrampolines} and - trampolines are always generated on platforms that need them - for nested functions. - -+@opindex ftrampoline-impl -+@item -ftrampoline-impl=@r{[}stack@r{|}heap@r{]} -+By default, trampolines are generated on stack. However, certain platforms -+(such as the Apple M1) do not permit an executable stack. Compiling with -+@option{-ftrampoline-impl=heap} generate calls to -+@code{__gcc_nested_func_ptr_created} and -+@code{__gcc_nested_func_ptr_deleted} in order to allocate and -+deallocate trampoline space on the executable heap. These functions are -+implemented in libgcc, and will only be provided on specific targets: -+x86_64 Darwin, x86_64 and aarch64 Linux. @emph{PLEASE NOTE}: Heap -+trampolines are @emph{not} guaranteed to be correctly deallocated if you -+@code{setjmp}, instantiate nested functions, and then @code{longjmp} back -+to a state prior to having allocated those nested functions. -+ - @opindex fvisibility - @item -fvisibility=@r{[}default@r{|}internal@r{|}hidden@r{|}protected@r{]} - Set the default ELF image symbol visibility to the specified option---all -@@ -24024,6 +24097,11 @@ without that switch. Using this switch may require recompiling all - other modules in a program, including system libraries. Use this - switch to conform to a non-default data model. - -+@opindex munreachable-traps -+@item -munreachable-traps -+Causes @code{__builtin_unreachable} to be rendered as a trap. This is the -+default for all Darwin architectures. -+ - @opindex mfix-and-continue - @opindex ffix-and-continue - @opindex findirect-data -@@ -24070,6 +24148,14 @@ an executable when linking, using the Darwin @file{libtool} command. - This causes GCC's output file to have the @samp{ALL} subtype, instead of - one controlled by the @option{-mcpu} or @option{-march} option. - -+@opindex nodefaultrpaths -+@item -nodefaultrpaths -+Do not add default run paths for the compiler library directories to -+executables, modules or dynamic libraries. On macOS 10.5 and later, -+the embedded runpath is added by default unless the user adds -+@option{-nodefaultrpaths} to the link line. Run paths are needed -+(and therefore enforced) to build on macOS version 10.11 or later. -+ - @item -allowable_client @var{client_name} - @itemx -client_name - @itemx -compatibility_version -@@ -29823,7 +29909,7 @@ the same as @option{-mbig}. - - @opindex mdynamic-no-pic - @item -mdynamic-no-pic --On Darwin and Mac OS X systems, compile code so that it is not -+On Darwin / macOS systems, compile code so that it is not - relocatable, but that its external references are relocatable. The - resulting code is suitable for applications, but not shared - libraries. -diff --git a/gcc/doc/plugins.texi b/gcc/doc/plugins.texi -index 26df8b4..f9a2318 100644 ---- a/gcc/doc/plugins.texi -+++ b/gcc/doc/plugins.texi -@@ -44,7 +44,7 @@ Plugins are loaded with - - Where @var{name} is the plugin name and @var{ext} is the platform-specific - dynamic library extension. It should be @code{dll} on Windows/MinGW, --@code{dylib} on Darwin/Mac OS X, and @code{so} on all other platforms. -+@code{dylib} on Darwin/macOS, and @code{so} on all other platforms. - The plugin arguments are parsed by GCC and passed to respective - plugins as key-value pairs. Multiple plugins can be invoked by - specifying multiple @option{-fplugin} arguments. -diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi -index a660e33..1080f85 100644 ---- a/gcc/doc/tm.texi -+++ b/gcc/doc/tm.texi -@@ -1042,6 +1042,10 @@ also define the hook to @code{default_promote_function_mode_always_promote} - if you would like to apply the same rules given by @code{PROMOTE_MODE}. - @end deftypefn - -+@deftypefn {Target Hook} machine_mode TARGET_PROMOTE_FUNCTION_MODE_CA (cumulative_args_t, @var{function_arg_info}, @var{const_tree}, int *@var{}, @var{int}) -+Like @code{promote_function_mode}, but takes a cumulative_args pointer and a current arg to supply the input. -+@end deftypefn -+ - @defmac PARM_BOUNDARY - Normal alignment required for function parameters on the stack, in - bits. All stack parameters receive at least this much alignment -@@ -4354,6 +4358,16 @@ with the specified mode and type. The default hook returns - @code{PARM_BOUNDARY} for all arguments. - @end deftypefn - -+@deftypefn {Target Hook} {unsigned int} TARGET_FUNCTION_ARG_BOUNDARY_CA (machine_mode @var{mode}, const_tree @var{type}, cumulative_args_t @var{ca}) -+This is the @code{cumulative_args_t}-based version of -+@code{TARGET_FUNCTION_ARG_BOUNDARY}. Define this hook if you need more -+fine-grained control over argument alignment, e.g. depending on whether -+it is a named argument or not, or any other criteria that you choose to -+place in the @var{ca} structure. -+ -+The default hook will call @code{TARGET_FUNCTION_ARG_BOUNDARY}. -+@end deftypefn -+ - @deftypefn {Target Hook} {unsigned int} TARGET_FUNCTION_ARG_ROUND_BOUNDARY (machine_mode @var{mode}, const_tree @var{type}) - Normally, the size of an argument is rounded up to @code{PARM_BOUNDARY}, - which is the default value for this hook. You can define this hook to -@@ -4361,6 +4375,16 @@ return a different value if an argument size must be rounded to a larger - value. - @end deftypefn - -+@deftypefn {Target Hook} {unsigned int} TARGET_FUNCTION_ARG_ROUND_BOUNDARY_CA (machine_mode @var{mode}, const_tree @var{type}, cumulative_args_t @var{ca}) -+This is the @code{cumulative_args_t}-based version of -+@code{TARGET_FUNCTION_ARG_ROUND_BOUNDARY}. Define this hook if you need more -+fine-grained control over argument size rounding, e.g. depending on whether -+it is a named argument or not, or any other criteria that you choose to -+place in the @var{ca} structure. -+ -+The default hook will call @code{TARGET_FUNCTION_ARG_ROUND_BOUNDARY}. -+@end deftypefn -+ - @defmac FUNCTION_ARG_REGNO_P (@var{regno}) - A C expression that is nonzero if @var{regno} is the number of a hard - register in which function arguments are sometimes passed. This does -@@ -5764,7 +5788,7 @@ This hook determines whether a function from a class of functions - Set this macro to 1 to use the "NeXT" Objective-C message sending conventions - by default. This calling convention involves passing the object, the selector - and the method arguments all at once to the method-lookup library function. --This is the usual setting when targeting Darwin/Mac OS X systems, which have -+This is the usual setting when targeting Darwin / macOS systems, which have - the NeXT runtime installed. - - If the macro is set to 0, the "GNU" Objective-C message sending convention -@@ -12365,6 +12389,11 @@ This target hook can be used to generate a target-specific code - If selftests are enabled, run any selftests for this target. - @end deftypefn - -+@deftypefn {Target Hook} bool TARGET_UNREACHABLE_SHOULD_TRAP (void) -+This hook should return @code{true} if the target wants @code{__builtin_unreachable} to expand to a trap or @code{abort ()}. -+ The default value is false. -+@end deftypefn -+ - @deftypefn {Target Hook} bool TARGET_MEMTAG_CAN_TAG_ADDRESSES () - True if the backend architecture naturally supports ignoring some region - of pointers. This feature means that @option{-fsanitize=hwaddress} can -diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in -index f7ab5d4..7f82c02 100644 ---- a/gcc/doc/tm.texi.in -+++ b/gcc/doc/tm.texi.in -@@ -938,6 +938,8 @@ applied. - - @hook TARGET_PROMOTE_FUNCTION_MODE - -+@hook TARGET_PROMOTE_FUNCTION_MODE_CA -+ - @defmac PARM_BOUNDARY - Normal alignment required for function parameters on the stack, in - bits. All stack parameters receive at least this much alignment -@@ -3341,8 +3343,12 @@ required. - - @hook TARGET_FUNCTION_ARG_BOUNDARY - -+@hook TARGET_FUNCTION_ARG_BOUNDARY_CA -+ - @hook TARGET_FUNCTION_ARG_ROUND_BOUNDARY - -+@hook TARGET_FUNCTION_ARG_ROUND_BOUNDARY_CA -+ - @defmac FUNCTION_ARG_REGNO_P (@var{regno}) - A C expression that is nonzero if @var{regno} is the number of a hard - register in which function arguments are sometimes passed. This does -@@ -4008,7 +4014,7 @@ macro, a reasonable default is used. - Set this macro to 1 to use the "NeXT" Objective-C message sending conventions - by default. This calling convention involves passing the object, the selector - and the method arguments all at once to the method-lookup library function. --This is the usual setting when targeting Darwin/Mac OS X systems, which have -+This is the usual setting when targeting Darwin / macOS systems, which have - the NeXT runtime installed. - - If the macro is set to 0, the "GNU" Objective-C message sending convention -@@ -7965,6 +7971,8 @@ maintainer is familiar with. - - @hook TARGET_RUN_TARGET_SELFTESTS - -+@hook TARGET_UNREACHABLE_SHOULD_TRAP -+ - @hook TARGET_MEMTAG_CAN_TAG_ADDRESSES - - @hook TARGET_MEMTAG_TAG_SIZE -diff --git a/gcc/exec-tool.in b/gcc/exec-tool.in -index bddf46a..a9120f3 100644 ---- a/gcc/exec-tool.in -+++ b/gcc/exec-tool.in -@@ -23,6 +23,8 @@ ORIGINAL_AS_FOR_TARGET="@ORIGINAL_AS_FOR_TARGET@" - ORIGINAL_LD_FOR_TARGET="@ORIGINAL_LD_FOR_TARGET@" - ORIGINAL_LD_BFD_FOR_TARGET="@ORIGINAL_LD_BFD_FOR_TARGET@" - ORIGINAL_LD_GOLD_FOR_TARGET="@ORIGINAL_LD_GOLD_FOR_TARGET@" -+ORIGINAL_LLD_FOR_TARGET="@ORIGINAL_LLD_FOR_TARGET@" -+ORIGINAL_CLASSIC_LD_FOR_TARGET="@ORIGINAL_CLASSIC_LD_FOR_TARGET@" - ORIGINAL_PLUGIN_LD_FOR_TARGET="@ORIGINAL_PLUGIN_LD_FOR_TARGET@" - ORIGINAL_NM_FOR_TARGET="@ORIGINAL_NM_FOR_TARGET@" - ORIGINAL_DSYMUTIL_FOR_TARGET="@ORIGINAL_DSYMUTIL_FOR_TARGET@" -@@ -39,24 +41,41 @@ case "$invoked" in - dir=gas - ;; - collect-ld) -- # Check -fuse-ld=bfd and -fuse-ld=gold -- case " $* " in -- *\ -fuse-ld=bfd\ *) -- original=$ORIGINAL_LD_BFD_FOR_TARGET -- ;; -- *\ -fuse-ld=gold\ *) -- original=$ORIGINAL_LD_GOLD_FOR_TARGET -- ;; -- *) -- # when using a linker plugin, gcc will always pass '-plugin' as the -- # first or second option to the linker. -- if test x"$1" = "x-plugin" || test x"$2" = "x-plugin"; then -- original=$ORIGINAL_PLUGIN_LD_FOR_TARGET -- else -- original=$ORIGINAL_LD_FOR_TARGET -- fi -- ;; -- esac -+ # when using a linker plugin, gcc will always pass '-plugin' as the -+ # first or second option to the linker. -+ if test x"$1" = "x-plugin" || test x"$2" = "x-plugin"; then -+ original=$ORIGINAL_PLUGIN_LD_FOR_TARGET -+ else -+ original=$ORIGINAL_LD_FOR_TARGET -+ fi -+ # Check -fuse-ld=bfd, -fuse-ld=gold and -fuse-ld=classic -+ # Remove -fuse-ld=classic from the command line -+ for arg do -+ # temporarily, remove the arg. -+ shift -+ case $arg in -+ -fuse-ld=bfd) -+ original=$ORIGINAL_LD_BFD_FOR_TARGET -+ ;; -+ -fuse-ld=gold) -+ original=$ORIGINAL_LD_GOLD_FOR_TARGET -+ ;; -+ -fuse-ld=lld) -+ original=$ORIGINAL_LLD_FOR_TARGET -+ # We want to remove this from the command line; by the slightly -+ # obtuse mechanism of not putting it back. -+ continue -+ ;; -+ -fuse-ld=classic) -+ original=$ORIGINAL_CLASSIC_LD_FOR_TARGET -+ # As for lld. -+ continue -+ ;; -+ *) ;; -+ esac -+ # if we want to keep the arg, put it back. -+ set -- "$@" "$arg" -+ done - prog=ld-new$exeext - if test "$original" = ../gold/ld-new$exeext; then - dir=gold -diff --git a/gcc/explow.cc b/gcc/explow.cc -index 6424c08..7c2973a 100644 ---- a/gcc/explow.cc -+++ b/gcc/explow.cc -@@ -37,6 +37,7 @@ along with GCC; see the file COPYING3. If not see - #include "langhooks.h" - #include "except.h" - #include "dojump.h" -+#include "calls.h" - #include "explow.h" - #include "expr.h" - #include "stringpool.h" -@@ -817,6 +818,16 @@ promote_function_mode (const_tree type, machine_mode mode, int *punsignedp, - return mode; - } - } -+ -+machine_mode -+promote_function_mode (cumulative_args_t args_so_far, function_arg_info arg, -+ const_tree funtype, int *punsignedp , int for_return) -+{ -+ return targetm.calls.promote_function_mode_ca (args_so_far, arg, funtype, -+ punsignedp, for_return); -+// return promote_function_mode (arg.type, arg.mode, punsignedp, funtype, for_return); -+} -+ - /* Return the mode to use to store a scalar of TYPE and MODE. - PUNSIGNEDP points to the signedness of the type and may be adjusted - to show what signedness to use on extension operations. */ -diff --git a/gcc/explow.h b/gcc/explow.h -index 2db4f5c..c7d2286 100644 ---- a/gcc/explow.h -+++ b/gcc/explow.h -@@ -20,6 +20,8 @@ along with GCC; see the file COPYING3. If not see - #ifndef GCC_EXPLOW_H - #define GCC_EXPLOW_H - -+#include "calls.h" /* for cummulative args stuff. */ -+ - /* Return a memory reference like MEMREF, but which is known to have a - valid address. */ - extern rtx validize_mem (rtx); -@@ -47,8 +49,13 @@ extern rtx force_not_mem (rtx); - - /* Return mode and signedness to use when an argument or result in the - given mode is promoted. */ --extern machine_mode promote_function_mode (const_tree, machine_mode, int *, -- const_tree, int); -+machine_mode promote_function_mode (const_tree, machine_mode, int *, -+ const_tree, int); -+ -+/* Return mode and signedness to use when an argument or result in the -+ given mode is promoted. */ -+machine_mode promote_function_mode (cumulative_args_t, function_arg_info, -+ const_tree, int *, int); - - /* Return mode and signedness to use when an object in the given mode - is promoted. */ -diff --git a/gcc/fortran/gfortran.texi b/gcc/fortran/gfortran.texi -index 87baf5a..908f2b7 100644 ---- a/gcc/fortran/gfortran.texi -+++ b/gcc/fortran/gfortran.texi -@@ -978,7 +978,7 @@ low level file descriptor corresponding to an open Fortran unit. Then, - using e.g. the @code{ISO_C_BINDING} feature, one can call the - underlying system call to flush dirty data to stable storage, such as - @code{fsync} on POSIX, @code{_commit} on MingW, or @code{fcntl(fd, --F_FULLSYNC, 0)} on Mac OS X. The following example shows how to call -+F_FULLSYNC, 0)} on macOS. The following example shows how to call - fsync: - - @smallexample -diff --git a/gcc/function.cc b/gcc/function.cc -index 8d6c447..4308e24 100644 ---- a/gcc/function.cc -+++ b/gcc/function.cc -@@ -58,8 +58,8 @@ along with GCC; see the file COPYING3. If not see - #include "varasm.h" - #include "except.h" - #include "dojump.h" --#include "explow.h" - #include "calls.h" -+#include "explow.h" - #include "expr.h" - #include "optabs-tree.h" - #include "output.h" -@@ -2448,7 +2448,10 @@ assign_parm_find_data_types (struct assign_parm_data_all *all, tree parm, - else if (DECL_CHAIN (parm)) - data->arg.named = 1; /* Not the last non-variadic parm. */ - else if (targetm.calls.strict_argument_naming (all->args_so_far)) -- data->arg.named = 1; /* Only variadic ones are unnamed. */ -+ { -+ data->arg.named = 1; /* Only variadic ones are unnamed. */ -+ data->arg.last_named = 1; -+ } - else - data->arg.named = 0; /* Treat as variadic. */ - -@@ -2490,9 +2493,12 @@ assign_parm_find_data_types (struct assign_parm_data_all *all, tree parm, - - /* Find mode as it is passed by the ABI. */ - unsignedp = TYPE_UNSIGNED (data->arg.type); -- data->arg.mode -- = promote_function_mode (data->arg.type, data->arg.mode, &unsignedp, -- TREE_TYPE (current_function_decl), 0); -+// data->arg.mode -+// = promote_function_mode (data->arg.type, data->arg.mode, &unsignedp, -+// TREE_TYPE (current_function_decl), 0); -+ data->arg.mode = promote_function_mode (all->args_so_far, data->arg, -+ TREE_TYPE (current_function_decl), -+ &unsignedp, 0); - } - - /* A subroutine of assign_parms. Invoke setup_incoming_varargs. */ -@@ -2505,6 +2511,7 @@ assign_parms_setup_varargs (struct assign_parm_data_all *all, - - function_arg_info last_named_arg = data->arg; - last_named_arg.named = true; -+ last_named_arg.last_named = true; - targetm.calls.setup_incoming_varargs (all->args_so_far, last_named_arg, - &varargs_pretend_bytes, no_rtl); - -@@ -2613,7 +2620,9 @@ assign_parm_find_entry_rtl (struct assign_parm_data_all *all, - - locate_and_pad_parm (data->arg.mode, data->arg.type, in_regs, - all->reg_parm_stack_space, -- entry_parm ? data->partial : 0, current_function_decl, -+ entry_parm ? data->partial : 0, -+ all->args_so_far, -+ current_function_decl, - &all->stack_args_size, &data->locate); - - /* Update parm_stack_boundary if this parameter is passed in the -@@ -3945,7 +3954,8 @@ gimplify_parameters (gimple_seq *cleanup) - if (data.arg.pass_by_reference) - { - tree type = TREE_TYPE (data.arg.type); -- function_arg_info orig_arg (type, data.arg.named); -+ function_arg_info orig_arg (type, data.arg.named, -+ data.arg.last_named); - if (reference_callee_copied (&all.args_so_far_v, orig_arg)) - { - tree local, t; -@@ -4048,6 +4058,7 @@ gimplify_parameters (gimple_seq *cleanup) - void - locate_and_pad_parm (machine_mode passed_mode, tree type, int in_regs, - int reg_parm_stack_space, int partial, -+ cumulative_args_t ca, - tree fndecl ATTRIBUTE_UNUSED, - struct args_size *initial_offset_ptr, - struct locate_and_pad_arg_data *locate) -@@ -4085,9 +4096,23 @@ locate_and_pad_parm (machine_mode passed_mode, tree type, int in_regs, - ? arg_size_in_bytes (type) - : size_int (GET_MODE_SIZE (passed_mode))); - where_pad = targetm.calls.function_arg_padding (passed_mode, type); -- boundary = targetm.calls.function_arg_boundary (passed_mode, type); -- round_boundary = targetm.calls.function_arg_round_boundary (passed_mode, -- type); -+ -+ if (flag_stack_use_cumulative_args) -+ { -+ boundary = targetm.calls.function_arg_boundary_ca (passed_mode, -+ type, -+ ca); -+ round_boundary = targetm.calls.function_arg_round_boundary_ca -+ (passed_mode, type, ca); -+ } -+ else -+ { -+ boundary = targetm.calls.function_arg_boundary (passed_mode, -+ type); -+ round_boundary = targetm.calls.function_arg_round_boundary -+ (passed_mode, type); -+ } -+ - locate->where_pad = where_pad; - - /* Alignment can't exceed MAX_SUPPORTED_STACK_ALIGNMENT. */ -diff --git a/gcc/function.h b/gcc/function.h -index d4ce8a7..09ab17e 100644 ---- a/gcc/function.h -+++ b/gcc/function.h -@@ -20,6 +20,7 @@ along with GCC; see the file COPYING3. If not see - #ifndef GCC_FUNCTION_H - #define GCC_FUNCTION_H - -+#include "cumulative-args.h" - - /* Stack of pending (incomplete) sequences saved by `start_sequence'. - Each element describes one pending sequence. -@@ -665,6 +666,7 @@ extern int aggregate_value_p (const_tree, const_tree); - extern bool use_register_for_decl (const_tree); - extern gimple_seq gimplify_parameters (gimple_seq *); - extern void locate_and_pad_parm (machine_mode, tree, int, int, int, -+ cumulative_args_t, - tree, struct args_size *, - struct locate_and_pad_arg_data *); - extern void generate_setjmp_warnings (void); -diff --git a/gcc/gcc.cc b/gcc/gcc.cc -index 16bb07f..d034974 100644 ---- a/gcc/gcc.cc -+++ b/gcc/gcc.cc -@@ -575,6 +575,7 @@ or with constant text in a single argument. - %l process LINK_SPEC as a spec. - %L process LIB_SPEC as a spec. - %M Output multilib_os_dir. -+ %P Output a RUNPATH_OPTION for each directory in startfile_prefixes. - %G process LIBGCC_SPEC as a spec. - %R Output the concatenation of target_system_root and - target_sysroot_suffix. -@@ -1178,6 +1179,10 @@ proper position among the other output files. */ - # define SYSROOT_HEADERS_SUFFIX_SPEC "" - #endif - -+#ifndef RUNPATH_OPTION -+# define RUNPATH_OPTION "-rpath" -+#endif -+ - static const char *asm_debug = ASM_DEBUG_SPEC; - static const char *asm_debug_option = ASM_DEBUG_OPTION_SPEC; - static const char *cpp_spec = CPP_SPEC; -@@ -5859,6 +5864,7 @@ struct spec_path_info { - size_t append_len; - bool omit_relative; - bool separate_options; -+ bool realpaths; - }; - - static void * -@@ -5868,6 +5874,16 @@ spec_path (char *path, void *data) - size_t len = 0; - char save = 0; - -+ /* The path must exist; we want to resolve it to the realpath so that this -+ can be embedded as a runpath. */ -+ if (info->realpaths) -+ path = lrealpath (path); -+ -+ /* However, if we failed to resolve it - perhaps because there was a bogus -+ -B option on the command line, then punt on this entry. */ -+ if (!path) -+ return NULL; -+ - if (info->omit_relative && !IS_ABSOLUTE_PATH (path)) - return NULL; - -@@ -6099,6 +6115,22 @@ do_spec_1 (const char *spec, int inswitch, const char *soft_matched_part) - info.omit_relative = false; - #endif - info.separate_options = false; -+ info.realpaths = false; -+ -+ for_each_path (&startfile_prefixes, true, 0, spec_path, &info); -+ } -+ break; -+ -+ case 'P': -+ { -+ struct spec_path_info info; -+ -+ info.option = RUNPATH_OPTION; -+ info.append_len = 0; -+ info.omit_relative = false; -+ info.separate_options = true; -+ /* We want to embed the actual paths that have the libraries. */ -+ info.realpaths = true; - - for_each_path (&startfile_prefixes, true, 0, spec_path, &info); - } -@@ -6425,6 +6457,7 @@ do_spec_1 (const char *spec, int inswitch, const char *soft_matched_part) - info.append_len = strlen (info.append); - info.omit_relative = false; - info.separate_options = true; -+ info.realpaths = false; - - for_each_path (&include_prefixes, false, info.append_len, - spec_path, &info); -diff --git a/gcc/ginclude/stddef.h b/gcc/ginclude/stddef.h -index 12ceef3..af07107 100644 ---- a/gcc/ginclude/stddef.h -+++ b/gcc/ginclude/stddef.h -@@ -428,9 +428,8 @@ typedef struct { - /* _Float128 is defined as a basic type, so max_align_t must be - sufficiently aligned for it. This code must work in C++, so we - use __float128 here; that is only available on some -- architectures, but only on i386 is extra alignment needed for -- __float128. */ --#ifdef __i386__ -+ architectures. */ -+#if defined(__i386__) || (__APPLE__ && __aarch64__) - __float128 __max_align_f128 __attribute__((__aligned__(__alignof(__float128)))); - #endif - } max_align_t; -diff --git a/gcc/jit/Make-lang.in b/gcc/jit/Make-lang.in -index 5507920..5bdba6c 100644 ---- a/gcc/jit/Make-lang.in -+++ b/gcc/jit/Make-lang.in -@@ -69,7 +69,7 @@ LIBGCCJIT_COMPAT = 0 - LIBGCCJIT_BASENAME = libgccjit - - LIBGCCJIT_SONAME = \ -- ${libdir}/$(LIBGCCJIT_BASENAME).$(LIBGCCJIT_VERSION_NUM).dylib -+ $(DARWIN_RPATH)/$(LIBGCCJIT_BASENAME).$(LIBGCCJIT_VERSION_NUM).dylib - LIBGCCJIT_FILENAME = $(LIBGCCJIT_BASENAME).$(LIBGCCJIT_VERSION_NUM).dylib - LIBGCCJIT_LINKER_NAME = $(LIBGCCJIT_BASENAME).dylib - -diff --git a/gcc/jit/jit-playback.cc b/gcc/jit/jit-playback.cc -index e06f161..2a04573 100644 ---- a/gcc/jit/jit-playback.cc -+++ b/gcc/jit/jit-playback.cc -@@ -3024,7 +3024,7 @@ invoke_driver (const char *ctxt_progname, - ADD_ARG ("-fno-use-linker-plugin"); - - #if defined (DARWIN_X86) || defined (DARWIN_PPC) -- /* OS X's linker defaults to treating undefined symbols as errors. -+ /* macOS's linker defaults to treating undefined symbols as errors. - If the context has any imported functions or globals they will be - undefined until the .so is dynamically-linked into the process. - Ensure that the driver passes in "-undefined dynamic_lookup" to the -diff --git a/gcc/jit/libgccjit.h b/gcc/jit/libgccjit.h -index 057d3e5..04545e4 100644 ---- a/gcc/jit/libgccjit.h -+++ b/gcc/jit/libgccjit.h -@@ -21,6 +21,9 @@ along with GCC; see the file COPYING3. If not see - #define LIBGCCJIT_H - - #include -+#ifdef __APPLE__ -+# include /* For ssize_t. */ -+#endif - - #ifdef __cplusplus - extern "C" { -diff --git a/gcc/m2/Make-lang.in b/gcc/m2/Make-lang.in -index 0ae3e18..320f930 100644 ---- a/gcc/m2/Make-lang.in -+++ b/gcc/m2/Make-lang.in -@@ -501,6 +501,11 @@ GM2_MIN_FLAGS=$(GM2_G) $(GM2_OS) \ - -Wpedantic-cast -Wpedantic-param-names -fno-exceptions \ - -ffunction-sections -fdata-sections $(GM2_CPP) - -+# ALL_LINKERFLAGS may include -pie (when GCC is configured with -+# --enable-host-pie), so use -fPIE if needed. (It would not be -+# a good idea to override CFLAGS.) -+GM2_PICFLAGS = $(PICFLAG) -+ - O2=-O2 -g - SO_O2=-O2 -g -fPIC - SO=-O0 -g -fPIC -@@ -1396,7 +1401,7 @@ m2/mc-boot-ch/$(SRC_PREFIX)%.o: m2/mc-boot-ch/$(SRC_PREFIX)%.c m2/gm2-libs/gm2-l - - m2/mc-boot-ch/$(SRC_PREFIX)%.o: m2/mc-boot-ch/$(SRC_PREFIX)%.cc m2/gm2-libs/gm2-libs-host.h - -test -d $(@D) || $(mkinstalldirs) $(@D) -- $(CXX) $(CXXFLAGS) -DHAVE_CONFIG_H -g -c -I. -Im2/gm2-libs -I$(srcdir)/../include -I$(srcdir) $(INCLUDES) -Im2/gm2-libs $< -o $@ -+ $(CXX) $(CXXFLAGS) $(GM2_PICFLAGS) -DHAVE_CONFIG_H -g -c -I. -Im2/gm2-libs -I$(srcdir)/../include -I$(srcdir) $(INCLUDES) -Im2/gm2-libs $< -o $@ - - m2/mc-boot/main.o: $(M2LINK) $(srcdir)/m2/init/mcinit - -test -d $(@D)/$(DEPDIR) || $(mkinstalldirs) $(@D)/$(DEPDIR) -diff --git a/gcc/objc/objc-act.cc b/gcc/objc/objc-act.cc -index fe2d2b5..8558059 100644 ---- a/gcc/objc/objc-act.cc -+++ b/gcc/objc/objc-act.cc -@@ -3317,7 +3317,7 @@ objc_build_string_object (tree string) - length = TREE_STRING_LENGTH (string) - 1; - - /* The target may have different ideas on how to construct an ObjC string -- literal. On Darwin (Mac OS X), for example, we may wish to obtain a -+ literal. On Darwin / macOS, for example, we may wish to obtain a - constant CFString reference instead. - At present, this is only supported for the NeXT runtime. */ - if (flag_next_runtime -@@ -10362,5 +10362,51 @@ objc_common_tree_size (enum tree_code code) - } - } - -+/* Information for Objective-C-specific features known to __has_feature. */ -+ -+struct objc_feature_info -+{ -+ typedef bool (*predicate_t) (); -+ -+ const char *ident; -+ predicate_t predicate; -+ -+ constexpr objc_feature_info (const char *name) -+ : ident (name), predicate (nullptr) {} -+ constexpr objc_feature_info (const char *name, predicate_t p) -+ : ident (name), predicate (p) {} -+ -+ bool has_feature () const -+ { -+ return predicate ? predicate () : true; -+ } -+}; -+ -+static bool objc_nonfragile_abi_p () -+{ -+ return flag_next_runtime && flag_objc_abi >= 2; -+} -+ -+static constexpr objc_feature_info objc_features[] = -+{ -+ { "objc_default_synthesize_properties" }, -+ { "objc_instancetype" }, -+ { "objc_nonfragile_abi", objc_nonfragile_abi_p } -+}; -+ -+/* Register Objective-C-specific features for __has_feature. */ -+ -+void -+objc_common_register_features () -+{ -+ for (unsigned i = 0; i < ARRAY_SIZE (objc_features); i++) -+ { -+ const objc_feature_info *info = objc_features + i; -+ if (!info->has_feature ()) -+ continue; -+ -+ c_common_register_feature (info->ident, true); -+ } -+} - - #include "gt-objc-objc-act.h" -diff --git a/gcc/objc/objc-act.h b/gcc/objc/objc-act.h -index e21ab52..bcf0249 100644 ---- a/gcc/objc/objc-act.h -+++ b/gcc/objc/objc-act.h -@@ -29,6 +29,9 @@ int objc_gimplify_expr (tree *, gimple_seq *, gimple_seq *); - void objc_common_init_ts (void); - const char *objc_get_sarif_source_language (const char *); - -+/* Register features common to Objective-C and Objective-C++. */ -+void objc_common_register_features (); -+ - /* NB: The remaining public functions are prototyped in c-common.h, for the - benefit of stub-objc.cc and objc-act.cc. */ - -diff --git a/gcc/objc/objc-lang.cc b/gcc/objc/objc-lang.cc -index 89b3be4..7568248 100644 ---- a/gcc/objc/objc-lang.cc -+++ b/gcc/objc/objc-lang.cc -@@ -58,6 +58,16 @@ objc_get_sarif_source_language (const char *) - return "objectivec"; - } - -+/* Implement c-family hook to add language-specific features -+ for __has_{feature,extension}. */ -+ -+void -+c_family_register_lang_features () -+{ -+ objc_common_register_features (); -+ c_register_features (); -+} -+ - /* Lang hook routines common to C and ObjC appear in c-objc-common.cc; - there should be very few (if any) routines below. */ - -diff --git a/gcc/objcp/objcp-lang.cc b/gcc/objcp/objcp-lang.cc -index 9887209..ede59a6 100644 ---- a/gcc/objcp/objcp-lang.cc -+++ b/gcc/objcp/objcp-lang.cc -@@ -80,6 +80,16 @@ objcp_tsubst_copy_and_build (tree t, tree args, tsubst_flags_t complain, - #undef RECURSE - } - -+/* Implement c-family hook to add language-specific features -+ for __has_{feature,extension}. */ -+ -+void -+c_family_register_lang_features () -+{ -+ objc_common_register_features (); -+ cp_register_features (); -+} -+ - static void - objcxx_init_ts (void) - { -diff --git a/gcc/opts.cc b/gcc/opts.cc -index e0ba89f..71371e2 100644 ---- a/gcc/opts.cc -+++ b/gcc/opts.cc -@@ -3215,6 +3215,7 @@ common_handle_option (struct gcc_options *opts, - break; - - case OPT_fuse_ld_bfd: -+ case OPT_fuse_ld_classic: - case OPT_fuse_ld_gold: - case OPT_fuse_ld_lld: - case OPT_fuse_ld_mold: -diff --git a/gcc/plugin.cc b/gcc/plugin.cc -index 142f3fa..c3e40b2 100644 ---- a/gcc/plugin.cc -+++ b/gcc/plugin.cc -@@ -190,10 +190,10 @@ add_new_plugin (const char* plugin_name) - #if defined(__MINGW32__) - static const char plugin_ext[] = ".dll"; - #elif defined(__APPLE__) -- /* Mac OS has two types of libraries: dynamic libraries (.dylib) and -+ /* macOS has two types of libraries: dynamic libraries (.dylib) and - plugins (.bundle). Both can be used with dlopen()/dlsym() but the - former cannot be linked at build time (i.e., with the -lfoo linker -- option). A GCC plugin is therefore probably a Mac OS plugin but their -+ option). A GCC plugin is therefore probably a macOS plugin but their - use seems to be quite rare and the .bundle extension is more of a - recommendation rather than the rule. This raises the questions of how - well they are supported by tools (e.g., libtool). So to avoid -diff --git a/gcc/target.def b/gcc/target.def -index 171bbd1..75b51d2 100644 ---- a/gcc/target.def -+++ b/gcc/target.def -@@ -4574,6 +4574,13 @@ if you would like to apply the same rules given by @code{PROMOTE_MODE}.", - const_tree funtype, int for_return), - default_promote_function_mode) - -+DEFHOOK -+(promote_function_mode_ca, -+ "Like @code{promote_function_mode}, but takes a cumulative_args pointer \ -+ and a current arg to supply the input.", -+ machine_mode, (cumulative_args_t, function_arg_info, const_tree, int *, int), -+ default_promote_function_mode_ca) -+ - DEFHOOK - (promote_prototypes, - "This target hook returns @code{true} if an argument declared in a\n\ -@@ -4992,6 +4999,18 @@ with the specified mode and type. The default hook returns\n\ - unsigned int, (machine_mode mode, const_tree type), - default_function_arg_boundary) - -+DEFHOOK -+(function_arg_boundary_ca, -+ "This is the @code{cumulative_args_t}-based version of\n\ -+@code{TARGET_FUNCTION_ARG_BOUNDARY}. Define this hook if you need more\n\ -+fine-grained control over argument alignment, e.g. depending on whether\n\ -+it is a named argument or not, or any other criteria that you choose to\n\ -+place in the @var{ca} structure.\n\ -+\n\ -+The default hook will call @code{TARGET_FUNCTION_ARG_BOUNDARY}.", -+ unsigned int, (machine_mode mode, const_tree type, cumulative_args_t ca), -+ default_function_arg_boundary_ca) -+ - DEFHOOK - (function_arg_round_boundary, - "Normally, the size of an argument is rounded up to @code{PARM_BOUNDARY},\n\ -@@ -5001,6 +5020,18 @@ value.", - unsigned int, (machine_mode mode, const_tree type), - default_function_arg_round_boundary) - -+DEFHOOK -+(function_arg_round_boundary_ca, -+ "This is the @code{cumulative_args_t}-based version of\n\ -+@code{TARGET_FUNCTION_ARG_ROUND_BOUNDARY}. Define this hook if you need more\n\ -+fine-grained control over argument size rounding, e.g. depending on whether\n\ -+it is a named argument or not, or any other criteria that you choose to\n\ -+place in the @var{ca} structure.\n\ -+\n\ -+The default hook will call @code{TARGET_FUNCTION_ARG_ROUND_BOUNDARY}.", -+ unsigned int, (machine_mode mode, const_tree type, cumulative_args_t ca), -+ default_function_arg_round_boundary_ca) -+ - /* Return the diagnostic message string if function without a prototype - is not allowed for this 'val' argument; NULL otherwise. */ - DEFHOOK -@@ -7138,6 +7169,16 @@ DEFHOOKPOD - @option{-fsanitize=shadow-call-stack}. The default value is false.", - bool, false) - -+/* This value represents whether __builtin_unreachable should be expanded -+ as a trap instruction (or an abort() if the trap is not available). */ -+DEFHOOK -+(unreachable_should_trap, -+ "This hook should return @code{true} if the target wants \ -+ @code{__builtin_unreachable} to expand to a trap or @code{abort ()}.\n\ -+ The default value is false.", -+ bool, (void), -+ hook_bool_void_false) -+ - /* Close the 'struct gcc_target' definition. */ - HOOK_VECTOR_END (C90_EMPTY_HACK) - -diff --git a/gcc/target.h b/gcc/target.h -index cd448e4..064523f 100644 ---- a/gcc/target.h -+++ b/gcc/target.h -@@ -51,22 +51,8 @@ - #include "insn-codes.h" - #include "tm.h" - #include "hard-reg-set.h" -- --#if CHECKING_P -- --struct cumulative_args_t { void *magic; void *p; }; -- --#else /* !CHECKING_P */ -- --/* When using a GCC build compiler, we could use -- __attribute__((transparent_union)) to get cumulative_args_t function -- arguments passed like scalars where the ABI would mandate a less -- efficient way of argument passing otherwise. However, that would come -- at the cost of less type-safe !CHECKING_P compilation. */ -- --union cumulative_args_t { void *p; }; -- --#endif /* !CHECKING_P */ -+#include "tree-core.h" -+#include "cumulative-args.h" - - /* Types of memory operation understood by the "by_pieces" infrastructure. - Used by the TARGET_USE_BY_PIECES_INFRASTRUCTURE_P target hook and -diff --git a/gcc/targhooks.cc b/gcc/targhooks.cc -index 51bf3fb..13a7c20 100644 ---- a/gcc/targhooks.cc -+++ b/gcc/targhooks.cc -@@ -159,6 +159,15 @@ default_promote_function_mode_always_promote (const_tree type, - return promote_mode (type, mode, punsignedp); - } - -+machine_mode -+default_promote_function_mode_ca (cumulative_args_t, function_arg_info arg, -+ const_tree funtype, int *punsignedp, -+ int for_return) -+{ -+ return promote_function_mode (arg.type, arg.mode, punsignedp, -+ funtype, for_return); -+} -+ - machine_mode - default_cc_modes_compatible (machine_mode m1, machine_mode m2) - { -@@ -856,6 +865,14 @@ default_function_arg_boundary (machine_mode mode ATTRIBUTE_UNUSED, - return PARM_BOUNDARY; - } - -+unsigned int -+default_function_arg_boundary_ca (machine_mode mode ATTRIBUTE_UNUSED, -+ const_tree type ATTRIBUTE_UNUSED, -+ cumulative_args_t ca ATTRIBUTE_UNUSED) -+{ -+ return default_function_arg_boundary (mode, type); -+} -+ - unsigned int - default_function_arg_round_boundary (machine_mode mode ATTRIBUTE_UNUSED, - const_tree type ATTRIBUTE_UNUSED) -@@ -863,6 +880,14 @@ default_function_arg_round_boundary (machine_mode mode ATTRIBUTE_UNUSED, - return PARM_BOUNDARY; - } - -+unsigned int -+default_function_arg_round_boundary_ca (machine_mode mode ATTRIBUTE_UNUSED, -+ const_tree type ATTRIBUTE_UNUSED, -+ cumulative_args_t ca ATTRIBUTE_UNUSED) -+{ -+ return default_function_arg_round_boundary (mode, type); -+} -+ - void - hook_void_bitmap (bitmap regs ATTRIBUTE_UNUSED) - { -diff --git a/gcc/targhooks.h b/gcc/targhooks.h -index cf3d310..cd4e830 100644 ---- a/gcc/targhooks.h -+++ b/gcc/targhooks.h -@@ -34,6 +34,9 @@ extern machine_mode default_promote_function_mode (const_tree, machine_mode, - extern machine_mode default_promote_function_mode_always_promote - (const_tree, machine_mode, int *, const_tree, int); - -+extern machine_mode default_promote_function_mode_ca -+ (cumulative_args_t, function_arg_info, const_tree, int *, int); -+ - extern machine_mode default_cc_modes_compatible (machine_mode, - machine_mode); - -@@ -158,6 +161,12 @@ extern unsigned int default_function_arg_boundary (machine_mode, - const_tree); - extern unsigned int default_function_arg_round_boundary (machine_mode, - const_tree); -+extern unsigned int default_function_arg_boundary_ca (machine_mode, -+ const_tree, -+ cumulative_args_t ca); -+extern unsigned int default_function_arg_round_boundary_ca (machine_mode, -+ const_tree, -+ cumulative_args_t ca); - extern bool hook_bool_const_rtx_commutative_p (const_rtx, int); - extern rtx default_function_value (const_tree, const_tree, bool); - extern HARD_REG_SET default_zero_call_used_regs (HARD_REG_SET); -diff --git a/gcc/tree-nested.cc b/gcc/tree-nested.cc -index 0f44b3d..8355425 100644 ---- a/gcc/tree-nested.cc -+++ b/gcc/tree-nested.cc -@@ -611,6 +611,14 @@ get_trampoline_type (struct nesting_info *info) - if (trampoline_type) - return trampoline_type; - -+ /* When trampolines are created off-stack then the only thing we need in the -+ local frame is a single pointer. */ -+ if (flag_trampoline_impl == TRAMPOLINE_IMPL_HEAP) -+ { -+ trampoline_type = build_pointer_type (void_type_node); -+ return trampoline_type; -+ } -+ - align = TRAMPOLINE_ALIGNMENT; - size = TRAMPOLINE_SIZE; - -@@ -2793,17 +2801,27 @@ convert_tramp_reference_op (tree *tp, int *walk_subtrees, void *data) - - /* Compute the address of the field holding the trampoline. */ - x = get_frame_field (info, target_context, x, &wi->gsi); -- x = build_addr (x); -- x = gsi_gimplify_val (info, x, &wi->gsi); - -- /* Do machine-specific ugliness. Normally this will involve -- computing extra alignment, but it can really be anything. */ -- if (descr) -- builtin = builtin_decl_implicit (BUILT_IN_ADJUST_DESCRIPTOR); -+ /* APB: We don't need to do the adjustment calls when using off-stack -+ trampolines, any such adjustment will be done when the off-stack -+ trampoline is created. */ -+ if (!descr && flag_trampoline_impl == TRAMPOLINE_IMPL_HEAP) -+ x = gsi_gimplify_val (info, x, &wi->gsi); - else -- builtin = builtin_decl_implicit (BUILT_IN_ADJUST_TRAMPOLINE); -- call = gimple_build_call (builtin, 1, x); -- x = init_tmp_var_with_call (info, &wi->gsi, call); -+ { -+ x = build_addr (x); -+ -+ x = gsi_gimplify_val (info, x, &wi->gsi); -+ -+ /* Do machine-specific ugliness. Normally this will involve -+ computing extra alignment, but it can really be anything. */ -+ if (descr) -+ builtin = builtin_decl_implicit (BUILT_IN_ADJUST_DESCRIPTOR); -+ else -+ builtin = builtin_decl_implicit (BUILT_IN_ADJUST_TRAMPOLINE); -+ call = gimple_build_call (builtin, 1, x); -+ x = init_tmp_var_with_call (info, &wi->gsi, call); -+ } - - /* Cast back to the proper function type. */ - x = build1 (NOP_EXPR, TREE_TYPE (t), x); -@@ -3382,6 +3400,7 @@ build_init_call_stmt (struct nesting_info *info, tree decl, tree field, - static void - finalize_nesting_tree_1 (struct nesting_info *root) - { -+ gimple_seq cleanup_list = NULL; - gimple_seq stmt_list = NULL; - gimple *stmt; - tree context = root->context; -@@ -3513,9 +3532,48 @@ finalize_nesting_tree_1 (struct nesting_info *root) - if (!field) - continue; - -- x = builtin_decl_implicit (BUILT_IN_INIT_TRAMPOLINE); -- stmt = build_init_call_stmt (root, i->context, field, x); -- gimple_seq_add_stmt (&stmt_list, stmt); -+ if (flag_trampoline_impl == TRAMPOLINE_IMPL_HEAP) -+ { -+ /* We pass a whole bunch of arguments to the builtin function that -+ creates the off-stack trampoline, these are -+ 1. The nested function chain value (that must be passed to the -+ nested function so it can find the function arguments). -+ 2. A pointer to the nested function implementation, -+ 3. The address in the local stack frame where we should write -+ the address of the trampoline. -+ -+ When this code was originally written I just kind of threw -+ everything at the builtin, figuring I'd work out what was -+ actually needed later, I think, the stack pointer could -+ certainly be dropped, arguments #2 and #4 are based off the -+ stack pointer anyway, so #1 doesn't seem to add much value. */ -+ tree arg1, arg2, arg3; -+ -+ gcc_assert (DECL_STATIC_CHAIN (i->context)); -+ arg1 = build_addr (root->frame_decl); -+ arg2 = build_addr (i->context); -+ -+ x = build3 (COMPONENT_REF, TREE_TYPE (field), -+ root->frame_decl, field, NULL_TREE); -+ arg3 = build_addr (x); -+ -+ x = builtin_decl_explicit (BUILT_IN_GCC_NESTED_PTR_CREATED); -+ stmt = gimple_build_call (x, 3, arg1, arg2, arg3); -+ gimple_seq_add_stmt (&stmt_list, stmt); -+ -+ /* This call to delete the nested function trampoline is added to -+ the cleanup list, and called when we exit the current scope. */ -+ x = builtin_decl_explicit (BUILT_IN_GCC_NESTED_PTR_DELETED); -+ stmt = gimple_build_call (x, 0); -+ gimple_seq_add_stmt (&cleanup_list, stmt); -+ } -+ else -+ { -+ /* Original code to initialise the on stack trampoline. */ -+ x = builtin_decl_implicit (BUILT_IN_INIT_TRAMPOLINE); -+ stmt = build_init_call_stmt (root, i->context, field, x); -+ gimple_seq_add_stmt (&stmt_list, stmt); -+ } - } - } - -@@ -3540,11 +3598,40 @@ finalize_nesting_tree_1 (struct nesting_info *root) - /* If we created initialization statements, insert them. */ - if (stmt_list) - { -- gbind *bind; -- annotate_all_with_location (stmt_list, DECL_SOURCE_LOCATION (context)); -- bind = gimple_seq_first_stmt_as_a_bind (gimple_body (context)); -- gimple_seq_add_seq (&stmt_list, gimple_bind_body (bind)); -- gimple_bind_set_body (bind, stmt_list); -+ if (flag_trampoline_impl == TRAMPOLINE_IMPL_HEAP) -+ { -+ /* Handle off-stack trampolines. */ -+ gbind *bind; -+ annotate_all_with_location (stmt_list, DECL_SOURCE_LOCATION (context)); -+ annotate_all_with_location (cleanup_list, DECL_SOURCE_LOCATION (context)); -+ bind = gimple_seq_first_stmt_as_a_bind (gimple_body (context)); -+ gimple_seq_add_seq (&stmt_list, gimple_bind_body (bind)); -+ -+ gimple_seq xxx_list = NULL; -+ -+ if (cleanup_list != NULL) -+ { -+ /* Maybe we shouldn't be creating this try/finally if -fno-exceptions is -+ in use. If this is the case, then maybe we should, instead, be -+ inserting the cleanup code onto every path out of this function? Not -+ yet figured out how we would do this. */ -+ gtry *t = gimple_build_try (stmt_list, cleanup_list, GIMPLE_TRY_FINALLY); -+ gimple_seq_add_stmt (&xxx_list, t); -+ } -+ else -+ xxx_list = stmt_list; -+ -+ gimple_bind_set_body (bind, xxx_list); -+ } -+ else -+ { -+ /* The traditional, on stack trampolines. */ -+ gbind *bind; -+ annotate_all_with_location (stmt_list, DECL_SOURCE_LOCATION (context)); -+ bind = gimple_seq_first_stmt_as_a_bind (gimple_body (context)); -+ gimple_seq_add_seq (&stmt_list, gimple_bind_body (bind)); -+ gimple_bind_set_body (bind, stmt_list); -+ } - } - - /* If a chain_decl was created, then it needs to be registered with -diff --git a/gcc/tree.cc b/gcc/tree.cc -index 12dea81..8837041 100644 ---- a/gcc/tree.cc -+++ b/gcc/tree.cc -@@ -9853,6 +9853,28 @@ build_common_builtin_nodes (void) - "__builtin_nonlocal_goto", - ECF_NORETURN | ECF_NOTHROW); - -+ tree ptr_ptr_type_node = build_pointer_type (ptr_type_node); -+ -+ if (!builtin_decl_explicit_p (BUILT_IN_GCC_NESTED_PTR_CREATED)) -+ { -+ ftype = build_function_type_list (void_type_node, -+ ptr_type_node, // void *chain -+ ptr_type_node, // void *func -+ ptr_ptr_type_node, // void **dst -+ NULL_TREE); -+ local_define_builtin ("__builtin___gcc_nested_func_ptr_created", ftype, -+ BUILT_IN_GCC_NESTED_PTR_CREATED, -+ "__gcc_nested_func_ptr_created", ECF_NOTHROW); -+ } -+ -+ if (!builtin_decl_explicit_p (BUILT_IN_GCC_NESTED_PTR_DELETED)) -+ { -+ ftype = build_function_type_list (void_type_node, NULL_TREE); -+ local_define_builtin ("__builtin___gcc_nested_func_ptr_deleted", ftype, -+ BUILT_IN_GCC_NESTED_PTR_DELETED, -+ "__gcc_nested_func_ptr_deleted", ECF_NOTHROW); -+ } -+ - ftype = build_function_type_list (void_type_node, - ptr_type_node, ptr_type_node, NULL_TREE); - local_define_builtin ("__builtin_setjmp_setup", ftype, -diff --git a/intl/Makefile.in b/intl/Makefile.in -index 409d693..5beebdc 100644 ---- a/intl/Makefile.in -+++ b/intl/Makefile.in -@@ -54,7 +54,7 @@ CTAGS = @CTAGS@ - ETAGS = @ETAGS@ - MKID = @MKID@ - --COMPILE = $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(DEFS-$@) $(INCLUDES) -+COMPILE = $(CC) -c $(CPPFLAGS) $(CFLAGS) @PICFLAG@ $(DEFS) $(DEFS-$@) $(INCLUDES) - - HEADERS = \ - gmo.h \ -diff --git a/intl/configure b/intl/configure -index 03f4048..79bb583 100755 ---- a/intl/configure -+++ b/intl/configure -@@ -623,6 +623,8 @@ ac_header_list= - ac_subst_vars='LTLIBOBJS - LIBOBJS - PICFLAG -+enable_host_pie -+enable_host_shared - BISON3_NO - BISON3_YES - INCINTL -@@ -731,6 +733,7 @@ with_libintl_prefix - with_libintl_type - enable_maintainer_mode - enable_host_shared -+enable_host_pie - ' - ac_precious_vars='build_alias - host_alias -@@ -1356,6 +1359,7 @@ Optional Features: - --disable-rpath do not hardcode runtime library paths - --enable-maintainer-mode enable rules only needed by maintainers - --enable-host-shared build host code as shared libraries -+ --enable-host-pie build host code as PIE - - Optional Packages: - --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] -@@ -6852,15 +6856,31 @@ fi - - - -+# Enable --enable-host-shared. - # Check whether --enable-host-shared was given. - if test "${enable_host_shared+set}" = set; then : -- enableval=$enable_host_shared; PICFLAG=-fPIC -+ enableval=$enable_host_shared; -+fi -+ -+ -+ -+# Enable --enable-host-pie. -+# Check whether --enable-host-pie was given. -+if test "${enable_host_pie+set}" = set; then : -+ enableval=$enable_host_pie; -+fi -+ -+ -+ -+if test x$enable_host_shared = xyes; then -+ PICFLAG=-fPIC -+elif test x$enable_host_pie = xyes; then -+ PICFLAG=-fPIE - else - PICFLAG= - fi - - -- - ac_config_files="$ac_config_files Makefile config.intl" - - cat >confcache <<\_ACEOF -diff --git a/intl/configure.ac b/intl/configure.ac -index 16a740a..81aa831 100644 ---- a/intl/configure.ac -+++ b/intl/configure.ac -@@ -83,10 +83,25 @@ fi - AC_SUBST(BISON3_YES) - AC_SUBST(BISON3_NO) - -+# Enable --enable-host-shared. - AC_ARG_ENABLE(host-shared, - [AS_HELP_STRING([--enable-host-shared], -- [build host code as shared libraries])], --[PICFLAG=-fPIC], [PICFLAG=]) -+ [build host code as shared libraries])]) -+AC_SUBST(enable_host_shared) -+ -+# Enable --enable-host-pie. -+AC_ARG_ENABLE(host-pie, -+[AS_HELP_STRING([--enable-host-pie], -+ [build host code as PIE])]) -+AC_SUBST(enable_host_pie) -+ -+if test x$enable_host_shared = xyes; then -+ PICFLAG=-fPIC -+elif test x$enable_host_pie = xyes; then -+ PICFLAG=-fPIE -+else -+ PICFLAG= -+fi - AC_SUBST(PICFLAG) - - AC_CONFIG_FILES(Makefile config.intl) -diff --git a/libatomic/Makefile.am b/libatomic/Makefile.am -index c6c8d81..3bb32f3 100644 ---- a/libatomic/Makefile.am -+++ b/libatomic/Makefile.am -@@ -65,8 +65,13 @@ libatomic_version_script = - libatomic_version_dep = - endif - libatomic_version_info = -version-info $(libtool_VERSION) -+if ENABLE_DARWIN_AT_RPATH -+libatomic_darwin_rpath = -Wc,-nodefaultrpaths -+libatomic_darwin_rpath += -Wl,-rpath,@loader_path -+endif - --libatomic_la_LDFLAGS = $(libatomic_version_info) $(libatomic_version_script) $(lt_host_flags) -+libatomic_la_LDFLAGS = $(libatomic_version_info) $(libatomic_version_script) \ -+ $(lt_host_flags) $(libatomic_darwin_rpath) - libatomic_la_SOURCES = gload.c gstore.c gcas.c gexch.c glfree.c lock.c init.c \ - fenv.c fence.c flag.c - -diff --git a/libatomic/Makefile.in b/libatomic/Makefile.in -index a0fa3df..ef7ef45 100644 ---- a/libatomic/Makefile.in -+++ b/libatomic/Makefile.in -@@ -417,7 +417,12 @@ noinst_LTLIBRARIES = libatomic_convenience.la - @LIBAT_BUILD_VERSIONED_SHLIB_GNU_TRUE@@LIBAT_BUILD_VERSIONED_SHLIB_TRUE@libatomic_version_dep = $(top_srcdir)/libatomic.map - @LIBAT_BUILD_VERSIONED_SHLIB_SUN_TRUE@@LIBAT_BUILD_VERSIONED_SHLIB_TRUE@libatomic_version_dep = libatomic.map-sun - libatomic_version_info = -version-info $(libtool_VERSION) --libatomic_la_LDFLAGS = $(libatomic_version_info) $(libatomic_version_script) $(lt_host_flags) -+@ENABLE_DARWIN_AT_RPATH_TRUE@libatomic_darwin_rpath = \ -+@ENABLE_DARWIN_AT_RPATH_TRUE@ -Wc,-nodefaultrpaths \ -+@ENABLE_DARWIN_AT_RPATH_TRUE@ -Wl,-rpath,@loader_path -+libatomic_la_LDFLAGS = $(libatomic_version_info) $(libatomic_version_script) \ -+ $(lt_host_flags) $(libatomic_darwin_rpath) -+ - libatomic_la_SOURCES = gload.c gstore.c gcas.c gexch.c glfree.c lock.c \ - init.c fenv.c fence.c flag.c $(am__append_2) - SIZEOBJS = load store cas exch fadd fsub fand fior fxor fnand tas -diff --git a/libatomic/configure b/libatomic/configure -index e47d2d7..7c1d46b 100755 ---- a/libatomic/configure -+++ b/libatomic/configure -@@ -658,6 +658,8 @@ OPT_LDFLAGS - SECTION_LDFLAGS - enable_aarch64_lse - libtool_VERSION -+ENABLE_DARWIN_AT_RPATH_FALSE -+ENABLE_DARWIN_AT_RPATH_TRUE - MAINT - MAINTAINER_MODE_FALSE - MAINTAINER_MODE_TRUE -@@ -803,6 +805,7 @@ with_pic - enable_fast_install - with_gnu_ld - enable_libtool_lock -+enable_darwin_at_rpath - enable_maintainer_mode - enable_symvers - enable_werror -@@ -1452,6 +1455,9 @@ Optional Features: - --enable-fast-install[=PKGS] - optimize for fast installation [default=yes] - --disable-libtool-lock avoid locking (might break parallel builds) -+ --enable-darwin-at-rpath -+ install libraries with @rpath/library-name, requires -+ rpaths to be added to executables - --enable-maintainer-mode - enable make rules and dependencies not useful (and - sometimes confusing) to the casual installer -@@ -7608,7 +7614,7 @@ $as_echo "$lt_cv_ld_force_load" >&6; } - # darwin 5.x (macOS 10.1) onwards we only need to adjust when the - # deployment target is forced to an earlier version. - case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host in -- UNSET,*-darwin[89]*|UNSET,*-darwin[12][0123456789]*) -+ UNSET,*-darwin[89]*|UNSET,*-darwin[12][0-9]*) - ;; - 10.[012][,.]*) - _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' -@@ -9581,6 +9587,49 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi - darwin* | rhapsody*) - - -+ -+ # Publish an arg to allow the user to select that Darwin host (and target) -+ # libraries should be given install-names like @rpath/libfoo.dylib. This -+ # requires that the user of the library then adds an 'rpath' to the DSO that -+ # needs access. -+ # NOTE: there are defaults below, for systems that support rpaths. The person -+ # configuring can override the defaults for any system version that supports -+ # them - they are, however, forced off for system versions without support. -+ # Check whether --enable-darwin-at-rpath was given. -+if test "${enable_darwin_at_rpath+set}" = set; then : -+ enableval=$enable_darwin_at_rpath; if test "x$enable_darwin_at_rpath" = "xyes"; then -+ # This is not supported before macOS 10.5 / Darwin9. -+ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in -+ UNSET,darwin[4-8]*|UNSET,rhapsody*|10.[0-4][,.]*) -+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Darwin @rpath library names are incompatible with OSX versions earlier than 10.5 (rpaths disabled)" >&5 -+$as_echo "$as_me: WARNING: Darwin @rpath library names are incompatible with OSX versions earlier than 10.5 (rpaths disabled)" >&2;} -+ enable_darwin_at_rpath=no -+ ;; -+ esac -+ fi -+else -+ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in -+ # As above, before 10.5 / Darwin9 this does not work. -+ UNSET,darwin[4-8]*|UNSET,rhapsody*|10.[0-4][,.]*) -+ enable_darwin_at_rpath=no -+ ;; -+ -+ # We cannot build and test reliably on macOS 10.11+ (Darwin15+) without use -+ # of rpaths, since runpaths set via DYLD_LIBRARY_PATH are elided by key -+ # system executables (e.g. /bin/sh). Force rpaths on for these systems. -+ UNSET,darwin1[5-9]*|UNSET,darwin2*|10.1[1-9][,.]*|1[1-9].*[,.]* ) -+ { $as_echo "$as_me:${as_lineno-$LINENO}: @rpath library names are needed on macOS versions later than 10.11 (rpaths have been enabled)" >&5 -+$as_echo "$as_me: @rpath library names are needed on macOS versions later than 10.11 (rpaths have been enabled)" >&6;} -+ enable_darwin_at_rpath=yes -+ ;; -+ # NOTE: we are not (yet) doing anything for 10.5 .. 10.10, since they can -+ # work with either DYLD_LIBRARY_PATH or embedded rpaths. -+ -+ esac -+ -+fi -+ -+ - archive_cmds_need_lc=no - hardcode_direct=no - hardcode_automatic=yes -@@ -9598,9 +9647,13 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi - esac - if test "$_lt_dar_can_shared" = "yes"; then - output_verbose_link_cmd=func_echo_all -- archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" -+ _lt_install_name='\$rpath/\$soname' -+ if test "x$enable_darwin_at_rpath" = "xyes"; then -+ _lt_install_name='@rpath/\$soname' -+ fi -+ archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name ${_lt_install_name} \$verstring ${_lt_dsymutil}" - module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" -- archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" -+ archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name ${_lt_install_name} \$verstring ${_lt_dar_export_syms}${_lt_dsymutil}" - module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" - - else -@@ -11406,7 +11459,7 @@ else - lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 - lt_status=$lt_dlunknown - cat > conftest.$ac_ext <<_LT_EOF --#line 11409 "configure" -+#line 11462 "configure" - #include "confdefs.h" - - #if HAVE_DLFCN_H -@@ -11512,7 +11565,7 @@ else - lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 - lt_status=$lt_dlunknown - cat > conftest.$ac_ext <<_LT_EOF --#line 11515 "configure" -+#line 11568 "configure" - #include "confdefs.h" - - #if HAVE_DLFCN_H -@@ -11797,6 +11850,15 @@ fi - - - -+ if test x$enable_darwin_at_rpath = xyes; then -+ ENABLE_DARWIN_AT_RPATH_TRUE= -+ ENABLE_DARWIN_AT_RPATH_FALSE='#' -+else -+ ENABLE_DARWIN_AT_RPATH_TRUE='#' -+ ENABLE_DARWIN_AT_RPATH_FALSE= -+fi -+ -+ - # For libtool versioning info, format is CURRENT:REVISION:AGE - libtool_VERSION=3:0:2 - -@@ -15924,6 +15986,10 @@ if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then - as_fn_error $? "conditional \"MAINTAINER_MODE\" was never defined. - Usually this means the macro was only invoked conditionally." "$LINENO" 5 - fi -+if test -z "${ENABLE_DARWIN_AT_RPATH_TRUE}" && test -z "${ENABLE_DARWIN_AT_RPATH_FALSE}"; then -+ as_fn_error $? "conditional \"ENABLE_DARWIN_AT_RPATH\" was never defined. -+Usually this means the macro was only invoked conditionally." "$LINENO" 5 -+fi - - if test -z "${LIBAT_BUILD_VERSIONED_SHLIB_TRUE}" && test -z "${LIBAT_BUILD_VERSIONED_SHLIB_FALSE}"; then - as_fn_error $? "conditional \"LIBAT_BUILD_VERSIONED_SHLIB\" was never defined. -diff --git a/libatomic/configure.ac b/libatomic/configure.ac -index 3130468..20981f1 100644 ---- a/libatomic/configure.ac -+++ b/libatomic/configure.ac -@@ -156,6 +156,8 @@ AC_SUBST(enable_shared) - AC_SUBST(enable_static) - AM_MAINTAINER_MODE - -+AM_CONDITIONAL([ENABLE_DARWIN_AT_RPATH], [test x$enable_darwin_at_rpath = xyes]) -+ - # For libtool versioning info, format is CURRENT:REVISION:AGE - libtool_VERSION=3:0:2 - AC_SUBST(libtool_VERSION) -diff --git a/libbacktrace/configure b/libbacktrace/configure -index 6af2c04..4a25e38 100755 ---- a/libbacktrace/configure -+++ b/libbacktrace/configure -@@ -681,6 +681,8 @@ PIC_FLAG - WARN_FLAGS - EXTRA_FLAGS - BACKTRACE_FILE -+ENABLE_DARWIN_AT_RPATH_FALSE -+ENABLE_DARWIN_AT_RPATH_TRUE - OTOOL64 - OTOOL - LIPO -@@ -805,6 +807,7 @@ with_pic - enable_fast_install - with_gnu_ld - enable_libtool_lock -+enable_darwin_at_rpath - enable_largefile - enable_cet - enable_werror -@@ -1453,6 +1456,9 @@ Optional Features: - --enable-fast-install[=PKGS] - optimize for fast installation [default=yes] - --disable-libtool-lock avoid locking (might break parallel builds) -+ --enable-darwin-at-rpath -+ install libraries with @rpath/library-name, requires -+ rpaths to be added to executables - --disable-largefile omit support for large files - --enable-cet enable Intel CET in target libraries [default=auto] - --disable-werror disable building with -Werror -@@ -8010,7 +8016,7 @@ $as_echo "$lt_cv_ld_force_load" >&6; } - # darwin 5.x (macOS 10.1) onwards we only need to adjust when the - # deployment target is forced to an earlier version. - case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host in -- UNSET,*-darwin[89]*|UNSET,*-darwin[12][0123456789]*) -+ UNSET,*-darwin[89]*|UNSET,*-darwin[12][0-9]*) - ;; - 10.[012][,.]*) - _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' -@@ -9716,6 +9722,49 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi - darwin* | rhapsody*) - - -+ -+ # Publish an arg to allow the user to select that Darwin host (and target) -+ # libraries should be given install-names like @rpath/libfoo.dylib. This -+ # requires that the user of the library then adds an 'rpath' to the DSO that -+ # needs access. -+ # NOTE: there are defaults below, for systems that support rpaths. The person -+ # configuring can override the defaults for any system version that supports -+ # them - they are, however, forced off for system versions without support. -+ # Check whether --enable-darwin-at-rpath was given. -+if test "${enable_darwin_at_rpath+set}" = set; then : -+ enableval=$enable_darwin_at_rpath; if test "x$enable_darwin_at_rpath" = "xyes"; then -+ # This is not supported before macOS 10.5 / Darwin9. -+ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in -+ UNSET,darwin[4-8]*|UNSET,rhapsody*|10.[0-4][,.]*) -+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Darwin @rpath library names are incompatible with OSX versions earlier than 10.5 (rpaths disabled)" >&5 -+$as_echo "$as_me: WARNING: Darwin @rpath library names are incompatible with OSX versions earlier than 10.5 (rpaths disabled)" >&2;} -+ enable_darwin_at_rpath=no -+ ;; -+ esac -+ fi -+else -+ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in -+ # As above, before 10.5 / Darwin9 this does not work. -+ UNSET,darwin[4-8]*|UNSET,rhapsody*|10.[0-4][,.]*) -+ enable_darwin_at_rpath=no -+ ;; -+ -+ # We cannot build and test reliably on macOS 10.11+ (Darwin15+) without use -+ # of rpaths, since runpaths set via DYLD_LIBRARY_PATH are elided by key -+ # system executables (e.g. /bin/sh). Force rpaths on for these systems. -+ UNSET,darwin1[5-9]*|UNSET,darwin2*|10.1[1-9][,.]*|1[1-9].*[,.]* ) -+ { $as_echo "$as_me:${as_lineno-$LINENO}: @rpath library names are needed on macOS versions later than 10.11 (rpaths have been enabled)" >&5 -+$as_echo "$as_me: @rpath library names are needed on macOS versions later than 10.11 (rpaths have been enabled)" >&6;} -+ enable_darwin_at_rpath=yes -+ ;; -+ # NOTE: we are not (yet) doing anything for 10.5 .. 10.10, since they can -+ # work with either DYLD_LIBRARY_PATH or embedded rpaths. -+ -+ esac -+ -+fi -+ -+ - archive_cmds_need_lc=no - hardcode_direct=no - hardcode_automatic=yes -@@ -9733,9 +9782,13 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi - esac - if test "$_lt_dar_can_shared" = "yes"; then - output_verbose_link_cmd=func_echo_all -- archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" -+ _lt_install_name='\$rpath/\$soname' -+ if test "x$enable_darwin_at_rpath" = "xyes"; then -+ _lt_install_name='@rpath/\$soname' -+ fi -+ archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name ${_lt_install_name} \$verstring ${_lt_dsymutil}" - module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" -- archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" -+ archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name ${_lt_install_name} \$verstring ${_lt_dar_export_syms}${_lt_dsymutil}" - module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" - - else -@@ -11541,7 +11594,7 @@ else - lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 - lt_status=$lt_dlunknown - cat > conftest.$ac_ext <<_LT_EOF --#line 11544 "configure" -+#line 11597 "configure" - #include "confdefs.h" - - #if HAVE_DLFCN_H -@@ -11647,7 +11700,7 @@ else - lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 - lt_status=$lt_dlunknown - cat > conftest.$ac_ext <<_LT_EOF --#line 11650 "configure" -+#line 11703 "configure" - #include "confdefs.h" - - #if HAVE_DLFCN_H -@@ -11886,6 +11939,15 @@ CC="$lt_save_CC" - - - -+ if test x$enable_darwin_at_rpath = xyes; then -+ ENABLE_DARWIN_AT_RPATH_TRUE= -+ ENABLE_DARWIN_AT_RPATH_FALSE='#' -+else -+ ENABLE_DARWIN_AT_RPATH_TRUE='#' -+ ENABLE_DARWIN_AT_RPATH_FALSE= -+fi -+ -+ - # Check whether --enable-largefile was given. - if test "${enable_largefile+set}" = set; then : - enableval=$enable_largefile; -@@ -14435,6 +14497,10 @@ if test -z "${HAVE_DWZ_TRUE}" && test -z "${HAVE_DWZ_FALSE}"; then - as_fn_error $? "conditional \"HAVE_DWZ\" was never defined. - Usually this means the macro was only invoked conditionally." "$LINENO" 5 - fi -+if test -z "${ENABLE_DARWIN_AT_RPATH_TRUE}" && test -z "${ENABLE_DARWIN_AT_RPATH_FALSE}"; then -+ as_fn_error $? "conditional \"ENABLE_DARWIN_AT_RPATH\" was never defined. -+Usually this means the macro was only invoked conditionally." "$LINENO" 5 -+fi - if test -z "${HAVE_ELF_TRUE}" && test -z "${HAVE_ELF_FALSE}"; then - as_fn_error $? "conditional \"HAVE_ELF\" was never defined. - Usually this means the macro was only invoked conditionally." "$LINENO" 5 -diff --git a/libbacktrace/configure.ac b/libbacktrace/configure.ac -index 39e6bf4..98b96fc 100644 ---- a/libbacktrace/configure.ac -+++ b/libbacktrace/configure.ac -@@ -84,6 +84,8 @@ AM_CONDITIONAL(HAVE_DWZ, test "$DWZ" != "") - LT_INIT - AM_PROG_LIBTOOL - -+AM_CONDITIONAL([ENABLE_DARWIN_AT_RPATH], [test x$enable_darwin_at_rpath = xyes]) -+ - AC_SYS_LARGEFILE - - backtrace_supported=yes -diff --git a/libcc1/configure b/libcc1/configure -index bae3b87..cd9acc3 100755 ---- a/libcc1/configure -+++ b/libcc1/configure -@@ -787,6 +787,7 @@ with_pic - enable_fast_install - with_gnu_ld - enable_libtool_lock -+enable_darwin_at_rpath - enable_cet - with_gcc_major_version_only - enable_werror_always -@@ -1439,6 +1440,9 @@ Optional Features: - --enable-fast-install[=PKGS] - optimize for fast installation [default=yes] - --disable-libtool-lock avoid locking (might break parallel builds) -+ --enable-darwin-at-rpath -+ install libraries with @rpath/library-name, requires -+ rpaths to be added to executables - --enable-cet enable Intel CET in host libraries [default=auto] - --enable-werror-always enable -Werror despite compiler version - --enable-plugin enable plugin support -@@ -7271,7 +7275,7 @@ $as_echo "$lt_cv_ld_force_load" >&6; } - # darwin 5.x (macOS 10.1) onwards we only need to adjust when the - # deployment target is forced to an earlier version. - case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host in -- UNSET,*-darwin[89]*|UNSET,*-darwin[12][0123456789]*) -+ UNSET,*-darwin[89]*|UNSET,*-darwin[12][0-9]*) - ;; - 10.[012][,.]*) - _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' -@@ -8976,6 +8980,49 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi - darwin* | rhapsody*) - - -+ -+ # Publish an arg to allow the user to select that Darwin host (and target) -+ # libraries should be given install-names like @rpath/libfoo.dylib. This -+ # requires that the user of the library then adds an 'rpath' to the DSO that -+ # needs access. -+ # NOTE: there are defaults below, for systems that support rpaths. The person -+ # configuring can override the defaults for any system version that supports -+ # them - they are, however, forced off for system versions without support. -+ # Check whether --enable-darwin-at-rpath was given. -+if test "${enable_darwin_at_rpath+set}" = set; then : -+ enableval=$enable_darwin_at_rpath; if test "x$enable_darwin_at_rpath" = "xyes"; then -+ # This is not supported before macOS 10.5 / Darwin9. -+ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in -+ UNSET,darwin[4-8]*|UNSET,rhapsody*|10.[0-4][,.]*) -+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Darwin @rpath library names are incompatible with OSX versions earlier than 10.5 (rpaths disabled)" >&5 -+$as_echo "$as_me: WARNING: Darwin @rpath library names are incompatible with OSX versions earlier than 10.5 (rpaths disabled)" >&2;} -+ enable_darwin_at_rpath=no -+ ;; -+ esac -+ fi -+else -+ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in -+ # As above, before 10.5 / Darwin9 this does not work. -+ UNSET,darwin[4-8]*|UNSET,rhapsody*|10.[0-4][,.]*) -+ enable_darwin_at_rpath=no -+ ;; -+ -+ # We cannot build and test reliably on macOS 10.11+ (Darwin15+) without use -+ # of rpaths, since runpaths set via DYLD_LIBRARY_PATH are elided by key -+ # system executables (e.g. /bin/sh). Force rpaths on for these systems. -+ UNSET,darwin1[5-9]*|UNSET,darwin2*|10.1[1-9][,.]*|1[1-9].*[,.]* ) -+ { $as_echo "$as_me:${as_lineno-$LINENO}: @rpath library names are needed on macOS versions later than 10.11 (rpaths have been enabled)" >&5 -+$as_echo "$as_me: @rpath library names are needed on macOS versions later than 10.11 (rpaths have been enabled)" >&6;} -+ enable_darwin_at_rpath=yes -+ ;; -+ # NOTE: we are not (yet) doing anything for 10.5 .. 10.10, since they can -+ # work with either DYLD_LIBRARY_PATH or embedded rpaths. -+ -+ esac -+ -+fi -+ -+ - archive_cmds_need_lc=no - hardcode_direct=no - hardcode_automatic=yes -@@ -8993,9 +9040,13 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi - esac - if test "$_lt_dar_can_shared" = "yes"; then - output_verbose_link_cmd=func_echo_all -- archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" -+ _lt_install_name='\$rpath/\$soname' -+ if test "x$enable_darwin_at_rpath" = "xyes"; then -+ _lt_install_name='@rpath/\$soname' -+ fi -+ archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name ${_lt_install_name} \$verstring ${_lt_dsymutil}" - module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" -- archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" -+ archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name ${_lt_install_name} \$verstring ${_lt_dar_export_syms}${_lt_dsymutil}" - module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" - - else -@@ -10801,7 +10852,7 @@ else - lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 - lt_status=$lt_dlunknown - cat > conftest.$ac_ext <<_LT_EOF --#line 10804 "configure" -+#line 10855 "configure" - #include "confdefs.h" - - #if HAVE_DLFCN_H -@@ -10907,7 +10958,7 @@ else - lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 - lt_status=$lt_dlunknown - cat > conftest.$ac_ext <<_LT_EOF --#line 10910 "configure" -+#line 10961 "configure" - #include "confdefs.h" - - #if HAVE_DLFCN_H -@@ -12189,6 +12240,49 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi - darwin* | rhapsody*) - - -+ -+ # Publish an arg to allow the user to select that Darwin host (and target) -+ # libraries should be given install-names like @rpath/libfoo.dylib. This -+ # requires that the user of the library then adds an 'rpath' to the DSO that -+ # needs access. -+ # NOTE: there are defaults below, for systems that support rpaths. The person -+ # configuring can override the defaults for any system version that supports -+ # them - they are, however, forced off for system versions without support. -+ # Check whether --enable-darwin-at-rpath was given. -+if test "${enable_darwin_at_rpath+set}" = set; then : -+ enableval=$enable_darwin_at_rpath; if test "x$enable_darwin_at_rpath" = "xyes"; then -+ # This is not supported before macOS 10.5 / Darwin9. -+ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in -+ UNSET,darwin[4-8]*|UNSET,rhapsody*|10.[0-4][,.]*) -+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Darwin @rpath library names are incompatible with OSX versions earlier than 10.5 (rpaths disabled)" >&5 -+$as_echo "$as_me: WARNING: Darwin @rpath library names are incompatible with OSX versions earlier than 10.5 (rpaths disabled)" >&2;} -+ enable_darwin_at_rpath=no -+ ;; -+ esac -+ fi -+else -+ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in -+ # As above, before 10.5 / Darwin9 this does not work. -+ UNSET,darwin[4-8]*|UNSET,rhapsody*|10.[0-4][,.]*) -+ enable_darwin_at_rpath=no -+ ;; -+ -+ # We cannot build and test reliably on macOS 10.11+ (Darwin15+) without use -+ # of rpaths, since runpaths set via DYLD_LIBRARY_PATH are elided by key -+ # system executables (e.g. /bin/sh). Force rpaths on for these systems. -+ UNSET,darwin1[5-9]*|UNSET,darwin2*|10.1[1-9][,.]*|1[1-9].*[,.]* ) -+ { $as_echo "$as_me:${as_lineno-$LINENO}: @rpath library names are needed on macOS versions later than 10.11 (rpaths have been enabled)" >&5 -+$as_echo "$as_me: @rpath library names are needed on macOS versions later than 10.11 (rpaths have been enabled)" >&6;} -+ enable_darwin_at_rpath=yes -+ ;; -+ # NOTE: we are not (yet) doing anything for 10.5 .. 10.10, since they can -+ # work with either DYLD_LIBRARY_PATH or embedded rpaths. -+ -+ esac -+ -+fi -+ -+ - archive_cmds_need_lc_CXX=no - hardcode_direct_CXX=no - hardcode_automatic_CXX=yes -@@ -12206,12 +12300,20 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi - esac - if test "$_lt_dar_can_shared" = "yes"; then - output_verbose_link_cmd=func_echo_all -- archive_cmds_CXX="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" -+ _lt_install_name='\$rpath/\$soname' -+ if test "x$enable_darwin_at_rpath" = "xyes"; then -+ _lt_install_name='@rpath/\$soname' -+ fi -+ archive_cmds_CXX="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name ${_lt_install_name} \$verstring ${_lt_dsymutil}" - module_cmds_CXX="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" -- archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" -+ archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name ${_lt_install_name} \$verstring ${_lt_dar_export_syms}${_lt_dsymutil}" - module_expsym_cmds_CXX="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" - if test "$lt_cv_apple_cc_single_mod" != "yes"; then -- archive_cmds_CXX="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}" -+ _lt_install_name='\$rpath/\$soname' -+ if test "x$enable_darwin_at_rpath" = "xyes"; then -+ _lt_install_name='@rpath/\$soname' -+ fi -+ archive_cmds_CXX="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name ${_lt_install_name} \$verstring${_lt_dsymutil}" - archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}" - fi - -diff --git a/libcody/Makefile.in b/libcody/Makefile.in -index bb87468..cb01b00 100644 ---- a/libcody/Makefile.in -+++ b/libcody/Makefile.in -@@ -31,7 +31,7 @@ endif - CXXOPTS += $(filter-out -DHAVE_CONFIG_H,@DEFS@) -include config.h - - # Linker options --LDFLAGS := @LDFLAGS@ -+LDFLAGS := @LDFLAGS@ @LD_PICFLAG@ - LIBS := @LIBS@ - - # Per-source & per-directory compile flags (warning: recursive) -diff --git a/libcody/configure b/libcody/configure -index da52a5c..0e536c0 100755 ---- a/libcody/configure -+++ b/libcody/configure -@@ -591,7 +591,10 @@ configure_args - AR - RANLIB - EXCEPTIONS -+LD_PICFLAG - PICFLAG -+enable_host_pie -+enable_host_shared - OBJEXT - EXEEXT - ac_ct_CXX -@@ -653,6 +656,7 @@ enable_maintainer_mode - with_compiler - enable_checking - enable_host_shared -+enable_host_pie - enable_exceptions - ' - ac_precious_vars='build_alias -@@ -1286,6 +1290,7 @@ Optional Features: - yes,no,all,none,release. Flags are: misc,valgrind or - other strings - --enable-host-shared build host code as shared libraries -+ --enable-host-pie build host code as PIE - --enable-exceptions enable exceptions & rtti - - Optional Packages: -@@ -2635,11 +2640,34 @@ fi - # Enable --enable-host-shared. - # Check whether --enable-host-shared was given. - if test "${enable_host_shared+set}" = set; then : -- enableval=$enable_host_shared; PICFLAG=-fPIC -+ enableval=$enable_host_shared; -+fi -+ -+ -+ -+# Enable --enable-host-pie. -+# Check whether --enable-host-pie was given. -+if test "${enable_host_pie+set}" = set; then : -+ enableval=$enable_host_pie; -+fi -+ -+ -+ -+if test x$enable_host_shared = xyes; then -+ PICFLAG=-fPIC -+elif test x$enable_host_pie = xyes; then -+ PICFLAG=-fPIE - else - PICFLAG= - fi - -+if test x$enable_host_pie = xyes; then -+ LD_PICFLAG=-pie -+else -+ LD_PICFLAG= -+fi -+ -+ - - - # Check whether --enable-exceptions was given. -diff --git a/libcody/configure.ac b/libcody/configure.ac -index 960191e..14e8dd4 100644 ---- a/libcody/configure.ac -+++ b/libcody/configure.ac -@@ -63,9 +63,31 @@ fi - # Enable --enable-host-shared. - AC_ARG_ENABLE(host-shared, - [AS_HELP_STRING([--enable-host-shared], -- [build host code as shared libraries])], --[PICFLAG=-fPIC], [PICFLAG=]) -+ [build host code as shared libraries])]) -+AC_SUBST(enable_host_shared) -+ -+# Enable --enable-host-pie. -+AC_ARG_ENABLE(host-pie, -+[AS_HELP_STRING([--enable-host-pie], -+ [build host code as PIE])]) -+AC_SUBST(enable_host_pie) -+ -+if test x$enable_host_shared = xyes; then -+ PICFLAG=-fPIC -+elif test x$enable_host_pie = xyes; then -+ PICFLAG=-fPIE -+else -+ PICFLAG= -+fi -+ -+if test x$enable_host_pie = xyes; then -+ LD_PICFLAG=-pie -+else -+ LD_PICFLAG= -+fi -+ - AC_SUBST(PICFLAG) -+AC_SUBST(LD_PICFLAG) - - NMS_ENABLE_EXCEPTIONS - -diff --git a/libcpp/configure b/libcpp/configure -index e9937cd..1389dda 100755 ---- a/libcpp/configure -+++ b/libcpp/configure -@@ -625,6 +625,8 @@ ac_includes_default="\ - ac_subst_vars='LTLIBOBJS - CET_HOST_FLAGS - PICFLAG -+enable_host_pie -+enable_host_shared - MAINT - USED_CATALOGS - PACKAGE -@@ -738,6 +740,7 @@ enable_maintainer_mode - enable_checking - enable_canonical_system_headers - enable_host_shared -+enable_host_pie - enable_cet - enable_valgrind_annotations - ' -@@ -1379,6 +1382,7 @@ Optional Features: - --enable-canonical-system-headers - enable or disable system headers canonicalization - --enable-host-shared build host code as shared libraries -+ --enable-host-pie build host code as PIE - --enable-cet enable Intel CET in host libraries [default=auto] - --enable-valgrind-annotations - enable valgrind runtime interaction -@@ -7605,7 +7609,23 @@ esac - # Enable --enable-host-shared. - # Check whether --enable-host-shared was given. - if test "${enable_host_shared+set}" = set; then : -- enableval=$enable_host_shared; PICFLAG=-fPIC -+ enableval=$enable_host_shared; -+fi -+ -+ -+ -+# Enable --enable-host-pie. -+# Check whether --enable-host-pie was given. -+if test "${enable_host_pie+set}" = set; then : -+ enableval=$enable_host_pie; -+fi -+ -+ -+ -+if test x$enable_host_shared = xyes; then -+ PICFLAG=-fPIC -+elif test x$enable_host_pie = xyes; then -+ PICFLAG=-fPIE - else - PICFLAG= - fi -diff --git a/libcpp/configure.ac b/libcpp/configure.ac -index 89ac99b..b29b4d6 100644 ---- a/libcpp/configure.ac -+++ b/libcpp/configure.ac -@@ -211,8 +211,23 @@ esac - # Enable --enable-host-shared. - AC_ARG_ENABLE(host-shared, - [AS_HELP_STRING([--enable-host-shared], -- [build host code as shared libraries])], --[PICFLAG=-fPIC], [PICFLAG=]) -+ [build host code as shared libraries])]) -+AC_SUBST(enable_host_shared) -+ -+# Enable --enable-host-pie. -+AC_ARG_ENABLE(host-pie, -+[AS_HELP_STRING([--enable-host-pie], -+ [build host code as PIE])]) -+AC_SUBST(enable_host_pie) -+ -+if test x$enable_host_shared = xyes; then -+ PICFLAG=-fPIC -+elif test x$enable_host_pie = xyes; then -+ PICFLAG=-fPIE -+else -+ PICFLAG= -+fi -+ - AC_SUBST(PICFLAG) - - # Enable Intel CET on Intel CET enabled host if jit is enabled. -diff --git a/libcpp/include/cpplib.h b/libcpp/include/cpplib.h -index b8e50ae..26474a4 100644 ---- a/libcpp/include/cpplib.h -+++ b/libcpp/include/cpplib.h -@@ -756,6 +756,9 @@ struct cpp_callbacks - /* Callback to determine whether a built-in function is recognized. */ - int (*has_builtin) (cpp_reader *); - -+ /* Callback to determine whether a feature is available. */ -+ int (*has_feature) (cpp_reader *, bool); -+ - /* Callback that can change a user lazy into normal macro. */ - void (*user_lazy_macro) (cpp_reader *, cpp_macro *, unsigned); - -@@ -960,7 +963,9 @@ enum cpp_builtin_type - BT_HAS_STD_ATTRIBUTE, /* `__has_c_attribute(x)' */ - BT_HAS_BUILTIN, /* `__has_builtin(x)' */ - BT_HAS_INCLUDE, /* `__has_include(x)' */ -- BT_HAS_INCLUDE_NEXT /* `__has_include_next(x)' */ -+ BT_HAS_INCLUDE_NEXT, /* `__has_include_next(x)' */ -+ BT_HAS_FEATURE, /* `__has_feature(x)' */ -+ BT_HAS_EXTENSION /* `__has_extension(x)' */ - }; - - #define CPP_HASHNODE(HNODE) ((cpp_hashnode *) (HNODE)) -diff --git a/libcpp/init.cc b/libcpp/init.cc -index c508f06..465dafe 100644 ---- a/libcpp/init.cc -+++ b/libcpp/init.cc -@@ -433,6 +433,8 @@ static const struct builtin_macro builtin_array[] = - B("__has_builtin", BT_HAS_BUILTIN, true), - B("__has_include", BT_HAS_INCLUDE, true), - B("__has_include_next",BT_HAS_INCLUDE_NEXT, true), -+ B("__has_feature", BT_HAS_FEATURE, true), -+ B("__has_extension", BT_HAS_EXTENSION, true), - /* Keep builtins not used for -traditional-cpp at the end, and - update init_builtins() if any more are added. */ - B("_Pragma", BT_PRAGMA, true), -diff --git a/libcpp/macro.cc b/libcpp/macro.cc -index d4238d4..d2e8f9b 100644 ---- a/libcpp/macro.cc -+++ b/libcpp/macro.cc -@@ -677,6 +677,12 @@ _cpp_builtin_macro_text (cpp_reader *pfile, cpp_hashnode *node, - number = builtin_has_include (pfile, node, - node->value.builtin == BT_HAS_INCLUDE_NEXT); - break; -+ -+ case BT_HAS_FEATURE: -+ case BT_HAS_EXTENSION: -+ number = pfile->cb.has_feature (pfile, -+ node->value.builtin == BT_HAS_FEATURE); -+ break; - } - - if (result == NULL) -diff --git a/libdecnumber/configure b/libdecnumber/configure -index fb6db05..84bc4ff 100755 ---- a/libdecnumber/configure -+++ b/libdecnumber/configure -@@ -626,6 +626,8 @@ ac_subst_vars='LTLIBOBJS - LIBOBJS - CET_HOST_FLAGS - PICFLAG -+enable_host_pie -+enable_host_shared - ADDITIONAL_OBJS - enable_decimal_float - target_os -@@ -706,6 +708,7 @@ enable_werror_always - enable_maintainer_mode - enable_decimal_float - enable_host_shared -+enable_host_pie - enable_cet - ' - ac_precious_vars='build_alias -@@ -1338,6 +1341,7 @@ Optional Features: - or 'dpd' choses which decimal floating point format - to use - --enable-host-shared build host code as shared libraries -+ --enable-host-pie build host code as PIE - --enable-cet enable Intel CET in host libraries [default=auto] - - Some influential environment variables: -@@ -5186,7 +5190,23 @@ $as_echo "#define AC_APPLE_UNIVERSAL_BUILD 1" >>confdefs.h - # Enable --enable-host-shared. - # Check whether --enable-host-shared was given. - if test "${enable_host_shared+set}" = set; then : -- enableval=$enable_host_shared; PICFLAG=-fPIC -+ enableval=$enable_host_shared; -+fi -+ -+ -+ -+# Enable --enable-host-pie. -+# Check whether --enable-host-pie was given. -+if test "${enable_host_pie+set}" = set; then : -+ enableval=$enable_host_pie; -+fi -+ -+ -+ -+if test x$enable_host_shared = xyes; then -+ PICFLAG=-fPIC -+elif test x$enable_host_pie = xyes; then -+ PICFLAG=-fPIE - else - PICFLAG= - fi -diff --git a/libdecnumber/configure.ac b/libdecnumber/configure.ac -index aafd06f..30a51ca 100644 ---- a/libdecnumber/configure.ac -+++ b/libdecnumber/configure.ac -@@ -100,8 +100,23 @@ AC_C_BIGENDIAN - # Enable --enable-host-shared. - AC_ARG_ENABLE(host-shared, - [AS_HELP_STRING([--enable-host-shared], -- [build host code as shared libraries])], --[PICFLAG=-fPIC], [PICFLAG=]) -+ [build host code as shared libraries])]) -+AC_SUBST(enable_host_shared) -+ -+# Enable --enable-host-pie. -+AC_ARG_ENABLE(host-pie, -+[AS_HELP_STRING([--enable-host-pie], -+ [build host code as PIE])]) -+AC_SUBST(enable_host_pie) -+ -+if test x$enable_host_shared = xyes; then -+ PICFLAG=-fPIC -+elif test x$enable_host_pie = xyes; then -+ PICFLAG=-fPIE -+else -+ PICFLAG= -+fi -+ - AC_SUBST(PICFLAG) - - # Enable Intel CET on Intel CET enabled host if jit is enabled. -diff --git a/libffi/Makefile.am b/libffi/Makefile.am -index c6d6f84..d2ae0c0 100644 ---- a/libffi/Makefile.am -+++ b/libffi/Makefile.am -@@ -214,7 +214,12 @@ libffi.map: $(top_srcdir)/libffi.map.in - $(COMPILE) -D$(TARGET) -DGENERATE_LIBFFI_MAP \ - -E -x assembler-with-cpp -o $@ $(top_srcdir)/libffi.map.in - --libffi_la_LDFLAGS = -no-undefined $(libffi_version_info) $(libffi_version_script) $(LTLDFLAGS) $(AM_LTLDFLAGS) -+if ENABLE_DARWIN_AT_RPATH -+libffi_darwin_rpath = -Wl,-rpath,@loader_path -+endif -+libffi_la_LDFLAGS = -no-undefined $(libffi_version_info) \ -+ $(libffi_version_script) $(LTLDFLAGS) $(AM_LTLDFLAGS) \ -+ $(libffi_darwin_rpath) - libffi_la_DEPENDENCIES = $(libffi_la_LIBADD) $(libffi_version_dep) - - AM_CPPFLAGS = -I. -I$(top_srcdir)/include -Iinclude -I$(top_srcdir)/src -diff --git a/libffi/Makefile.in b/libffi/Makefile.in -index 5524a6a..34e77a4 100644 ---- a/libffi/Makefile.in -+++ b/libffi/Makefile.in -@@ -597,7 +597,11 @@ AM_CFLAGS = -Wall -g -fexceptions $(CET_FLAGS) $(am__append_2) - @LIBFFI_BUILD_VERSIONED_SHLIB_GNU_TRUE@@LIBFFI_BUILD_VERSIONED_SHLIB_TRUE@libffi_version_dep = libffi.map - @LIBFFI_BUILD_VERSIONED_SHLIB_SUN_TRUE@@LIBFFI_BUILD_VERSIONED_SHLIB_TRUE@libffi_version_dep = libffi.map-sun - libffi_version_info = -version-info `grep -v '^\#' $(srcdir)/libtool-version` --libffi_la_LDFLAGS = -no-undefined $(libffi_version_info) $(libffi_version_script) $(LTLDFLAGS) $(AM_LTLDFLAGS) -+@ENABLE_DARWIN_AT_RPATH_TRUE@libffi_darwin_rpath = -Wl,-rpath,@loader_path -+libffi_la_LDFLAGS = -no-undefined $(libffi_version_info) \ -+ $(libffi_version_script) $(LTLDFLAGS) $(AM_LTLDFLAGS) \ -+ $(libffi_darwin_rpath) -+ - libffi_la_DEPENDENCIES = $(libffi_la_LIBADD) $(libffi_version_dep) - AM_CPPFLAGS = -I. -I$(top_srcdir)/include -Iinclude -I$(top_srcdir)/src - AM_CCASFLAGS = $(AM_CPPFLAGS) $(CET_FLAGS) -diff --git a/libffi/configure b/libffi/configure -index 2bb9f8d..0fae8b5 100755 ---- a/libffi/configure -+++ b/libffi/configure -@@ -667,6 +667,8 @@ MAINT - MAINTAINER_MODE_FALSE - MAINTAINER_MODE_TRUE - READELF -+ENABLE_DARWIN_AT_RPATH_FALSE -+ENABLE_DARWIN_AT_RPATH_TRUE - CXXCPP - CPP - OTOOL64 -@@ -810,6 +812,7 @@ with_pic - enable_fast_install - with_gnu_ld - enable_libtool_lock -+enable_darwin_at_rpath - enable_maintainer_mode - enable_pax_emutramp - enable_debug -@@ -1465,6 +1468,9 @@ Optional Features: - --enable-fast-install[=PKGS] - optimize for fast installation [default=yes] - --disable-libtool-lock avoid locking (might break parallel builds) -+ --enable-darwin-at-rpath -+ install libraries with @rpath/library-name, requires -+ rpaths to be added to executables - --enable-maintainer-mode - enable make rules and dependencies not useful (and - sometimes confusing) to the casual installer -@@ -7797,7 +7803,7 @@ $as_echo "$lt_cv_ld_force_load" >&6; } - # darwin 5.x (macOS 10.1) onwards we only need to adjust when the - # deployment target is forced to an earlier version. - case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host in -- UNSET,*-darwin[89]*|UNSET,*-darwin[12][0123456789]*) -+ UNSET,*-darwin[89]*|UNSET,*-darwin[12][0-9]*) - ;; - 10.[012][,.]*) - _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' -@@ -9771,6 +9777,49 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi - darwin* | rhapsody*) - - -+ -+ # Publish an arg to allow the user to select that Darwin host (and target) -+ # libraries should be given install-names like @rpath/libfoo.dylib. This -+ # requires that the user of the library then adds an 'rpath' to the DSO that -+ # needs access. -+ # NOTE: there are defaults below, for systems that support rpaths. The person -+ # configuring can override the defaults for any system version that supports -+ # them - they are, however, forced off for system versions without support. -+ # Check whether --enable-darwin-at-rpath was given. -+if test "${enable_darwin_at_rpath+set}" = set; then : -+ enableval=$enable_darwin_at_rpath; if test "x$enable_darwin_at_rpath" = "xyes"; then -+ # This is not supported before macOS 10.5 / Darwin9. -+ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in -+ UNSET,darwin[4-8]*|UNSET,rhapsody*|10.[0-4][,.]*) -+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Darwin @rpath library names are incompatible with OSX versions earlier than 10.5 (rpaths disabled)" >&5 -+$as_echo "$as_me: WARNING: Darwin @rpath library names are incompatible with OSX versions earlier than 10.5 (rpaths disabled)" >&2;} -+ enable_darwin_at_rpath=no -+ ;; -+ esac -+ fi -+else -+ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in -+ # As above, before 10.5 / Darwin9 this does not work. -+ UNSET,darwin[4-8]*|UNSET,rhapsody*|10.[0-4][,.]*) -+ enable_darwin_at_rpath=no -+ ;; -+ -+ # We cannot build and test reliably on macOS 10.11+ (Darwin15+) without use -+ # of rpaths, since runpaths set via DYLD_LIBRARY_PATH are elided by key -+ # system executables (e.g. /bin/sh). Force rpaths on for these systems. -+ UNSET,darwin1[5-9]*|UNSET,darwin2*|10.1[1-9][,.]*|1[1-9].*[,.]* ) -+ { $as_echo "$as_me:${as_lineno-$LINENO}: @rpath library names are needed on macOS versions later than 10.11 (rpaths have been enabled)" >&5 -+$as_echo "$as_me: @rpath library names are needed on macOS versions later than 10.11 (rpaths have been enabled)" >&6;} -+ enable_darwin_at_rpath=yes -+ ;; -+ # NOTE: we are not (yet) doing anything for 10.5 .. 10.10, since they can -+ # work with either DYLD_LIBRARY_PATH or embedded rpaths. -+ -+ esac -+ -+fi -+ -+ - archive_cmds_need_lc=no - hardcode_direct=no - hardcode_automatic=yes -@@ -9788,9 +9837,13 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi - esac - if test "$_lt_dar_can_shared" = "yes"; then - output_verbose_link_cmd=func_echo_all -- archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" -+ _lt_install_name='\$rpath/\$soname' -+ if test "x$enable_darwin_at_rpath" = "xyes"; then -+ _lt_install_name='@rpath/\$soname' -+ fi -+ archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name ${_lt_install_name} \$verstring ${_lt_dsymutil}" - module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" -- archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" -+ archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name ${_lt_install_name} \$verstring ${_lt_dar_export_syms}${_lt_dsymutil}" - module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" - - else -@@ -11596,7 +11649,7 @@ else - lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 - lt_status=$lt_dlunknown - cat > conftest.$ac_ext <<_LT_EOF --#line 11599 "configure" -+#line 11652 "configure" - #include "confdefs.h" - - #if HAVE_DLFCN_H -@@ -11702,7 +11755,7 @@ else - lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 - lt_status=$lt_dlunknown - cat > conftest.$ac_ext <<_LT_EOF --#line 11705 "configure" -+#line 11758 "configure" - #include "confdefs.h" - - #if HAVE_DLFCN_H -@@ -12578,6 +12631,49 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi - darwin* | rhapsody*) - - -+ -+ # Publish an arg to allow the user to select that Darwin host (and target) -+ # libraries should be given install-names like @rpath/libfoo.dylib. This -+ # requires that the user of the library then adds an 'rpath' to the DSO that -+ # needs access. -+ # NOTE: there are defaults below, for systems that support rpaths. The person -+ # configuring can override the defaults for any system version that supports -+ # them - they are, however, forced off for system versions without support. -+ # Check whether --enable-darwin-at-rpath was given. -+if test "${enable_darwin_at_rpath+set}" = set; then : -+ enableval=$enable_darwin_at_rpath; if test "x$enable_darwin_at_rpath" = "xyes"; then -+ # This is not supported before macOS 10.5 / Darwin9. -+ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in -+ UNSET,darwin[4-8]*|UNSET,rhapsody*|10.[0-4][,.]*) -+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Darwin @rpath library names are incompatible with OSX versions earlier than 10.5 (rpaths disabled)" >&5 -+$as_echo "$as_me: WARNING: Darwin @rpath library names are incompatible with OSX versions earlier than 10.5 (rpaths disabled)" >&2;} -+ enable_darwin_at_rpath=no -+ ;; -+ esac -+ fi -+else -+ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in -+ # As above, before 10.5 / Darwin9 this does not work. -+ UNSET,darwin[4-8]*|UNSET,rhapsody*|10.[0-4][,.]*) -+ enable_darwin_at_rpath=no -+ ;; -+ -+ # We cannot build and test reliably on macOS 10.11+ (Darwin15+) without use -+ # of rpaths, since runpaths set via DYLD_LIBRARY_PATH are elided by key -+ # system executables (e.g. /bin/sh). Force rpaths on for these systems. -+ UNSET,darwin1[5-9]*|UNSET,darwin2*|10.1[1-9][,.]*|1[1-9].*[,.]* ) -+ { $as_echo "$as_me:${as_lineno-$LINENO}: @rpath library names are needed on macOS versions later than 10.11 (rpaths have been enabled)" >&5 -+$as_echo "$as_me: @rpath library names are needed on macOS versions later than 10.11 (rpaths have been enabled)" >&6;} -+ enable_darwin_at_rpath=yes -+ ;; -+ # NOTE: we are not (yet) doing anything for 10.5 .. 10.10, since they can -+ # work with either DYLD_LIBRARY_PATH or embedded rpaths. -+ -+ esac -+ -+fi -+ -+ - archive_cmds_need_lc_CXX=no - hardcode_direct_CXX=no - hardcode_automatic_CXX=yes -@@ -12595,12 +12691,20 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi - esac - if test "$_lt_dar_can_shared" = "yes"; then - output_verbose_link_cmd=func_echo_all -- archive_cmds_CXX="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" -+ _lt_install_name='\$rpath/\$soname' -+ if test "x$enable_darwin_at_rpath" = "xyes"; then -+ _lt_install_name='@rpath/\$soname' -+ fi -+ archive_cmds_CXX="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name ${_lt_install_name} \$verstring ${_lt_dsymutil}" - module_cmds_CXX="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" -- archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" -+ archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name ${_lt_install_name} \$verstring ${_lt_dar_export_syms}${_lt_dsymutil}" - module_expsym_cmds_CXX="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" - if test "$lt_cv_apple_cc_single_mod" != "yes"; then -- archive_cmds_CXX="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}" -+ _lt_install_name='\$rpath/\$soname' -+ if test "x$enable_darwin_at_rpath" = "xyes"; then -+ _lt_install_name='@rpath/\$soname' -+ fi -+ archive_cmds_CXX="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name ${_lt_install_name} \$verstring${_lt_dsymutil}" - archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}" - fi - -@@ -14970,6 +15074,14 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu - # Only expand once: - - -+ if test x$enable_darwin_at_rpath = xyes; then -+ ENABLE_DARWIN_AT_RPATH_TRUE= -+ ENABLE_DARWIN_AT_RPATH_FALSE='#' -+else -+ ENABLE_DARWIN_AT_RPATH_TRUE='#' -+ ENABLE_DARWIN_AT_RPATH_FALSE= -+fi -+ - - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}readelf", so it can be a program name with args. -@@ -17115,6 +17227,10 @@ if test -z "${am__fastdepCCAS_TRUE}" && test -z "${am__fastdepCCAS_FALSE}"; then - as_fn_error $? "conditional \"am__fastdepCCAS\" was never defined. - Usually this means the macro was only invoked conditionally." "$LINENO" 5 - fi -+if test -z "${ENABLE_DARWIN_AT_RPATH_TRUE}" && test -z "${ENABLE_DARWIN_AT_RPATH_FALSE}"; then -+ as_fn_error $? "conditional \"ENABLE_DARWIN_AT_RPATH\" was never defined. -+Usually this means the macro was only invoked conditionally." "$LINENO" 5 -+fi - if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then - as_fn_error $? "conditional \"MAINTAINER_MODE\" was never defined. - Usually this means the macro was only invoked conditionally." "$LINENO" 5 -diff --git a/libffi/configure.ac b/libffi/configure.ac -index 014d89d..716f20a 100644 ---- a/libffi/configure.ac -+++ b/libffi/configure.ac -@@ -55,6 +55,7 @@ AC_SUBST(CET_FLAGS) - AM_PROG_AS - AM_PROG_CC_C_O - AC_PROG_LIBTOOL -+AM_CONDITIONAL([ENABLE_DARWIN_AT_RPATH], [test x$enable_darwin_at_rpath = xyes]) - - AC_CHECK_TOOL(READELF, readelf) - -diff --git a/libffi/doc/version.texi b/libffi/doc/version.texi -index f2b741e..6261b21 100644 ---- a/libffi/doc/version.texi -+++ b/libffi/doc/version.texi -@@ -1,4 +1,4 @@ --@set UPDATED 27 June 2021 --@set UPDATED-MONTH June 2021 -+@set UPDATED 31 August 2022 -+@set UPDATED-MONTH August 2022 - @set EDITION 3.4.2 - @set VERSION 3.4.2 -diff --git b/libgcc/config/aarch64/heap-trampoline.c b/libgcc/config/aarch64/heap-trampoline.c -new file mode 100644 -index 0000000..b2c69aa ---- /dev/null -+++ b/libgcc/config/aarch64/heap-trampoline.c -@@ -0,0 +1,185 @@ -+/* Copyright The GNU Toolchain Authors. */ -+ -+/* libc is required to allocate trampolines. */ -+#ifndef inhibit_libc -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#if __APPLE__ -+/* For pthread_jit_write_protect_np */ -+#include -+#endif -+ -+/* HEAP_T_ATTR is provided to allow targets to build the exported functions -+ as weak definitions. */ -+#ifndef HEAP_T_ATTR -+# define HEAP_T_ATTR -+#endif -+ -+void *allocate_trampoline_page (void); -+int get_trampolines_per_page (void); -+struct tramp_ctrl_data *allocate_tramp_ctrl (struct tramp_ctrl_data *parent); -+void *allocate_trampoline_page (void); -+ -+void __gcc_nested_func_ptr_created (void *chain, void *func, void **dst); -+void __gcc_nested_func_ptr_deleted (void); -+ -+#if defined(__linux__) -+static const unsigned char aarch64_trampoline_insns[6][4] = { -+ {0x5f, 0x24, 0x03, 0xd5}, /* hint 34 */ -+ {0xb1, 0x00, 0x00, 0x58}, /* ldr x17, .+20 */ -+ {0xd2, 0x00, 0x00, 0x58}, /* ldr x18, .+24 */ -+ {0x20, 0x02, 0x1f, 0xd6}, /* br x17 */ -+ {0x9f, 0x3f, 0x03, 0xd5}, /* dsb sy */ -+ {0xdf, 0x3f, 0x03, 0xd5} /* isb */ -+}; -+ -+#elif __APPLE__ -+static const unsigned char aarch64_trampoline_insns[6][4] = { -+ {0x5f, 0x24, 0x03, 0xd5}, /* hint 34 */ -+ {0xb1, 0x00, 0x00, 0x58}, /* ldr x17, .+20 */ -+ {0xd0, 0x00, 0x00, 0x58}, /* ldr x16, .+24 */ -+ {0x20, 0x02, 0x1f, 0xd6}, /* br x17 */ -+ {0x9f, 0x3f, 0x03, 0xd5}, /* dsb sy */ -+ {0xdf, 0x3f, 0x03, 0xd5} /* isb */ -+}; -+ -+#else -+#error "Unsupported AArch64 platform for heap trampolines" -+#endif -+ -+struct aarch64_trampoline { -+ unsigned char insns[6][4]; -+ void *func_ptr; -+ void *chain_ptr; -+}; -+ -+struct tramp_ctrl_data -+{ -+ struct tramp_ctrl_data *prev; -+ -+ int free_trampolines; -+ -+ /* This will be pointing to an executable mmap'ed page. */ -+ struct aarch64_trampoline *trampolines; -+}; -+ -+int -+get_trampolines_per_page (void) -+{ -+ return getpagesize() / sizeof(struct aarch64_trampoline); -+} -+ -+static _Thread_local struct tramp_ctrl_data *tramp_ctrl_curr = NULL; -+ -+void * -+allocate_trampoline_page (void) -+{ -+ void *page; -+ -+#if defined(__linux__) -+ page = mmap (0, getpagesize (), PROT_WRITE | PROT_EXEC, -+ MAP_ANON | MAP_PRIVATE, 0, 0); -+#elif __APPLE__ -+ page = mmap (0, getpagesize (), PROT_WRITE | PROT_EXEC, -+ MAP_ANON | MAP_PRIVATE | MAP_JIT, 0, 0); -+#else -+ page = MAP_FAILED; -+#endif -+ -+ return page; -+} -+ -+struct tramp_ctrl_data * -+allocate_tramp_ctrl (struct tramp_ctrl_data *parent) -+{ -+ struct tramp_ctrl_data *p = malloc (sizeof (struct tramp_ctrl_data)); -+ if (p == NULL) -+ return NULL; -+ -+ p->trampolines = allocate_trampoline_page (); -+ -+ if (p->trampolines == MAP_FAILED) -+ return NULL; -+ -+ p->prev = parent; -+ p->free_trampolines = get_trampolines_per_page(); -+ -+ return p; -+} -+ -+HEAP_T_ATTR -+void -+__gcc_nested_func_ptr_created (void *chain, void *func, void **dst) -+{ -+ if (tramp_ctrl_curr == NULL) -+ { -+ tramp_ctrl_curr = allocate_tramp_ctrl (NULL); -+ if (tramp_ctrl_curr == NULL) -+ abort (); -+ } -+ -+ if (tramp_ctrl_curr->free_trampolines == 0) -+ { -+ void *tramp_ctrl = allocate_tramp_ctrl (tramp_ctrl_curr); -+ if (!tramp_ctrl) -+ abort (); -+ -+ tramp_ctrl_curr = tramp_ctrl; -+ } -+ -+ struct aarch64_trampoline *trampoline -+ = &tramp_ctrl_curr->trampolines[get_trampolines_per_page () -+ - tramp_ctrl_curr->free_trampolines]; -+ -+#if __APPLE__ -+ /* Disable write protection for the MAP_JIT regions in this thread (see -+ https://developer.apple.com/documentation/apple-silicon/porting-just-in-time-compilers-to-apple-silicon) */ -+ pthread_jit_write_protect_np (0); -+#endif -+ -+ memcpy (trampoline->insns, aarch64_trampoline_insns, -+ sizeof(aarch64_trampoline_insns)); -+ trampoline->func_ptr = func; -+ trampoline->chain_ptr = chain; -+ -+#if __APPLE__ -+ /* Re-enable write protection. */ -+ pthread_jit_write_protect_np (1); -+#endif -+ -+ tramp_ctrl_curr->free_trampolines -= 1; -+ -+ __builtin___clear_cache ((void *)trampoline->insns, -+ ((void *)trampoline->insns + sizeof(trampoline->insns))); -+ -+ *dst = &trampoline->insns; -+} -+ -+HEAP_T_ATTR -+void -+__gcc_nested_func_ptr_deleted (void) -+{ -+ if (tramp_ctrl_curr == NULL) -+ abort (); -+ -+ tramp_ctrl_curr->free_trampolines += 1; -+ -+ if (tramp_ctrl_curr->free_trampolines == get_trampolines_per_page ()) -+ { -+ if (tramp_ctrl_curr->prev == NULL) -+ return; -+ -+ munmap (tramp_ctrl_curr->trampolines, getpagesize()); -+ struct tramp_ctrl_data *prev = tramp_ctrl_curr->prev; -+ free (tramp_ctrl_curr); -+ tramp_ctrl_curr = prev; -+ } -+} -+ -+#endif /* !inhibit_libc */ -diff --git a/libgcc/config/aarch64/lse.S b/libgcc/config/aarch64/lse.S -index dde3a28..87ee33b 100644 ---- a/libgcc/config/aarch64/lse.S -+++ b/libgcc/config/aarch64/lse.S -@@ -58,7 +58,11 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see - #endif - - /* Declare the symbol gating the LSE implementations. */ -+#if __ELF__ - .hidden __aarch64_have_lse_atomics -+#else -+ .private_extern __aarch64_have_lse_atomics -+#endif - - /* Turn size and memory model defines into mnemonic fragments. */ - #if SIZE == 1 -@@ -164,6 +168,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see - #define BTI_C hint 34 - - /* Start and end a function. */ -+#if __ELF__ - .macro STARTFN name - .text - .balign 16 -@@ -187,6 +192,29 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see - cbz w(tmp0), \label - .endm - -+#else -+.macro STARTFN name -+ .text -+ .balign 16 -+ .private_extern _\name -+_\name: -+ .cfi_startproc -+ BTI_C -+.endm -+ -+.macro ENDFN name -+ .cfi_endproc -+.endm -+ -+/* Branch to LABEL if LSE is disabled. */ -+.macro JUMP_IF_NOT_LSE label -+ adrp x(tmp0), ___aarch64_have_lse_atomics@PAGE -+ ldrb w(tmp0), [x(tmp0), ___aarch64_have_lse_atomics@PAGEOFF] -+ cbz w(tmp0), \label -+.endm -+ -+#endif -+ - #ifdef L_cas - - STARTFN NAME(cas) -diff --git a/libgcc/config/aarch64/sfp-machine.h b/libgcc/config/aarch64/sfp-machine.h -index 97c38a3..b35e2c5 100644 ---- a/libgcc/config/aarch64/sfp-machine.h -+++ b/libgcc/config/aarch64/sfp-machine.h -@@ -124,6 +124,27 @@ void __sfp_handle_exceptions (int); - - - /* Define ALIASNAME as a strong alias for NAME. */ -+#if defined __APPLE__ -+/* Mach-O doesn't support aliasing, so we build a secondary function for -+ the alias - we need to do a bit of a dance to find out what the type of -+ the arguments is and then apply that to the secondary function. -+ If these functions ever return anything but CMPtype we need to revisit -+ this... */ -+typedef float alias_HFtype __attribute__ ((mode (HF))); -+typedef float alias_SFtype __attribute__ ((mode (SF))); -+typedef float alias_DFtype __attribute__ ((mode (DF))); -+typedef float alias_TFtype __attribute__ ((mode (TF))); -+#define ALIAS_SELECTOR \ -+ CMPtype (*) (alias_HFtype, alias_HFtype): (alias_HFtype) 0, \ -+ CMPtype (*) (alias_SFtype, alias_SFtype): (alias_SFtype) 0, \ -+ CMPtype (*) (alias_DFtype, alias_DFtype): (alias_DFtype) 0, \ -+ CMPtype (*) (alias_TFtype, alias_TFtype): (alias_TFtype) 0 -+#define strong_alias(name, aliasname) \ -+ CMPtype aliasname (__typeof (_Generic (name, ALIAS_SELECTOR)) a, \ -+ __typeof (_Generic (name, ALIAS_SELECTOR)) b) \ -+ { return name (a, b); } -+#else - # define strong_alias(name, aliasname) _strong_alias(name, aliasname) - # define _strong_alias(name, aliasname) \ - extern __typeof (name) aliasname __attribute__ ((alias (#name))); -+#endif -diff --git b/libgcc/config/aarch64/t-darwin b/libgcc/config/aarch64/t-darwin -new file mode 100644 -index 0000000..f6ecda7 ---- /dev/null -+++ b/libgcc/config/aarch64/t-darwin -@@ -0,0 +1,7 @@ -+# Ensure we have a suitable minimum OS version. -+ -+HOST_LIBGCC2_CFLAGS += -mmacosx-version-min=11.0 -+ -+LIB2_SIDITI_CONV_FUNCS = yes -+ -+BUILD_LIBGCCS1 = -diff --git b/libgcc/config/aarch64/t-heap-trampoline b/libgcc/config/aarch64/t-heap-trampoline -new file mode 100644 -index 0000000..6468fb8 ---- /dev/null -+++ b/libgcc/config/aarch64/t-heap-trampoline -@@ -0,0 +1,20 @@ -+# Copyright The GNU Toolchain Authors. -+ -+# This file is part of GCC. -+# -+# GCC 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 3, or (at your option) -+# any later version. -+# -+# GCC 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. -+# -+# You should have received a copy of the GNU General Public License -+# along with GCC; see the file COPYING3. If not see -+# . -+ -+LIB2ADDEH += $(srcdir)/config/aarch64/heap-trampoline.c -+LIB2ADDEHSHARED += $(srcdir)/config/aarch64/heap-trampoline.c -diff --git b/libgcc/config/i386/heap-trampoline.c b/libgcc/config/i386/heap-trampoline.c -new file mode 100644 -index 0000000..2e8df1c ---- /dev/null -+++ b/libgcc/config/i386/heap-trampoline.c -@@ -0,0 +1,255 @@ -+/* Copyright The GNU Toolchain Authors. */ -+ -+/* libc is required to allocate trampolines. */ -+#ifndef inhibit_libc -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#if __APPLE__ && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 101400 -+/* For pthread_jit_write_protect_np */ -+#include -+#endif -+ -+/* HEAP_T_ATTR is provided to allow targets to build the exported functions -+ as weak definitions. */ -+#ifndef HEAP_T_ATTR -+# define HEAP_T_ATTR -+#endif -+ -+void *allocate_trampoline_page (void); -+int get_trampolines_per_page (void); -+struct tramp_ctrl_data *allocate_tramp_ctrl (struct tramp_ctrl_data *parent); -+void *allocate_trampoline_page (void); -+ -+void __gcc_nested_func_ptr_created (void *chain, void *func, void **dst); -+void __gcc_nested_func_ptr_deleted (void); -+ -+#if __x86_64__ -+ -+#ifdef __LP64__ -+static const uint8_t trampoline_insns[] = { -+#if defined __CET__ && (__CET__ & 1) != 0 -+ /* endbr64. */ -+ 0xf3, 0x0f, 0x1e, 0xfa, -+#endif -+ -+ /* movabsq $,%r11 */ -+ 0x49, 0xbb, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ -+ /* movabsq $,%r10 */ -+ 0x49, 0xba, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ -+ /* rex.WB jmpq *%r11 */ -+ 0x41, 0xff, 0xe3, -+ -+ /* Pad to the multiple of 4 bytes. */ -+ 0x90 -+}; -+#else -+static const uint8_t trampoline_insns[] = { -+#if defined __CET__ && (__CET__ & 1) != 0 -+ /* endbr64. */ -+ 0xf3, 0x0f, 0x1e, 0xfa, -+#endif -+ -+ /* movl $,%r11d */ -+ 0x41, 0xbb, -+ 0x00, 0x00, 0x00, 0x00, -+ -+ /* movl $,%r10d */ -+ 0x41, 0xba, -+ 0x00, 0x00, 0x00, 0x00, -+ -+ /* rex.WB jmpq *%r11 */ -+ 0x41, 0xff, 0xe3, -+ -+ /* Pad to the multiple of 4 bytes. */ -+ 0x90 -+}; -+#endif -+ -+union ix86_trampoline { -+ uint8_t insns[sizeof(trampoline_insns)]; -+ -+ struct __attribute__((packed)) fields { -+#if defined __CET__ && (__CET__ & 1) != 0 -+ uint8_t endbr64[4]; -+#endif -+ uint8_t insn_0[2]; -+ void *func_ptr; -+ uint8_t insn_1[2]; -+ void *chain_ptr; -+ uint8_t insn_2[3]; -+ uint8_t pad; -+ } fields; -+}; -+ -+#elif __i386__ -+ -+static const uint8_t trampoline_insns[] = { -+ /* movl $,%ecx */ -+ 0xb9, -+ 0x00, 0x00, 0x00, 0x00, -+ -+ /* jmpl -. */ -+ 0xe9, -+ 0x00, 0x00, 0x00, 0x00, -+}; -+ -+union ix86_trampoline { -+ uint8_t insns[sizeof(trampoline_insns)]; -+ -+ struct __attribute__((packed)) fields { -+ uint8_t insn_0[1]; -+ void *chain_ptr; -+ uint8_t insn_1[1]; -+ uintptr_t func_offset; -+ } fields; -+}; -+ -+#else -+#error unsupported architecture/ABI -+#endif -+ -+struct tramp_ctrl_data -+{ -+ struct tramp_ctrl_data *prev; -+ -+ int free_trampolines; -+ -+ /* This will be pointing to an executable mmap'ed page. */ -+ union ix86_trampoline *trampolines; -+}; -+ -+int -+get_trampolines_per_page (void) -+{ -+ return getpagesize() / sizeof(union ix86_trampoline); -+} -+ -+static _Thread_local struct tramp_ctrl_data *tramp_ctrl_curr = NULL; -+ -+void * -+allocate_trampoline_page (void) -+{ -+ void *page; -+ -+#if defined(__gnu_linux__) -+ page = mmap (0, getpagesize (), PROT_WRITE | PROT_EXEC, -+ MAP_ANON | MAP_PRIVATE, 0, 0); -+#elif __APPLE__ -+# if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 101400 -+ page = mmap (0, getpagesize (), PROT_WRITE | PROT_EXEC, -+ MAP_ANON | MAP_PRIVATE | MAP_JIT, 0, 0); -+# else -+ page = mmap (0, getpagesize (), PROT_WRITE | PROT_EXEC, -+ MAP_ANON | MAP_PRIVATE, 0, 0); -+# endif -+#else -+ page = MAP_FAILED; -+#endif -+ -+ return page; -+} -+ -+struct tramp_ctrl_data * -+allocate_tramp_ctrl (struct tramp_ctrl_data *parent) -+{ -+ struct tramp_ctrl_data *p = malloc (sizeof (struct tramp_ctrl_data)); -+ if (p == NULL) -+ return NULL; -+ -+ p->trampolines = allocate_trampoline_page (); -+ -+ if (p->trampolines == MAP_FAILED) -+ return NULL; -+ -+ p->prev = parent; -+ p->free_trampolines = get_trampolines_per_page(); -+ -+ return p; -+} -+ -+HEAP_T_ATTR -+void -+__gcc_nested_func_ptr_created (void *chain, void *func, void **dst) -+{ -+ if (tramp_ctrl_curr == NULL) -+ { -+ tramp_ctrl_curr = allocate_tramp_ctrl (NULL); -+ if (tramp_ctrl_curr == NULL) -+ abort (); -+ } -+ -+ if (tramp_ctrl_curr->free_trampolines == 0) -+ { -+ void *tramp_ctrl = allocate_tramp_ctrl (tramp_ctrl_curr); -+ if (!tramp_ctrl) -+ abort (); -+ -+ tramp_ctrl_curr = tramp_ctrl; -+ } -+ -+ union ix86_trampoline *trampoline -+ = &tramp_ctrl_curr->trampolines[get_trampolines_per_page () -+ - tramp_ctrl_curr->free_trampolines]; -+ -+#if __APPLE__ && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 101400 -+ /* Disable write protection for the MAP_JIT regions in this thread (see -+ https://developer.apple.com/documentation/apple-silicon/porting-just-in-time-compilers-to-apple-silicon) */ -+ pthread_jit_write_protect_np (0); -+#endif -+ -+ memcpy (trampoline->insns, trampoline_insns, -+ sizeof(trampoline_insns)); -+ trampoline->fields.chain_ptr = chain; -+#if __x86_64__ -+ trampoline->fields.func_ptr = func; -+#elif __i386__ -+ uintptr_t off_add = (uintptr_t) &trampoline->fields.func_offset; -+ off_add += 4; -+ trampoline->fields.func_offset = (uintptr_t)func - off_add; -+#endif -+ -+#if __APPLE__ && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 101400 -+ /* Re-enable write protection. */ -+ pthread_jit_write_protect_np (1); -+#endif -+ -+ tramp_ctrl_curr->free_trampolines -= 1; -+ -+ __builtin___clear_cache ((void *)trampoline->insns, -+ ((void *)trampoline->insns + sizeof(trampoline->insns))); -+ -+ *dst = &trampoline->insns; -+} -+ -+HEAP_T_ATTR -+void -+__gcc_nested_func_ptr_deleted (void) -+{ -+ if (tramp_ctrl_curr == NULL) -+ abort (); -+ -+ tramp_ctrl_curr->free_trampolines += 1; -+ -+ if (tramp_ctrl_curr->free_trampolines == get_trampolines_per_page ()) -+ { -+ if (tramp_ctrl_curr->prev == NULL) -+ return; -+ -+ munmap (tramp_ctrl_curr->trampolines, getpagesize()); -+ struct tramp_ctrl_data *prev = tramp_ctrl_curr->prev; -+ free (tramp_ctrl_curr); -+ tramp_ctrl_curr = prev; -+ } -+} -+ -+#endif /* !inhibit_libc */ -diff --git a/libgcc/config/i386/t-darwin b/libgcc/config/i386/t-darwin -index 4c18da1..84efe35 100644 ---- a/libgcc/config/i386/t-darwin -+++ b/libgcc/config/i386/t-darwin -@@ -5,5 +5,3 @@ LIB2FUNCS_EXCLUDE = _fixtfdi _fixunstfdi _floatditf _floatunditf - # Extra symbols for this port. - SHLIB_MAPFILES += $(srcdir)/config/i386/libgcc-darwin.ver - --# Build a legacy libgcc_s.1 --BUILD_LIBGCCS1 = YES -diff --git b/libgcc/config/i386/t-heap-trampoline b/libgcc/config/i386/t-heap-trampoline -new file mode 100644 -index 0000000..5cd11f5 ---- /dev/null -+++ b/libgcc/config/i386/t-heap-trampoline -@@ -0,0 +1,20 @@ -+# Copyright The GNU Toolchain Authors. -+ -+# This file is part of GCC. -+# -+# GCC 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 3, or (at your option) -+# any later version. -+# -+# GCC 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. -+# -+# You should have received a copy of the GNU General Public License -+# along with GCC; see the file COPYING3. If not see -+# . -+ -+LIB2ADDEH += $(srcdir)/config/i386/heap-trampoline.c -+LIB2ADDEHSHARED += $(srcdir)/config/i386/heap-trampoline.c -diff --git a/libgcc/config/rs6000/t-darwin b/libgcc/config/rs6000/t-darwin -index 183d0df..8b513bd 100644 ---- a/libgcc/config/rs6000/t-darwin -+++ b/libgcc/config/rs6000/t-darwin -@@ -56,6 +56,3 @@ unwind-dw2_s.o: HOST_LIBGCC2_CFLAGS += -maltivec - unwind-dw2.o: HOST_LIBGCC2_CFLAGS += -maltivec - - LIB2ADDEH += $(srcdir)/config/rs6000/darwin-fallback.c -- --# Build a legacy libgcc_s.1 --BUILD_LIBGCCS1 = YES -diff --git b/libgcc/config/rs6000/t-darwin-libgccs1 b/libgcc/config/rs6000/t-darwin-libgccs1 -new file mode 100644 -index 0000000..7dc252e ---- /dev/null -+++ b/libgcc/config/rs6000/t-darwin-libgccs1 -@@ -0,0 +1,3 @@ -+ -+# Build a legacy libgcc_s.1 -+BUILD_LIBGCCS1 = YES -\ No newline at end of file -diff --git a/libgcc/config/t-darwin b/libgcc/config/t-darwin -index a3bb70c..0f65b54 100644 ---- a/libgcc/config/t-darwin -+++ b/libgcc/config/t-darwin -@@ -51,5 +51,18 @@ LIB2ADDEH = $(srcdir)/unwind-dw2.c \ - # Do not build a shared unwind lib by default. - LIBEHSOBJS= - -+# Make heap trampoline helpers weak definitions so that we can merge them from -+# multiple DSOs. -+heap-trampoline.o: HOST_LIBGCC2_CFLAGS += \ -+ -DHEAP_T_ATTR='__attribute__((__weak__,__visibility__("default")))' -+heap-trampoline_s.o: HOST_LIBGCC2_CFLAGS += \ -+ -DHEAP_T_ATTR='__attribute__((__weak__,__visibility__("default")))' -+ -+# Make a heap trampoline support CRT so that it can be linked optionally, use -+# the shared version so that we can link with DSOs. -+libheapt_w.a: heap-trampoline_s.o -+ $(AR_CREATE_FOR_TARGET) $@ $< -+ $(RANLIB_FOR_TARGET) $@ -+ - # Symbols for all the sub-ports. - SHLIB_MAPFILES = libgcc-std.ver $(srcdir)/config/libgcc-libsystem.ver -diff --git b/libgcc/config/t-darwin-min-11 b/libgcc/config/t-darwin-min-11 -new file mode 100644 -index 0000000..4009d41 ---- /dev/null -+++ b/libgcc/config/t-darwin-min-11 -@@ -0,0 +1,3 @@ -+# Support building with -mmacosx-version-min back to macOS 11. -+DARWIN_MIN_LIB_VERSION = -mmacosx-version-min=11 -+DARWIN_MIN_CRT_VERSION = -mmacosx-version-min=11 -diff --git b/libgcc/config/t-darwin-rpath b/libgcc/config/t-darwin-rpath -new file mode 100644 -index 0000000..e73d7f3 ---- /dev/null -+++ b/libgcc/config/t-darwin-rpath -@@ -0,0 +1,2 @@ -+# Use @rpath and add a search path to exes and dylibs that depend on this. -+SHLIB_RPATH = @rpath -diff --git a/libgcc/config/t-slibgcc-darwin b/libgcc/config/t-slibgcc-darwin -index cb0cbbd..da48868 100644 ---- a/libgcc/config/t-slibgcc-darwin -+++ b/libgcc/config/t-slibgcc-darwin -@@ -1,4 +1,4 @@ --# Build a shared libgcc library with the darwin linker. -+# Build a shared libgcc library able to use embedded runpaths. - - SHLIB_SOVERSION = 1.1 - SHLIB_SO_MINVERSION = 1 -@@ -6,7 +6,6 @@ SHLIB_VERSTRING = -compatibility_version $(SHLIB_SO_MINVERSION) \ - -current_version $(SHLIB_SOVERSION) - SHLIB_EXT = .dylib - SHLIB_LC = -lSystem --SHLIB_INSTALL_DIR = $(slibdir) - - SHLIB_MKMAP = $(srcdir)/mkmap-flat.awk - SHLIB_MKMAP_OPTS = -v leading_underscore=1 -@@ -23,11 +22,16 @@ SHLIB_SONAME = @shlib_base_name@$(SHLIB_EXT) - # subdir. The code under MULTIBUILDTOP combines these into a single FAT - # library, that is what we eventually install. - -+# When enable_darwin_at_rpath is true, use @rpath instead of $(slibdir) for -+# this and dylibs that depend on this. So this def must come first and be -+# overridden in a make fragment that depends on the rpath setting. -+SHLIB_RPATH = $(slibdir) -+ - SHLIB_LINK = $(CC) $(LIBGCC2_CFLAGS) $(LDFLAGS) -dynamiclib -nodefaultlibs \ -- -install_name $(SHLIB_INSTALL_DIR)/$(SHLIB_INSTALL_NAME) \ -+ -install_name $(SHLIB_RPATH)/$(SHLIB_INSTALL_NAME) \ - -single_module -o $(SHLIB_DIR)/$(SHLIB_SONAME) \ - -Wl,-exported_symbols_list,$(SHLIB_MAP) \ -- $(SHLIB_VERSTRING) \ -+ $(SHLIB_VERSTRING) -nodefaultrpaths \ - @multilib_flags@ @shlib_objs@ $(SHLIB_LC) - - # we do our own thing -@@ -63,9 +67,9 @@ EHS_INSTNAME = libgcc_ehs.$(SHLIB_SOVERSION)$(SHLIB_EXT) - libgcc_ehs$(SHLIB_EXT): $(LIBEHSOBJS) $(extra-parts) - mkdir -p $(MULTIDIR) - $(CC) $(LIBGCC2_CFLAGS) $(LDFLAGS) -dynamiclib -nodefaultlibs \ -- -install_name $(SHLIB_INSTALL_DIR)/$(EHS_INSTNAME) \ -+ -install_name $(SHLIB_RPATH)/$(EHS_INSTNAME) \ - -o $(MULTIDIR)/libgcc_ehs$(SHLIB_EXT) $(SHLIB_VERSTRING) \ -- $(LIBEHSOBJS) $(SHLIB_LC) -+ -nodefaultrpaths $(LIBEHSOBJS) $(SHLIB_LC) - - all: libgcc_ehs$(SHLIB_EXT) - -@@ -122,12 +126,12 @@ libgcc_s.1.dylib: all-multi libgcc_s.$(SHLIB_SOVERSION)$(SHLIB_EXT) \ - cp ../$${mlib}/libgcc/$${mlib}/libgcc_ehs$(SHLIB_EXT) \ - ./libgcc_ehs.$(SHLIB_SOVERSION)$(SHLIB_EXT)_T_$${mlib} || exit 1 ; \ - arch=`$(LIPO) -info libgcc_s.$(SHLIB_SOVERSION)$(SHLIB_EXT)_T_$${mlib} | sed -e 's/.*:\ //'` ; \ -- $(CC) -arch $${arch} -nodefaultlibs -dynamiclib \ -+ $(CC) -arch $${arch} -nodefaultlibs -dynamiclib -nodefaultrpaths \ - -o libgcc_s.1$(SHLIB_EXT)_T_$${mlib} \ - -Wl,-reexport_library,libgcc_s.$(SHLIB_SOVERSION)$(SHLIB_EXT)_T_$${mlib} \ - -Wl,-reexport_library,libgcc_ehs.$(SHLIB_SOVERSION)$(SHLIB_EXT)_T_$${mlib} \ -- -install_name $(SHLIB_INSTALL_DIR)/libgcc_s.1.dylib \ -- -compatibility_version 1 -current_version 1 ; \ -+ -install_name $(SHLIB_RPATH)/libgcc_s.1.dylib \ -+ -compatibility_version 1 -current_version 1.1 ; \ - done - $(LIPO) -output libgcc_s.1$(SHLIB_EXT) -create libgcc_s.1$(SHLIB_EXT)_T* - rm libgcc_s.$(SHLIB_SOVERSION)$(SHLIB_EXT)_T* -@@ -141,13 +145,13 @@ libgcc_s.1.dylib: all-multi libgcc_s.$(SHLIB_SOVERSION)$(SHLIB_EXT) - cp ../$${mlib}/libgcc/$${mlib}/libgcc_s$(SHLIB_EXT) \ - ./libgcc_s.$(SHLIB_SOVERSION)$(SHLIB_EXT)_T_$${mlib} || exit 1 ; \ - arch=`$(LIPO) -info libgcc_s.$(SHLIB_SOVERSION)$(SHLIB_EXT)_T_$${mlib} | sed -e 's/.*:\ //'` ; \ -- $(CC) -arch $${arch} -nodefaultlibs -dynamiclib \ -+ $(CC) -arch $${arch} -nodefaultlibs -dynamiclib -nodefaultrpaths \ - -o libgcc_s.1$(SHLIB_EXT)_T_$${mlib} \ - -Wl,-reexport_library,libgcc_s.$(SHLIB_SOVERSION)$(SHLIB_EXT)_T_$${mlib} \ - -lSystem \ - -Wl,-reexported_symbols_list,$(srcdir)/config/darwin-unwind.ver \ -- -install_name $(SHLIB_INSTALL_DIR)/libgcc_s.1.dylib \ -- -compatibility_version 1 -current_version 1 ; \ -+ -install_name $(SHLIB_RPATH)/libgcc_s.1.dylib \ -+ -compatibility_version 1 -current_version 1.1 ; \ - done - $(LIPO) -output libgcc_s.1$(SHLIB_EXT) -create libgcc_s.1$(SHLIB_EXT)_T* - rm libgcc_s.$(SHLIB_SOVERSION)$(SHLIB_EXT)_T* -diff --git a/libgcc/config.host b/libgcc/config.host -index c94d69d..e96b913 100644 ---- a/libgcc/config.host -+++ b/libgcc/config.host -@@ -82,7 +82,7 @@ m32c*-*-*) - cpu_type=m32c - tmake_file=t-fdpbit - ;; --aarch64*-*-*) -+aarch64*-*-* | arm64*-*-*) - cpu_type=aarch64 - ;; - alpha*-*-*) -@@ -233,16 +233,21 @@ case ${host} in - ;; - esac - tmake_file="$tmake_file t-slibgcc-darwin" -- # newer toolsets produce warnings when building for unsupported versions. - case ${host} in -- *-*-darwin1[89]* | *-*-darwin2* ) -- tmake_file="t-darwin-min-8 $tmake_file" -+ x86_64-*-darwin2[0-3]*) -+ tmake_file="t-darwin-min-11 t-darwin-libgccs1 $tmake_file" -+ ;; -+ *-*-darwin2*) -+ tmake_file="t-darwin-min-11 t-darwin-libgccs1 $tmake_file" -+ ;; -+ *-*-darwin1[89]*) -+ tmake_file="t-darwin-min-8 t-darwin-libgccs1 $tmake_file" - ;; - *-*-darwin9* | *-*-darwin1[0-7]*) -- tmake_file="t-darwin-min-5 $tmake_file" -+ tmake_file="t-darwin-min-5 t-darwin-libgccs1 $tmake_file" - ;; - *-*-darwin[4-8]*) -- tmake_file="t-darwin-min-1 $tmake_file" -+ tmake_file="t-darwin-min-1 t-darwin-libgccs1 $tmake_file" - ;; - *) - # Fall back to configuring for the oldest system known to work with -@@ -251,7 +256,29 @@ case ${host} in - echo "Warning: libgcc configured to support macOS 10.5" 1>&2 - ;; - esac -- extra_parts="crt3.o libd10-uwfef.a crttms.o crttme.o libemutls_w.a" -+ # We are not using libtool to build the libs here, so we need to replicate -+ # a little of the logic around setting Darwin rpaths. Setting an explicit -+ # yes or no is honoured, otherwise we choose a suitable default. -+ # Sadly, this has to be kept in line with the rules in libtool.m4. -+ # This make fragment will override the setting in t-slibgcc-darwin so it -+ # must appear after it. -+ if test "x$enable_darwin_at_rpath" = "x"; then -+ echo "enable_darwin_at_rpath is unset" 1>&2 -+ case ${host} in -+ *-darwin[45678]*) ;; -+ *-darwin9* | *-darwin1[01234]*) ;; # We might default these on later. -+ *-darwin*) -+ echo "but is needed after macOS 10.11 (setting it on)" 1>&2 -+ enable_darwin_at_rpath=yes -+ ;; -+ esac -+ else -+ echo "enable_darwin_at_rpath is '$enable_darwin_at_rpath'" 1>&2 -+ fi -+ if test "x$enable_darwin_at_rpath" = "xyes"; then -+ tmake_file="$tmake_file t-darwin-rpath " -+ fi -+ extra_parts="crt3.o crttms.o crttme.o libemutls_w.a " - ;; - *-*-dragonfly*) - tmake_file="$tmake_file t-crtstuff-pic t-libgcc-pic t-eh-dw2-dip" -@@ -395,6 +422,15 @@ aarch64*-*-elf | aarch64*-*-rtems*) - tmake_file="${tmake_file} t-dfprules" - md_unwind_header=aarch64/aarch64-unwind.h - ;; -+aarch64*-*-darwin*) -+ extra_parts="$extra_parts crtfastmath.o libheapt_w.a" -+ tmake_file="${tmake_file} ${cpu_type}/t-aarch64" -+ tmake_file="${tmake_file} ${cpu_type}/t-lse " -+ tmake_file="${tmake_file} ${cpu_type}/t-softfp t-softfp " -+ tmake_file="${tmake_file} t-crtfm t-dfprules" -+ tmake_file="${tmake_file} ${cpu_type}/t-heap-trampoline" -+ md_unwind_header=aarch64/aarch64-unwind.h -+ ;; - aarch64*-*-freebsd*) - extra_parts="$extra_parts crtfastmath.o" - tmake_file="${tmake_file} ${cpu_type}/t-aarch64" -@@ -423,6 +459,7 @@ aarch64*-*-linux*) - tmake_file="${tmake_file} ${cpu_type}/t-lse t-slibgcc-libgcc" - tmake_file="${tmake_file} ${cpu_type}/t-softfp t-softfp t-crtfm" - tmake_file="${tmake_file} t-dfprules" -+ tmake_file="${tmake_file} ${cpu_type}/t-heap-trampoline" - ;; - aarch64*-*-vxworks7*) - extra_parts="$extra_parts crtfastmath.o" -@@ -691,12 +728,18 @@ hppa*-*-netbsd*) - i[34567]86-*-darwin*) - tmake_file="$tmake_file i386/t-crtpc t-crtfm i386/t-msabi" - tm_file="$tm_file i386/darwin-lib.h" -- extra_parts="$extra_parts crtprec32.o crtprec64.o crtprec80.o crtfastmath.o" -+ extra_parts="$extra_parts libd10-uwfef.a " -+ extra_parts="$extra_parts crtprec32.o crtprec64.o crtprec80.o" -+ extra_parts="$extra_parts crtfastmath.o libheapt_w.a" -+ tmake_file="${tmake_file} i386/t-heap-trampoline" - ;; - x86_64-*-darwin*) - tmake_file="$tmake_file i386/t-crtpc t-crtfm i386/t-msabi" - tm_file="$tm_file i386/darwin-lib.h" -- extra_parts="$extra_parts crtprec32.o crtprec64.o crtprec80.o crtfastmath.o" -+ extra_parts="$extra_parts libd10-uwfef.a " -+ extra_parts="$extra_parts crtprec32.o crtprec64.o crtprec80.o" -+ extra_parts="$extra_parts crtfastmath.o libheapt_w.a" -+ tmake_file="${tmake_file} i386/t-heap-trampoline" - ;; - i[34567]86-*-elfiamcu) - tmake_file="$tmake_file i386/t-crtstuff t-softfp-sfdftf i386/32/t-softfp i386/32/t-iamcu i386/t-softfp t-softfp t-dfprules" -@@ -746,6 +789,7 @@ i[34567]86-*-linux*) - tmake_file="${tmake_file} i386/t-crtpc t-crtfm i386/t-crtstuff t-dfprules" - tm_file="${tm_file} i386/elf-lib.h" - md_unwind_header=i386/linux-unwind.h -+ tmake_file="${tmake_file} i386/t-heap-trampoline" - ;; - i[34567]86-*-kfreebsd*-gnu | i[34567]86-*-kopensolaris*-gnu) - extra_parts="$extra_parts crtprec32.o crtprec64.o crtprec80.o crtfastmath.o" -@@ -763,6 +807,7 @@ x86_64-*-linux*) - tmake_file="${tmake_file} i386/t-crtpc t-crtfm i386/t-crtstuff t-dfprules" - tm_file="${tm_file} i386/elf-lib.h" - md_unwind_header=i386/linux-unwind.h -+ tmake_file="${tmake_file} i386/t-heap-trampoline" - ;; - x86_64-*-kfreebsd*-gnu) - extra_parts="$extra_parts crtprec32.o crtprec64.o crtprec80.o crtfastmath.o" -@@ -1171,12 +1216,14 @@ powerpc-*-darwin*) - # We build the darwin10 EH shim for Rosetta (running on x86 machines). - tm_file="$tm_file i386/darwin-lib.h" - tmake_file="$tmake_file rs6000/t-ppc64-fp rs6000/t-ibm-ldouble" -+ extra_parts="$extra_parts libd10-uwfef.a " - extra_parts="$extra_parts crt2.o crt3_2.o libef_ppc.a dw_ppc.o" - ;; - powerpc64-*-darwin*) - # We build the darwin10 EH shim for Rosetta (running on x86 machines). - tm_file="$tm_file i386/darwin-lib.h" - tmake_file="$tmake_file rs6000/t-darwin64 rs6000/t-ibm-ldouble" -+ extra_parts="$extra_parts libd10-uwfef.a " - extra_parts="$extra_parts crt2.o crt3_2.o libef_ppc.a dw_ppc.o" - ;; - powerpc*-*-freebsd*) -diff --git a/libgcc/libgcc-std.ver.in b/libgcc/libgcc-std.ver.in -index c4f87a5..ad854bf 100644 ---- a/libgcc/libgcc-std.ver.in -+++ b/libgcc/libgcc-std.ver.in -@@ -1944,3 +1944,9 @@ GCC_7.0.0 { - __PFX__divmoddi4 - __PFX__divmodti4 - } -+ -+%inherit GCC_14.0.0 GCC_7.0.0 -+GCC_14.0.0 { -+ __gcc_nested_func_ptr_created -+ __gcc_nested_func_ptr_deleted -+} -diff --git a/libgcc/libgcc2.h b/libgcc/libgcc2.h -index 3ec9bbd..a7a5dff 100644 ---- a/libgcc/libgcc2.h -+++ b/libgcc/libgcc2.h -@@ -29,6 +29,9 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see - #pragma GCC visibility push(default) - #endif - -+extern void __gcc_nested_func_ptr_created (void *, void *, void **); -+extern void __gcc_nested_func_ptr_deleted (void); -+ - extern int __gcc_bcmp (const unsigned char *, const unsigned char *, size_t); - extern void __clear_cache (void *, void *); - extern void __eprintf (const char *, const char *, unsigned int, const char *) -diff --git a/libgfortran/Makefile.am b/libgfortran/Makefile.am -index 454ad12..3d21373 100644 ---- a/libgfortran/Makefile.am -+++ b/libgfortran/Makefile.am -@@ -37,6 +37,11 @@ else - version_arg = - version_dep = - endif -+extra_darwin_ldflags_libgfortran = @extra_ldflags_libgfortran@ -+if ENABLE_DARWIN_AT_RPATH -+extra_darwin_ldflags_libgfortran += -Wc,-nodefaultrpaths -+extra_darwin_ldflags_libgfortran += -Wl,-rpath,@loader_path -+endif - - gfor_c_HEADERS = ISO_Fortran_binding.h - gfor_cdir = $(libdir)/gcc/$(target_alias)/$(gcc_version)/include -@@ -50,7 +55,7 @@ libgfortran_la_LINK = $(LINK) $(libgfortran_la_LDFLAGS) - libgfortran_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` \ - $(LTLDFLAGS) $(LIBQUADLIB) ../libbacktrace/libbacktrace.la \ - $(HWCAP_LDFLAGS) \ -- $(LIBM) $(extra_ldflags_libgfortran) \ -+ $(LIBM) $(extra_darwin_ldflags_libgfortran) \ - $(version_arg) -Wc,-shared-libgcc - libgfortran_la_DEPENDENCIES = $(version_dep) libgfortran.spec $(LIBQUADLIB_DEP) - -diff --git a/libgfortran/Makefile.in b/libgfortran/Makefile.in -index 23df076..ed0d05f 100644 ---- a/libgfortran/Makefile.in -+++ b/libgfortran/Makefile.in -@@ -91,8 +91,10 @@ POST_UNINSTALL = : - build_triplet = @build@ - host_triplet = @host@ - target_triplet = @target@ --@LIBGFOR_MINIMAL_TRUE@am__append_1 = -DLIBGFOR_MINIMAL --@LIBGFOR_MINIMAL_FALSE@am__append_2 = \ -+@ENABLE_DARWIN_AT_RPATH_TRUE@am__append_1 = -Wc,-nodefaultrpaths \ -+@ENABLE_DARWIN_AT_RPATH_TRUE@ -Wl,-rpath,@loader_path -+@LIBGFOR_MINIMAL_TRUE@am__append_2 = -DLIBGFOR_MINIMAL -+@LIBGFOR_MINIMAL_FALSE@am__append_3 = \ - @LIBGFOR_MINIMAL_FALSE@io/close.c \ - @LIBGFOR_MINIMAL_FALSE@io/file_pos.c \ - @LIBGFOR_MINIMAL_FALSE@io/format.c \ -@@ -110,7 +112,7 @@ target_triplet = @target@ - @LIBGFOR_MINIMAL_FALSE@io/fbuf.c \ - @LIBGFOR_MINIMAL_FALSE@io/async.c - --@LIBGFOR_MINIMAL_FALSE@am__append_3 = \ -+@LIBGFOR_MINIMAL_FALSE@am__append_4 = \ - @LIBGFOR_MINIMAL_FALSE@intrinsics/access.c \ - @LIBGFOR_MINIMAL_FALSE@intrinsics/c99_functions.c \ - @LIBGFOR_MINIMAL_FALSE@intrinsics/chdir.c \ -@@ -143,9 +145,9 @@ target_triplet = @target@ - @LIBGFOR_MINIMAL_FALSE@intrinsics/umask.c \ - @LIBGFOR_MINIMAL_FALSE@intrinsics/unlink.c - --@IEEE_SUPPORT_TRUE@am__append_4 = ieee/ieee_helper.c --@LIBGFOR_MINIMAL_TRUE@am__append_5 = runtime/minimal.c --@LIBGFOR_MINIMAL_FALSE@am__append_6 = \ -+@IEEE_SUPPORT_TRUE@am__append_5 = ieee/ieee_helper.c -+@LIBGFOR_MINIMAL_TRUE@am__append_6 = runtime/minimal.c -+@LIBGFOR_MINIMAL_FALSE@am__append_7 = \ - @LIBGFOR_MINIMAL_FALSE@runtime/backtrace.c \ - @LIBGFOR_MINIMAL_FALSE@runtime/convert_char.c \ - @LIBGFOR_MINIMAL_FALSE@runtime/environ.c \ -@@ -157,7 +159,7 @@ target_triplet = @target@ - - - # dummy sources for libtool --@onestep_TRUE@am__append_7 = libgfortran_c.c libgfortran_f.f90 -+@onestep_TRUE@am__append_8 = libgfortran_c.c libgfortran_f.f90 - subdir = . - ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 - am__aclocal_m4_deps = $(top_srcdir)/../config/depstand.m4 \ -@@ -589,7 +591,7 @@ AMTAR = @AMTAR@ - - # Some targets require additional compiler options for IEEE compatibility. - AM_CFLAGS = @AM_CFLAGS@ -fcx-fortran-rules $(SECTION_FLAGS) \ -- $(IEEE_FLAGS) $(am__append_1) -+ $(IEEE_FLAGS) $(am__append_2) - AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ - AM_FCFLAGS = @AM_FCFLAGS@ $(IEEE_FLAGS) - AR = @AR@ -@@ -749,6 +751,8 @@ gcc_version := $(shell @get_gcc_base_ver@ $(top_srcdir)/../gcc/BASE-VER) - @LIBGFOR_USE_SYMVER_FALSE@version_dep = - @LIBGFOR_USE_SYMVER_GNU_TRUE@@LIBGFOR_USE_SYMVER_TRUE@version_dep = gfortran.ver - @LIBGFOR_USE_SYMVER_SUN_TRUE@@LIBGFOR_USE_SYMVER_TRUE@version_dep = gfortran.ver-sun gfortran.ver -+extra_darwin_ldflags_libgfortran = @extra_ldflags_libgfortran@ \ -+ $(am__append_1) - gfor_c_HEADERS = ISO_Fortran_binding.h - gfor_cdir = $(libdir)/gcc/$(target_alias)/$(gcc_version)/include - LTLDFLAGS = $(shell $(SHELL) $(top_srcdir)/../libtool-ldflags $(LDFLAGS)) \ -@@ -760,7 +764,7 @@ libgfortran_la_LINK = $(LINK) $(libgfortran_la_LDFLAGS) - libgfortran_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` \ - $(LTLDFLAGS) $(LIBQUADLIB) ../libbacktrace/libbacktrace.la \ - $(HWCAP_LDFLAGS) \ -- $(LIBM) $(extra_ldflags_libgfortran) \ -+ $(LIBM) $(extra_darwin_ldflags_libgfortran) \ - $(version_arg) -Wc,-shared-libgcc - - libgfortran_la_DEPENDENCIES = $(version_dep) libgfortran.spec $(LIBQUADLIB_DEP) -@@ -781,7 +785,7 @@ AM_CPPFLAGS = -iquote$(srcdir)/io -I$(srcdir)/$(MULTISRCTOP)../gcc \ - -I$(MULTIBUILDTOP)../libbacktrace \ - -I../libbacktrace - --gfor_io_src = io/size_from_kind.c $(am__append_2) -+gfor_io_src = io/size_from_kind.c $(am__append_3) - gfor_io_headers = \ - io/io.h \ - io/fbuf.h \ -@@ -803,7 +807,7 @@ gfor_helper_src = intrinsics/associated.c intrinsics/abort.c \ - intrinsics/selected_int_kind.f90 \ - intrinsics/selected_real_kind.f90 intrinsics/trigd.c \ - intrinsics/unpack_generic.c runtime/in_pack_generic.c \ -- runtime/in_unpack_generic.c $(am__append_3) $(am__append_4) -+ runtime/in_unpack_generic.c $(am__append_4) $(am__append_5) - @IEEE_SUPPORT_TRUE@gfor_ieee_helper_src = ieee/ieee_helper.c - @IEEE_SUPPORT_FALSE@gfor_ieee_src = - @IEEE_SUPPORT_TRUE@gfor_ieee_src = \ -@@ -812,8 +816,8 @@ gfor_helper_src = intrinsics/associated.c intrinsics/abort.c \ - @IEEE_SUPPORT_TRUE@ieee/ieee_features.F90 - - gfor_src = runtime/bounds.c runtime/compile_options.c runtime/memory.c \ -- runtime/string.c runtime/select.c $(am__append_5) \ -- $(am__append_6) -+ runtime/string.c runtime/select.c $(am__append_6) \ -+ $(am__append_7) - i_all_c = \ - $(srcdir)/generated/all_l1.c \ - $(srcdir)/generated/all_l2.c \ -@@ -1653,7 +1657,7 @@ intrinsics/random_init.f90 - - BUILT_SOURCES = $(gfor_built_src) $(gfor_built_specific_src) \ - $(gfor_built_specific2_src) $(gfor_misc_specifics) \ -- $(am__append_7) -+ $(am__append_8) - prereq_SRC = $(gfor_src) $(gfor_built_src) $(gfor_io_src) \ - $(gfor_helper_src) $(gfor_ieee_src) $(gfor_io_headers) $(gfor_specific_src) - -diff --git a/libgfortran/configure b/libgfortran/configure -index d7c3a5e..feb75f6 100755 ---- a/libgfortran/configure -+++ b/libgfortran/configure -@@ -654,6 +654,8 @@ extra_ldflags_libgfortran - ac_ct_FC - FCFLAGS - FC -+ENABLE_DARWIN_AT_RPATH_FALSE -+ENABLE_DARWIN_AT_RPATH_TRUE - enable_static - enable_shared - lt_host_flags -@@ -823,6 +825,7 @@ enable_static - with_pic - enable_fast_install - enable_libtool_lock -+enable_darwin_at_rpath - enable_largefile - enable_libquadmath_support - with_gcc_major_version_only -@@ -1478,6 +1481,9 @@ Optional Features: - --enable-fast-install[=PKGS] - optimize for fast installation [default=yes] - --disable-libtool-lock avoid locking (might break parallel builds) -+ --enable-darwin-at-rpath -+ install libraries with @rpath/library-name, requires -+ rpaths to be added to executables - --disable-largefile omit support for large files - --disable-libquadmath-support - disable libquadmath support for Fortran -@@ -9235,7 +9241,7 @@ $as_echo "$lt_cv_ld_force_load" >&6; } - # darwin 5.x (macOS 10.1) onwards we only need to adjust when the - # deployment target is forced to an earlier version. - case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host in -- UNSET,*-darwin[89]*|UNSET,*-darwin[12][0123456789]*) -+ UNSET,*-darwin[89]*|UNSET,*-darwin[12][0-9]*) - ;; - 10.[012][,.]*) - _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' -@@ -10945,6 +10951,49 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi - darwin* | rhapsody*) - - -+ -+ # Publish an arg to allow the user to select that Darwin host (and target) -+ # libraries should be given install-names like @rpath/libfoo.dylib. This -+ # requires that the user of the library then adds an 'rpath' to the DSO that -+ # needs access. -+ # NOTE: there are defaults below, for systems that support rpaths. The person -+ # configuring can override the defaults for any system version that supports -+ # them - they are, however, forced off for system versions without support. -+ # Check whether --enable-darwin-at-rpath was given. -+if test "${enable_darwin_at_rpath+set}" = set; then : -+ enableval=$enable_darwin_at_rpath; if test "x$enable_darwin_at_rpath" = "xyes"; then -+ # This is not supported before macOS 10.5 / Darwin9. -+ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in -+ UNSET,darwin[4-8]*|UNSET,rhapsody*|10.[0-4][,.]*) -+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Darwin @rpath library names are incompatible with OSX versions earlier than 10.5 (rpaths disabled)" >&5 -+$as_echo "$as_me: WARNING: Darwin @rpath library names are incompatible with OSX versions earlier than 10.5 (rpaths disabled)" >&2;} -+ enable_darwin_at_rpath=no -+ ;; -+ esac -+ fi -+else -+ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in -+ # As above, before 10.5 / Darwin9 this does not work. -+ UNSET,darwin[4-8]*|UNSET,rhapsody*|10.[0-4][,.]*) -+ enable_darwin_at_rpath=no -+ ;; -+ -+ # We cannot build and test reliably on macOS 10.11+ (Darwin15+) without use -+ # of rpaths, since runpaths set via DYLD_LIBRARY_PATH are elided by key -+ # system executables (e.g. /bin/sh). Force rpaths on for these systems. -+ UNSET,darwin1[5-9]*|UNSET,darwin2*|10.1[1-9][,.]*|1[1-9].*[,.]* ) -+ { $as_echo "$as_me:${as_lineno-$LINENO}: @rpath library names are needed on macOS versions later than 10.11 (rpaths have been enabled)" >&5 -+$as_echo "$as_me: @rpath library names are needed on macOS versions later than 10.11 (rpaths have been enabled)" >&6;} -+ enable_darwin_at_rpath=yes -+ ;; -+ # NOTE: we are not (yet) doing anything for 10.5 .. 10.10, since they can -+ # work with either DYLD_LIBRARY_PATH or embedded rpaths. -+ -+ esac -+ -+fi -+ -+ - archive_cmds_need_lc=no - hardcode_direct=no - hardcode_automatic=yes -@@ -10962,9 +11011,13 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi - esac - if test "$_lt_dar_can_shared" = "yes"; then - output_verbose_link_cmd=func_echo_all -- archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" -+ _lt_install_name='\$rpath/\$soname' -+ if test "x$enable_darwin_at_rpath" = "xyes"; then -+ _lt_install_name='@rpath/\$soname' -+ fi -+ archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name ${_lt_install_name} \$verstring ${_lt_dsymutil}" - module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" -- archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" -+ archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name ${_lt_install_name} \$verstring ${_lt_dar_export_syms}${_lt_dsymutil}" - module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" - - else -@@ -12791,7 +12844,7 @@ else - lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 - lt_status=$lt_dlunknown - cat > conftest.$ac_ext <<_LT_EOF --#line 12794 "configure" -+#line 12847 "configure" - #include "confdefs.h" - - #if HAVE_DLFCN_H -@@ -12897,7 +12950,7 @@ else - lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 - lt_status=$lt_dlunknown - cat > conftest.$ac_ext <<_LT_EOF --#line 12900 "configure" -+#line 12953 "configure" - #include "confdefs.h" - - #if HAVE_DLFCN_H -@@ -13299,6 +13352,14 @@ esac - - - -+ if test x$enable_darwin_at_rpath = xyes; then -+ ENABLE_DARWIN_AT_RPATH_TRUE= -+ ENABLE_DARWIN_AT_RPATH_FALSE='#' -+else -+ ENABLE_DARWIN_AT_RPATH_TRUE='#' -+ ENABLE_DARWIN_AT_RPATH_FALSE= -+fi -+ - #AC_MSG_NOTICE([====== Finished libtool configuration]) ; sleep 10 - - # We need gfortran to compile parts of the library -@@ -14942,6 +15003,49 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi - darwin* | rhapsody*) - - -+ -+ # Publish an arg to allow the user to select that Darwin host (and target) -+ # libraries should be given install-names like @rpath/libfoo.dylib. This -+ # requires that the user of the library then adds an 'rpath' to the DSO that -+ # needs access. -+ # NOTE: there are defaults below, for systems that support rpaths. The person -+ # configuring can override the defaults for any system version that supports -+ # them - they are, however, forced off for system versions without support. -+ # Check whether --enable-darwin-at-rpath was given. -+if test "${enable_darwin_at_rpath+set}" = set; then : -+ enableval=$enable_darwin_at_rpath; if test "x$enable_darwin_at_rpath" = "xyes"; then -+ # This is not supported before macOS 10.5 / Darwin9. -+ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in -+ UNSET,darwin[4-8]*|UNSET,rhapsody*|10.[0-4][,.]*) -+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Darwin @rpath library names are incompatible with OSX versions earlier than 10.5 (rpaths disabled)" >&5 -+$as_echo "$as_me: WARNING: Darwin @rpath library names are incompatible with OSX versions earlier than 10.5 (rpaths disabled)" >&2;} -+ enable_darwin_at_rpath=no -+ ;; -+ esac -+ fi -+else -+ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in -+ # As above, before 10.5 / Darwin9 this does not work. -+ UNSET,darwin[4-8]*|UNSET,rhapsody*|10.[0-4][,.]*) -+ enable_darwin_at_rpath=no -+ ;; -+ -+ # We cannot build and test reliably on macOS 10.11+ (Darwin15+) without use -+ # of rpaths, since runpaths set via DYLD_LIBRARY_PATH are elided by key -+ # system executables (e.g. /bin/sh). Force rpaths on for these systems. -+ UNSET,darwin1[5-9]*|UNSET,darwin2*|10.1[1-9][,.]*|1[1-9].*[,.]* ) -+ { $as_echo "$as_me:${as_lineno-$LINENO}: @rpath library names are needed on macOS versions later than 10.11 (rpaths have been enabled)" >&5 -+$as_echo "$as_me: @rpath library names are needed on macOS versions later than 10.11 (rpaths have been enabled)" >&6;} -+ enable_darwin_at_rpath=yes -+ ;; -+ # NOTE: we are not (yet) doing anything for 10.5 .. 10.10, since they can -+ # work with either DYLD_LIBRARY_PATH or embedded rpaths. -+ -+ esac -+ -+fi -+ -+ - archive_cmds_need_lc_FC=no - hardcode_direct_FC=no - hardcode_automatic_FC=yes -@@ -14959,9 +15063,13 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi - esac - if test "$_lt_dar_can_shared" = "yes"; then - output_verbose_link_cmd=func_echo_all -- archive_cmds_FC="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" -+ _lt_install_name='\$rpath/\$soname' -+ if test "x$enable_darwin_at_rpath" = "xyes"; then -+ _lt_install_name='@rpath/\$soname' -+ fi -+ archive_cmds_FC="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name ${_lt_install_name} \$verstring ${_lt_dsymutil}" - module_cmds_FC="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" -- archive_expsym_cmds_FC="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" -+ archive_expsym_cmds_FC="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name ${_lt_install_name} \$verstring ${_lt_dar_export_syms}${_lt_dsymutil}" - module_expsym_cmds_FC="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" - - else -@@ -16234,9 +16342,10 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu - - - # extra LD Flags which are required for targets -+extra_ldflags_libgfortran= - case "${host}" in -- *-darwin*) -- # Darwin needs -single_module when linking libgfortran -+ *-*-darwin[4567]*) -+ # Earlier Darwin needs -single_module when linking libgfortran - extra_ldflags_libgfortran=-Wl,-single_module - ;; - esac -@@ -31597,6 +31706,10 @@ if test -z "${HAVE_HWCAP_TRUE}" && test -z "${HAVE_HWCAP_FALSE}"; then - as_fn_error $? "conditional \"HAVE_HWCAP\" was never defined. - Usually this means the macro was only invoked conditionally." "$LINENO" 5 - fi -+if test -z "${ENABLE_DARWIN_AT_RPATH_TRUE}" && test -z "${ENABLE_DARWIN_AT_RPATH_FALSE}"; then -+ as_fn_error $? "conditional \"ENABLE_DARWIN_AT_RPATH\" was never defined. -+Usually this means the macro was only invoked conditionally." "$LINENO" 5 -+fi - if test -z "${IEEE_SUPPORT_TRUE}" && test -z "${IEEE_SUPPORT_FALSE}"; then - as_fn_error $? "conditional \"IEEE_SUPPORT\" was never defined. - Usually this means the macro was only invoked conditionally." "$LINENO" 5 -diff --git a/libgfortran/configure.ac b/libgfortran/configure.ac -index 07b9a48..4ee63cf 100644 ---- a/libgfortran/configure.ac -+++ b/libgfortran/configure.ac -@@ -282,6 +282,7 @@ LT_LIB_M - ACX_LT_HOST_FLAGS - AC_SUBST(enable_shared) - AC_SUBST(enable_static) -+AM_CONDITIONAL([ENABLE_DARWIN_AT_RPATH], [test x$enable_darwin_at_rpath = xyes]) - #AC_MSG_NOTICE([====== Finished libtool configuration]) ; sleep 10 - - # We need gfortran to compile parts of the library -@@ -290,9 +291,10 @@ FC="$GFORTRAN" - AC_PROG_FC(gfortran) - - # extra LD Flags which are required for targets -+extra_ldflags_libgfortran= - case "${host}" in -- *-darwin*) -- # Darwin needs -single_module when linking libgfortran -+ *-*-darwin[[4567]]*) -+ # Earlier Darwin needs -single_module when linking libgfortran - extra_ldflags_libgfortran=-Wl,-single_module - ;; - esac -diff --git a/libgm2/Makefile.am b/libgm2/Makefile.am -index 95df3ed..aa35e74 100644 ---- a/libgm2/Makefile.am -+++ b/libgm2/Makefile.am -@@ -46,6 +46,12 @@ SUBDIRS = libm2min libm2log libm2cor libm2iso libm2pim - GM2_BUILDDIR := $(shell pwd) - gm2_cdir = $(libdir)/gcc/$(target_alias)/$(gcc_version)/include - -+if ENABLE_DARWIN_AT_RPATH -+DARWIN_AT_RPATH=yes -+else -+DARWIN_AT_RPATH=yes -+endif -+ - # Work around what appears to be a GNU make bug handling MAKEFLAGS - # values defined in terms of make variables, as is the case for CC and - # friends when we are called from the top level Makefile. -@@ -91,7 +97,8 @@ AM_MAKEFLAGS = \ - "WERROR=$(WERROR)" \ - "TARGET_LIB_PATH=$(TARGET_LIB_PATH)" \ - "TARGET_LIB_PATH_libgm2=$(TARGET_LIB_PATH_libgm2)" \ -- "LIBTOOL=$(GM2_BUILDDIR)/libtool" -+ "LIBTOOL=$(GM2_BUILDDIR)/libtool" \ -+ "DARWIN_AT_RPATH=$(DARWIN_AT_RPATH)" - - # Subdir rules rely on $(FLAGS_TO_PASS) - FLAGS_TO_PASS = $(AM_MAKEFLAGS) -diff --git a/libgm2/Makefile.in b/libgm2/Makefile.in -index 2b9592b..f97f6d0 100644 ---- a/libgm2/Makefile.in -+++ b/libgm2/Makefile.in -@@ -90,15 +90,15 @@ host_triplet = @host@ - target_triplet = @target@ - subdir = . - ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 --am__aclocal_m4_deps = $(top_srcdir)/../libtool.m4 \ -- $(top_srcdir)/../ltoptions.m4 $(top_srcdir)/../ltsugar.m4 \ -- $(top_srcdir)/../ltversion.m4 $(top_srcdir)/../lt~obsolete.m4 \ -- $(top_srcdir)/../config/acx.m4 \ -+am__aclocal_m4_deps = $(top_srcdir)/../config/acx.m4 \ - $(top_srcdir)/../config/depstand.m4 \ - $(top_srcdir)/../config/lead-dot.m4 \ - $(top_srcdir)/../config/multi.m4 \ - $(top_srcdir)/../config/no-executables.m4 \ -- $(top_srcdir)/../config/override.m4 $(top_srcdir)/configure.ac -+ $(top_srcdir)/../config/override.m4 \ -+ $(top_srcdir)/../libtool.m4 $(top_srcdir)/../ltoptions.m4 \ -+ $(top_srcdir)/../ltsugar.m4 $(top_srcdir)/../ltversion.m4 \ -+ $(top_srcdir)/../lt~obsolete.m4 $(top_srcdir)/configure.ac - am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ - $(ACLOCAL_M4) - DIST_COMMON = $(srcdir)/Makefile.am $(top_srcdir)/configure \ -@@ -344,6 +344,8 @@ GM2_SRC = $(GCC_DIR)/m2 - SUBDIRS = libm2min libm2log libm2cor libm2iso libm2pim - GM2_BUILDDIR := $(shell pwd) - gm2_cdir = $(libdir)/gcc/$(target_alias)/$(gcc_version)/include -+@ENABLE_DARWIN_AT_RPATH_FALSE@DARWIN_AT_RPATH = yes -+@ENABLE_DARWIN_AT_RPATH_TRUE@DARWIN_AT_RPATH = yes - - # Work around what appears to be a GNU make bug handling MAKEFLAGS - # values defined in terms of make variables, as is the case for CC and -@@ -390,7 +392,8 @@ AM_MAKEFLAGS = \ - "WERROR=$(WERROR)" \ - "TARGET_LIB_PATH=$(TARGET_LIB_PATH)" \ - "TARGET_LIB_PATH_libgm2=$(TARGET_LIB_PATH_libgm2)" \ -- "LIBTOOL=$(GM2_BUILDDIR)/libtool" -+ "LIBTOOL=$(GM2_BUILDDIR)/libtool" \ -+ "DARWIN_AT_RPATH=$(DARWIN_AT_RPATH)" - - - # Subdir rules rely on $(FLAGS_TO_PASS) -diff --git a/libgm2/aclocal.m4 b/libgm2/aclocal.m4 -index c352303..832065f 100644 ---- a/libgm2/aclocal.m4 -+++ b/libgm2/aclocal.m4 -@@ -1187,14 +1187,14 @@ AC_SUBST([am__tar]) - AC_SUBST([am__untar]) - ]) # _AM_PROG_TAR - --m4_include([../libtool.m4]) --m4_include([../ltoptions.m4]) --m4_include([../ltsugar.m4]) --m4_include([../ltversion.m4]) --m4_include([../lt~obsolete.m4]) - m4_include([../config/acx.m4]) - m4_include([../config/depstand.m4]) - m4_include([../config/lead-dot.m4]) - m4_include([../config/multi.m4]) - m4_include([../config/no-executables.m4]) - m4_include([../config/override.m4]) -+m4_include([../libtool.m4]) -+m4_include([../ltoptions.m4]) -+m4_include([../ltsugar.m4]) -+m4_include([../ltversion.m4]) -+m4_include([../lt~obsolete.m4]) -diff --git a/libgm2/configure b/libgm2/configure -index bf35b40..64f4f80 100755 ---- a/libgm2/configure -+++ b/libgm2/configure -@@ -649,6 +649,8 @@ GM2_FOR_TARGET - CC_FOR_BUILD - enable_static - enable_shared -+ENABLE_DARWIN_AT_RPATH_FALSE -+ENABLE_DARWIN_AT_RPATH_TRUE - CXXCPP - OTOOL64 - OTOOL -@@ -806,6 +808,7 @@ with_pic - enable_fast_install - with_gnu_ld - enable_libtool_lock -+enable_darwin_at_rpath - with_gcc_major_version_only - ' - ac_precious_vars='build_alias -@@ -1456,6 +1459,9 @@ Optional Features: - --enable-fast-install[=PKGS] - optimize for fast installation [default=yes] - --disable-libtool-lock avoid locking (might break parallel builds) -+ --enable-darwin-at-rpath -+ install libraries with @rpath/library-name, requires -+ rpaths to be added to executables - - Optional Packages: - --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] -@@ -6611,10 +6617,6 @@ fi - - - --enable_dlopen=yes -- -- -- - case `pwd` in - *\ * | *\ *) - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5 -@@ -9185,7 +9187,7 @@ $as_echo "$lt_cv_ld_force_load" >&6; } - # darwin 5.x (macOS 10.1) onwards we only need to adjust when the - # deployment target is forced to an earlier version. - case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host in -- UNSET,*-darwin[89]*|UNSET,*-darwin[12][0123456789]*) -+ UNSET,*-darwin[89]*|UNSET,*-darwin[12][0-9]*) - ;; - 10.[012][,.]*) - _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' -@@ -9233,6 +9235,8 @@ done - - - -+ enable_dlopen=no -+ - - enable_win32_dll=no - -@@ -10896,6 +10900,49 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi - darwin* | rhapsody*) - - -+ -+ # Publish an arg to allow the user to select that Darwin host (and target) -+ # libraries should be given install-names like @rpath/libfoo.dylib. This -+ # requires that the user of the library then adds an 'rpath' to the DSO that -+ # needs access. -+ # NOTE: there are defaults below, for systems that support rpaths. The person -+ # configuring can override the defaults for any system version that supports -+ # them - they are, however, forced off for system versions without support. -+ # Check whether --enable-darwin-at-rpath was given. -+if test "${enable_darwin_at_rpath+set}" = set; then : -+ enableval=$enable_darwin_at_rpath; if test "x$enable_darwin_at_rpath" = "xyes"; then -+ # This is not supported before macOS 10.5 / Darwin9. -+ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in -+ UNSET,darwin[4-8]*|UNSET,rhapsody*|10.[0-4][,.]*) -+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Darwin @rpath library names are incompatible with OSX versions earlier than 10.5 (rpaths disabled)" >&5 -+$as_echo "$as_me: WARNING: Darwin @rpath library names are incompatible with OSX versions earlier than 10.5 (rpaths disabled)" >&2;} -+ enable_darwin_at_rpath=no -+ ;; -+ esac -+ fi -+else -+ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in -+ # As above, before 10.5 / Darwin9 this does not work. -+ UNSET,darwin[4-8]*|UNSET,rhapsody*|10.[0-4][,.]*) -+ enable_darwin_at_rpath=no -+ ;; -+ -+ # We cannot build and test reliably on macOS 10.11+ (Darwin15+) without use -+ # of rpaths, since runpaths set via DYLD_LIBRARY_PATH are elided by key -+ # system executables (e.g. /bin/sh). Force rpaths on for these systems. -+ UNSET,darwin1[5-9]*|UNSET,darwin2*|10.1[1-9][,.]*|1[1-9].*[,.]* ) -+ { $as_echo "$as_me:${as_lineno-$LINENO}: @rpath library names are needed on macOS versions later than 10.11 (rpaths have been enabled)" >&5 -+$as_echo "$as_me: @rpath library names are needed on macOS versions later than 10.11 (rpaths have been enabled)" >&6;} -+ enable_darwin_at_rpath=yes -+ ;; -+ # NOTE: we are not (yet) doing anything for 10.5 .. 10.10, since they can -+ # work with either DYLD_LIBRARY_PATH or embedded rpaths. -+ -+ esac -+ -+fi -+ -+ - archive_cmds_need_lc=no - hardcode_direct=no - hardcode_automatic=yes -@@ -10913,9 +10960,13 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi - esac - if test "$_lt_dar_can_shared" = "yes"; then - output_verbose_link_cmd=func_echo_all -- archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" -+ _lt_install_name='\$rpath/\$soname' -+ if test "x$enable_darwin_at_rpath" = "xyes"; then -+ _lt_install_name='@rpath/\$soname' -+ fi -+ archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name ${_lt_install_name} \$verstring ${_lt_dsymutil}" - module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" -- archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" -+ archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name ${_lt_install_name} \$verstring ${_lt_dar_export_syms}${_lt_dsymutil}" - module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" - - else -@@ -12742,7 +12793,7 @@ else - lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 - lt_status=$lt_dlunknown - cat > conftest.$ac_ext <<_LT_EOF --#line 12745 "configure" -+#line 12796 "configure" - #include "confdefs.h" - - #if HAVE_DLFCN_H -@@ -12848,7 +12899,7 @@ else - lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 - lt_status=$lt_dlunknown - cat > conftest.$ac_ext <<_LT_EOF --#line 12851 "configure" -+#line 12902 "configure" - #include "confdefs.h" - - #if HAVE_DLFCN_H -@@ -13730,6 +13781,49 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi - darwin* | rhapsody*) - - -+ -+ # Publish an arg to allow the user to select that Darwin host (and target) -+ # libraries should be given install-names like @rpath/libfoo.dylib. This -+ # requires that the user of the library then adds an 'rpath' to the DSO that -+ # needs access. -+ # NOTE: there are defaults below, for systems that support rpaths. The person -+ # configuring can override the defaults for any system version that supports -+ # them - they are, however, forced off for system versions without support. -+ # Check whether --enable-darwin-at-rpath was given. -+if test "${enable_darwin_at_rpath+set}" = set; then : -+ enableval=$enable_darwin_at_rpath; if test "x$enable_darwin_at_rpath" = "xyes"; then -+ # This is not supported before macOS 10.5 / Darwin9. -+ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in -+ UNSET,darwin[4-8]*|UNSET,rhapsody*|10.[0-4][,.]*) -+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Darwin @rpath library names are incompatible with OSX versions earlier than 10.5 (rpaths disabled)" >&5 -+$as_echo "$as_me: WARNING: Darwin @rpath library names are incompatible with OSX versions earlier than 10.5 (rpaths disabled)" >&2;} -+ enable_darwin_at_rpath=no -+ ;; -+ esac -+ fi -+else -+ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in -+ # As above, before 10.5 / Darwin9 this does not work. -+ UNSET,darwin[4-8]*|UNSET,rhapsody*|10.[0-4][,.]*) -+ enable_darwin_at_rpath=no -+ ;; -+ -+ # We cannot build and test reliably on macOS 10.11+ (Darwin15+) without use -+ # of rpaths, since runpaths set via DYLD_LIBRARY_PATH are elided by key -+ # system executables (e.g. /bin/sh). Force rpaths on for these systems. -+ UNSET,darwin1[5-9]*|UNSET,darwin2*|10.1[1-9][,.]*|1[1-9].*[,.]* ) -+ { $as_echo "$as_me:${as_lineno-$LINENO}: @rpath library names are needed on macOS versions later than 10.11 (rpaths have been enabled)" >&5 -+$as_echo "$as_me: @rpath library names are needed on macOS versions later than 10.11 (rpaths have been enabled)" >&6;} -+ enable_darwin_at_rpath=yes -+ ;; -+ # NOTE: we are not (yet) doing anything for 10.5 .. 10.10, since they can -+ # work with either DYLD_LIBRARY_PATH or embedded rpaths. -+ -+ esac -+ -+fi -+ -+ - archive_cmds_need_lc_CXX=no - hardcode_direct_CXX=no - hardcode_automatic_CXX=yes -@@ -13747,12 +13841,20 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi - esac - if test "$_lt_dar_can_shared" = "yes"; then - output_verbose_link_cmd=func_echo_all -- archive_cmds_CXX="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" -+ _lt_install_name='\$rpath/\$soname' -+ if test "x$enable_darwin_at_rpath" = "xyes"; then -+ _lt_install_name='@rpath/\$soname' -+ fi -+ archive_cmds_CXX="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name ${_lt_install_name} \$verstring ${_lt_dsymutil}" - module_cmds_CXX="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" -- archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" -+ archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name ${_lt_install_name} \$verstring ${_lt_dar_export_syms}${_lt_dsymutil}" - module_expsym_cmds_CXX="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" - if test "$lt_cv_apple_cc_single_mod" != "yes"; then -- archive_cmds_CXX="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}" -+ _lt_install_name='\$rpath/\$soname' -+ if test "x$enable_darwin_at_rpath" = "xyes"; then -+ _lt_install_name='@rpath/\$soname' -+ fi -+ archive_cmds_CXX="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name ${_lt_install_name} \$verstring${_lt_dsymutil}" - archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}" - fi - -@@ -16126,6 +16228,21 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu - - - -+enable_dlopen=yes -+ -+ -+ -+ -+ if test x$enable_darwin_at_rpath = xyes; then -+ ENABLE_DARWIN_AT_RPATH_TRUE= -+ ENABLE_DARWIN_AT_RPATH_FALSE='#' -+else -+ ENABLE_DARWIN_AT_RPATH_TRUE='#' -+ ENABLE_DARWIN_AT_RPATH_FALSE= -+fi -+ -+ -+ - - - if test "${multilib}" = "yes"; then -@@ -20314,6 +20431,10 @@ if test -z "${am__fastdepCCAS_TRUE}" && test -z "${am__fastdepCCAS_FALSE}"; then - as_fn_error $? "conditional \"am__fastdepCCAS\" was never defined. - Usually this means the macro was only invoked conditionally." "$LINENO" 5 - fi -+if test -z "${ENABLE_DARWIN_AT_RPATH_TRUE}" && test -z "${ENABLE_DARWIN_AT_RPATH_FALSE}"; then -+ as_fn_error $? "conditional \"ENABLE_DARWIN_AT_RPATH\" was never defined. -+Usually this means the macro was only invoked conditionally." "$LINENO" 5 -+fi - if test -z "${BUILD_PIMLIB_TRUE}" && test -z "${BUILD_PIMLIB_FALSE}"; then - as_fn_error $? "conditional \"BUILD_PIMLIB\" was never defined. - Usually this means the macro was only invoked conditionally." "$LINENO" 5 -diff --git a/libgm2/configure.ac b/libgm2/configure.ac -index 9386bbf..305d2dc 100644 ---- a/libgm2/configure.ac -+++ b/libgm2/configure.ac -@@ -213,8 +213,12 @@ AC_PATH_PROG(PERL, perl, perl-not-found-in-path-error) - AC_PROG_MAKE_SET - AC_PROG_INSTALL - --AC_LIBTOOL_DLOPEN - AM_PROG_LIBTOOL -+LT_INIT -+AC_LIBTOOL_DLOPEN -+ -+AM_CONDITIONAL([ENABLE_DARWIN_AT_RPATH], [test x$enable_darwin_at_rpath = xyes]) -+ - AC_SUBST(enable_shared) - AC_SUBST(enable_static) - -diff --git a/libgm2/libm2cor/Makefile.am b/libgm2/libm2cor/Makefile.am -index ae96b4b..a08e6a9 100644 ---- a/libgm2/libm2cor/Makefile.am -+++ b/libgm2/libm2cor/Makefile.am -@@ -123,6 +123,10 @@ libm2cor_la_link_flags = -Wl,-undefined,dynamic_lookup - else - libm2cor_la_link_flags = - endif -+if ENABLE_DARWIN_AT_RPATH -+libm2cor_la_link_flags += -nodefaultrpaths -Wl,-rpath,@loader_path/ -+endif -+ - libm2cor_la_LINK = $(LINK) -version-info $(libtool_VERSION) $(libm2cor_la_link_flags) - BUILT_SOURCES = SYSTEM.def - CLEANFILES = SYSTEM.def -diff --git a/libgm2/libm2cor/Makefile.in b/libgm2/libm2cor/Makefile.in -index 8daf0ea..9e14c90 100644 ---- a/libgm2/libm2cor/Makefile.in -+++ b/libgm2/libm2cor/Makefile.in -@@ -105,17 +105,18 @@ POST_UNINSTALL = : - build_triplet = @build@ - host_triplet = @host@ - target_triplet = @target@ -+@BUILD_CORLIB_TRUE@@ENABLE_DARWIN_AT_RPATH_TRUE@am__append_1 = -nodefaultrpaths -Wl,-rpath,@loader_path/ - subdir = libm2cor - ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 --am__aclocal_m4_deps = $(top_srcdir)/../libtool.m4 \ -- $(top_srcdir)/../ltoptions.m4 $(top_srcdir)/../ltsugar.m4 \ -- $(top_srcdir)/../ltversion.m4 $(top_srcdir)/../lt~obsolete.m4 \ -- $(top_srcdir)/../config/acx.m4 \ -+am__aclocal_m4_deps = $(top_srcdir)/../config/acx.m4 \ - $(top_srcdir)/../config/depstand.m4 \ - $(top_srcdir)/../config/lead-dot.m4 \ - $(top_srcdir)/../config/multi.m4 \ - $(top_srcdir)/../config/no-executables.m4 \ -- $(top_srcdir)/../config/override.m4 $(top_srcdir)/configure.ac -+ $(top_srcdir)/../config/override.m4 \ -+ $(top_srcdir)/../libtool.m4 $(top_srcdir)/../ltoptions.m4 \ -+ $(top_srcdir)/../ltsugar.m4 $(top_srcdir)/../ltversion.m4 \ -+ $(top_srcdir)/../lt~obsolete.m4 $(top_srcdir)/configure.ac - am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ - $(ACLOCAL_M4) - DIST_COMMON = $(srcdir)/Makefile.am -@@ -469,8 +470,10 @@ FLAGS_TO_PASS = $(AM_MAKEFLAGS) - @BUILD_CORLIB_TRUE@ -fm2-pathname=m2iso -I$(GM2_SRC)/gm2-libs-iso \ - @BUILD_CORLIB_TRUE@ -fm2-g -g -Wcase-enum -Wreturn-type -fcase -fm2-prefix=m2cor - --@BUILD_CORLIB_TRUE@@TARGET_DARWIN_FALSE@libm2cor_la_link_flags = --@BUILD_CORLIB_TRUE@@TARGET_DARWIN_TRUE@libm2cor_la_link_flags = -Wl,-undefined,dynamic_lookup -+@BUILD_CORLIB_TRUE@@TARGET_DARWIN_FALSE@libm2cor_la_link_flags = \ -+@BUILD_CORLIB_TRUE@@TARGET_DARWIN_FALSE@ $(am__append_1) -+@BUILD_CORLIB_TRUE@@TARGET_DARWIN_TRUE@libm2cor_la_link_flags = -Wl,-undefined,dynamic_lookup \ -+@BUILD_CORLIB_TRUE@@TARGET_DARWIN_TRUE@ $(am__append_1) - @BUILD_CORLIB_TRUE@libm2cor_la_LINK = $(LINK) -version-info $(libtool_VERSION) $(libm2cor_la_link_flags) - @BUILD_CORLIB_TRUE@BUILT_SOURCES = SYSTEM.def - @BUILD_CORLIB_TRUE@CLEANFILES = SYSTEM.def -diff --git a/libgm2/libm2iso/Makefile.am b/libgm2/libm2iso/Makefile.am -index 90d344f..e88c4b6 100644 ---- a/libgm2/libm2iso/Makefile.am -+++ b/libgm2/libm2iso/Makefile.am -@@ -197,6 +197,10 @@ libm2iso_la_link_flags = -Wl,-undefined,dynamic_lookup - else - libm2iso_la_link_flags = - endif -+if ENABLE_DARWIN_AT_RPATH -+libm2iso_la_link_flags += -nodefaultrpaths -Wl,-rpath,@loader_path/ -+endif -+ - libm2iso_la_LINK = $(LINK) -version-info $(libtool_VERSION) $(libm2iso_la_link_flags) - CLEANFILES = SYSTEM.def - BUILT_SOURCES = SYSTEM.def -diff --git a/libgm2/libm2iso/Makefile.in b/libgm2/libm2iso/Makefile.in -index 8d6443d..7be5ad1 100644 ---- a/libgm2/libm2iso/Makefile.in -+++ b/libgm2/libm2iso/Makefile.in -@@ -105,17 +105,18 @@ POST_UNINSTALL = : - build_triplet = @build@ - host_triplet = @host@ - target_triplet = @target@ -+@BUILD_ISOLIB_TRUE@@ENABLE_DARWIN_AT_RPATH_TRUE@am__append_1 = -nodefaultrpaths -Wl,-rpath,@loader_path/ - subdir = libm2iso - ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 --am__aclocal_m4_deps = $(top_srcdir)/../libtool.m4 \ -- $(top_srcdir)/../ltoptions.m4 $(top_srcdir)/../ltsugar.m4 \ -- $(top_srcdir)/../ltversion.m4 $(top_srcdir)/../lt~obsolete.m4 \ -- $(top_srcdir)/../config/acx.m4 \ -+am__aclocal_m4_deps = $(top_srcdir)/../config/acx.m4 \ - $(top_srcdir)/../config/depstand.m4 \ - $(top_srcdir)/../config/lead-dot.m4 \ - $(top_srcdir)/../config/multi.m4 \ - $(top_srcdir)/../config/no-executables.m4 \ -- $(top_srcdir)/../config/override.m4 $(top_srcdir)/configure.ac -+ $(top_srcdir)/../config/override.m4 \ -+ $(top_srcdir)/../libtool.m4 $(top_srcdir)/../ltoptions.m4 \ -+ $(top_srcdir)/../ltsugar.m4 $(top_srcdir)/../ltversion.m4 \ -+ $(top_srcdir)/../lt~obsolete.m4 $(top_srcdir)/configure.ac - am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ - $(ACLOCAL_M4) - DIST_COMMON = $(srcdir)/Makefile.am -@@ -570,8 +571,10 @@ FLAGS_TO_PASS = $(AM_MAKEFLAGS) - @BUILD_ISOLIB_TRUE@ -fm2-pathname=m2pim -I$(GM2_SRC)/gm2-libs \ - @BUILD_ISOLIB_TRUE@ -fiso -fextended-opaque -fm2-g -g -Wcase-enum -Wreturn-type -fcase -fm2-prefix=m2iso - --@BUILD_ISOLIB_TRUE@@TARGET_DARWIN_FALSE@libm2iso_la_link_flags = --@BUILD_ISOLIB_TRUE@@TARGET_DARWIN_TRUE@libm2iso_la_link_flags = -Wl,-undefined,dynamic_lookup -+@BUILD_ISOLIB_TRUE@@TARGET_DARWIN_FALSE@libm2iso_la_link_flags = \ -+@BUILD_ISOLIB_TRUE@@TARGET_DARWIN_FALSE@ $(am__append_1) -+@BUILD_ISOLIB_TRUE@@TARGET_DARWIN_TRUE@libm2iso_la_link_flags = -Wl,-undefined,dynamic_lookup \ -+@BUILD_ISOLIB_TRUE@@TARGET_DARWIN_TRUE@ $(am__append_1) - @BUILD_ISOLIB_TRUE@libm2iso_la_LINK = $(LINK) -version-info $(libtool_VERSION) $(libm2iso_la_link_flags) - @BUILD_ISOLIB_TRUE@CLEANFILES = SYSTEM.def - @BUILD_ISOLIB_TRUE@BUILT_SOURCES = SYSTEM.def -diff --git a/libgm2/libm2log/Makefile.am b/libgm2/libm2log/Makefile.am -index 27f3840..25f5f9b 100644 ---- a/libgm2/libm2log/Makefile.am -+++ b/libgm2/libm2log/Makefile.am -@@ -142,6 +142,9 @@ libm2log_la_link_flags = -Wl,-undefined,dynamic_lookup - else - libm2log_la_link_flags = - endif -+if ENABLE_DARWIN_AT_RPATH -+libm2log_la_link_flags += -nodefaultrpaths -Wl,-rpath,@loader_path/ -+endif - libm2log_la_LINK = $(LINK) -version-info $(libtool_VERSION) $(libm2log_la_link_flags) - BUILT_SOURCES = ../libm2pim/SYSTEM.def - -diff --git a/libgm2/libm2log/Makefile.in b/libgm2/libm2log/Makefile.in -index 2188f9e..f82ddb6 100644 ---- a/libgm2/libm2log/Makefile.in -+++ b/libgm2/libm2log/Makefile.in -@@ -105,17 +105,18 @@ POST_UNINSTALL = : - build_triplet = @build@ - host_triplet = @host@ - target_triplet = @target@ -+@BUILD_LOGLIB_TRUE@@ENABLE_DARWIN_AT_RPATH_TRUE@am__append_1 = -nodefaultrpaths -Wl,-rpath,@loader_path/ - subdir = libm2log - ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 --am__aclocal_m4_deps = $(top_srcdir)/../libtool.m4 \ -- $(top_srcdir)/../ltoptions.m4 $(top_srcdir)/../ltsugar.m4 \ -- $(top_srcdir)/../ltversion.m4 $(top_srcdir)/../lt~obsolete.m4 \ -- $(top_srcdir)/../config/acx.m4 \ -+am__aclocal_m4_deps = $(top_srcdir)/../config/acx.m4 \ - $(top_srcdir)/../config/depstand.m4 \ - $(top_srcdir)/../config/lead-dot.m4 \ - $(top_srcdir)/../config/multi.m4 \ - $(top_srcdir)/../config/no-executables.m4 \ -- $(top_srcdir)/../config/override.m4 $(top_srcdir)/configure.ac -+ $(top_srcdir)/../config/override.m4 \ -+ $(top_srcdir)/../libtool.m4 $(top_srcdir)/../ltoptions.m4 \ -+ $(top_srcdir)/../ltsugar.m4 $(top_srcdir)/../ltversion.m4 \ -+ $(top_srcdir)/../lt~obsolete.m4 $(top_srcdir)/configure.ac - am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ - $(ACLOCAL_M4) - DIST_COMMON = $(srcdir)/Makefile.am -@@ -478,8 +479,10 @@ FLAGS_TO_PASS = $(AM_MAKEFLAGS) - @BUILD_LOGLIB_TRUE@ -fm2-pathname=m2iso -I$(GM2_SRC)/gm2-libs-iso \ - @BUILD_LOGLIB_TRUE@ -Wcase-enum -Wreturn-type -fcase -fm2-prefix=m2log - --@BUILD_LOGLIB_TRUE@@TARGET_DARWIN_FALSE@libm2log_la_link_flags = --@BUILD_LOGLIB_TRUE@@TARGET_DARWIN_TRUE@libm2log_la_link_flags = -Wl,-undefined,dynamic_lookup -+@BUILD_LOGLIB_TRUE@@TARGET_DARWIN_FALSE@libm2log_la_link_flags = \ -+@BUILD_LOGLIB_TRUE@@TARGET_DARWIN_FALSE@ $(am__append_1) -+@BUILD_LOGLIB_TRUE@@TARGET_DARWIN_TRUE@libm2log_la_link_flags = -Wl,-undefined,dynamic_lookup \ -+@BUILD_LOGLIB_TRUE@@TARGET_DARWIN_TRUE@ $(am__append_1) - @BUILD_LOGLIB_TRUE@libm2log_la_LINK = $(LINK) -version-info $(libtool_VERSION) $(libm2log_la_link_flags) - @BUILD_LOGLIB_TRUE@BUILT_SOURCES = ../libm2pim/SYSTEM.def - @BUILD_LOGLIB_TRUE@M2LIBDIR = /m2/m2log/ -diff --git a/libgm2/libm2min/Makefile.am b/libgm2/libm2min/Makefile.am -index 1ff1600..2141176 100644 ---- a/libgm2/libm2min/Makefile.am -+++ b/libgm2/libm2min/Makefile.am -@@ -113,6 +113,9 @@ libm2min_la_link_flags = -Wl,-undefined,dynamic_lookup - else - libm2min_la_link_flags = - endif -+if ENABLE_DARWIN_AT_RPATH -+libm2min_la_link_flags += -nodefaultrpaths -Wl,-rpath,@loader_path/ -+endif - libm2min_la_LINK = $(LINK) -version-info $(libtool_VERSION) $(libm2min_la_link_flags) - BUILT_SOURCES = SYSTEM.def - CLEANFILES = SYSTEM.def -diff --git a/libgm2/libm2min/Makefile.in b/libgm2/libm2min/Makefile.in -index 42cba0e..ed3312d 100644 ---- a/libgm2/libm2min/Makefile.in -+++ b/libgm2/libm2min/Makefile.in -@@ -105,17 +105,18 @@ POST_UNINSTALL = : - build_triplet = @build@ - host_triplet = @host@ - target_triplet = @target@ -+@ENABLE_DARWIN_AT_RPATH_TRUE@am__append_1 = -nodefaultrpaths -Wl,-rpath,@loader_path/ - subdir = libm2min - ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 --am__aclocal_m4_deps = $(top_srcdir)/../libtool.m4 \ -- $(top_srcdir)/../ltoptions.m4 $(top_srcdir)/../ltsugar.m4 \ -- $(top_srcdir)/../ltversion.m4 $(top_srcdir)/../lt~obsolete.m4 \ -- $(top_srcdir)/../config/acx.m4 \ -+am__aclocal_m4_deps = $(top_srcdir)/../config/acx.m4 \ - $(top_srcdir)/../config/depstand.m4 \ - $(top_srcdir)/../config/lead-dot.m4 \ - $(top_srcdir)/../config/multi.m4 \ - $(top_srcdir)/../config/no-executables.m4 \ -- $(top_srcdir)/../config/override.m4 $(top_srcdir)/configure.ac -+ $(top_srcdir)/../config/override.m4 \ -+ $(top_srcdir)/../libtool.m4 $(top_srcdir)/../ltoptions.m4 \ -+ $(top_srcdir)/../ltsugar.m4 $(top_srcdir)/../ltversion.m4 \ -+ $(top_srcdir)/../lt~obsolete.m4 $(top_srcdir)/configure.ac - am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ - $(ACLOCAL_M4) - DIST_COMMON = $(srcdir)/Makefile.am -@@ -442,8 +443,10 @@ libm2min_la_M2FLAGS = \ - -fm2-pathname=m2pim -I$(GM2_SRC)/gm2-libs -fno-exceptions \ - -fno-m2-plugin -fno-scaffold-dynamic -fno-scaffold-main -fm2-prefix=m2min - --@TARGET_DARWIN_FALSE@libm2min_la_link_flags = --@TARGET_DARWIN_TRUE@libm2min_la_link_flags = -Wl,-undefined,dynamic_lookup -+@TARGET_DARWIN_FALSE@libm2min_la_link_flags = $(am__append_1) -+@TARGET_DARWIN_TRUE@libm2min_la_link_flags = \ -+@TARGET_DARWIN_TRUE@ -Wl,-undefined,dynamic_lookup \ -+@TARGET_DARWIN_TRUE@ $(am__append_1) - libm2min_la_LINK = $(LINK) -version-info $(libtool_VERSION) $(libm2min_la_link_flags) - BUILT_SOURCES = SYSTEM.def - CLEANFILES = SYSTEM.def -diff --git a/libgm2/libm2pim/Makefile.am b/libgm2/libm2pim/Makefile.am -index ac172b9..61d6c81 100644 ---- a/libgm2/libm2pim/Makefile.am -+++ b/libgm2/libm2pim/Makefile.am -@@ -175,6 +175,9 @@ libm2pim_la_link_flags = -Wl,-undefined,dynamic_lookup - else - libm2pim_la_link_flags = - endif -+if ENABLE_DARWIN_AT_RPATH -+libm2pim_la_link_flags += -nodefaultrpaths -Wl,-rpath,@loader_path/ -+endif - libm2pim_la_LINK = $(LINK) -version-info $(libtool_VERSION) $(libm2pim_la_link_flags) - BUILT_SOURCES = SYSTEM.def - CLEANFILES = SYSTEM.def -diff --git a/libgm2/libm2pim/Makefile.in b/libgm2/libm2pim/Makefile.in -index 4c2d574..0f3a6fe 100644 ---- a/libgm2/libm2pim/Makefile.in -+++ b/libgm2/libm2pim/Makefile.in -@@ -105,17 +105,18 @@ POST_UNINSTALL = : - build_triplet = @build@ - host_triplet = @host@ - target_triplet = @target@ -+@BUILD_PIMLIB_TRUE@@ENABLE_DARWIN_AT_RPATH_TRUE@am__append_1 = -nodefaultrpaths -Wl,-rpath,@loader_path/ - subdir = libm2pim - ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 --am__aclocal_m4_deps = $(top_srcdir)/../libtool.m4 \ -- $(top_srcdir)/../ltoptions.m4 $(top_srcdir)/../ltsugar.m4 \ -- $(top_srcdir)/../ltversion.m4 $(top_srcdir)/../lt~obsolete.m4 \ -- $(top_srcdir)/../config/acx.m4 \ -+am__aclocal_m4_deps = $(top_srcdir)/../config/acx.m4 \ - $(top_srcdir)/../config/depstand.m4 \ - $(top_srcdir)/../config/lead-dot.m4 \ - $(top_srcdir)/../config/multi.m4 \ - $(top_srcdir)/../config/no-executables.m4 \ -- $(top_srcdir)/../config/override.m4 $(top_srcdir)/configure.ac -+ $(top_srcdir)/../config/override.m4 \ -+ $(top_srcdir)/../libtool.m4 $(top_srcdir)/../ltoptions.m4 \ -+ $(top_srcdir)/../ltsugar.m4 $(top_srcdir)/../ltversion.m4 \ -+ $(top_srcdir)/../lt~obsolete.m4 $(top_srcdir)/configure.ac - am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ - $(ACLOCAL_M4) - DIST_COMMON = $(srcdir)/Makefile.am -@@ -539,8 +540,10 @@ FLAGS_TO_PASS = $(AM_MAKEFLAGS) - @BUILD_PIMLIB_TRUE@ -fm2-pathname=m2iso -I$(GM2_SRC)/gm2-libs-iso \ - @BUILD_PIMLIB_TRUE@ -fm2-g -g -Wcase-enum -Wreturn-type -fcase -fm2-prefix=m2pim - --@BUILD_PIMLIB_TRUE@@TARGET_DARWIN_FALSE@libm2pim_la_link_flags = --@BUILD_PIMLIB_TRUE@@TARGET_DARWIN_TRUE@libm2pim_la_link_flags = -Wl,-undefined,dynamic_lookup -+@BUILD_PIMLIB_TRUE@@TARGET_DARWIN_FALSE@libm2pim_la_link_flags = \ -+@BUILD_PIMLIB_TRUE@@TARGET_DARWIN_FALSE@ $(am__append_1) -+@BUILD_PIMLIB_TRUE@@TARGET_DARWIN_TRUE@libm2pim_la_link_flags = -Wl,-undefined,dynamic_lookup \ -+@BUILD_PIMLIB_TRUE@@TARGET_DARWIN_TRUE@ $(am__append_1) - @BUILD_PIMLIB_TRUE@libm2pim_la_LINK = $(LINK) -version-info $(libtool_VERSION) $(libm2pim_la_link_flags) - @BUILD_PIMLIB_TRUE@BUILT_SOURCES = SYSTEM.def - @BUILD_PIMLIB_TRUE@CLEANFILES = SYSTEM.def -diff --git a/libgo/configure b/libgo/configure -index a607dbf..72d46c3 100755 ---- a/libgo/configure -+++ b/libgo/configure -@@ -708,6 +708,8 @@ glibgo_toolexecdir - WERROR - WARN_FLAGS - CC_FOR_BUILD -+ENABLE_DARWIN_AT_RPATH_FALSE -+ENABLE_DARWIN_AT_RPATH_TRUE - enable_static - enable_shared - CPP -@@ -11544,7 +11546,7 @@ else - lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 - lt_status=$lt_dlunknown - cat > conftest.$ac_ext <<_LT_EOF --#line 11547 "configure" -+#line 11549 "configure" - #include "confdefs.h" - - #if HAVE_DLFCN_H -@@ -11650,7 +11652,7 @@ else - lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 - lt_status=$lt_dlunknown - cat > conftest.$ac_ext <<_LT_EOF --#line 11653 "configure" -+#line 11655 "configure" - #include "confdefs.h" - - #if HAVE_DLFCN_H -@@ -13779,6 +13781,14 @@ CC="$lt_save_CC" - - - -+ if test x$enable_darwin_at_rpath = xyes; then -+ ENABLE_DARWIN_AT_RPATH_TRUE= -+ ENABLE_DARWIN_AT_RPATH_FALSE='#' -+else -+ ENABLE_DARWIN_AT_RPATH_TRUE='#' -+ ENABLE_DARWIN_AT_RPATH_FALSE= -+fi -+ - - CC_FOR_BUILD=${CC_FOR_BUILD:-gcc} - -@@ -16386,6 +16396,10 @@ if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then - as_fn_error $? "conditional \"MAINTAINER_MODE\" was never defined. - Usually this means the macro was only invoked conditionally." "$LINENO" 5 - fi -+if test -z "${ENABLE_DARWIN_AT_RPATH_TRUE}" && test -z "${ENABLE_DARWIN_AT_RPATH_FALSE}"; then -+ as_fn_error $? "conditional \"ENABLE_DARWIN_AT_RPATH\" was never defined. -+Usually this means the macro was only invoked conditionally." "$LINENO" 5 -+fi - if test -z "${USE_LIBFFI_TRUE}" && test -z "${USE_LIBFFI_FALSE}"; then - as_fn_error $? "conditional \"USE_LIBFFI\" was never defined. - Usually this means the macro was only invoked conditionally." "$LINENO" 5 -diff --git a/libgo/configure.ac b/libgo/configure.ac -index a59aa09..6f1ac32 100644 ---- a/libgo/configure.ac -+++ b/libgo/configure.ac -@@ -53,6 +53,7 @@ AC_LIBTOOL_DLOPEN - AM_PROG_LIBTOOL - AC_SUBST(enable_shared) - AC_SUBST(enable_static) -+AM_CONDITIONAL([ENABLE_DARWIN_AT_RPATH], [test x$enable_darwin_at_rpath = xyes]) - - CC_FOR_BUILD=${CC_FOR_BUILD:-gcc} - AC_SUBST(CC_FOR_BUILD) -diff --git a/libgomp/Makefile.am b/libgomp/Makefile.am -index 428f7a9..ceb8c91 100644 ---- a/libgomp/Makefile.am -+++ b/libgomp/Makefile.am -@@ -53,9 +53,14 @@ else - libgomp_version_script = - libgomp_version_dep = - endif -+ - libgomp_version_info = -version-info $(libtool_VERSION) -+if ENABLE_DARWIN_AT_RPATH -+libgomp_darwin_rpath = -Wc,-nodefaultrpaths -+libgomp_darwin_rpath += -Wl,-rpath,@loader_path -+endif - libgomp_la_LDFLAGS = $(libgomp_version_info) $(libgomp_version_script) \ -- $(lt_host_flags) -+ $(lt_host_flags) $(libgomp_darwin_rpath) - libgomp_la_LIBADD = - libgomp_la_DEPENDENCIES = $(libgomp_version_dep) - libgomp_la_LINK = $(LINK) $(libgomp_la_LDFLAGS) -diff --git a/libgomp/Makefile.in b/libgomp/Makefile.in -index f1afb5e..ef97186 100644 ---- a/libgomp/Makefile.in -+++ b/libgomp/Makefile.in -@@ -535,8 +535,11 @@ nodist_toolexeclib_HEADERS = libgomp.spec - @LIBGOMP_BUILD_VERSIONED_SHLIB_GNU_TRUE@@LIBGOMP_BUILD_VERSIONED_SHLIB_TRUE@libgomp_version_dep = libgomp.ver - @LIBGOMP_BUILD_VERSIONED_SHLIB_SUN_TRUE@@LIBGOMP_BUILD_VERSIONED_SHLIB_TRUE@libgomp_version_dep = libgomp.ver-sun - libgomp_version_info = -version-info $(libtool_VERSION) -+@ENABLE_DARWIN_AT_RPATH_TRUE@libgomp_darwin_rpath = \ -+@ENABLE_DARWIN_AT_RPATH_TRUE@ -Wc,-nodefaultrpaths \ -+@ENABLE_DARWIN_AT_RPATH_TRUE@ -Wl,-rpath,@loader_path - libgomp_la_LDFLAGS = $(libgomp_version_info) $(libgomp_version_script) \ -- $(lt_host_flags) -+ $(lt_host_flags) $(libgomp_darwin_rpath) - - libgomp_la_LIBADD = $(DL_LIBS) - libgomp_la_DEPENDENCIES = $(libgomp_version_dep) -diff --git a/libgomp/configure b/libgomp/configure -index 389500d..1c219c2 100755 ---- a/libgomp/configure -+++ b/libgomp/configure -@@ -682,6 +682,8 @@ FC - MAINT - MAINTAINER_MODE_FALSE - MAINTAINER_MODE_TRUE -+ENABLE_DARWIN_AT_RPATH_FALSE -+ENABLE_DARWIN_AT_RPATH_TRUE - enable_static - enable_shared - lt_host_flags -@@ -822,6 +824,7 @@ with_pic - enable_fast_install - with_gnu_ld - enable_libtool_lock -+enable_darwin_at_rpath - enable_maintainer_mode - enable_linux_futex - enable_tls -@@ -1477,6 +1480,9 @@ Optional Features: - --enable-fast-install[=PKGS] - optimize for fast installation [default=yes] - --disable-libtool-lock avoid locking (might break parallel builds) -+ --enable-darwin-at-rpath -+ install libraries with @rpath/library-name, requires -+ rpaths to be added to executables - --enable-maintainer-mode - enable make rules and dependencies not useful (and - sometimes confusing) to the casual installer -@@ -7621,7 +7627,7 @@ $as_echo "$lt_cv_ld_force_load" >&6; } - # darwin 5.x (macOS 10.1) onwards we only need to adjust when the - # deployment target is forced to an earlier version. - case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host in -- UNSET,*-darwin[89]*|UNSET,*-darwin[12][0123456789]*) -+ UNSET,*-darwin[89]*|UNSET,*-darwin[12][0-9]*) - ;; - 10.[012][,.]*) - _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' -@@ -9594,6 +9600,49 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi - darwin* | rhapsody*) - - -+ -+ # Publish an arg to allow the user to select that Darwin host (and target) -+ # libraries should be given install-names like @rpath/libfoo.dylib. This -+ # requires that the user of the library then adds an 'rpath' to the DSO that -+ # needs access. -+ # NOTE: there are defaults below, for systems that support rpaths. The person -+ # configuring can override the defaults for any system version that supports -+ # them - they are, however, forced off for system versions without support. -+ # Check whether --enable-darwin-at-rpath was given. -+if test "${enable_darwin_at_rpath+set}" = set; then : -+ enableval=$enable_darwin_at_rpath; if test "x$enable_darwin_at_rpath" = "xyes"; then -+ # This is not supported before macOS 10.5 / Darwin9. -+ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in -+ UNSET,darwin[4-8]*|UNSET,rhapsody*|10.[0-4][,.]*) -+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Darwin @rpath library names are incompatible with OSX versions earlier than 10.5 (rpaths disabled)" >&5 -+$as_echo "$as_me: WARNING: Darwin @rpath library names are incompatible with OSX versions earlier than 10.5 (rpaths disabled)" >&2;} -+ enable_darwin_at_rpath=no -+ ;; -+ esac -+ fi -+else -+ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in -+ # As above, before 10.5 / Darwin9 this does not work. -+ UNSET,darwin[4-8]*|UNSET,rhapsody*|10.[0-4][,.]*) -+ enable_darwin_at_rpath=no -+ ;; -+ -+ # We cannot build and test reliably on macOS 10.11+ (Darwin15+) without use -+ # of rpaths, since runpaths set via DYLD_LIBRARY_PATH are elided by key -+ # system executables (e.g. /bin/sh). Force rpaths on for these systems. -+ UNSET,darwin1[5-9]*|UNSET,darwin2*|10.1[1-9][,.]*|1[1-9].*[,.]* ) -+ { $as_echo "$as_me:${as_lineno-$LINENO}: @rpath library names are needed on macOS versions later than 10.11 (rpaths have been enabled)" >&5 -+$as_echo "$as_me: @rpath library names are needed on macOS versions later than 10.11 (rpaths have been enabled)" >&6;} -+ enable_darwin_at_rpath=yes -+ ;; -+ # NOTE: we are not (yet) doing anything for 10.5 .. 10.10, since they can -+ # work with either DYLD_LIBRARY_PATH or embedded rpaths. -+ -+ esac -+ -+fi -+ -+ - archive_cmds_need_lc=no - hardcode_direct=no - hardcode_automatic=yes -@@ -9611,9 +9660,13 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi - esac - if test "$_lt_dar_can_shared" = "yes"; then - output_verbose_link_cmd=func_echo_all -- archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" -+ _lt_install_name='\$rpath/\$soname' -+ if test "x$enable_darwin_at_rpath" = "xyes"; then -+ _lt_install_name='@rpath/\$soname' -+ fi -+ archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name ${_lt_install_name} \$verstring ${_lt_dsymutil}" - module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" -- archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" -+ archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name ${_lt_install_name} \$verstring ${_lt_dar_export_syms}${_lt_dsymutil}" - module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" - - else -@@ -11419,7 +11472,7 @@ else - lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 - lt_status=$lt_dlunknown - cat > conftest.$ac_ext <<_LT_EOF --#line 11422 "configure" -+#line 11475 "configure" - #include "confdefs.h" - - #if HAVE_DLFCN_H -@@ -11525,7 +11578,7 @@ else - lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 - lt_status=$lt_dlunknown - cat > conftest.$ac_ext <<_LT_EOF --#line 11528 "configure" -+#line 11581 "configure" - #include "confdefs.h" - - #if HAVE_DLFCN_H -@@ -11786,6 +11839,14 @@ esac - - - -+ if test x$enable_darwin_at_rpath = xyes; then -+ ENABLE_DARWIN_AT_RPATH_TRUE= -+ ENABLE_DARWIN_AT_RPATH_FALSE='#' -+else -+ ENABLE_DARWIN_AT_RPATH_TRUE='#' -+ ENABLE_DARWIN_AT_RPATH_FALSE= -+fi -+ - - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable maintainer-specific portions of Makefiles" >&5 -@@ -13461,6 +13522,49 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi - darwin* | rhapsody*) - - -+ -+ # Publish an arg to allow the user to select that Darwin host (and target) -+ # libraries should be given install-names like @rpath/libfoo.dylib. This -+ # requires that the user of the library then adds an 'rpath' to the DSO that -+ # needs access. -+ # NOTE: there are defaults below, for systems that support rpaths. The person -+ # configuring can override the defaults for any system version that supports -+ # them - they are, however, forced off for system versions without support. -+ # Check whether --enable-darwin-at-rpath was given. -+if test "${enable_darwin_at_rpath+set}" = set; then : -+ enableval=$enable_darwin_at_rpath; if test "x$enable_darwin_at_rpath" = "xyes"; then -+ # This is not supported before macOS 10.5 / Darwin9. -+ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in -+ UNSET,darwin[4-8]*|UNSET,rhapsody*|10.[0-4][,.]*) -+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Darwin @rpath library names are incompatible with OSX versions earlier than 10.5 (rpaths disabled)" >&5 -+$as_echo "$as_me: WARNING: Darwin @rpath library names are incompatible with OSX versions earlier than 10.5 (rpaths disabled)" >&2;} -+ enable_darwin_at_rpath=no -+ ;; -+ esac -+ fi -+else -+ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in -+ # As above, before 10.5 / Darwin9 this does not work. -+ UNSET,darwin[4-8]*|UNSET,rhapsody*|10.[0-4][,.]*) -+ enable_darwin_at_rpath=no -+ ;; -+ -+ # We cannot build and test reliably on macOS 10.11+ (Darwin15+) without use -+ # of rpaths, since runpaths set via DYLD_LIBRARY_PATH are elided by key -+ # system executables (e.g. /bin/sh). Force rpaths on for these systems. -+ UNSET,darwin1[5-9]*|UNSET,darwin2*|10.1[1-9][,.]*|1[1-9].*[,.]* ) -+ { $as_echo "$as_me:${as_lineno-$LINENO}: @rpath library names are needed on macOS versions later than 10.11 (rpaths have been enabled)" >&5 -+$as_echo "$as_me: @rpath library names are needed on macOS versions later than 10.11 (rpaths have been enabled)" >&6;} -+ enable_darwin_at_rpath=yes -+ ;; -+ # NOTE: we are not (yet) doing anything for 10.5 .. 10.10, since they can -+ # work with either DYLD_LIBRARY_PATH or embedded rpaths. -+ -+ esac -+ -+fi -+ -+ - archive_cmds_need_lc_FC=no - hardcode_direct_FC=no - hardcode_automatic_FC=yes -@@ -13478,9 +13582,13 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi - esac - if test "$_lt_dar_can_shared" = "yes"; then - output_verbose_link_cmd=func_echo_all -- archive_cmds_FC="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" -+ _lt_install_name='\$rpath/\$soname' -+ if test "x$enable_darwin_at_rpath" = "xyes"; then -+ _lt_install_name='@rpath/\$soname' -+ fi -+ archive_cmds_FC="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name ${_lt_install_name} \$verstring ${_lt_dsymutil}" - module_cmds_FC="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" -- archive_expsym_cmds_FC="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" -+ archive_expsym_cmds_FC="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name ${_lt_install_name} \$verstring ${_lt_dar_export_syms}${_lt_dsymutil}" - module_expsym_cmds_FC="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" - - else -@@ -17129,6 +17237,10 @@ if test -z "${BUILD_INFO_TRUE}" && test -z "${BUILD_INFO_FALSE}"; then - as_fn_error $? "conditional \"BUILD_INFO\" was never defined. - Usually this means the macro was only invoked conditionally." "$LINENO" 5 - fi -+if test -z "${ENABLE_DARWIN_AT_RPATH_TRUE}" && test -z "${ENABLE_DARWIN_AT_RPATH_FALSE}"; then -+ as_fn_error $? "conditional \"ENABLE_DARWIN_AT_RPATH\" was never defined. -+Usually this means the macro was only invoked conditionally." "$LINENO" 5 -+fi - if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then - as_fn_error $? "conditional \"MAINTAINER_MODE\" was never defined. - Usually this means the macro was only invoked conditionally." "$LINENO" 5 -diff --git a/libgomp/configure.ac b/libgomp/configure.ac -index dd88f20..5deba11 100644 ---- a/libgomp/configure.ac -+++ b/libgomp/configure.ac -@@ -149,6 +149,7 @@ AM_PROG_LIBTOOL - ACX_LT_HOST_FLAGS - AC_SUBST(enable_shared) - AC_SUBST(enable_static) -+AM_CONDITIONAL([ENABLE_DARWIN_AT_RPATH], [test x$enable_darwin_at_rpath = xyes]) - - AM_MAINTAINER_MODE - -diff --git a/libiberty/configure b/libiberty/configure -index 860f981..b8a19c4 100755 ---- a/libiberty/configure -+++ b/libiberty/configure -@@ -5258,8 +5258,8 @@ case "${enable_shared}" in - *) shared=yes ;; - esac - --# ...unless --enable-host-shared was passed from top-level config: --if [ "${enable_host_shared}" = "yes" ]; then -+# ...unless --enable-host-{shared,pie} was passed from top-level config: -+if [ "${enable_host_shared}" = "yes" ] || [ "${enable_host_pie}" = "yes" ]; then - shared=yes - fi - -diff --git a/libiberty/configure.ac b/libiberty/configure.ac -index 28d996f..6747a7b 100644 ---- a/libiberty/configure.ac -+++ b/libiberty/configure.ac -@@ -233,8 +233,8 @@ case "${enable_shared}" in - *) shared=yes ;; - esac - --# ...unless --enable-host-shared was passed from top-level config: --if [[ "${enable_host_shared}" = "yes" ]]; then -+# ...unless --enable-host-{shared,pie} was passed from top-level config: -+if [[ "${enable_host_shared}" = "yes" ]] || [[ "${enable_host_pie}" = "yes" ]]; then - shared=yes - fi - -diff --git a/libitm/Makefile.am b/libitm/Makefile.am -index 3f31ad3..a25317b 100644 ---- a/libitm/Makefile.am -+++ b/libitm/Makefile.am -@@ -54,7 +54,12 @@ libitm_version_info = -version-info $(libtool_VERSION) - # want or need libstdc++. - libitm_la_DEPENDENCIES = $(libitm_version_dep) - libitm_la_LINK = $(LINK) $(libitm_la_LDFLAGS) --libitm_la_LDFLAGS = $(libitm_version_info) $(libitm_version_script) -+if ENABLE_DARWIN_AT_RPATH -+libitm_darwin_rpath = -Wc,-nodefaultrpaths -+libitm_darwin_rpath += -Wl,-rpath,@loader_path -+endif -+libitm_la_LDFLAGS = $(libitm_version_info) $(libitm_version_script) \ -+ $(libitm_darwin_rpath) - - libitm_la_SOURCES = \ - aatree.cc alloc.cc alloc_c.cc alloc_cpp.cc barrier.cc beginend.cc \ -diff --git a/libitm/Makefile.in b/libitm/Makefile.in -index 7f53ea9..ed28db4 100644 ---- a/libitm/Makefile.in -+++ b/libitm/Makefile.in -@@ -481,7 +481,12 @@ libitm_version_info = -version-info $(libtool_VERSION) - # want or need libstdc++. - libitm_la_DEPENDENCIES = $(libitm_version_dep) - libitm_la_LINK = $(LINK) $(libitm_la_LDFLAGS) --libitm_la_LDFLAGS = $(libitm_version_info) $(libitm_version_script) -+@ENABLE_DARWIN_AT_RPATH_TRUE@libitm_darwin_rpath = \ -+@ENABLE_DARWIN_AT_RPATH_TRUE@ -Wc,-nodefaultrpaths \ -+@ENABLE_DARWIN_AT_RPATH_TRUE@ -Wl,-rpath,@loader_path -+libitm_la_LDFLAGS = $(libitm_version_info) $(libitm_version_script) \ -+ $(libitm_darwin_rpath) -+ - libitm_la_SOURCES = aatree.cc alloc.cc alloc_c.cc alloc_cpp.cc \ - barrier.cc beginend.cc clone.cc eh_cpp.cc local.cc query.cc \ - retry.cc rwlock.cc useraction.cc util.cc sjlj.S tls.cc \ -diff --git a/libitm/config/aarch64/sjlj.S b/libitm/config/aarch64/sjlj.S -index 0342516..2c27f46 100644 ---- a/libitm/config/aarch64/sjlj.S -+++ b/libitm/config/aarch64/sjlj.S -@@ -57,10 +57,19 @@ - - .text - .align 2 -+#if __ELF__ - .global _ITM_beginTransaction - .type _ITM_beginTransaction, %function - - _ITM_beginTransaction: -+ -+#elif __MACH__ -+ .global __ITM_beginTransaction -+ -+__ITM_beginTransaction: -+ -+#endif -+ - cfi_startproc - CFI_PAC_KEY - PAC_AND_BTI -@@ -84,8 +93,13 @@ _ITM_beginTransaction: - - /* Invoke GTM_begin_transaction with the struct we just built. */ - mov x1, sp -+#if __ELF__ - bl GTM_begin_transaction -- -+#elif __MACH__ -+ bl _GTM_begin_transaction -+#else -+#error "unexpected object format" -+#endif - /* Return; we don't need to restore any of the call-saved regs. */ - ldp x29, x30, [sp], 11*16 - cfi_adjust_cfa_offset(-11*16) -@@ -95,14 +109,23 @@ _ITM_beginTransaction: - CFI_PAC_TOGGLE - ret - cfi_endproc -+#if __ELF__ - .size _ITM_beginTransaction, . - _ITM_beginTransaction -+#endif - - .align 2 -+#if __ELF__ - .global GTM_longjmp - .hidden GTM_longjmp - .type GTM_longjmp, %function - - GTM_longjmp: -+ -+#elif __MACH__ -+ .private_extern _GTM_longjmp -+ -+_GTM_longjmp: -+#endif - /* The first parameter becomes the return value (x0). - The third parameter is ignored for now. */ - cfi_startproc -@@ -126,7 +149,9 @@ GTM_longjmp: - CFI_PAC_TOGGLE - br x30 - cfi_endproc -+#if __ELF__ - .size GTM_longjmp, . - GTM_longjmp -+#endif - - /* GNU_PROPERTY_AARCH64_* macros from elf.h for use in asm code. */ - #define FEATURE_1_AND 0xc0000000 -diff --git a/libitm/configure b/libitm/configure -index 6230c04..b941ecf 100755 ---- a/libitm/configure -+++ b/libitm/configure -@@ -660,6 +660,8 @@ libtool_VERSION - MAINT - MAINTAINER_MODE_FALSE - MAINTAINER_MODE_TRUE -+ENABLE_DARWIN_AT_RPATH_FALSE -+ENABLE_DARWIN_AT_RPATH_TRUE - enable_static - enable_shared - CXXCPP -@@ -810,6 +812,7 @@ with_pic - enable_fast_install - with_gnu_ld - enable_libtool_lock -+enable_darwin_at_rpath - enable_maintainer_mode - enable_linux_futex - enable_tls -@@ -1462,6 +1465,9 @@ Optional Features: - --enable-fast-install[=PKGS] - optimize for fast installation [default=yes] - --disable-libtool-lock avoid locking (might break parallel builds) -+ --enable-darwin-at-rpath -+ install libraries with @rpath/library-name, requires -+ rpaths to be added to executables - --enable-maintainer-mode - enable make rules and dependencies not useful (and - sometimes confusing) to the casual installer -@@ -8283,7 +8289,7 @@ $as_echo "$lt_cv_ld_force_load" >&6; } - # darwin 5.x (macOS 10.1) onwards we only need to adjust when the - # deployment target is forced to an earlier version. - case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host in -- UNSET,*-darwin[89]*|UNSET,*-darwin[12][0123456789]*) -+ UNSET,*-darwin[89]*|UNSET,*-darwin[12][0-9]*) - ;; - 10.[012][,.]*) - _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' -@@ -10257,6 +10263,49 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi - darwin* | rhapsody*) - - -+ -+ # Publish an arg to allow the user to select that Darwin host (and target) -+ # libraries should be given install-names like @rpath/libfoo.dylib. This -+ # requires that the user of the library then adds an 'rpath' to the DSO that -+ # needs access. -+ # NOTE: there are defaults below, for systems that support rpaths. The person -+ # configuring can override the defaults for any system version that supports -+ # them - they are, however, forced off for system versions without support. -+ # Check whether --enable-darwin-at-rpath was given. -+if test "${enable_darwin_at_rpath+set}" = set; then : -+ enableval=$enable_darwin_at_rpath; if test "x$enable_darwin_at_rpath" = "xyes"; then -+ # This is not supported before macOS 10.5 / Darwin9. -+ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in -+ UNSET,darwin[4-8]*|UNSET,rhapsody*|10.[0-4][,.]*) -+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Darwin @rpath library names are incompatible with OSX versions earlier than 10.5 (rpaths disabled)" >&5 -+$as_echo "$as_me: WARNING: Darwin @rpath library names are incompatible with OSX versions earlier than 10.5 (rpaths disabled)" >&2;} -+ enable_darwin_at_rpath=no -+ ;; -+ esac -+ fi -+else -+ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in -+ # As above, before 10.5 / Darwin9 this does not work. -+ UNSET,darwin[4-8]*|UNSET,rhapsody*|10.[0-4][,.]*) -+ enable_darwin_at_rpath=no -+ ;; -+ -+ # We cannot build and test reliably on macOS 10.11+ (Darwin15+) without use -+ # of rpaths, since runpaths set via DYLD_LIBRARY_PATH are elided by key -+ # system executables (e.g. /bin/sh). Force rpaths on for these systems. -+ UNSET,darwin1[5-9]*|UNSET,darwin2*|10.1[1-9][,.]*|1[1-9].*[,.]* ) -+ { $as_echo "$as_me:${as_lineno-$LINENO}: @rpath library names are needed on macOS versions later than 10.11 (rpaths have been enabled)" >&5 -+$as_echo "$as_me: @rpath library names are needed on macOS versions later than 10.11 (rpaths have been enabled)" >&6;} -+ enable_darwin_at_rpath=yes -+ ;; -+ # NOTE: we are not (yet) doing anything for 10.5 .. 10.10, since they can -+ # work with either DYLD_LIBRARY_PATH or embedded rpaths. -+ -+ esac -+ -+fi -+ -+ - archive_cmds_need_lc=no - hardcode_direct=no - hardcode_automatic=yes -@@ -10274,9 +10323,13 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi - esac - if test "$_lt_dar_can_shared" = "yes"; then - output_verbose_link_cmd=func_echo_all -- archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" -+ _lt_install_name='\$rpath/\$soname' -+ if test "x$enable_darwin_at_rpath" = "xyes"; then -+ _lt_install_name='@rpath/\$soname' -+ fi -+ archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name ${_lt_install_name} \$verstring ${_lt_dsymutil}" - module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" -- archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" -+ archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name ${_lt_install_name} \$verstring ${_lt_dar_export_syms}${_lt_dsymutil}" - module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" - - else -@@ -12082,7 +12135,7 @@ else - lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 - lt_status=$lt_dlunknown - cat > conftest.$ac_ext <<_LT_EOF --#line 12085 "configure" -+#line 12138 "configure" - #include "confdefs.h" - - #if HAVE_DLFCN_H -@@ -12188,7 +12241,7 @@ else - lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 - lt_status=$lt_dlunknown - cat > conftest.$ac_ext <<_LT_EOF --#line 12191 "configure" -+#line 12244 "configure" - #include "confdefs.h" - - #if HAVE_DLFCN_H -@@ -13064,6 +13117,49 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi - darwin* | rhapsody*) - - -+ -+ # Publish an arg to allow the user to select that Darwin host (and target) -+ # libraries should be given install-names like @rpath/libfoo.dylib. This -+ # requires that the user of the library then adds an 'rpath' to the DSO that -+ # needs access. -+ # NOTE: there are defaults below, for systems that support rpaths. The person -+ # configuring can override the defaults for any system version that supports -+ # them - they are, however, forced off for system versions without support. -+ # Check whether --enable-darwin-at-rpath was given. -+if test "${enable_darwin_at_rpath+set}" = set; then : -+ enableval=$enable_darwin_at_rpath; if test "x$enable_darwin_at_rpath" = "xyes"; then -+ # This is not supported before macOS 10.5 / Darwin9. -+ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in -+ UNSET,darwin[4-8]*|UNSET,rhapsody*|10.[0-4][,.]*) -+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Darwin @rpath library names are incompatible with OSX versions earlier than 10.5 (rpaths disabled)" >&5 -+$as_echo "$as_me: WARNING: Darwin @rpath library names are incompatible with OSX versions earlier than 10.5 (rpaths disabled)" >&2;} -+ enable_darwin_at_rpath=no -+ ;; -+ esac -+ fi -+else -+ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in -+ # As above, before 10.5 / Darwin9 this does not work. -+ UNSET,darwin[4-8]*|UNSET,rhapsody*|10.[0-4][,.]*) -+ enable_darwin_at_rpath=no -+ ;; -+ -+ # We cannot build and test reliably on macOS 10.11+ (Darwin15+) without use -+ # of rpaths, since runpaths set via DYLD_LIBRARY_PATH are elided by key -+ # system executables (e.g. /bin/sh). Force rpaths on for these systems. -+ UNSET,darwin1[5-9]*|UNSET,darwin2*|10.1[1-9][,.]*|1[1-9].*[,.]* ) -+ { $as_echo "$as_me:${as_lineno-$LINENO}: @rpath library names are needed on macOS versions later than 10.11 (rpaths have been enabled)" >&5 -+$as_echo "$as_me: @rpath library names are needed on macOS versions later than 10.11 (rpaths have been enabled)" >&6;} -+ enable_darwin_at_rpath=yes -+ ;; -+ # NOTE: we are not (yet) doing anything for 10.5 .. 10.10, since they can -+ # work with either DYLD_LIBRARY_PATH or embedded rpaths. -+ -+ esac -+ -+fi -+ -+ - archive_cmds_need_lc_CXX=no - hardcode_direct_CXX=no - hardcode_automatic_CXX=yes -@@ -13081,12 +13177,20 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi - esac - if test "$_lt_dar_can_shared" = "yes"; then - output_verbose_link_cmd=func_echo_all -- archive_cmds_CXX="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" -+ _lt_install_name='\$rpath/\$soname' -+ if test "x$enable_darwin_at_rpath" = "xyes"; then -+ _lt_install_name='@rpath/\$soname' -+ fi -+ archive_cmds_CXX="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name ${_lt_install_name} \$verstring ${_lt_dsymutil}" - module_cmds_CXX="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" -- archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" -+ archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name ${_lt_install_name} \$verstring ${_lt_dar_export_syms}${_lt_dsymutil}" - module_expsym_cmds_CXX="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" - if test "$lt_cv_apple_cc_single_mod" != "yes"; then -- archive_cmds_CXX="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}" -+ _lt_install_name='\$rpath/\$soname' -+ if test "x$enable_darwin_at_rpath" = "xyes"; then -+ _lt_install_name='@rpath/\$soname' -+ fi -+ archive_cmds_CXX="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name ${_lt_install_name} \$verstring${_lt_dsymutil}" - archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}" - fi - -@@ -15458,6 +15562,14 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu - - - -+ if test x$enable_darwin_at_rpath = xyes; then -+ ENABLE_DARWIN_AT_RPATH_TRUE= -+ ENABLE_DARWIN_AT_RPATH_FALSE='#' -+else -+ ENABLE_DARWIN_AT_RPATH_TRUE='#' -+ ENABLE_DARWIN_AT_RPATH_FALSE= -+fi -+ - - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable maintainer-specific portions of Makefiles" >&5 -@@ -18216,6 +18328,10 @@ if test -z "${BUILD_INFO_TRUE}" && test -z "${BUILD_INFO_FALSE}"; then - as_fn_error $? "conditional \"BUILD_INFO\" was never defined. - Usually this means the macro was only invoked conditionally." "$LINENO" 5 - fi -+if test -z "${ENABLE_DARWIN_AT_RPATH_TRUE}" && test -z "${ENABLE_DARWIN_AT_RPATH_FALSE}"; then -+ as_fn_error $? "conditional \"ENABLE_DARWIN_AT_RPATH\" was never defined. -+Usually this means the macro was only invoked conditionally." "$LINENO" 5 -+fi - if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then - as_fn_error $? "conditional \"MAINTAINER_MODE\" was never defined. - Usually this means the macro was only invoked conditionally." "$LINENO" 5 -diff --git a/libitm/configure.ac b/libitm/configure.ac -index 050d6b2..d0d108e 100644 ---- a/libitm/configure.ac -+++ b/libitm/configure.ac -@@ -157,6 +157,7 @@ AM_CONDITIONAL(BUILD_INFO, test $gcc_cv_prog_makeinfo_modern = "yes") - AM_PROG_LIBTOOL - AC_SUBST(enable_shared) - AC_SUBST(enable_static) -+AM_CONDITIONAL([ENABLE_DARWIN_AT_RPATH], [test x$enable_darwin_at_rpath = xyes]) - - AM_MAINTAINER_MODE - -diff --git a/libitm/configure.tgt b/libitm/configure.tgt -index 0362e61..2818a58 100644 ---- a/libitm/configure.tgt -+++ b/libitm/configure.tgt -@@ -50,7 +50,7 @@ fi - # Map the target cpu to an ARCH sub-directory. At the same time, - # work out any special compilation flags as necessary. - case "${target_cpu}" in -- aarch64*) ARCH=aarch64 ;; -+ aarch64* | arm64*) ARCH=aarch64 ;; - alpha*) ARCH=alpha ;; - rs6000 | powerpc*) - XCFLAGS="${XCFLAGS} -mhtm" -diff --git a/libobjc/configure b/libobjc/configure -index 6da20b8..ce18c24 100755 ---- a/libobjc/configure -+++ b/libobjc/configure -@@ -636,6 +636,9 @@ OBJC_BOEHM_GC_LIBS - OBJC_BOEHM_GC_INCLUDES - OBJC_BOEHM_GC - OBJC_GCFLAGS -+extra_ldflags_libobjc -+ENABLE_DARWIN_AT_RPATH_FALSE -+ENABLE_DARWIN_AT_RPATH_TRUE - SET_MAKE - CPP - OTOOL64 -@@ -667,7 +670,6 @@ RANLIB - AR - AS - XCFLAGS --extra_ldflags_libobjc - lt_host_flags - OBJEXT - EXEEXT -@@ -755,6 +757,7 @@ with_pic - enable_fast_install - with_gnu_ld - enable_libtool_lock -+enable_darwin_at_rpath - enable_tls - enable_objc_gc - with_target_bdw_gc -@@ -1392,6 +1395,9 @@ Optional Features: - --enable-fast-install[=PKGS] - optimize for fast installation [default=yes] - --disable-libtool-lock avoid locking (might break parallel builds) -+ --enable-darwin-at-rpath -+ install libraries with @rpath/library-name, requires -+ rpaths to be added to executables - --enable-tls Use thread-local storage [default=yes] - --enable-objc-gc enable use of Boehm's garbage collector with the GNU - Objective-C runtime -@@ -3431,17 +3437,6 @@ esac - - - --case "${host}" in -- *-darwin*) -- # Darwin needs -single_module when linking libobjc -- extra_ldflags_libobjc='$(lt_host_flags) -Wl,-single_module' -- ;; -- *-cygwin*|*-mingw*) -- # Tell libtool to build DLLs on Windows -- extra_ldflags_libobjc='$(lt_host_flags)' -- ;; --esac -- - - # Add CET specific flags if CET is enabled - -@@ -6973,7 +6968,7 @@ $as_echo "$lt_cv_ld_force_load" >&6; } - # darwin 5.x (macOS 10.1) onwards we only need to adjust when the - # deployment target is forced to an earlier version. - case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host in -- UNSET,*-darwin[89]*|UNSET,*-darwin[12][0123456789]*) -+ UNSET,*-darwin[89]*|UNSET,*-darwin[12][0-9]*) - ;; - 10.[012][,.]*) - _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' -@@ -8950,6 +8945,49 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi - darwin* | rhapsody*) - - -+ -+ # Publish an arg to allow the user to select that Darwin host (and target) -+ # libraries should be given install-names like @rpath/libfoo.dylib. This -+ # requires that the user of the library then adds an 'rpath' to the DSO that -+ # needs access. -+ # NOTE: there are defaults below, for systems that support rpaths. The person -+ # configuring can override the defaults for any system version that supports -+ # them - they are, however, forced off for system versions without support. -+ # Check whether --enable-darwin-at-rpath was given. -+if test "${enable_darwin_at_rpath+set}" = set; then : -+ enableval=$enable_darwin_at_rpath; if test "x$enable_darwin_at_rpath" = "xyes"; then -+ # This is not supported before macOS 10.5 / Darwin9. -+ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in -+ UNSET,darwin[4-8]*|UNSET,rhapsody*|10.[0-4][,.]*) -+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Darwin @rpath library names are incompatible with OSX versions earlier than 10.5 (rpaths disabled)" >&5 -+$as_echo "$as_me: WARNING: Darwin @rpath library names are incompatible with OSX versions earlier than 10.5 (rpaths disabled)" >&2;} -+ enable_darwin_at_rpath=no -+ ;; -+ esac -+ fi -+else -+ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in -+ # As above, before 10.5 / Darwin9 this does not work. -+ UNSET,darwin[4-8]*|UNSET,rhapsody*|10.[0-4][,.]*) -+ enable_darwin_at_rpath=no -+ ;; -+ -+ # We cannot build and test reliably on macOS 10.11+ (Darwin15+) without use -+ # of rpaths, since runpaths set via DYLD_LIBRARY_PATH are elided by key -+ # system executables (e.g. /bin/sh). Force rpaths on for these systems. -+ UNSET,darwin1[5-9]*|UNSET,darwin2*|10.1[1-9][,.]*|1[1-9].*[,.]* ) -+ { $as_echo "$as_me:${as_lineno-$LINENO}: @rpath library names are needed on macOS versions later than 10.11 (rpaths have been enabled)" >&5 -+$as_echo "$as_me: @rpath library names are needed on macOS versions later than 10.11 (rpaths have been enabled)" >&6;} -+ enable_darwin_at_rpath=yes -+ ;; -+ # NOTE: we are not (yet) doing anything for 10.5 .. 10.10, since they can -+ # work with either DYLD_LIBRARY_PATH or embedded rpaths. -+ -+ esac -+ -+fi -+ -+ - archive_cmds_need_lc=no - hardcode_direct=no - hardcode_automatic=yes -@@ -8967,9 +9005,13 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi - esac - if test "$_lt_dar_can_shared" = "yes"; then - output_verbose_link_cmd=func_echo_all -- archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" -+ _lt_install_name='\$rpath/\$soname' -+ if test "x$enable_darwin_at_rpath" = "xyes"; then -+ _lt_install_name='@rpath/\$soname' -+ fi -+ archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name ${_lt_install_name} \$verstring ${_lt_dsymutil}" - module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" -- archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" -+ archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name ${_lt_install_name} \$verstring ${_lt_dar_export_syms}${_lt_dsymutil}" - module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" - - else -@@ -10796,7 +10838,7 @@ else - lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 - lt_status=$lt_dlunknown - cat > conftest.$ac_ext <<_LT_EOF --#line 10799 "configure" -+#line 10841 "configure" - #include "confdefs.h" - - #if HAVE_DLFCN_H -@@ -10902,7 +10944,7 @@ else - lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 - lt_status=$lt_dlunknown - cat > conftest.$ac_ext <<_LT_EOF --#line 10905 "configure" -+#line 10947 "configure" - #include "confdefs.h" - - #if HAVE_DLFCN_H -@@ -11174,6 +11216,38 @@ $as_echo "no" >&6; } - fi - - -+ if test x$enable_darwin_at_rpath = xyes; then -+ ENABLE_DARWIN_AT_RPATH_TRUE= -+ ENABLE_DARWIN_AT_RPATH_FALSE='#' -+else -+ ENABLE_DARWIN_AT_RPATH_TRUE='#' -+ ENABLE_DARWIN_AT_RPATH_FALSE= -+fi -+ -+ -+# Must come after libtool is initialized. -+case "${host}" in -+ *-darwin[4567]*) -+ # Earlier Darwin versions need -single_module when linking libobjc; they -+ # do not support @rpath. -+ extra_ldflags_libobjc='$(lt_host_flags) -Wl,-single_module' -+ ;; -+ *-darwin*) -+ # Otherwise, single_module is the default and multi-module is ignored and -+ # obsolete. -+ extra_ldflags_libobjc='$(lt_host_flags)' -+ if test "x$enable_darwin_at_rpath" = "xyes"; then -+ extra_ldflags_libobjc="${extra_ldflags_libobjc} -Wc,-nodefaultrpaths" -+ extra_ldflags_libobjc="${extra_ldflags_libobjc} -Wl,-rpath,@loader_path" -+ fi -+ ;; -+ *-cygwin*|*-mingw*) -+ # Tell libtool to build DLLs on Windows -+ extra_ldflags_libobjc='$(lt_host_flags)' -+ ;; -+esac -+ -+ - # ------- - # Headers - # ------- -@@ -11915,6 +11989,10 @@ if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then - as_fn_error $? "conditional \"MAINTAINER_MODE\" was never defined. - Usually this means the macro was only invoked conditionally." "$LINENO" 5 - fi -+if test -z "${ENABLE_DARWIN_AT_RPATH_TRUE}" && test -z "${ENABLE_DARWIN_AT_RPATH_FALSE}"; then -+ as_fn_error $? "conditional \"ENABLE_DARWIN_AT_RPATH\" was never defined. -+Usually this means the macro was only invoked conditionally." "$LINENO" 5 -+fi - - : "${CONFIG_STATUS=./config.status}" - ac_write_fail=0 -diff --git a/libobjc/configure.ac b/libobjc/configure.ac -index 9bd7d59..cb21ebb 100644 ---- a/libobjc/configure.ac -+++ b/libobjc/configure.ac -@@ -148,17 +148,6 @@ m4_rename_force([real_PRECIOUS],[_AC_ARG_VAR_PRECIOUS]) - - # extra LD Flags which are required for targets - ACX_LT_HOST_FLAGS --case "${host}" in -- *-darwin*) -- # Darwin needs -single_module when linking libobjc -- extra_ldflags_libobjc='$(lt_host_flags) -Wl,-single_module' -- ;; -- *-cygwin*|*-mingw*) -- # Tell libtool to build DLLs on Windows -- extra_ldflags_libobjc='$(lt_host_flags)' -- ;; --esac --AC_SUBST(extra_ldflags_libobjc) - - # Add CET specific flags if CET is enabled - GCC_CET_FLAGS(CET_FLAGS) -@@ -183,6 +172,31 @@ AM_PROG_CC_C_O - - AC_PROG_MAKE_SET - -+AM_CONDITIONAL([ENABLE_DARWIN_AT_RPATH], [test x$enable_darwin_at_rpath = xyes]) -+ -+# Must come after libtool is initialized. -+case "${host}" in -+ *-darwin[[4567]]*) -+ # Earlier Darwin versions need -single_module when linking libobjc; they -+ # do not support @rpath. -+ extra_ldflags_libobjc='$(lt_host_flags) -Wl,-single_module' -+ ;; -+ *-darwin*) -+ # Otherwise, single_module is the default and multi-module is ignored and -+ # obsolete. -+ extra_ldflags_libobjc='$(lt_host_flags)' -+ if test "x$enable_darwin_at_rpath" = "xyes"; then -+ extra_ldflags_libobjc="${extra_ldflags_libobjc} -Wc,-nodefaultrpaths" -+ extra_ldflags_libobjc="${extra_ldflags_libobjc} -Wl,-rpath,@loader_path" -+ fi -+ ;; -+ *-cygwin*|*-mingw*) -+ # Tell libtool to build DLLs on Windows -+ extra_ldflags_libobjc='$(lt_host_flags)' -+ ;; -+esac -+AC_SUBST(extra_ldflags_libobjc) -+ - # ------- - # Headers - # ------- -diff --git a/libphobos/configure b/libphobos/configure -index 925c53c..2e8c06d 100755 ---- a/libphobos/configure -+++ b/libphobos/configure -@@ -707,6 +707,8 @@ get_gcc_base_ver - phobos_compiler_shared_flag - phobos_compiler_pic_flag - phobos_lt_pic_flag -+ENABLE_DARWIN_AT_RPATH_FALSE -+ENABLE_DARWIN_AT_RPATH_TRUE - enable_static - enable_shared - OTOOL64 -@@ -838,6 +840,7 @@ with_pic - enable_fast_install - with_gnu_ld - enable_libtool_lock -+enable_darwin_at_rpath - with_gcc_major_version_only - enable_werror - with_libatomic -@@ -1490,6 +1493,9 @@ Optional Features: - --enable-fast-install[=PKGS] - optimize for fast installation [default=yes] - --disable-libtool-lock avoid locking (might break parallel builds) -+ --enable-darwin-at-rpath -+ install libraries with @rpath/library-name, requires -+ rpaths to be added to executables - --enable-werror turns on -Werror [default=no] - --enable-version-specific-runtime-libs - Specify that runtime libraries should be installed -@@ -8244,7 +8250,7 @@ $as_echo "$lt_cv_ld_force_load" >&6; } - # darwin 5.x (macOS 10.1) onwards we only need to adjust when the - # deployment target is forced to an earlier version. - case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host in -- UNSET,*-darwin[89]*|UNSET,*-darwin[12][0123456789]*) -+ UNSET,*-darwin[89]*|UNSET,*-darwin[12][0-9]*) - ;; - 10.[012][,.]*) - _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' -@@ -9949,6 +9955,49 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi - darwin* | rhapsody*) - - -+ -+ # Publish an arg to allow the user to select that Darwin host (and target) -+ # libraries should be given install-names like @rpath/libfoo.dylib. This -+ # requires that the user of the library then adds an 'rpath' to the DSO that -+ # needs access. -+ # NOTE: there are defaults below, for systems that support rpaths. The person -+ # configuring can override the defaults for any system version that supports -+ # them - they are, however, forced off for system versions without support. -+ # Check whether --enable-darwin-at-rpath was given. -+if test "${enable_darwin_at_rpath+set}" = set; then : -+ enableval=$enable_darwin_at_rpath; if test "x$enable_darwin_at_rpath" = "xyes"; then -+ # This is not supported before macOS 10.5 / Darwin9. -+ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in -+ UNSET,darwin[4-8]*|UNSET,rhapsody*|10.[0-4][,.]*) -+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Darwin @rpath library names are incompatible with OSX versions earlier than 10.5 (rpaths disabled)" >&5 -+$as_echo "$as_me: WARNING: Darwin @rpath library names are incompatible with OSX versions earlier than 10.5 (rpaths disabled)" >&2;} -+ enable_darwin_at_rpath=no -+ ;; -+ esac -+ fi -+else -+ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in -+ # As above, before 10.5 / Darwin9 this does not work. -+ UNSET,darwin[4-8]*|UNSET,rhapsody*|10.[0-4][,.]*) -+ enable_darwin_at_rpath=no -+ ;; -+ -+ # We cannot build and test reliably on macOS 10.11+ (Darwin15+) without use -+ # of rpaths, since runpaths set via DYLD_LIBRARY_PATH are elided by key -+ # system executables (e.g. /bin/sh). Force rpaths on for these systems. -+ UNSET,darwin1[5-9]*|UNSET,darwin2*|10.1[1-9][,.]*|1[1-9].*[,.]* ) -+ { $as_echo "$as_me:${as_lineno-$LINENO}: @rpath library names are needed on macOS versions later than 10.11 (rpaths have been enabled)" >&5 -+$as_echo "$as_me: @rpath library names are needed on macOS versions later than 10.11 (rpaths have been enabled)" >&6;} -+ enable_darwin_at_rpath=yes -+ ;; -+ # NOTE: we are not (yet) doing anything for 10.5 .. 10.10, since they can -+ # work with either DYLD_LIBRARY_PATH or embedded rpaths. -+ -+ esac -+ -+fi -+ -+ - archive_cmds_need_lc=no - hardcode_direct=no - hardcode_automatic=yes -@@ -9966,9 +10015,13 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi - esac - if test "$_lt_dar_can_shared" = "yes"; then - output_verbose_link_cmd=func_echo_all -- archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" -+ _lt_install_name='\$rpath/\$soname' -+ if test "x$enable_darwin_at_rpath" = "xyes"; then -+ _lt_install_name='@rpath/\$soname' -+ fi -+ archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name ${_lt_install_name} \$verstring ${_lt_dsymutil}" - module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" -- archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" -+ archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name ${_lt_install_name} \$verstring ${_lt_dar_export_syms}${_lt_dsymutil}" - module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" - - else -@@ -11774,7 +11827,7 @@ else - lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 - lt_status=$lt_dlunknown - cat > conftest.$ac_ext <<_LT_EOF --#line 11777 "configure" -+#line 11830 "configure" - #include "confdefs.h" - - #if HAVE_DLFCN_H -@@ -11880,7 +11933,7 @@ else - lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 - lt_status=$lt_dlunknown - cat > conftest.$ac_ext <<_LT_EOF --#line 11883 "configure" -+#line 11936 "configure" - #include "confdefs.h" - - #if HAVE_DLFCN_H -@@ -13405,6 +13458,49 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi - darwin* | rhapsody*) - - -+ -+ # Publish an arg to allow the user to select that Darwin host (and target) -+ # libraries should be given install-names like @rpath/libfoo.dylib. This -+ # requires that the user of the library then adds an 'rpath' to the DSO that -+ # needs access. -+ # NOTE: there are defaults below, for systems that support rpaths. The person -+ # configuring can override the defaults for any system version that supports -+ # them - they are, however, forced off for system versions without support. -+ # Check whether --enable-darwin-at-rpath was given. -+if test "${enable_darwin_at_rpath+set}" = set; then : -+ enableval=$enable_darwin_at_rpath; if test "x$enable_darwin_at_rpath" = "xyes"; then -+ # This is not supported before macOS 10.5 / Darwin9. -+ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in -+ UNSET,darwin[4-8]*|UNSET,rhapsody*|10.[0-4][,.]*) -+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Darwin @rpath library names are incompatible with OSX versions earlier than 10.5 (rpaths disabled)" >&5 -+$as_echo "$as_me: WARNING: Darwin @rpath library names are incompatible with OSX versions earlier than 10.5 (rpaths disabled)" >&2;} -+ enable_darwin_at_rpath=no -+ ;; -+ esac -+ fi -+else -+ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in -+ # As above, before 10.5 / Darwin9 this does not work. -+ UNSET,darwin[4-8]*|UNSET,rhapsody*|10.[0-4][,.]*) -+ enable_darwin_at_rpath=no -+ ;; -+ -+ # We cannot build and test reliably on macOS 10.11+ (Darwin15+) without use -+ # of rpaths, since runpaths set via DYLD_LIBRARY_PATH are elided by key -+ # system executables (e.g. /bin/sh). Force rpaths on for these systems. -+ UNSET,darwin1[5-9]*|UNSET,darwin2*|10.1[1-9][,.]*|1[1-9].*[,.]* ) -+ { $as_echo "$as_me:${as_lineno-$LINENO}: @rpath library names are needed on macOS versions later than 10.11 (rpaths have been enabled)" >&5 -+$as_echo "$as_me: @rpath library names are needed on macOS versions later than 10.11 (rpaths have been enabled)" >&6;} -+ enable_darwin_at_rpath=yes -+ ;; -+ # NOTE: we are not (yet) doing anything for 10.5 .. 10.10, since they can -+ # work with either DYLD_LIBRARY_PATH or embedded rpaths. -+ -+ esac -+ -+fi -+ -+ - archive_cmds_need_lc_D=no - hardcode_direct_D=no - hardcode_automatic_D=yes -@@ -13422,9 +13518,13 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi - esac - if test "$_lt_dar_can_shared" = "yes"; then - output_verbose_link_cmd=func_echo_all -- archive_cmds_D="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" -+ _lt_install_name='\$rpath/\$soname' -+ if test "x$enable_darwin_at_rpath" = "xyes"; then -+ _lt_install_name='@rpath/\$soname' -+ fi -+ archive_cmds_D="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name ${_lt_install_name} \$verstring ${_lt_dsymutil}" - module_cmds_D="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" -- archive_expsym_cmds_D="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" -+ archive_expsym_cmds_D="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name ${_lt_install_name} \$verstring ${_lt_dar_export_syms}${_lt_dsymutil}" - module_expsym_cmds_D="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" - - else -@@ -14026,6 +14126,14 @@ CFLAGS=$lt_save_CFLAGS - - - -+ if test x$enable_darwin_at_rpath = xyes; then -+ ENABLE_DARWIN_AT_RPATH_TRUE= -+ ENABLE_DARWIN_AT_RPATH_FALSE='#' -+else -+ ENABLE_DARWIN_AT_RPATH_TRUE='#' -+ ENABLE_DARWIN_AT_RPATH_FALSE= -+fi -+ - - # libtool variables for Phobos shared and position-independent compiles. - # -@@ -15750,6 +15858,10 @@ if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then - as_fn_error $? "conditional \"MAINTAINER_MODE\" was never defined. - Usually this means the macro was only invoked conditionally." "$LINENO" 5 - fi -+if test -z "${ENABLE_DARWIN_AT_RPATH_TRUE}" && test -z "${ENABLE_DARWIN_AT_RPATH_FALSE}"; then -+ as_fn_error $? "conditional \"ENABLE_DARWIN_AT_RPATH\" was never defined. -+Usually this means the macro was only invoked conditionally." "$LINENO" 5 -+fi - if test -z "${DRUNTIME_CPU_AARCH64_TRUE}" && test -z "${DRUNTIME_CPU_AARCH64_FALSE}"; then - as_fn_error $? "conditional \"DRUNTIME_CPU_AARCH64\" was never defined. - Usually this means the macro was only invoked conditionally." "$LINENO" 5 -diff --git a/libphobos/configure.ac b/libphobos/configure.ac -index 464f410..ba8b5ec 100644 ---- a/libphobos/configure.ac -+++ b/libphobos/configure.ac -@@ -93,6 +93,7 @@ AM_PROG_LIBTOOL - WITH_LOCAL_DRUNTIME([LT_LANG([D])], []) - AC_SUBST(enable_shared) - AC_SUBST(enable_static) -+AM_CONDITIONAL([ENABLE_DARWIN_AT_RPATH], [test x$enable_darwin_at_rpath = xyes]) - - # libtool variables for Phobos shared and position-independent compiles. - # -diff --git a/libphobos/libdruntime/Makefile.am b/libphobos/libdruntime/Makefile.am -index 8225ba4..1869488 100644 ---- a/libphobos/libdruntime/Makefile.am -+++ b/libphobos/libdruntime/Makefile.am -@@ -128,8 +128,11 @@ ALL_DRUNTIME_SOURCES = $(DRUNTIME_DSOURCES) $(DRUNTIME_CSOURCES) \ - toolexeclib_LTLIBRARIES = libgdruntime.la - libgdruntime_la_SOURCES = $(ALL_DRUNTIME_SOURCES) - libgdruntime_la_LIBTOOLFLAGS = -+if ENABLE_DARWIN_AT_RPATH -+libgdruntime_darwin_rpath = -Wl,-rpath,@loader_path -+endif - libgdruntime_la_LDFLAGS = -Wc,-nophoboslib,-dstartfiles,-B../src,-Bgcc \ -- -version-info $(libtool_VERSION) -+ -version-info $(libtool_VERSION) $(libgdruntime_darwin_rpath) - libgdruntime_la_LIBADD = $(LIBATOMIC) $(LIBBACKTRACE) - libgdruntime_la_DEPENDENCIES = $(DRTSTUFF) - # Also override library link commands: This is not strictly -diff --git a/libphobos/libdruntime/Makefile.in b/libphobos/libdruntime/Makefile.in -index 797d643..cd13090 100644 ---- a/libphobos/libdruntime/Makefile.in -+++ b/libphobos/libdruntime/Makefile.in -@@ -810,8 +810,9 @@ ALL_DRUNTIME_SOURCES = $(DRUNTIME_DSOURCES) $(DRUNTIME_CSOURCES) \ - toolexeclib_LTLIBRARIES = libgdruntime.la - libgdruntime_la_SOURCES = $(ALL_DRUNTIME_SOURCES) - libgdruntime_la_LIBTOOLFLAGS = -+@ENABLE_DARWIN_AT_RPATH_TRUE@libgdruntime_darwin_rpath = -Wl,-rpath,@loader_path - libgdruntime_la_LDFLAGS = -Wc,-nophoboslib,-dstartfiles,-B../src,-Bgcc \ -- -version-info $(libtool_VERSION) -+ -version-info $(libtool_VERSION) $(libgdruntime_darwin_rpath) - - libgdruntime_la_LIBADD = $(LIBATOMIC) $(LIBBACKTRACE) - libgdruntime_la_DEPENDENCIES = $(DRTSTUFF) -diff --git a/libphobos/src/Makefile.am b/libphobos/src/Makefile.am -index 6474fca..f6521ed 100644 ---- a/libphobos/src/Makefile.am -+++ b/libphobos/src/Makefile.am -@@ -44,8 +44,11 @@ toolexeclib_DATA = libgphobos.spec - toolexeclib_LTLIBRARIES = libgphobos.la - libgphobos_la_SOURCES = $(ALL_PHOBOS_SOURCES) - libgphobos_la_LIBTOOLFLAGS = -+if ENABLE_DARWIN_AT_RPATH -+libgphobos_darwin_rpath = -Wl,-rpath,@loader_path -+endif - libgphobos_la_LDFLAGS = -Wc,-nophoboslib,-dstartfiles,-B../libdruntime/gcc \ -- -version-info $(libtool_VERSION) -+ -version-info $(libtool_VERSION) $(libgphobos_darwin_rpath) - if ENABLE_LIBDRUNTIME_ONLY - libgphobos_la_LIBADD = ../libdruntime/libgdruntime_convenience.la - else -diff --git a/libphobos/src/Makefile.in b/libphobos/src/Makefile.in -index a622958..cc3358b 100644 ---- a/libphobos/src/Makefile.in -+++ b/libphobos/src/Makefile.in -@@ -529,8 +529,9 @@ toolexeclib_DATA = libgphobos.spec - toolexeclib_LTLIBRARIES = libgphobos.la - libgphobos_la_SOURCES = $(ALL_PHOBOS_SOURCES) - libgphobos_la_LIBTOOLFLAGS = -+@ENABLE_DARWIN_AT_RPATH_TRUE@libgphobos_darwin_rpath = -Wl,-rpath,@loader_path - libgphobos_la_LDFLAGS = -Wc,-nophoboslib,-dstartfiles,-B../libdruntime/gcc \ -- -version-info $(libtool_VERSION) -+ -version-info $(libtool_VERSION) $(libgphobos_darwin_rpath) - - @ENABLE_LIBDRUNTIME_ONLY_FALSE@libgphobos_la_LIBADD = \ - @ENABLE_LIBDRUNTIME_ONLY_FALSE@ ../libdruntime/libgdruntime_convenience.la $(LIBZ) -diff --git a/libquadmath/Makefile.am b/libquadmath/Makefile.am -index 35dffb4..f199adf 100644 ---- a/libquadmath/Makefile.am -+++ b/libquadmath/Makefile.am -@@ -36,8 +36,13 @@ endif - - toolexeclib_LTLIBRARIES = libquadmath.la - libquadmath_la_LIBADD = -+ -+if ENABLE_DARWIN_AT_RPATH -+libquadmath_darwin_rpath = -Wc,-nodefaultrpaths -+libquadmath_darwin_rpath += -Wl,-rpath,@loader_path -+endif - libquadmath_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` \ -- $(version_arg) $(lt_host_flags) -lm -+ $(version_arg) $(lt_host_flags) $(LIBM) $(libquadmath_darwin_rpath) - libquadmath_la_DEPENDENCIES = $(version_dep) $(libquadmath_la_LIBADD) - - nodist_libsubinclude_HEADERS = quadmath.h quadmath_weak.h -diff --git a/libquadmath/Makefile.in b/libquadmath/Makefile.in -index 8c01121..7002575 100644 ---- a/libquadmath/Makefile.in -+++ b/libquadmath/Makefile.in -@@ -355,6 +355,7 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ - INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ - LD = @LD@ - LDFLAGS = @LDFLAGS@ -+LIBM = @LIBM@ - LIBOBJS = @LIBOBJS@ - LIBS = @LIBS@ - LIBTOOL = @LIBTOOL@ -@@ -463,8 +464,10 @@ AUTOMAKE_OPTIONS = foreign info-in-builddir - @BUILD_LIBQUADMATH_TRUE@@LIBQUAD_USE_SYMVER_SUN_TRUE@@LIBQUAD_USE_SYMVER_TRUE@version_dep = quadmath.map-sun - @BUILD_LIBQUADMATH_TRUE@toolexeclib_LTLIBRARIES = libquadmath.la - @BUILD_LIBQUADMATH_TRUE@libquadmath_la_LIBADD = -+@BUILD_LIBQUADMATH_TRUE@@ENABLE_DARWIN_AT_RPATH_TRUE@libquadmath_darwin_rpath = -Wc,-nodefaultrpaths \ -+@BUILD_LIBQUADMATH_TRUE@@ENABLE_DARWIN_AT_RPATH_TRUE@ -Wl,-rpath,@loader_path - @BUILD_LIBQUADMATH_TRUE@libquadmath_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` \ --@BUILD_LIBQUADMATH_TRUE@ $(version_arg) $(lt_host_flags) -lm -+@BUILD_LIBQUADMATH_TRUE@ $(version_arg) $(lt_host_flags) $(LIBM) $(libquadmath_darwin_rpath) - - @BUILD_LIBQUADMATH_TRUE@libquadmath_la_DEPENDENCIES = $(version_dep) $(libquadmath_la_LIBADD) - @BUILD_LIBQUADMATH_TRUE@nodist_libsubinclude_HEADERS = quadmath.h quadmath_weak.h -diff --git a/libquadmath/configure b/libquadmath/configure -index 958fb87..c51d4f3 100755 ---- a/libquadmath/configure -+++ b/libquadmath/configure -@@ -644,11 +644,14 @@ LIBQUAD_USE_SYMVER_GNU_FALSE - LIBQUAD_USE_SYMVER_GNU_TRUE - LIBQUAD_USE_SYMVER_FALSE - LIBQUAD_USE_SYMVER_TRUE -+LIBM - toolexeclibdir - toolexecdir - MAINT - MAINTAINER_MODE_FALSE - MAINTAINER_MODE_TRUE -+ENABLE_DARWIN_AT_RPATH_FALSE -+ENABLE_DARWIN_AT_RPATH_TRUE - enable_static - enable_shared - lt_host_flags -@@ -785,6 +788,7 @@ with_pic - enable_fast_install - with_gnu_ld - enable_libtool_lock -+enable_darwin_at_rpath - enable_maintainer_mode - with_toolexeclibdir - enable_symvers -@@ -1435,6 +1439,9 @@ Optional Features: - --enable-fast-install[=PKGS] - optimize for fast installation [default=yes] - --disable-libtool-lock avoid locking (might break parallel builds) -+ --enable-darwin-at-rpath -+ install libraries with @rpath/library-name, requires -+ rpaths to be added to executables - --enable-maintainer-mode - enable make rules and dependencies not useful (and - sometimes confusing) to the casual installer -@@ -7272,7 +7279,7 @@ $as_echo "$lt_cv_ld_force_load" >&6; } - # darwin 5.x (macOS 10.1) onwards we only need to adjust when the - # deployment target is forced to an earlier version. - case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host in -- UNSET,*-darwin[89]*|UNSET,*-darwin[12][0123456789]*) -+ UNSET,*-darwin[89]*|UNSET,*-darwin[12][0-9]*) - ;; - 10.[012][,.]*) - _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' -@@ -8984,6 +8991,49 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi - darwin* | rhapsody*) - - -+ -+ # Publish an arg to allow the user to select that Darwin host (and target) -+ # libraries should be given install-names like @rpath/libfoo.dylib. This -+ # requires that the user of the library then adds an 'rpath' to the DSO that -+ # needs access. -+ # NOTE: there are defaults below, for systems that support rpaths. The person -+ # configuring can override the defaults for any system version that supports -+ # them - they are, however, forced off for system versions without support. -+ # Check whether --enable-darwin-at-rpath was given. -+if test "${enable_darwin_at_rpath+set}" = set; then : -+ enableval=$enable_darwin_at_rpath; if test "x$enable_darwin_at_rpath" = "xyes"; then -+ # This is not supported before macOS 10.5 / Darwin9. -+ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in -+ UNSET,darwin[4-8]*|UNSET,rhapsody*|10.[0-4][,.]*) -+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Darwin @rpath library names are incompatible with OSX versions earlier than 10.5 (rpaths disabled)" >&5 -+$as_echo "$as_me: WARNING: Darwin @rpath library names are incompatible with OSX versions earlier than 10.5 (rpaths disabled)" >&2;} -+ enable_darwin_at_rpath=no -+ ;; -+ esac -+ fi -+else -+ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in -+ # As above, before 10.5 / Darwin9 this does not work. -+ UNSET,darwin[4-8]*|UNSET,rhapsody*|10.[0-4][,.]*) -+ enable_darwin_at_rpath=no -+ ;; -+ -+ # We cannot build and test reliably on macOS 10.11+ (Darwin15+) without use -+ # of rpaths, since runpaths set via DYLD_LIBRARY_PATH are elided by key -+ # system executables (e.g. /bin/sh). Force rpaths on for these systems. -+ UNSET,darwin1[5-9]*|UNSET,darwin2*|10.1[1-9][,.]*|1[1-9].*[,.]* ) -+ { $as_echo "$as_me:${as_lineno-$LINENO}: @rpath library names are needed on macOS versions later than 10.11 (rpaths have been enabled)" >&5 -+$as_echo "$as_me: @rpath library names are needed on macOS versions later than 10.11 (rpaths have been enabled)" >&6;} -+ enable_darwin_at_rpath=yes -+ ;; -+ # NOTE: we are not (yet) doing anything for 10.5 .. 10.10, since they can -+ # work with either DYLD_LIBRARY_PATH or embedded rpaths. -+ -+ esac -+ -+fi -+ -+ - archive_cmds_need_lc=no - hardcode_direct=no - hardcode_automatic=yes -@@ -9001,9 +9051,13 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi - esac - if test "$_lt_dar_can_shared" = "yes"; then - output_verbose_link_cmd=func_echo_all -- archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" -+ _lt_install_name='\$rpath/\$soname' -+ if test "x$enable_darwin_at_rpath" = "xyes"; then -+ _lt_install_name='@rpath/\$soname' -+ fi -+ archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name ${_lt_install_name} \$verstring ${_lt_dsymutil}" - module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" -- archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" -+ archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name ${_lt_install_name} \$verstring ${_lt_dar_export_syms}${_lt_dsymutil}" - module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" - - else -@@ -10830,7 +10884,7 @@ else - lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 - lt_status=$lt_dlunknown - cat > conftest.$ac_ext <<_LT_EOF --#line 10833 "configure" -+#line 10887 "configure" - #include "confdefs.h" - - #if HAVE_DLFCN_H -@@ -10936,7 +10990,7 @@ else - lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 - lt_status=$lt_dlunknown - cat > conftest.$ac_ext <<_LT_EOF --#line 10939 "configure" -+#line 10993 "configure" - #include "confdefs.h" - - #if HAVE_DLFCN_H -@@ -11197,6 +11251,14 @@ esac - - - -+ if test x$enable_darwin_at_rpath = xyes; then -+ ENABLE_DARWIN_AT_RPATH_TRUE= -+ ENABLE_DARWIN_AT_RPATH_FALSE='#' -+else -+ ENABLE_DARWIN_AT_RPATH_TRUE='#' -+ ENABLE_DARWIN_AT_RPATH_FALSE= -+fi -+ - - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable maintainer-specific portions of Makefiles" >&5 -@@ -12161,6 +12223,20 @@ esac - - - -+# AC_CHECK_LIBM variant which avoids AC_CHECK_LIB (that doesn't work -+# on bare metal). In the past we've used -lm in Makefile.am unconditionally, -+# let's use it there unless target knows it doesn't need that. -+LIBM= -+case $host in -+*-*-beos* | *-*-cegcc* | *-*-cygwin* | *-*-haiku* | *-*-pw32* | *-*-darwin*) -+ # These system don't have libm, or don't need it -+ ;; -+*) -+ LIBM=-lm -+ ;; -+esac -+ -+ - for ac_header in fenv.h langinfo.h locale.h wchar.h wctype.h limits.h ctype.h printf.h errno.h - do : - as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` -@@ -13421,6 +13497,10 @@ if test -z "${BUILD_INFO_TRUE}" && test -z "${BUILD_INFO_FALSE}"; then - as_fn_error $? "conditional \"BUILD_INFO\" was never defined. - Usually this means the macro was only invoked conditionally." "$LINENO" 5 - fi -+if test -z "${ENABLE_DARWIN_AT_RPATH_TRUE}" && test -z "${ENABLE_DARWIN_AT_RPATH_FALSE}"; then -+ as_fn_error $? "conditional \"ENABLE_DARWIN_AT_RPATH\" was never defined. -+Usually this means the macro was only invoked conditionally." "$LINENO" 5 -+fi - if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then - as_fn_error $? "conditional \"MAINTAINER_MODE\" was never defined. - Usually this means the macro was only invoked conditionally." "$LINENO" 5 -diff --git a/libquadmath/configure.ac b/libquadmath/configure.ac -index eec4084..349be26 100644 ---- a/libquadmath/configure.ac -+++ b/libquadmath/configure.ac -@@ -59,6 +59,7 @@ AM_PROG_LIBTOOL - ACX_LT_HOST_FLAGS - AC_SUBST(enable_shared) - AC_SUBST(enable_static) -+AM_CONDITIONAL([ENABLE_DARWIN_AT_RPATH], [test x$enable_darwin_at_rpath = xyes]) - - AM_MAINTAINER_MODE - -@@ -121,6 +122,20 @@ esac - AC_SUBST(toolexecdir) - AC_SUBST(toolexeclibdir) - -+# AC_CHECK_LIBM variant which avoids AC_CHECK_LIB (that doesn't work -+# on bare metal). In the past we've used -lm in Makefile.am unconditionally, -+# let's use it there unless target knows it doesn't need that. -+LIBM= -+case $host in -+*-*-beos* | *-*-cegcc* | *-*-cygwin* | *-*-haiku* | *-*-pw32* | *-*-darwin*) -+ # These system don't have libm, or don't need it -+ ;; -+*) -+ LIBM=-lm -+ ;; -+esac -+AC_SUBST([LIBM]) -+ - AC_CHECK_HEADERS(fenv.h langinfo.h locale.h wchar.h wctype.h limits.h ctype.h printf.h errno.h) - LIBQUAD_CHECK_MATH_H_SIGNGAM - -diff --git a/libsanitizer/asan/Makefile.am b/libsanitizer/asan/Makefile.am -index 4f802f7..223d3e0 100644 ---- a/libsanitizer/asan/Makefile.am -+++ b/libsanitizer/asan/Makefile.am -@@ -60,7 +60,12 @@ libasan_la_LIBADD += $(top_builddir)/libbacktrace/libsanitizer_libbacktrace.la - endif - libasan_la_LIBADD += $(LIBSTDCXX_RAW_CXX_LDFLAGS) - --libasan_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` $(link_libasan) -+if ENABLE_DARWIN_AT_RPATH -+libasan_darwin_rpath = -Wc,-nodefaultrpaths -+libasan_darwin_rpath += -Wl,-rpath,@loader_path -+endif -+libasan_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` \ -+ $(link_libasan) $(libasan_darwin_rpath) - - libasan_preinit.o: asan_preinit.o - cp $< $@ -diff --git a/libsanitizer/asan/Makefile.in b/libsanitizer/asan/Makefile.in -index 7833a9a..e88e5e0 100644 ---- a/libsanitizer/asan/Makefile.in -+++ b/libsanitizer/asan/Makefile.in -@@ -465,7 +465,12 @@ libasan_la_LIBADD = \ - $(top_builddir)/sanitizer_common/libsanitizer_common.la \ - $(top_builddir)/lsan/libsanitizer_lsan.la $(am__append_2) \ - $(am__append_3) $(LIBSTDCXX_RAW_CXX_LDFLAGS) --libasan_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` $(link_libasan) -+@ENABLE_DARWIN_AT_RPATH_TRUE@libasan_darwin_rpath = \ -+@ENABLE_DARWIN_AT_RPATH_TRUE@ -Wc,-nodefaultrpaths \ -+@ENABLE_DARWIN_AT_RPATH_TRUE@ -Wl,-rpath,@loader_path -+libasan_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` \ -+ $(link_libasan) $(libasan_darwin_rpath) -+ - - # Work around what appears to be a GNU make bug handling MAKEFLAGS - # values defined in terms of make variables, as is the case for CC and -diff --git a/libsanitizer/configure b/libsanitizer/configure -index e7984f9..dac8308 100755 ---- a/libsanitizer/configure -+++ b/libsanitizer/configure -@@ -666,6 +666,8 @@ LSAN_SUPPORTED_FALSE - LSAN_SUPPORTED_TRUE - TSAN_SUPPORTED_FALSE - TSAN_SUPPORTED_TRUE -+ENABLE_DARWIN_AT_RPATH_FALSE -+ENABLE_DARWIN_AT_RPATH_TRUE - enable_static - enable_shared - CXXCPP -@@ -817,6 +819,7 @@ with_pic - enable_fast_install - with_gnu_ld - enable_libtool_lock -+enable_darwin_at_rpath - enable_werror - with_gcc_major_version_only - enable_cet -@@ -1471,6 +1474,9 @@ Optional Features: - --enable-fast-install[=PKGS] - optimize for fast installation [default=yes] - --disable-libtool-lock avoid locking (might break parallel builds) -+ --enable-darwin-at-rpath -+ install libraries with @rpath/library-name, requires -+ rpaths to be added to executables - --disable-werror disable building with -Werror - --enable-cet enable Intel CET in target libraries [default=auto] - -@@ -8853,7 +8859,7 @@ $as_echo "$lt_cv_ld_force_load" >&6; } - # darwin 5.x (macOS 10.1) onwards we only need to adjust when the - # deployment target is forced to an earlier version. - case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host in -- UNSET,*-darwin[89]*|UNSET,*-darwin[12][0123456789]*) -+ UNSET,*-darwin[89]*|UNSET,*-darwin[12][0-9]*) - ;; - 10.[012][,.]*) - _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' -@@ -10558,6 +10564,49 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi - darwin* | rhapsody*) - - -+ -+ # Publish an arg to allow the user to select that Darwin host (and target) -+ # libraries should be given install-names like @rpath/libfoo.dylib. This -+ # requires that the user of the library then adds an 'rpath' to the DSO that -+ # needs access. -+ # NOTE: there are defaults below, for systems that support rpaths. The person -+ # configuring can override the defaults for any system version that supports -+ # them - they are, however, forced off for system versions without support. -+ # Check whether --enable-darwin-at-rpath was given. -+if test "${enable_darwin_at_rpath+set}" = set; then : -+ enableval=$enable_darwin_at_rpath; if test "x$enable_darwin_at_rpath" = "xyes"; then -+ # This is not supported before macOS 10.5 / Darwin9. -+ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in -+ UNSET,darwin[4-8]*|UNSET,rhapsody*|10.[0-4][,.]*) -+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Darwin @rpath library names are incompatible with OSX versions earlier than 10.5 (rpaths disabled)" >&5 -+$as_echo "$as_me: WARNING: Darwin @rpath library names are incompatible with OSX versions earlier than 10.5 (rpaths disabled)" >&2;} -+ enable_darwin_at_rpath=no -+ ;; -+ esac -+ fi -+else -+ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in -+ # As above, before 10.5 / Darwin9 this does not work. -+ UNSET,darwin[4-8]*|UNSET,rhapsody*|10.[0-4][,.]*) -+ enable_darwin_at_rpath=no -+ ;; -+ -+ # We cannot build and test reliably on macOS 10.11+ (Darwin15+) without use -+ # of rpaths, since runpaths set via DYLD_LIBRARY_PATH are elided by key -+ # system executables (e.g. /bin/sh). Force rpaths on for these systems. -+ UNSET,darwin1[5-9]*|UNSET,darwin2*|10.1[1-9][,.]*|1[1-9].*[,.]* ) -+ { $as_echo "$as_me:${as_lineno-$LINENO}: @rpath library names are needed on macOS versions later than 10.11 (rpaths have been enabled)" >&5 -+$as_echo "$as_me: @rpath library names are needed on macOS versions later than 10.11 (rpaths have been enabled)" >&6;} -+ enable_darwin_at_rpath=yes -+ ;; -+ # NOTE: we are not (yet) doing anything for 10.5 .. 10.10, since they can -+ # work with either DYLD_LIBRARY_PATH or embedded rpaths. -+ -+ esac -+ -+fi -+ -+ - archive_cmds_need_lc=no - hardcode_direct=no - hardcode_automatic=yes -@@ -10575,9 +10624,13 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi - esac - if test "$_lt_dar_can_shared" = "yes"; then - output_verbose_link_cmd=func_echo_all -- archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" -+ _lt_install_name='\$rpath/\$soname' -+ if test "x$enable_darwin_at_rpath" = "xyes"; then -+ _lt_install_name='@rpath/\$soname' -+ fi -+ archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name ${_lt_install_name} \$verstring ${_lt_dsymutil}" - module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" -- archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" -+ archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name ${_lt_install_name} \$verstring ${_lt_dar_export_syms}${_lt_dsymutil}" - module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" - - else -@@ -12383,7 +12436,7 @@ else - lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 - lt_status=$lt_dlunknown - cat > conftest.$ac_ext <<_LT_EOF --#line 12386 "configure" -+#line 12439 "configure" - #include "confdefs.h" - - #if HAVE_DLFCN_H -@@ -12489,7 +12542,7 @@ else - lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 - lt_status=$lt_dlunknown - cat > conftest.$ac_ext <<_LT_EOF --#line 12492 "configure" -+#line 12545 "configure" - #include "confdefs.h" - - #if HAVE_DLFCN_H -@@ -13365,6 +13418,49 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi - darwin* | rhapsody*) - - -+ -+ # Publish an arg to allow the user to select that Darwin host (and target) -+ # libraries should be given install-names like @rpath/libfoo.dylib. This -+ # requires that the user of the library then adds an 'rpath' to the DSO that -+ # needs access. -+ # NOTE: there are defaults below, for systems that support rpaths. The person -+ # configuring can override the defaults for any system version that supports -+ # them - they are, however, forced off for system versions without support. -+ # Check whether --enable-darwin-at-rpath was given. -+if test "${enable_darwin_at_rpath+set}" = set; then : -+ enableval=$enable_darwin_at_rpath; if test "x$enable_darwin_at_rpath" = "xyes"; then -+ # This is not supported before macOS 10.5 / Darwin9. -+ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in -+ UNSET,darwin[4-8]*|UNSET,rhapsody*|10.[0-4][,.]*) -+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Darwin @rpath library names are incompatible with OSX versions earlier than 10.5 (rpaths disabled)" >&5 -+$as_echo "$as_me: WARNING: Darwin @rpath library names are incompatible with OSX versions earlier than 10.5 (rpaths disabled)" >&2;} -+ enable_darwin_at_rpath=no -+ ;; -+ esac -+ fi -+else -+ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in -+ # As above, before 10.5 / Darwin9 this does not work. -+ UNSET,darwin[4-8]*|UNSET,rhapsody*|10.[0-4][,.]*) -+ enable_darwin_at_rpath=no -+ ;; -+ -+ # We cannot build and test reliably on macOS 10.11+ (Darwin15+) without use -+ # of rpaths, since runpaths set via DYLD_LIBRARY_PATH are elided by key -+ # system executables (e.g. /bin/sh). Force rpaths on for these systems. -+ UNSET,darwin1[5-9]*|UNSET,darwin2*|10.1[1-9][,.]*|1[1-9].*[,.]* ) -+ { $as_echo "$as_me:${as_lineno-$LINENO}: @rpath library names are needed on macOS versions later than 10.11 (rpaths have been enabled)" >&5 -+$as_echo "$as_me: @rpath library names are needed on macOS versions later than 10.11 (rpaths have been enabled)" >&6;} -+ enable_darwin_at_rpath=yes -+ ;; -+ # NOTE: we are not (yet) doing anything for 10.5 .. 10.10, since they can -+ # work with either DYLD_LIBRARY_PATH or embedded rpaths. -+ -+ esac -+ -+fi -+ -+ - archive_cmds_need_lc_CXX=no - hardcode_direct_CXX=no - hardcode_automatic_CXX=yes -@@ -13382,12 +13478,20 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi - esac - if test "$_lt_dar_can_shared" = "yes"; then - output_verbose_link_cmd=func_echo_all -- archive_cmds_CXX="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" -+ _lt_install_name='\$rpath/\$soname' -+ if test "x$enable_darwin_at_rpath" = "xyes"; then -+ _lt_install_name='@rpath/\$soname' -+ fi -+ archive_cmds_CXX="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name ${_lt_install_name} \$verstring ${_lt_dsymutil}" - module_cmds_CXX="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" -- archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" -+ archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name ${_lt_install_name} \$verstring ${_lt_dar_export_syms}${_lt_dsymutil}" - module_expsym_cmds_CXX="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" - if test "$lt_cv_apple_cc_single_mod" != "yes"; then -- archive_cmds_CXX="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}" -+ _lt_install_name='\$rpath/\$soname' -+ if test "x$enable_darwin_at_rpath" = "xyes"; then -+ _lt_install_name='@rpath/\$soname' -+ fi -+ archive_cmds_CXX="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name ${_lt_install_name} \$verstring${_lt_dsymutil}" - archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}" - fi - -@@ -15807,6 +15911,15 @@ esac - - - -+ if test x$enable_darwin_at_rpath = xyes; then -+ ENABLE_DARWIN_AT_RPATH_TRUE= -+ ENABLE_DARWIN_AT_RPATH_FALSE='#' -+else -+ ENABLE_DARWIN_AT_RPATH_TRUE='#' -+ ENABLE_DARWIN_AT_RPATH_FALSE= -+fi -+ -+ - # The cast to long int works around a bug in the HP C Compiler - # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects - # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. -@@ -17205,6 +17318,10 @@ if test -z "${am__fastdepCCAS_TRUE}" && test -z "${am__fastdepCCAS_FALSE}"; then - as_fn_error $? "conditional \"am__fastdepCCAS\" was never defined. - Usually this means the macro was only invoked conditionally." "$LINENO" 5 - fi -+if test -z "${ENABLE_DARWIN_AT_RPATH_TRUE}" && test -z "${ENABLE_DARWIN_AT_RPATH_FALSE}"; then -+ as_fn_error $? "conditional \"ENABLE_DARWIN_AT_RPATH\" was never defined. -+Usually this means the macro was only invoked conditionally." "$LINENO" 5 -+fi - if test -z "${TSAN_SUPPORTED_TRUE}" && test -z "${TSAN_SUPPORTED_FALSE}"; then - as_fn_error $? "conditional \"TSAN_SUPPORTED\" was never defined. - Usually this means the macro was only invoked conditionally." "$LINENO" 5 -diff --git a/libsanitizer/configure.ac b/libsanitizer/configure.ac -index 04cd891..5906c8d 100644 ---- a/libsanitizer/configure.ac -+++ b/libsanitizer/configure.ac -@@ -85,6 +85,8 @@ esac - AC_SUBST(enable_shared) - AC_SUBST(enable_static) - -+AM_CONDITIONAL([ENABLE_DARWIN_AT_RPATH], [test x$enable_darwin_at_rpath = xyes]) -+ - AC_CHECK_SIZEOF([void *]) - - if test "${multilib}" = "yes"; then -diff --git a/libsanitizer/hwasan/Makefile.am b/libsanitizer/hwasan/Makefile.am -index 5a89189..11b1a9c 100644 ---- a/libsanitizer/hwasan/Makefile.am -+++ b/libsanitizer/hwasan/Makefile.am -@@ -47,7 +47,11 @@ libhwasan_la_LIBADD += $(top_builddir)/libbacktrace/libsanitizer_libbacktrace.la - endif - libhwasan_la_LIBADD += $(LIBSTDCXX_RAW_CXX_LDFLAGS) - --libhwasan_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` $(link_libhwasan) -+if ENABLE_DARWIN_AT_RPATH -+libhwasan_darwin_rpath = -nodefaultrpaths -Wl,-rpath,@loader_path/ -+endif -+libhwasan_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` \ -+ $(link_libhwasan) $(libhwasan_darwin_rpath) - - libhwasan_preinit.o: hwasan_preinit.o - cp $< $@ -diff --git a/libsanitizer/hwasan/Makefile.in b/libsanitizer/hwasan/Makefile.in -index 4240aa9..f9ec8f9 100644 ---- a/libsanitizer/hwasan/Makefile.in -+++ b/libsanitizer/hwasan/Makefile.in -@@ -445,7 +445,10 @@ libhwasan_la_SOURCES = $(hwasan_files) - libhwasan_la_LIBADD = \ - $(top_builddir)/sanitizer_common/libsanitizer_common.la \ - $(am__append_1) $(am__append_2) $(LIBSTDCXX_RAW_CXX_LDFLAGS) --libhwasan_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` $(link_libhwasan) -+@ENABLE_DARWIN_AT_RPATH_TRUE@libhwasan_darwin_rpath = -nodefaultrpaths -Wl,-rpath,@loader_path/ -+libhwasan_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` \ -+ $(link_libhwasan) $(libhwasan_darwin_rpath) -+ - - # Work around what appears to be a GNU make bug handling MAKEFLAGS - # values defined in terms of make variables, as is the case for CC and -diff --git a/libsanitizer/lsan/Makefile.am b/libsanitizer/lsan/Makefile.am -index 6ff28ff..7701b0e 100644 ---- a/libsanitizer/lsan/Makefile.am -+++ b/libsanitizer/lsan/Makefile.am -@@ -41,8 +41,12 @@ if LIBBACKTRACE_SUPPORTED - liblsan_la_LIBADD += $(top_builddir)/libbacktrace/libsanitizer_libbacktrace.la - endif - liblsan_la_LIBADD += $(LIBSTDCXX_RAW_CXX_LDFLAGS) --liblsan_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` $(link_liblsan) -- -+if ENABLE_DARWIN_AT_RPATH -+liblsan_darwin_rpath = -Wc,-nodefaultrpaths -+liblsan_darwin_rpath += -Wl,-rpath,@loader_path -+endif -+liblsan_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` \ -+ $(link_liblsan) $(liblsan_darwin_rpath) - liblsan_preinit.o: lsan_preinit.o - cp $< $@ - -diff --git a/libsanitizer/lsan/Makefile.in b/libsanitizer/lsan/Makefile.in -index d8fd4ee..078edf0 100644 ---- a/libsanitizer/lsan/Makefile.in -+++ b/libsanitizer/lsan/Makefile.in -@@ -413,7 +413,12 @@ liblsan_la_LIBADD = \ - $(top_builddir)/sanitizer_common/libsanitizer_common.la \ - $(top_builddir)/interception/libinterception.la \ - $(am__append_1) $(LIBSTDCXX_RAW_CXX_LDFLAGS) --liblsan_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` $(link_liblsan) -+@ENABLE_DARWIN_AT_RPATH_TRUE@liblsan_darwin_rpath = \ -+@ENABLE_DARWIN_AT_RPATH_TRUE@ -Wc,-nodefaultrpaths \ -+@ENABLE_DARWIN_AT_RPATH_TRUE@ -Wl,-rpath,@loader_path -+liblsan_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` \ -+ $(link_liblsan) $(liblsan_darwin_rpath) -+ - - # Work around what appears to be a GNU make bug handling MAKEFLAGS - # values defined in terms of make variables, as is the case for CC and -@@ -788,7 +793,6 @@ uninstall-am: uninstall-nodist_toolexeclibHEADERS \ - - .PRECIOUS: Makefile - -- - liblsan_preinit.o: lsan_preinit.o - cp $< $@ - -diff --git a/libsanitizer/tsan/Makefile.am b/libsanitizer/tsan/Makefile.am -index da80743..01290b0 100644 ---- a/libsanitizer/tsan/Makefile.am -+++ b/libsanitizer/tsan/Makefile.am -@@ -57,7 +57,11 @@ libtsan_la_LIBADD += $(top_builddir)/libbacktrace/libsanitizer_libbacktrace.la - libtsan_la_DEPENDENCIES +=$(top_builddir)/libbacktrace/libsanitizer_libbacktrace.la - endif - libtsan_la_LIBADD += $(LIBSTDCXX_RAW_CXX_LDFLAGS) --libtsan_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` $(link_libtsan) -+if ENABLE_DARWIN_AT_RPATH -+libtsan_darwin_rpath = -nodefaultrpaths -Wl,-rpath,@loader_path/ -+endif -+libtsan_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` \ -+ $(link_libtsan) $(libtsan_darwin_rpath) - - libtsan_preinit.o: tsan_preinit.o - cp $< $@ -diff --git a/libsanitizer/tsan/Makefile.in b/libsanitizer/tsan/Makefile.in -index 3649883..9501158 100644 ---- a/libsanitizer/tsan/Makefile.in -+++ b/libsanitizer/tsan/Makefile.in -@@ -464,7 +464,10 @@ libtsan_la_DEPENDENCIES = \ - $(top_builddir)/sanitizer_common/libsanitizer_common.la \ - $(top_builddir)/interception/libinterception.la \ - $(TSAN_TARGET_DEPENDENT_OBJECTS) $(am__append_2) --libtsan_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` $(link_libtsan) -+@ENABLE_DARWIN_AT_RPATH_TRUE@libtsan_darwin_rpath = -nodefaultrpaths -Wl,-rpath,@loader_path/ -+libtsan_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` \ -+ $(link_libtsan) $(libtsan_darwin_rpath) -+ - - # Work around what appears to be a GNU make bug handling MAKEFLAGS - # values defined in terms of make variables, as is the case for CC and -diff --git a/libsanitizer/ubsan/Makefile.am b/libsanitizer/ubsan/Makefile.am -index d480f26..7769b34 100644 ---- a/libsanitizer/ubsan/Makefile.am -+++ b/libsanitizer/ubsan/Makefile.am -@@ -36,7 +36,12 @@ if LIBBACKTRACE_SUPPORTED - libubsan_la_LIBADD += $(top_builddir)/libbacktrace/libsanitizer_libbacktrace.la - endif - libubsan_la_LIBADD += $(LIBSTDCXX_RAW_CXX_LDFLAGS) --libubsan_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` $(link_libubsan) -+if ENABLE_DARWIN_AT_RPATH -+libubsan_darwin_rpath = -Wc,-nodefaultrpaths -+libubsan_darwin_rpath += -Wl,-rpath,@loader_path -+endif -+libubsan_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` \ -+ $(link_libubsan) $(libubsan_darwin_rpath) - - # Use special rules for files that require RTTI support. - ubsan_handlers_cxx.% ubsan_type_hash.% ubsan_type_hash_itanium.% : AM_CXXFLAGS += -frtti -diff --git a/libsanitizer/ubsan/Makefile.in b/libsanitizer/ubsan/Makefile.in -index 92a8e38..7e51480 100644 ---- a/libsanitizer/ubsan/Makefile.in -+++ b/libsanitizer/ubsan/Makefile.in -@@ -400,7 +400,12 @@ libubsan_la_SOURCES = $(ubsan_files) - libubsan_la_LIBADD = \ - $(top_builddir)/sanitizer_common/libsanitizer_common.la \ - $(am__append_1) $(am__append_2) $(LIBSTDCXX_RAW_CXX_LDFLAGS) --libubsan_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` $(link_libubsan) -+@ENABLE_DARWIN_AT_RPATH_TRUE@libubsan_darwin_rpath = \ -+@ENABLE_DARWIN_AT_RPATH_TRUE@ -Wc,-nodefaultrpaths \ -+@ENABLE_DARWIN_AT_RPATH_TRUE@ -Wl,-rpath,@loader_path -+libubsan_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` \ -+ $(link_libubsan) $(libubsan_darwin_rpath) -+ - - # Work around what appears to be a GNU make bug handling MAKEFLAGS - # values defined in terms of make variables, as is the case for CC and -diff --git a/libssp/Makefile.am b/libssp/Makefile.am -index 1636e43..f7ed2aa 100644 ---- a/libssp/Makefile.am -+++ b/libssp/Makefile.am -@@ -49,8 +49,12 @@ libssp_la_SOURCES = \ - vsnprintf-chk.c vsprintf-chk.c - libssp_la_LIBADD = - libssp_la_DEPENDENCIES = $(version_dep) $(libssp_la_LIBADD) -+if ENABLE_DARWIN_AT_RPATH -+libssp_darwin_rpath = -Wc,-nodefaultrpaths -+libssp_darwin_rpath += -Wl,-rpath,@loader_path -+endif - libssp_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` \ -- $(version_arg) $(lt_host_flags) -+ $(version_arg) $(lt_host_flags) $(libssp_darwin_rpath) - - libssp_nonshared_la_SOURCES = \ - ssp-local.c -diff --git a/libssp/Makefile.in b/libssp/Makefile.in -index bc8a0dc..1cf8636 100644 ---- a/libssp/Makefile.in -+++ b/libssp/Makefile.in -@@ -376,8 +376,11 @@ libssp_la_SOURCES = \ - - libssp_la_LIBADD = - libssp_la_DEPENDENCIES = $(version_dep) $(libssp_la_LIBADD) -+@ENABLE_DARWIN_AT_RPATH_TRUE@libssp_darwin_rpath = \ -+@ENABLE_DARWIN_AT_RPATH_TRUE@ -Wc,-nodefaultrpaths \ -+@ENABLE_DARWIN_AT_RPATH_TRUE@ -Wl,-rpath,@loader_path - libssp_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` \ -- $(version_arg) $(lt_host_flags) -+ $(version_arg) $(lt_host_flags) $(libssp_darwin_rpath) - - libssp_nonshared_la_SOURCES = \ - ssp-local.c -diff --git a/libssp/configure b/libssp/configure -index 492915d..72102be 100755 ---- a/libssp/configure -+++ b/libssp/configure -@@ -636,6 +636,8 @@ LIBOBJS - get_gcc_base_ver - toolexeclibdir - toolexecdir -+ENABLE_DARWIN_AT_RPATH_FALSE -+ENABLE_DARWIN_AT_RPATH_TRUE - enable_static - enable_shared - lt_host_flags -@@ -781,6 +783,7 @@ with_pic - enable_fast_install - with_gnu_ld - enable_libtool_lock -+enable_darwin_at_rpath - with_toolexeclibdir - with_gcc_major_version_only - ' -@@ -1426,6 +1429,9 @@ Optional Features: - --enable-fast-install[=PKGS] - optimize for fast installation [default=yes] - --disable-libtool-lock avoid locking (might break parallel builds) -+ --enable-darwin-at-rpath -+ install libraries with @rpath/library-name, requires -+ rpaths to be added to executables - - Optional Packages: - --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] -@@ -7458,7 +7464,7 @@ $as_echo "$lt_cv_ld_force_load" >&6; } - # darwin 5.x (macOS 10.1) onwards we only need to adjust when the - # deployment target is forced to an earlier version. - case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host in -- UNSET,*-darwin[89]*|UNSET,*-darwin[12][0123456789]*) -+ UNSET,*-darwin[89]*|UNSET,*-darwin[12][0-9]*) - ;; - 10.[012][,.]*) - _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' -@@ -9170,6 +9176,49 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi - darwin* | rhapsody*) - - -+ -+ # Publish an arg to allow the user to select that Darwin host (and target) -+ # libraries should be given install-names like @rpath/libfoo.dylib. This -+ # requires that the user of the library then adds an 'rpath' to the DSO that -+ # needs access. -+ # NOTE: there are defaults below, for systems that support rpaths. The person -+ # configuring can override the defaults for any system version that supports -+ # them - they are, however, forced off for system versions without support. -+ # Check whether --enable-darwin-at-rpath was given. -+if test "${enable_darwin_at_rpath+set}" = set; then : -+ enableval=$enable_darwin_at_rpath; if test "x$enable_darwin_at_rpath" = "xyes"; then -+ # This is not supported before macOS 10.5 / Darwin9. -+ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in -+ UNSET,darwin[4-8]*|UNSET,rhapsody*|10.[0-4][,.]*) -+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Darwin @rpath library names are incompatible with OSX versions earlier than 10.5 (rpaths disabled)" >&5 -+$as_echo "$as_me: WARNING: Darwin @rpath library names are incompatible with OSX versions earlier than 10.5 (rpaths disabled)" >&2;} -+ enable_darwin_at_rpath=no -+ ;; -+ esac -+ fi -+else -+ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in -+ # As above, before 10.5 / Darwin9 this does not work. -+ UNSET,darwin[4-8]*|UNSET,rhapsody*|10.[0-4][,.]*) -+ enable_darwin_at_rpath=no -+ ;; -+ -+ # We cannot build and test reliably on macOS 10.11+ (Darwin15+) without use -+ # of rpaths, since runpaths set via DYLD_LIBRARY_PATH are elided by key -+ # system executables (e.g. /bin/sh). Force rpaths on for these systems. -+ UNSET,darwin1[5-9]*|UNSET,darwin2*|10.1[1-9][,.]*|1[1-9].*[,.]* ) -+ { $as_echo "$as_me:${as_lineno-$LINENO}: @rpath library names are needed on macOS versions later than 10.11 (rpaths have been enabled)" >&5 -+$as_echo "$as_me: @rpath library names are needed on macOS versions later than 10.11 (rpaths have been enabled)" >&6;} -+ enable_darwin_at_rpath=yes -+ ;; -+ # NOTE: we are not (yet) doing anything for 10.5 .. 10.10, since they can -+ # work with either DYLD_LIBRARY_PATH or embedded rpaths. -+ -+ esac -+ -+fi -+ -+ - archive_cmds_need_lc=no - hardcode_direct=no - hardcode_automatic=yes -@@ -9187,9 +9236,13 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi - esac - if test "$_lt_dar_can_shared" = "yes"; then - output_verbose_link_cmd=func_echo_all -- archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" -+ _lt_install_name='\$rpath/\$soname' -+ if test "x$enable_darwin_at_rpath" = "xyes"; then -+ _lt_install_name='@rpath/\$soname' -+ fi -+ archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name ${_lt_install_name} \$verstring ${_lt_dsymutil}" - module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" -- archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" -+ archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name ${_lt_install_name} \$verstring ${_lt_dar_export_syms}${_lt_dsymutil}" - module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" - - else -@@ -11016,7 +11069,7 @@ else - lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 - lt_status=$lt_dlunknown - cat > conftest.$ac_ext <<_LT_EOF --#line 11019 "configure" -+#line 11072 "configure" - #include "confdefs.h" - - #if HAVE_DLFCN_H -@@ -11122,7 +11175,7 @@ else - lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 - lt_status=$lt_dlunknown - cat > conftest.$ac_ext <<_LT_EOF --#line 11125 "configure" -+#line 11178 "configure" - #include "confdefs.h" - - #if HAVE_DLFCN_H -@@ -11400,6 +11453,15 @@ fi - - - -+ if test x$enable_darwin_at_rpath = xyes; then -+ ENABLE_DARWIN_AT_RPATH_TRUE= -+ ENABLE_DARWIN_AT_RPATH_FALSE='#' -+else -+ ENABLE_DARWIN_AT_RPATH_TRUE='#' -+ ENABLE_DARWIN_AT_RPATH_FALSE= -+fi -+ -+ - # Calculate toolexeclibdir - # Also toolexecdir, though it's only used in toolexeclibdir - case ${version_specific_libs} in -@@ -11609,6 +11671,10 @@ if test -z "${LIBSSP_USE_SYMVER_SUN_TRUE}" && test -z "${LIBSSP_USE_SYMVER_SUN_F - as_fn_error $? "conditional \"LIBSSP_USE_SYMVER_SUN\" was never defined. - Usually this means the macro was only invoked conditionally." "$LINENO" 5 - fi -+if test -z "${ENABLE_DARWIN_AT_RPATH_TRUE}" && test -z "${ENABLE_DARWIN_AT_RPATH_FALSE}"; then -+ as_fn_error $? "conditional \"ENABLE_DARWIN_AT_RPATH\" was never defined. -+Usually this means the macro was only invoked conditionally." "$LINENO" 5 -+fi - - : "${CONFIG_STATUS=./config.status}" - ac_write_fail=0 -diff --git a/libssp/configure.ac b/libssp/configure.ac -index f30f81c..90778e2 100644 ---- a/libssp/configure.ac -+++ b/libssp/configure.ac -@@ -165,6 +165,8 @@ AC_SUBST(enable_static) - - GCC_WITH_TOOLEXECLIBDIR - -+AM_CONDITIONAL([ENABLE_DARWIN_AT_RPATH], [test x$enable_darwin_at_rpath = xyes]) -+ - # Calculate toolexeclibdir - # Also toolexecdir, though it's only used in toolexeclibdir - case ${version_specific_libs} in -diff --git a/libstdc++-v3/configure b/libstdc++-v3/configure -index d35baaf..4cac54b 100755 ---- a/libstdc++-v3/configure -+++ b/libstdc++-v3/configure -@@ -791,6 +791,8 @@ glibcxx_compiler_pic_flag - glibcxx_lt_pic_flag - OS_IS_DARWIN_FALSE - OS_IS_DARWIN_TRUE -+ENABLE_DARWIN_AT_RPATH_FALSE -+ENABLE_DARWIN_AT_RPATH_TRUE - enable_static - enable_shared - lt_host_flags -@@ -926,6 +928,7 @@ with_pic - enable_fast_install - with_gnu_ld - enable_libtool_lock -+enable_darwin_at_rpath - enable_hosted_libstdcxx - enable_libstdcxx_hosted - enable_libstdcxx_verbose -@@ -1617,6 +1620,9 @@ Optional Features: - --enable-fast-install[=PKGS] - optimize for fast installation [default=yes] - --disable-libtool-lock avoid locking (might break parallel builds) -+ --enable-darwin-at-rpath -+ install libraries with @rpath/library-name, requires -+ rpaths to be added to executables - --disable-hosted-libstdcxx - only build freestanding C++ runtime support - --disable-libstdcxx-hosted -@@ -8503,7 +8509,7 @@ $as_echo "$lt_cv_ld_force_load" >&6; } - # darwin 5.x (macOS 10.1) onwards we only need to adjust when the - # deployment target is forced to an earlier version. - case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host in -- UNSET,*-darwin[89]*|UNSET,*-darwin[12][0123456789]*) -+ UNSET,*-darwin[89]*|UNSET,*-darwin[12][0-9]*) - ;; - 10.[012][,.]*) - _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' -@@ -10343,6 +10349,49 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi - darwin* | rhapsody*) - - -+ -+ # Publish an arg to allow the user to select that Darwin host (and target) -+ # libraries should be given install-names like @rpath/libfoo.dylib. This -+ # requires that the user of the library then adds an 'rpath' to the DSO that -+ # needs access. -+ # NOTE: there are defaults below, for systems that support rpaths. The person -+ # configuring can override the defaults for any system version that supports -+ # them - they are, however, forced off for system versions without support. -+ # Check whether --enable-darwin-at-rpath was given. -+if test "${enable_darwin_at_rpath+set}" = set; then : -+ enableval=$enable_darwin_at_rpath; if test "x$enable_darwin_at_rpath" = "xyes"; then -+ # This is not supported before macOS 10.5 / Darwin9. -+ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in -+ UNSET,darwin[4-8]*|UNSET,rhapsody*|10.[0-4][,.]*) -+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Darwin @rpath library names are incompatible with OSX versions earlier than 10.5 (rpaths disabled)" >&5 -+$as_echo "$as_me: WARNING: Darwin @rpath library names are incompatible with OSX versions earlier than 10.5 (rpaths disabled)" >&2;} -+ enable_darwin_at_rpath=no -+ ;; -+ esac -+ fi -+else -+ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in -+ # As above, before 10.5 / Darwin9 this does not work. -+ UNSET,darwin[4-8]*|UNSET,rhapsody*|10.[0-4][,.]*) -+ enable_darwin_at_rpath=no -+ ;; -+ -+ # We cannot build and test reliably on macOS 10.11+ (Darwin15+) without use -+ # of rpaths, since runpaths set via DYLD_LIBRARY_PATH are elided by key -+ # system executables (e.g. /bin/sh). Force rpaths on for these systems. -+ UNSET,darwin1[5-9]*|UNSET,darwin2*|10.1[1-9][,.]*|1[1-9].*[,.]* ) -+ { $as_echo "$as_me:${as_lineno-$LINENO}: @rpath library names are needed on macOS versions later than 10.11 (rpaths have been enabled)" >&5 -+$as_echo "$as_me: @rpath library names are needed on macOS versions later than 10.11 (rpaths have been enabled)" >&6;} -+ enable_darwin_at_rpath=yes -+ ;; -+ # NOTE: we are not (yet) doing anything for 10.5 .. 10.10, since they can -+ # work with either DYLD_LIBRARY_PATH or embedded rpaths. -+ -+ esac -+ -+fi -+ -+ - archive_cmds_need_lc=no - hardcode_direct=no - hardcode_automatic=yes -@@ -10360,9 +10409,13 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi - esac - if test "$_lt_dar_can_shared" = "yes"; then - output_verbose_link_cmd=func_echo_all -- archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" -+ _lt_install_name='\$rpath/\$soname' -+ if test "x$enable_darwin_at_rpath" = "xyes"; then -+ _lt_install_name='@rpath/\$soname' -+ fi -+ archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name ${_lt_install_name} \$verstring ${_lt_dsymutil}" - module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" -- archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" -+ archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name ${_lt_install_name} \$verstring ${_lt_dar_export_syms}${_lt_dsymutil}" - module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" - - else -@@ -12189,7 +12242,7 @@ else - lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 - lt_status=$lt_dlunknown - cat > conftest.$ac_ext <<_LT_EOF --#line 12192 "configure" -+#line 12245 "configure" - #include "confdefs.h" - - #if HAVE_DLFCN_H -@@ -12295,7 +12348,7 @@ else - lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 - lt_status=$lt_dlunknown - cat > conftest.$ac_ext <<_LT_EOF --#line 12298 "configure" -+#line 12351 "configure" - #include "confdefs.h" - - #if HAVE_DLFCN_H -@@ -13177,6 +13230,49 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi - darwin* | rhapsody*) - - -+ -+ # Publish an arg to allow the user to select that Darwin host (and target) -+ # libraries should be given install-names like @rpath/libfoo.dylib. This -+ # requires that the user of the library then adds an 'rpath' to the DSO that -+ # needs access. -+ # NOTE: there are defaults below, for systems that support rpaths. The person -+ # configuring can override the defaults for any system version that supports -+ # them - they are, however, forced off for system versions without support. -+ # Check whether --enable-darwin-at-rpath was given. -+if test "${enable_darwin_at_rpath+set}" = set; then : -+ enableval=$enable_darwin_at_rpath; if test "x$enable_darwin_at_rpath" = "xyes"; then -+ # This is not supported before macOS 10.5 / Darwin9. -+ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in -+ UNSET,darwin[4-8]*|UNSET,rhapsody*|10.[0-4][,.]*) -+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Darwin @rpath library names are incompatible with OSX versions earlier than 10.5 (rpaths disabled)" >&5 -+$as_echo "$as_me: WARNING: Darwin @rpath library names are incompatible with OSX versions earlier than 10.5 (rpaths disabled)" >&2;} -+ enable_darwin_at_rpath=no -+ ;; -+ esac -+ fi -+else -+ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in -+ # As above, before 10.5 / Darwin9 this does not work. -+ UNSET,darwin[4-8]*|UNSET,rhapsody*|10.[0-4][,.]*) -+ enable_darwin_at_rpath=no -+ ;; -+ -+ # We cannot build and test reliably on macOS 10.11+ (Darwin15+) without use -+ # of rpaths, since runpaths set via DYLD_LIBRARY_PATH are elided by key -+ # system executables (e.g. /bin/sh). Force rpaths on for these systems. -+ UNSET,darwin1[5-9]*|UNSET,darwin2*|10.1[1-9][,.]*|1[1-9].*[,.]* ) -+ { $as_echo "$as_me:${as_lineno-$LINENO}: @rpath library names are needed on macOS versions later than 10.11 (rpaths have been enabled)" >&5 -+$as_echo "$as_me: @rpath library names are needed on macOS versions later than 10.11 (rpaths have been enabled)" >&6;} -+ enable_darwin_at_rpath=yes -+ ;; -+ # NOTE: we are not (yet) doing anything for 10.5 .. 10.10, since they can -+ # work with either DYLD_LIBRARY_PATH or embedded rpaths. -+ -+ esac -+ -+fi -+ -+ - archive_cmds_need_lc_CXX=no - hardcode_direct_CXX=no - hardcode_automatic_CXX=yes -@@ -13194,12 +13290,20 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi - esac - if test "$_lt_dar_can_shared" = "yes"; then - output_verbose_link_cmd=func_echo_all -- archive_cmds_CXX="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" -+ _lt_install_name='\$rpath/\$soname' -+ if test "x$enable_darwin_at_rpath" = "xyes"; then -+ _lt_install_name='@rpath/\$soname' -+ fi -+ archive_cmds_CXX="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name ${_lt_install_name} \$verstring ${_lt_dsymutil}" - module_cmds_CXX="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" -- archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" -+ archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name ${_lt_install_name} \$verstring ${_lt_dar_export_syms}${_lt_dsymutil}" - module_expsym_cmds_CXX="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" - if test "$lt_cv_apple_cc_single_mod" != "yes"; then -- archive_cmds_CXX="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}" -+ _lt_install_name='\$rpath/\$soname' -+ if test "x$enable_darwin_at_rpath" = "xyes"; then -+ _lt_install_name='@rpath/\$soname' -+ fi -+ archive_cmds_CXX="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name ${_lt_install_name} \$verstring${_lt_dsymutil}" - archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}" - fi - -@@ -15596,6 +15700,14 @@ esac - - - -+ if test x$enable_darwin_at_rpath = xyes; then -+ ENABLE_DARWIN_AT_RPATH_TRUE= -+ ENABLE_DARWIN_AT_RPATH_FALSE='#' -+else -+ ENABLE_DARWIN_AT_RPATH_TRUE='#' -+ ENABLE_DARWIN_AT_RPATH_FALSE= -+fi -+ - - os_is_darwin=no - case ${host_os} in -@@ -16033,7 +16145,7 @@ $as_echo "$glibcxx_cv_atomic_long_long" >&6; } - # Fake what AC_TRY_COMPILE does. - - cat > conftest.$ac_ext << EOF --#line 16036 "configure" -+#line 16148 "configure" - int main() - { - typedef bool atomic_type; -@@ -16068,7 +16180,7 @@ $as_echo "$glibcxx_cv_atomic_bool" >&6; } - rm -f conftest* - - cat > conftest.$ac_ext << EOF --#line 16071 "configure" -+#line 16183 "configure" - int main() - { - typedef short atomic_type; -@@ -16103,7 +16215,7 @@ $as_echo "$glibcxx_cv_atomic_short" >&6; } - rm -f conftest* - - cat > conftest.$ac_ext << EOF --#line 16106 "configure" -+#line 16218 "configure" - int main() - { - // NB: _Atomic_word not necessarily int. -@@ -16139,7 +16251,7 @@ $as_echo "$glibcxx_cv_atomic_int" >&6; } - rm -f conftest* - - cat > conftest.$ac_ext << EOF --#line 16142 "configure" -+#line 16254 "configure" - int main() - { - typedef long long atomic_type; -@@ -16295,7 +16407,7 @@ $as_echo "mutex" >&6; } - # unnecessary for this test. - - cat > conftest.$ac_ext << EOF --#line 16298 "configure" -+#line 16410 "configure" - int main() - { - _Decimal32 d1; -@@ -16337,7 +16449,7 @@ ac_compiler_gnu=$ac_cv_cxx_compiler_gnu - # unnecessary for this test. - - cat > conftest.$ac_ext << EOF --#line 16340 "configure" -+#line 16452 "configure" - template - struct same - { typedef T2 type; }; -@@ -73309,6 +73421,10 @@ if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then - as_fn_error $? "conditional \"MAINTAINER_MODE\" was never defined. - Usually this means the macro was only invoked conditionally." "$LINENO" 5 - fi -+if test -z "${ENABLE_DARWIN_AT_RPATH_TRUE}" && test -z "${ENABLE_DARWIN_AT_RPATH_FALSE}"; then -+ as_fn_error $? "conditional \"ENABLE_DARWIN_AT_RPATH\" was never defined. -+Usually this means the macro was only invoked conditionally." "$LINENO" 5 -+fi - if test -z "${OS_IS_DARWIN_TRUE}" && test -z "${OS_IS_DARWIN_FALSE}"; then - as_fn_error $? "conditional \"OS_IS_DARWIN\" was never defined. - Usually this means the macro was only invoked conditionally." "$LINENO" 5 -diff --git a/libstdc++-v3/configure.ac b/libstdc++-v3/configure.ac -index 0c3c7a2..6dde72c 100644 ---- a/libstdc++-v3/configure.ac -+++ b/libstdc++-v3/configure.ac -@@ -108,6 +108,7 @@ AM_PROG_LIBTOOL - ACX_LT_HOST_FLAGS - AC_SUBST(enable_shared) - AC_SUBST(enable_static) -+AM_CONDITIONAL([ENABLE_DARWIN_AT_RPATH], [test x$enable_darwin_at_rpath = xyes]) - - os_is_darwin=no - case ${host_os} in -diff --git a/libstdc++-v3/src/Makefile.am b/libstdc++-v3/src/Makefile.am -index 5b9af41..925137c 100644 ---- a/libstdc++-v3/src/Makefile.am -+++ b/libstdc++-v3/src/Makefile.am -@@ -152,8 +152,13 @@ libstdc___la_DEPENDENCIES = \ - $(top_builddir)/src/c++17/libc++17convenience.la \ - $(top_builddir)/src/c++20/libc++20convenience.la - -+if ENABLE_DARWIN_AT_RPATH -+libstdc___darwin_rpath = -Wc,-nodefaultrpaths -+libstdc___darwin_rpath += -Wl,-rpath,@loader_path -+endif -+ - libstdc___la_LDFLAGS = \ -- -version-info $(libtool_VERSION) ${version_arg} -lm -+ -version-info $(libtool_VERSION) ${version_arg} -lm $(libstdc___darwin_rpath) - - libstdc___la_LINK = $(CXXLINK) $(libstdc___la_LDFLAGS) $(lt_host_flags) - -diff --git a/libstdc++-v3/src/Makefile.in b/libstdc++-v3/src/Makefile.in -index f42d957..0ce75f3 100644 ---- a/libstdc++-v3/src/Makefile.in -+++ b/libstdc++-v3/src/Makefile.in -@@ -560,8 +560,11 @@ libstdc___la_DEPENDENCIES = \ - $(top_builddir)/src/c++17/libc++17convenience.la \ - $(top_builddir)/src/c++20/libc++20convenience.la - -+@ENABLE_DARWIN_AT_RPATH_TRUE@libstdc___darwin_rpath = \ -+@ENABLE_DARWIN_AT_RPATH_TRUE@ -Wc,-nodefaultrpaths \ -+@ENABLE_DARWIN_AT_RPATH_TRUE@ -Wl,-rpath,@loader_path - libstdc___la_LDFLAGS = \ -- -version-info $(libtool_VERSION) ${version_arg} -lm -+ -version-info $(libtool_VERSION) ${version_arg} -lm $(libstdc___darwin_rpath) - - libstdc___la_LINK = $(CXXLINK) $(libstdc___la_LDFLAGS) $(lt_host_flags) - @GLIBCXX_LDBL_ALT128_COMPAT_FALSE@@GLIBCXX_LDBL_COMPAT_TRUE@LTCXXCOMPILE64 = $(LTCXXCOMPILE) -diff --git a/libtool.m4 b/libtool.m4 -index b92e284..5361f26 100644 ---- a/libtool.m4 -+++ b/libtool.m4 -@@ -1005,7 +1005,7 @@ _LT_EOF - # darwin 5.x (macOS 10.1) onwards we only need to adjust when the - # deployment target is forced to an earlier version. - case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host in -- UNSET,*-darwin[[89]]*|UNSET,*-darwin[[12]][[0123456789]]*) -+ UNSET,*-darwin[[89]]*|UNSET,*-darwin[[12]][[0-9]]*) - ;; - 10.[[012]][[,.]]*) - _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' -@@ -1039,6 +1039,45 @@ _LT_EOF - m4_defun([_LT_DARWIN_LINKER_FEATURES], - [ - m4_require([_LT_REQUIRED_DARWIN_CHECKS]) -+ -+ # Publish an arg to allow the user to select that Darwin host (and target) -+ # libraries should be given install-names like @rpath/libfoo.dylib. This -+ # requires that the user of the library then adds an 'rpath' to the DSO that -+ # needs access. -+ # NOTE: there are defaults below, for systems that support rpaths. The person -+ # configuring can override the defaults for any system version that supports -+ # them - they are, however, forced off for system versions without support. -+ AC_ARG_ENABLE([darwin-at-rpath], -+ AS_HELP_STRING([--enable-darwin-at-rpath], -+ [install libraries with @rpath/library-name, requires rpaths to be added to executables]), -+ [if test "x$enable_darwin_at_rpath" = "xyes"; then -+ # This is not supported before macOS 10.5 / Darwin9. -+ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in -+ UNSET,darwin[[4-8]]*|UNSET,rhapsody*|10.[[0-4]][[,.]]*) -+ AC_MSG_WARN([Darwin @rpath library names are incompatible with OSX versions earlier than 10.5 (rpaths disabled)]) -+ enable_darwin_at_rpath=no -+ ;; -+ esac -+ fi], -+ [case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in -+ # As above, before 10.5 / Darwin9 this does not work. -+ UNSET,darwin[[4-8]]*|UNSET,rhapsody*|10.[[0-4]][[,.]]*) -+ enable_darwin_at_rpath=no -+ ;; -+ -+ # We cannot build and test reliably on macOS 10.11+ (Darwin15+) without use -+ # of rpaths, since runpaths set via DYLD_LIBRARY_PATH are elided by key -+ # system executables (e.g. /bin/sh). Force rpaths on for these systems. -+ UNSET,darwin1[[5-9]]*|UNSET,darwin2*|10.1[[1-9]][[,.]]*|1[[1-9]].*[[,.]]* ) -+ AC_MSG_NOTICE([@rpath library names are needed on macOS versions later than 10.11 (rpaths have been enabled)]) -+ enable_darwin_at_rpath=yes -+ ;; -+ # NOTE: we are not (yet) doing anything for 10.5 .. 10.10, since they can -+ # work with either DYLD_LIBRARY_PATH or embedded rpaths. -+ -+ esac -+ ]) -+ - _LT_TAGVAR(archive_cmds_need_lc, $1)=no - _LT_TAGVAR(hardcode_direct, $1)=no - _LT_TAGVAR(hardcode_automatic, $1)=yes -@@ -1056,13 +1095,21 @@ m4_defun([_LT_DARWIN_LINKER_FEATURES], - esac - if test "$_lt_dar_can_shared" = "yes"; then - output_verbose_link_cmd=func_echo_all -- _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" -+ _lt_install_name='\$rpath/\$soname' -+ if test "x$enable_darwin_at_rpath" = "xyes"; then -+ _lt_install_name='@rpath/\$soname' -+ fi -+ _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name ${_lt_install_name} \$verstring ${_lt_dsymutil}" - _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" -- _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" -+ _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name ${_lt_install_name} \$verstring ${_lt_dar_export_syms}${_lt_dsymutil}" - _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" - m4_if([$1], [CXX], - [ if test "$lt_cv_apple_cc_single_mod" != "yes"; then -- _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}" -+ _lt_install_name='\$rpath/\$soname' -+ if test "x$enable_darwin_at_rpath" = "xyes"; then -+ _lt_install_name='@rpath/\$soname' -+ fi -+ _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name ${_lt_install_name} \$verstring${_lt_dsymutil}" - _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}" - fi - ],[]) -@@ -6466,7 +6513,6 @@ fi # test "$_lt_caught_CXX_error" != yes - AC_LANG_POP - ])# _LT_LANG_CXX_CONFIG - -- - # _LT_SYS_HIDDEN_LIBDEPS([TAGNAME]) - # --------------------------------- - # Figure out "hidden" library dependencies from verbose -diff --git a/libvtv/configure b/libvtv/configure -index e7e490d..da4fe61 100755 ---- a/libvtv/configure -+++ b/libvtv/configure -@@ -640,6 +640,8 @@ VTV_CYGMIN_FALSE - VTV_CYGMIN_TRUE - XCFLAGS - libtool_VERSION -+ENABLE_DARWIN_AT_RPATH_FALSE -+ENABLE_DARWIN_AT_RPATH_TRUE - enable_static - enable_shared - lt_host_flags -@@ -797,6 +799,7 @@ with_pic - enable_fast_install - with_gnu_ld - enable_libtool_lock -+enable_darwin_at_rpath - enable_cet - with_gcc_major_version_only - ' -@@ -1446,6 +1449,9 @@ Optional Features: - --enable-fast-install[=PKGS] - optimize for fast installation [default=yes] - --disable-libtool-lock avoid locking (might break parallel builds) -+ --enable-darwin-at-rpath -+ install libraries with @rpath/library-name, requires -+ rpaths to be added to executables - --enable-cet enable Intel CET in target libraries [default=auto] - - Optional Packages: -@@ -8748,7 +8754,7 @@ $as_echo "$lt_cv_ld_force_load" >&6; } - # darwin 5.x (macOS 10.1) onwards we only need to adjust when the - # deployment target is forced to an earlier version. - case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host in -- UNSET,*-darwin[89]*|UNSET,*-darwin[12][0123456789]*) -+ UNSET,*-darwin[89]*|UNSET,*-darwin[12][0-9]*) - ;; - 10.[012][,.]*) - _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' -@@ -10453,6 +10459,49 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi - darwin* | rhapsody*) - - -+ -+ # Publish an arg to allow the user to select that Darwin host (and target) -+ # libraries should be given install-names like @rpath/libfoo.dylib. This -+ # requires that the user of the library then adds an 'rpath' to the DSO that -+ # needs access. -+ # NOTE: there are defaults below, for systems that support rpaths. The person -+ # configuring can override the defaults for any system version that supports -+ # them - they are, however, forced off for system versions without support. -+ # Check whether --enable-darwin-at-rpath was given. -+if test "${enable_darwin_at_rpath+set}" = set; then : -+ enableval=$enable_darwin_at_rpath; if test "x$enable_darwin_at_rpath" = "xyes"; then -+ # This is not supported before macOS 10.5 / Darwin9. -+ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in -+ UNSET,darwin[4-8]*|UNSET,rhapsody*|10.[0-4][,.]*) -+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Darwin @rpath library names are incompatible with OSX versions earlier than 10.5 (rpaths disabled)" >&5 -+$as_echo "$as_me: WARNING: Darwin @rpath library names are incompatible with OSX versions earlier than 10.5 (rpaths disabled)" >&2;} -+ enable_darwin_at_rpath=no -+ ;; -+ esac -+ fi -+else -+ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in -+ # As above, before 10.5 / Darwin9 this does not work. -+ UNSET,darwin[4-8]*|UNSET,rhapsody*|10.[0-4][,.]*) -+ enable_darwin_at_rpath=no -+ ;; -+ -+ # We cannot build and test reliably on macOS 10.11+ (Darwin15+) without use -+ # of rpaths, since runpaths set via DYLD_LIBRARY_PATH are elided by key -+ # system executables (e.g. /bin/sh). Force rpaths on for these systems. -+ UNSET,darwin1[5-9]*|UNSET,darwin2*|10.1[1-9][,.]*|1[1-9].*[,.]* ) -+ { $as_echo "$as_me:${as_lineno-$LINENO}: @rpath library names are needed on macOS versions later than 10.11 (rpaths have been enabled)" >&5 -+$as_echo "$as_me: @rpath library names are needed on macOS versions later than 10.11 (rpaths have been enabled)" >&6;} -+ enable_darwin_at_rpath=yes -+ ;; -+ # NOTE: we are not (yet) doing anything for 10.5 .. 10.10, since they can -+ # work with either DYLD_LIBRARY_PATH or embedded rpaths. -+ -+ esac -+ -+fi -+ -+ - archive_cmds_need_lc=no - hardcode_direct=no - hardcode_automatic=yes -@@ -10470,9 +10519,13 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi - esac - if test "$_lt_dar_can_shared" = "yes"; then - output_verbose_link_cmd=func_echo_all -- archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" -+ _lt_install_name='\$rpath/\$soname' -+ if test "x$enable_darwin_at_rpath" = "xyes"; then -+ _lt_install_name='@rpath/\$soname' -+ fi -+ archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name ${_lt_install_name} \$verstring ${_lt_dsymutil}" - module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" -- archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" -+ archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name ${_lt_install_name} \$verstring ${_lt_dar_export_syms}${_lt_dsymutil}" - module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" - - else -@@ -12278,7 +12331,7 @@ else - lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 - lt_status=$lt_dlunknown - cat > conftest.$ac_ext <<_LT_EOF --#line 12281 "configure" -+#line 12334 "configure" - #include "confdefs.h" - - #if HAVE_DLFCN_H -@@ -12384,7 +12437,7 @@ else - lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 - lt_status=$lt_dlunknown - cat > conftest.$ac_ext <<_LT_EOF --#line 12387 "configure" -+#line 12440 "configure" - #include "confdefs.h" - - #if HAVE_DLFCN_H -@@ -13260,6 +13313,49 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi - darwin* | rhapsody*) - - -+ -+ # Publish an arg to allow the user to select that Darwin host (and target) -+ # libraries should be given install-names like @rpath/libfoo.dylib. This -+ # requires that the user of the library then adds an 'rpath' to the DSO that -+ # needs access. -+ # NOTE: there are defaults below, for systems that support rpaths. The person -+ # configuring can override the defaults for any system version that supports -+ # them - they are, however, forced off for system versions without support. -+ # Check whether --enable-darwin-at-rpath was given. -+if test "${enable_darwin_at_rpath+set}" = set; then : -+ enableval=$enable_darwin_at_rpath; if test "x$enable_darwin_at_rpath" = "xyes"; then -+ # This is not supported before macOS 10.5 / Darwin9. -+ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in -+ UNSET,darwin[4-8]*|UNSET,rhapsody*|10.[0-4][,.]*) -+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Darwin @rpath library names are incompatible with OSX versions earlier than 10.5 (rpaths disabled)" >&5 -+$as_echo "$as_me: WARNING: Darwin @rpath library names are incompatible with OSX versions earlier than 10.5 (rpaths disabled)" >&2;} -+ enable_darwin_at_rpath=no -+ ;; -+ esac -+ fi -+else -+ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in -+ # As above, before 10.5 / Darwin9 this does not work. -+ UNSET,darwin[4-8]*|UNSET,rhapsody*|10.[0-4][,.]*) -+ enable_darwin_at_rpath=no -+ ;; -+ -+ # We cannot build and test reliably on macOS 10.11+ (Darwin15+) without use -+ # of rpaths, since runpaths set via DYLD_LIBRARY_PATH are elided by key -+ # system executables (e.g. /bin/sh). Force rpaths on for these systems. -+ UNSET,darwin1[5-9]*|UNSET,darwin2*|10.1[1-9][,.]*|1[1-9].*[,.]* ) -+ { $as_echo "$as_me:${as_lineno-$LINENO}: @rpath library names are needed on macOS versions later than 10.11 (rpaths have been enabled)" >&5 -+$as_echo "$as_me: @rpath library names are needed on macOS versions later than 10.11 (rpaths have been enabled)" >&6;} -+ enable_darwin_at_rpath=yes -+ ;; -+ # NOTE: we are not (yet) doing anything for 10.5 .. 10.10, since they can -+ # work with either DYLD_LIBRARY_PATH or embedded rpaths. -+ -+ esac -+ -+fi -+ -+ - archive_cmds_need_lc_CXX=no - hardcode_direct_CXX=no - hardcode_automatic_CXX=yes -@@ -13277,12 +13373,20 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi - esac - if test "$_lt_dar_can_shared" = "yes"; then - output_verbose_link_cmd=func_echo_all -- archive_cmds_CXX="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" -+ _lt_install_name='\$rpath/\$soname' -+ if test "x$enable_darwin_at_rpath" = "xyes"; then -+ _lt_install_name='@rpath/\$soname' -+ fi -+ archive_cmds_CXX="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name ${_lt_install_name} \$verstring ${_lt_dsymutil}" - module_cmds_CXX="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" -- archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" -+ archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name ${_lt_install_name} \$verstring ${_lt_dar_export_syms}${_lt_dsymutil}" - module_expsym_cmds_CXX="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" - if test "$lt_cv_apple_cc_single_mod" != "yes"; then -- archive_cmds_CXX="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}" -+ _lt_install_name='\$rpath/\$soname' -+ if test "x$enable_darwin_at_rpath" = "xyes"; then -+ _lt_install_name='@rpath/\$soname' -+ fi -+ archive_cmds_CXX="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name ${_lt_install_name} \$verstring${_lt_dsymutil}" - archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}" - fi - -@@ -15676,6 +15780,14 @@ esac - - - -+ if test x$enable_darwin_at_rpath = xyes; then -+ ENABLE_DARWIN_AT_RPATH_TRUE= -+ ENABLE_DARWIN_AT_RPATH_FALSE='#' -+else -+ ENABLE_DARWIN_AT_RPATH_TRUE='#' -+ ENABLE_DARWIN_AT_RPATH_FALSE= -+fi -+ - - # For libtool versioning info, format is CURRENT:REVISION:AGE - libtool_VERSION=1:0:0 -@@ -16021,6 +16133,10 @@ if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then - as_fn_error $? "conditional \"am__fastdepCXX\" was never defined. - Usually this means the macro was only invoked conditionally." "$LINENO" 5 - fi -+if test -z "${ENABLE_DARWIN_AT_RPATH_TRUE}" && test -z "${ENABLE_DARWIN_AT_RPATH_FALSE}"; then -+ as_fn_error $? "conditional \"ENABLE_DARWIN_AT_RPATH\" was never defined. -+Usually this means the macro was only invoked conditionally." "$LINENO" 5 -+fi - if test -z "${VTV_CYGMIN_TRUE}" && test -z "${VTV_CYGMIN_FALSE}"; then - as_fn_error $? "conditional \"VTV_CYGMIN\" was never defined. - Usually this means the macro was only invoked conditionally." "$LINENO" 5 -diff --git a/libvtv/configure.ac b/libvtv/configure.ac -index f3b937e..50aaadb 100644 ---- a/libvtv/configure.ac -+++ b/libvtv/configure.ac -@@ -153,6 +153,7 @@ AM_PROG_LIBTOOL - ACX_LT_HOST_FLAGS - AC_SUBST(enable_shared) - AC_SUBST(enable_static) -+AM_CONDITIONAL([ENABLE_DARWIN_AT_RPATH], [test x$enable_darwin_at_rpath = xyes]) - - # For libtool versioning info, format is CURRENT:REVISION:AGE - libtool_VERSION=1:0:0 -diff --git a/lto-plugin/configure b/lto-plugin/configure -index d522bd2..c3b1b5f 100755 ---- a/lto-plugin/configure -+++ b/lto-plugin/configure -@@ -634,6 +634,8 @@ LTLIBOBJS - LIBOBJS - target_noncanonical - lt_host_flags -+ENABLE_DARWIN_AT_RPATH_FALSE -+ENABLE_DARWIN_AT_RPATH_TRUE - OTOOL64 - OTOOL - LIPO -@@ -786,6 +788,7 @@ with_pic - enable_fast_install - with_gnu_ld - enable_libtool_lock -+enable_darwin_at_rpath - ' - ac_precious_vars='build_alias - host_alias -@@ -1431,6 +1434,9 @@ Optional Features: - --enable-fast-install[=PKGS] - optimize for fast installation [default=yes] - --disable-libtool-lock avoid locking (might break parallel builds) -+ --enable-darwin-at-rpath -+ install libraries with @rpath/library-name, requires -+ rpaths to be added to executables - - Optional Packages: - --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] -@@ -8603,7 +8609,7 @@ $as_echo "$lt_cv_ld_force_load" >&6; } - # darwin 5.x (macOS 10.1) onwards we only need to adjust when the - # deployment target is forced to an earlier version. - case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host in -- UNSET,*-darwin[89]*|UNSET,*-darwin[12][0123456789]*) -+ UNSET,*-darwin[89]*|UNSET,*-darwin[12][0-9]*) - ;; - 10.[012][,.]*) - _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' -@@ -10309,6 +10315,49 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi - darwin* | rhapsody*) - - -+ -+ # Publish an arg to allow the user to select that Darwin host (and target) -+ # libraries should be given install-names like @rpath/libfoo.dylib. This -+ # requires that the user of the library then adds an 'rpath' to the DSO that -+ # needs access. -+ # NOTE: there are defaults below, for systems that support rpaths. The person -+ # configuring can override the defaults for any system version that supports -+ # them - they are, however, forced off for system versions without support. -+ # Check whether --enable-darwin-at-rpath was given. -+if test "${enable_darwin_at_rpath+set}" = set; then : -+ enableval=$enable_darwin_at_rpath; if test "x$enable_darwin_at_rpath" = "xyes"; then -+ # This is not supported before macOS 10.5 / Darwin9. -+ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in -+ UNSET,darwin[4-8]*|UNSET,rhapsody*|10.[0-4][,.]*) -+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Darwin @rpath library names are incompatible with OSX versions earlier than 10.5 (rpaths disabled)" >&5 -+$as_echo "$as_me: WARNING: Darwin @rpath library names are incompatible with OSX versions earlier than 10.5 (rpaths disabled)" >&2;} -+ enable_darwin_at_rpath=no -+ ;; -+ esac -+ fi -+else -+ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in -+ # As above, before 10.5 / Darwin9 this does not work. -+ UNSET,darwin[4-8]*|UNSET,rhapsody*|10.[0-4][,.]*) -+ enable_darwin_at_rpath=no -+ ;; -+ -+ # We cannot build and test reliably on macOS 10.11+ (Darwin15+) without use -+ # of rpaths, since runpaths set via DYLD_LIBRARY_PATH are elided by key -+ # system executables (e.g. /bin/sh). Force rpaths on for these systems. -+ UNSET,darwin1[5-9]*|UNSET,darwin2*|10.1[1-9][,.]*|1[1-9].*[,.]* ) -+ { $as_echo "$as_me:${as_lineno-$LINENO}: @rpath library names are needed on macOS versions later than 10.11 (rpaths have been enabled)" >&5 -+$as_echo "$as_me: @rpath library names are needed on macOS versions later than 10.11 (rpaths have been enabled)" >&6;} -+ enable_darwin_at_rpath=yes -+ ;; -+ # NOTE: we are not (yet) doing anything for 10.5 .. 10.10, since they can -+ # work with either DYLD_LIBRARY_PATH or embedded rpaths. -+ -+ esac -+ -+fi -+ -+ - archive_cmds_need_lc=no - hardcode_direct=no - hardcode_automatic=yes -@@ -10326,9 +10375,13 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi - esac - if test "$_lt_dar_can_shared" = "yes"; then - output_verbose_link_cmd=func_echo_all -- archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" -+ _lt_install_name='\$rpath/\$soname' -+ if test "x$enable_darwin_at_rpath" = "xyes"; then -+ _lt_install_name='@rpath/\$soname' -+ fi -+ archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name ${_lt_install_name} \$verstring ${_lt_dsymutil}" - module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" -- archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" -+ archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name ${_lt_install_name} \$verstring ${_lt_dar_export_syms}${_lt_dsymutil}" - module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" - - else -@@ -12134,7 +12187,7 @@ else - lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 - lt_status=$lt_dlunknown - cat > conftest.$ac_ext <<_LT_EOF --#line 12137 "configure" -+#line 12190 "configure" - #include "confdefs.h" - - #if HAVE_DLFCN_H -@@ -12240,7 +12293,7 @@ else - lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 - lt_status=$lt_dlunknown - cat > conftest.$ac_ext <<_LT_EOF --#line 12243 "configure" -+#line 12296 "configure" - #include "confdefs.h" - - #if HAVE_DLFCN_H -@@ -12477,6 +12530,14 @@ CC="$lt_save_CC" - # Only expand once: - - -+ if test x$enable_darwin_at_rpath = xyes; then -+ ENABLE_DARWIN_AT_RPATH_TRUE= -+ ENABLE_DARWIN_AT_RPATH_FALSE='#' -+else -+ ENABLE_DARWIN_AT_RPATH_TRUE='#' -+ ENABLE_DARWIN_AT_RPATH_FALSE= -+fi -+ - - - -@@ -12723,6 +12784,10 @@ if test -z "${LTO_PLUGIN_USE_SYMVER_SUN_TRUE}" && test -z "${LTO_PLUGIN_USE_SYMV - as_fn_error $? "conditional \"LTO_PLUGIN_USE_SYMVER_SUN\" was never defined. - Usually this means the macro was only invoked conditionally." "$LINENO" 5 - fi -+if test -z "${ENABLE_DARWIN_AT_RPATH_TRUE}" && test -z "${ENABLE_DARWIN_AT_RPATH_FALSE}"; then -+ as_fn_error $? "conditional \"ENABLE_DARWIN_AT_RPATH\" was never defined. -+Usually this means the macro was only invoked conditionally." "$LINENO" 5 -+fi - - : "${CONFIG_STATUS=./config.status}" - ac_write_fail=0 -diff --git a/lto-plugin/configure.ac b/lto-plugin/configure.ac -index 0a72027..5812bbb 100644 ---- a/lto-plugin/configure.ac -+++ b/lto-plugin/configure.ac -@@ -110,6 +110,7 @@ fi - AC_SUBST(ac_lto_plugin_extra_ldflags) - - AM_PROG_LIBTOOL -+AM_CONDITIONAL([ENABLE_DARWIN_AT_RPATH], [test x$enable_darwin_at_rpath = xyes]) - ACX_LT_HOST_FLAGS - AC_SUBST(target_noncanonical) - AC_TYPE_INT64_T -diff --git a/zlib/Makefile.in b/zlib/Makefile.in -index 3f5102d..80fe3b6 100644 ---- a/zlib/Makefile.in -+++ b/zlib/Makefile.in -@@ -353,6 +353,8 @@ datadir = @datadir@ - datarootdir = @datarootdir@ - docdir = @docdir@ - dvidir = @dvidir@ -+enable_host_pie = @enable_host_pie@ -+enable_host_shared = @enable_host_shared@ - exec_prefix = @exec_prefix@ - host = @host@ - host_alias = @host_alias@ -diff --git a/zlib/configure b/zlib/configure -index e35ac6e..a7673a8 100755 ---- a/zlib/configure -+++ b/zlib/configure -@@ -635,10 +635,14 @@ am__EXEEXT_TRUE - LTLIBOBJS - LIBOBJS - PICFLAG -+enable_host_pie -+enable_host_shared - TARGET_LIBRARY_FALSE - TARGET_LIBRARY_TRUE - toolexeclibdir - toolexecdir -+ENABLE_DARWIN_AT_RPATH_FALSE -+ENABLE_DARWIN_AT_RPATH_TRUE - CPP - OTOOL64 - OTOOL -@@ -776,8 +780,10 @@ with_pic - enable_fast_install - with_gnu_ld - enable_libtool_lock -+enable_darwin_at_rpath - with_toolexeclibdir - enable_host_shared -+enable_host_pie - ' - ac_precious_vars='build_alias - host_alias -@@ -1419,7 +1425,11 @@ Optional Features: - --enable-fast-install[=PKGS] - optimize for fast installation [default=yes] - --disable-libtool-lock avoid locking (might break parallel builds) -+ --enable-darwin-at-rpath -+ install libraries with @rpath/library-name, requires -+ rpaths to be added to executables - --enable-host-shared build host code as shared libraries -+ --enable-host-pie build host code as PIE - - Optional Packages: - --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] -@@ -6934,7 +6944,7 @@ $as_echo "$lt_cv_ld_force_load" >&6; } - # darwin 5.x (macOS 10.1) onwards we only need to adjust when the - # deployment target is forced to an earlier version. - case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host in -- UNSET,*-darwin[89]*|UNSET,*-darwin[12][0123456789]*) -+ UNSET,*-darwin[89]*|UNSET,*-darwin[12][0-9]*) - ;; - 10.[012][,.]*) - _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' -@@ -8913,6 +8923,49 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi - darwin* | rhapsody*) - - -+ -+ # Publish an arg to allow the user to select that Darwin host (and target) -+ # libraries should be given install-names like @rpath/libfoo.dylib. This -+ # requires that the user of the library then adds an 'rpath' to the DSO that -+ # needs access. -+ # NOTE: there are defaults below, for systems that support rpaths. The person -+ # configuring can override the defaults for any system version that supports -+ # them - they are, however, forced off for system versions without support. -+ # Check whether --enable-darwin-at-rpath was given. -+if test "${enable_darwin_at_rpath+set}" = set; then : -+ enableval=$enable_darwin_at_rpath; if test "x$enable_darwin_at_rpath" = "xyes"; then -+ # This is not supported before macOS 10.5 / Darwin9. -+ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in -+ UNSET,darwin[4-8]*|UNSET,rhapsody*|10.[0-4][,.]*) -+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Darwin @rpath library names are incompatible with OSX versions earlier than 10.5 (rpaths disabled)" >&5 -+$as_echo "$as_me: WARNING: Darwin @rpath library names are incompatible with OSX versions earlier than 10.5 (rpaths disabled)" >&2;} -+ enable_darwin_at_rpath=no -+ ;; -+ esac -+ fi -+else -+ case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in -+ # As above, before 10.5 / Darwin9 this does not work. -+ UNSET,darwin[4-8]*|UNSET,rhapsody*|10.[0-4][,.]*) -+ enable_darwin_at_rpath=no -+ ;; -+ -+ # We cannot build and test reliably on macOS 10.11+ (Darwin15+) without use -+ # of rpaths, since runpaths set via DYLD_LIBRARY_PATH are elided by key -+ # system executables (e.g. /bin/sh). Force rpaths on for these systems. -+ UNSET,darwin1[5-9]*|UNSET,darwin2*|10.1[1-9][,.]*|1[1-9].*[,.]* ) -+ { $as_echo "$as_me:${as_lineno-$LINENO}: @rpath library names are needed on macOS versions later than 10.11 (rpaths have been enabled)" >&5 -+$as_echo "$as_me: @rpath library names are needed on macOS versions later than 10.11 (rpaths have been enabled)" >&6;} -+ enable_darwin_at_rpath=yes -+ ;; -+ # NOTE: we are not (yet) doing anything for 10.5 .. 10.10, since they can -+ # work with either DYLD_LIBRARY_PATH or embedded rpaths. -+ -+ esac -+ -+fi -+ -+ - archive_cmds_need_lc=no - hardcode_direct=no - hardcode_automatic=yes -@@ -8930,9 +8983,13 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi - esac - if test "$_lt_dar_can_shared" = "yes"; then - output_verbose_link_cmd=func_echo_all -- archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" -+ _lt_install_name='\$rpath/\$soname' -+ if test "x$enable_darwin_at_rpath" = "xyes"; then -+ _lt_install_name='@rpath/\$soname' -+ fi -+ archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name ${_lt_install_name} \$verstring ${_lt_dsymutil}" - module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" -- archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" -+ archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name ${_lt_install_name} \$verstring ${_lt_dar_export_syms}${_lt_dsymutil}" - module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" - - else -@@ -10759,7 +10816,7 @@ else - lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 - lt_status=$lt_dlunknown - cat > conftest.$ac_ext <<_LT_EOF --#line 10762 "configure" -+#line 10819 "configure" - #include "confdefs.h" - - #if HAVE_DLFCN_H -@@ -10865,7 +10922,7 @@ else - lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 - lt_status=$lt_dlunknown - cat > conftest.$ac_ext <<_LT_EOF --#line 10868 "configure" -+#line 10925 "configure" - #include "confdefs.h" - - #if HAVE_DLFCN_H -@@ -11102,6 +11159,14 @@ CC="$lt_save_CC" - # Only expand once: - - -+ if test x$enable_darwin_at_rpath = xyes; then -+ ENABLE_DARWIN_AT_RPATH_TRUE= -+ ENABLE_DARWIN_AT_RPATH_FALSE='#' -+else -+ ENABLE_DARWIN_AT_RPATH_TRUE='#' -+ ENABLE_DARWIN_AT_RPATH_FALSE= -+fi -+ - - # Find CPP now so that any conditional tests below won't do it and - # thereby make the resulting definitions conditional. -@@ -11548,15 +11613,31 @@ else - multilib_arg= - fi - -+# Enable --enable-host-shared. - # Check whether --enable-host-shared was given. - if test "${enable_host_shared+set}" = set; then : -- enableval=$enable_host_shared; PICFLAG=-fPIC -+ enableval=$enable_host_shared; -+fi -+ -+ -+ -+# Enable --enable-host-pie. -+# Check whether --enable-host-pie was given. -+if test "${enable_host_pie+set}" = set; then : -+ enableval=$enable_host_pie; -+fi -+ -+ -+ -+if test x$enable_host_shared = xyes; then -+ PICFLAG=-fPIC -+elif test x$enable_host_pie = xyes; then -+ PICFLAG=-fPIE - else - PICFLAG= - fi - - -- - ac_config_files="$ac_config_files Makefile" - - cat >confcache <<\_ACEOF -@@ -11732,6 +11813,10 @@ if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then - as_fn_error $? "conditional \"am__fastdepCC\" was never defined. - Usually this means the macro was only invoked conditionally." "$LINENO" 5 - fi -+if test -z "${ENABLE_DARWIN_AT_RPATH_TRUE}" && test -z "${ENABLE_DARWIN_AT_RPATH_FALSE}"; then -+ as_fn_error $? "conditional \"ENABLE_DARWIN_AT_RPATH\" was never defined. -+Usually this means the macro was only invoked conditionally." "$LINENO" 5 -+fi - if test -z "${TARGET_LIBRARY_TRUE}" && test -z "${TARGET_LIBRARY_FALSE}"; then - as_fn_error $? "conditional \"TARGET_LIBRARY\" was never defined. - Usually this means the macro was only invoked conditionally." "$LINENO" 5 -diff --git a/zlib/configure.ac b/zlib/configure.ac -index be1cfe2..9501cdf 100644 ---- a/zlib/configure.ac -+++ b/zlib/configure.ac -@@ -64,6 +64,7 @@ GCC_CET_FLAGS(CET_FLAGS) - AC_SUBST(CET_FLAGS) - - AC_PROG_LIBTOOL -+AM_CONDITIONAL([ENABLE_DARWIN_AT_RPATH], [test x$enable_darwin_at_rpath = xyes]) - - # Find CPP now so that any conditional tests below won't do it and - # thereby make the resulting definitions conditional. -@@ -122,11 +123,26 @@ else - multilib_arg= - fi - -+# Enable --enable-host-shared. - AC_ARG_ENABLE(host-shared, - [AS_HELP_STRING([--enable-host-shared], -- [build host code as shared libraries])], --[PICFLAG=-fPIC], [PICFLAG=]) --AC_SUBST(PICFLAG) -+ [build host code as shared libraries])]) -+AC_SUBST(enable_host_shared) -+ -+# Enable --enable-host-pie. -+AC_ARG_ENABLE(host-pie, -+[AS_HELP_STRING([--enable-host-pie], -+ [build host code as PIE])]) -+AC_SUBST(enable_host_pie) -+ -+if test x$enable_host_shared = xyes; then -+ PICFLAG=-fPIC -+elif test x$enable_host_pie = xyes; then -+ PICFLAG=-fPIE -+else -+ PICFLAG= -+fi - -+AC_SUBST(PICFLAG) - AC_CONFIG_FILES([Makefile]) - AC_OUTPUT diff --git a/build/pkgs/gcc/patches/gcc-multiarch.patch b/build/pkgs/gcc/patches/gcc-multiarch.patch deleted file mode 100644 index 869bb212859..00000000000 --- a/build/pkgs/gcc/patches/gcc-multiarch.patch +++ /dev/null @@ -1,235 +0,0 @@ -# DP: - Remaining multiarch patches, not yet submitted upstream. -# DP: - Add MULTIARCH_DIRNAME definitions for multilib configurations, -# DP: which are used for the non-multilib builds. - -2013-06-12 Matthias Klose - - * config/i386/t-linux64: Set MULTIARCH_DIRNAME. - * config/i386/t-kfreebsd: Set MULTIARCH_DIRNAME. - * config.gcc (i[34567]86-*-linux* | x86_64-*-linux*): Prepend - i386/t-linux to $tmake_file; - set default ABI to N64 for mips64el. - * config/mips/t-linux64: Set MULTIARCH_DIRNAME. - * config/rs6000/t-linux64: Set MULTIARCH_DIRNAME. - * config/s390/t-linux64: Set MULTIARCH_DIRNAME. - * config/sparc/t-linux64: Set MULTIARCH_DIRNAME. - * src/gcc/config/mips/mips.h: (/usr)/lib as default path. - -Index: b/gcc/config/sh/t-linux -=================================================================== ---- a/gcc/config/sh/t-linux -+++ b/gcc/config/sh/t-linux -@@ -1,3 +1,11 @@ - MULTILIB_DIRNAMES= - MULTILIB_MATCHES= -+ -+ifneq (,$(findstring sh4,$(target))) -+MULTILIB_OSDIRNAMES = .:sh4-linux-gnu sh4_nofpu-linux-gnu:sh4-linux-gnu -+MULTIARCH_DIRNAME = $(call if_multiarch,sh4-linux-gnu) -+else -+MULTILIB_OSDIRNAMES = .:sh3-linux-gnu sh3_nofpu-linux-gnu:sh3-linux-gnu -+MULTIARCH_DIRNAME = $(call if_multiarch,sh3-linux-gnu) -+endif - MULTILIB_EXCEPTIONS=m1 mb/m1 m2a -Index: b/gcc/config/sparc/t-linux64 -=================================================================== ---- a/gcc/config/sparc/t-linux64 -+++ b/gcc/config/sparc/t-linux64 -@@ -27,3 +27,5 @@ MULTILIB_OPTIONS = m64/m32 - MULTILIB_DIRNAMES = 64 32 - MULTILIB_OSDIRNAMES = ../lib64$(call if_multiarch,:sparc64-linux-gnu) - MULTILIB_OSDIRNAMES += $(if $(wildcard $(shell echo $(SYSTEM_HEADER_DIR))/../../usr/lib32),../lib32,../lib)$(call if_multiarch,:sparc-linux-gnu) -+ -+MULTIARCH_DIRNAME = $(call if_multiarch,sparc$(if $(findstring 64,$(target)),64)-linux-gnu) -Index: b/gcc/config/s390/t-linux64 -=================================================================== ---- a/gcc/config/s390/t-linux64 -+++ b/gcc/config/s390/t-linux64 -@@ -9,3 +9,5 @@ MULTILIB_OPTIONS = m64/m31 - MULTILIB_DIRNAMES = 64 32 - MULTILIB_OSDIRNAMES = ../lib64$(call if_multiarch,:s390x-linux-gnu) - MULTILIB_OSDIRNAMES += $(if $(wildcard $(shell echo $(SYSTEM_HEADER_DIR))/../../usr/lib32),../lib32,../lib)$(call if_multiarch,:s390-linux-gnu) -+ -+MULTIARCH_DIRNAME = $(call if_multiarch,s390$(if $(findstring s390x,$(target)),x)-linux-gnu) -Index: b/gcc/config/rs6000/t-linux64 -=================================================================== ---- a/gcc/config/rs6000/t-linux64 -+++ b/gcc/config/rs6000/t-linux64 -@@ -31,6 +31,8 @@ MULTILIB_EXTRA_OPTS := - MULTILIB_OSDIRNAMES := m64=../lib64$(call if_multiarch,:powerpc64-linux-gnu) - MULTILIB_OSDIRNAMES += m32=$(if $(wildcard $(shell echo $(SYSTEM_HEADER_DIR))/../../usr/lib32),../lib32,../lib)$(call if_multiarch,:powerpc-linux-gnu) - -+MULTIARCH_DIRNAME = $(call if_multiarch,powerpc$(if $(findstring 64,$(target)),64)-linux-gnu) -+ - rs6000-linux.o: $(srcdir)/config/rs6000/rs6000-linux.cc - $(COMPILE) $< - $(POSTCOMPILE) -Index: b/gcc/config/i386/t-linux64 -=================================================================== ---- a/gcc/config/i386/t-linux64 -+++ b/gcc/config/i386/t-linux64 -@@ -36,3 +36,13 @@ MULTILIB_DIRNAMES = $(patsubst m%, %, - MULTILIB_OSDIRNAMES = m64=../lib64$(call if_multiarch,:x86_64-linux-gnu) - MULTILIB_OSDIRNAMES+= m32=$(if $(wildcard $(shell echo $(SYSTEM_HEADER_DIR))/../../usr/lib32),../lib32,../lib)$(call if_multiarch,:i386-linux-gnu) - MULTILIB_OSDIRNAMES+= mx32=../libx32$(call if_multiarch,:x86_64-linux-gnux32) -+ -+ifneq (,$(findstring x86_64,$(target))) -+ ifneq (,$(findstring biarchx32.h,$(tm_include_list))) -+ MULTIARCH_DIRNAME = $(call if_multiarch,x86_64-linux-gnux32) -+ else -+ MULTIARCH_DIRNAME = $(call if_multiarch,x86_64-linux-gnu) -+ endif -+else -+ MULTIARCH_DIRNAME = $(call if_multiarch,i386-linux-gnu) -+endif -Index: b/gcc/config/i386/t-kfreebsd -=================================================================== ---- a/gcc/config/i386/t-kfreebsd -+++ b/gcc/config/i386/t-kfreebsd -@@ -1,5 +1,9 @@ --MULTIARCH_DIRNAME = $(call if_multiarch,i386-kfreebsd-gnu) -+ifeq (,$(MULTIARCH_DIRNAME)) -+ MULTIARCH_DIRNAME = $(call if_multiarch,i386-kfreebsd-gnu) -+endif - - # MULTILIB_OSDIRNAMES are set in t-linux64. - KFREEBSD_OS = $(filter kfreebsd%, $(word 3, $(subst -, ,$(target)))) - MULTILIB_OSDIRNAMES := $(filter-out mx32=%,$(subst linux,$(KFREEBSD_OS),$(MULTILIB_OSDIRNAMES))) -+ -+MULTIARCH_DIRNAME := $(subst linux,$(KFREEBSD_OS),$(MULTIARCH_DIRNAME)) -Index: b/gcc/config/mips/t-linux64 -=================================================================== ---- a/gcc/config/mips/t-linux64 -+++ b/gcc/config/mips/t-linux64 -@@ -18,24 +18,28 @@ - - MULTILIB_OPTIONS = mabi=n32/mabi=32/mabi=64 - MULTILIB_DIRNAMES = n32 32 64 -+MIPS_R6 = $(if $(findstring r6, $(firstword $(subst -, ,$(target)))),r6) -+MIPS_32 = $(if $(findstring r6, $(firstword $(subst -, ,$(target)))),32) -+MIPS_ISA = $(if $(findstring r6, $(firstword $(subst -, ,$(target)))),isa) - MIPS_EL = $(if $(filter %el, $(firstword $(subst -, ,$(target)))),el) - MIPS_SOFT = $(if $(strip $(filter MASK_SOFT_FLOAT_ABI, $(target_cpu_default)) $(filter soft, $(with_float))),soft) -+ - ifeq (yes,$(enable_multiarch)) - ifneq (,$(findstring gnuabi64,$(target))) - MULTILIB_OSDIRNAMES = \ -- ../lib32$(call if_multiarch,:mips64$(MIPS_EL)-linux-gnuabin32$(MIPS_SOFT)) \ -- ../libo32$(call if_multiarch,:mips$(MIPS_EL)-linux-gnu$(MIPS_SOFT)) \ -- ../lib$(call if_multiarch,:mips64$(MIPS_EL)-linux-gnuabi64$(MIPS_SOFT)) -+ ../lib32$(call if_multiarch,:mips$(MIPS_ISA)64$(MIPS_R6)$(MIPS_EL)-linux-gnuabin32$(MIPS_SOFT)) \ -+ ../libo32$(call if_multiarch,:mips$(MIPS_ISA)$(MIPS_32)$(MIPS_R6)$(MIPS_EL)-linux-gnu$(MIPS_SOFT)) \ -+ ../lib$(call if_multiarch,:mips$(MIPS_ISA)64$(MIPS_R6)$(MIPS_EL)-linux-gnuabi64$(MIPS_SOFT)) - else ifneq (,$(findstring gnuabin32,$(target))) - MULTILIB_OSDIRNAMES = \ -- ../lib$(call if_multiarch,:mips64$(MIPS_EL)-linux-gnuabin32$(MIPS_SOFT)) \ -- ../libo32$(call if_multiarch,:mips$(MIPS_EL)-linux-gnu$(MIPS_SOFT)) \ -- ../lib64$(call if_multiarch,:mips64$(MIPS_EL)-linux-gnuabi64$(MIPS_SOFT)) -+ ../lib$(call if_multiarch,:mips$(MIPS_ISA)64$(MIPS_R6)$(MIPS_EL)-linux-gnuabin32$(MIPS_SOFT)) \ -+ ../libo32$(call if_multiarch,:mips$(MIPS_ISA)$(MIPS_32)$(MIPS_R6)$(MIPS_EL)-linux-gnu$(MIPS_SOFT)) \ -+ ../lib64$(call if_multiarch,:mips$(MIPS_ISA)64$(MIPS_R6)$(MIPS_EL)-linux-gnuabi64$(MIPS_SOFT)) - else - MULTILIB_OSDIRNAMES = \ -- ../lib32$(call if_multiarch,:mips64$(MIPS_EL)-linux-gnuabin32$(MIPS_SOFT)) \ -- ../lib$(call if_multiarch,:mips$(MIPS_EL)-linux-gnu$(MIPS_SOFT)) \ -- ../lib64$(call if_multiarch,:mips64$(MIPS_EL)-linux-gnuabi64$(MIPS_SOFT)) -+ ../lib32$(call if_multiarch,:mips$(MIPS_ISA)64$(MIPS_R6)$(MIPS_EL)-linux-gnuabin32$(MIPS_SOFT)) \ -+ ../lib$(call if_multiarch,:mips$(MIPS_ISA)$(MIPS_32)$(MIPS_R6)$(MIPS_EL)-linux-gnu$(MIPS_SOFT)) \ -+ ../lib64$(call if_multiarch,:mips$(MIPS_ISA)64$(MIPS_R6)$(MIPS_EL)-linux-gnuabi64$(MIPS_SOFT)) - endif - else - MULTILIB_OSDIRNAMES = \ -@@ -43,3 +47,13 @@ else - ../lib$(call if_multiarch,:mips$(MIPS_EL)-linux-gnu$(MIPS_SOFT)) \ - ../lib64$(call if_multiarch,:mips64$(MIPS_EL)-linux-gnuabi64$(MIPS_SOFT)) - endif -+ -+ifneq (,$(findstring abin32,$(target))) -+MULTIARCH_DIRNAME = $(call if_multiarch,mips$(MIPS_ISA)64$(MIPS_R6)$(MIPS_EL)-linux-gnuabin32$(MIPS_SOFT)) -+else -+ifneq (,$(findstring abi64,$(target))) -+MULTIARCH_DIRNAME = $(call if_multiarch,mips$(MIPS_ISA)64$(MIPS_R6)$(MIPS_EL)-linux-gnuabi64$(MIPS_SOFT)) -+else -+MULTIARCH_DIRNAME = $(call if_multiarch,mips$(MIPS_ISA)$(MIPS_32)$(MIPS_R6)$(MIPS_EL)-linux-gnu$(MIPS_SOFT)) -+endif -+endif -Index: b/gcc/config.gcc -=================================================================== ---- a/gcc/config.gcc -+++ b/gcc/config.gcc -@@ -2519,7 +2519,8 @@ mips*-*-linux*) # Linux MIPS, either - extra_options="${extra_options} linux-android.opt" - case ${target} in - mipsisa32r6*) -- default_mips_arch=mips32r6 -+ with_arch_32="mips32r6" -+ with_arch_64="mips64r6" - ;; - mipsisa32r2*) - default_mips_arch=mips32r2 -@@ -2541,7 +2542,8 @@ mips*-*-linux*) # Linux MIPS, either - ;; - mipsisa64r6*-*-linux-gnuabi64) - default_mips_abi=64 -- default_mips_arch=mips64r6 -+ with_arch_32="mips32r6" -+ with_arch_64="mips64r6" - enable_mips_multilibs="yes" - ;; - mipsisa64r6*-*-linux*) -@@ -5656,7 +5658,7 @@ case ${target} in - ;; - i[34567]86-*-linux* | x86_64-*-linux*) - extra_objs="${extra_objs} gnu-property.o" -- tmake_file="$tmake_file i386/t-linux i386/t-gnu-property" -+ tmake_file="i386/t-linux $tmake_file i386/t-gnu-property" - ;; - i[34567]86-*-kfreebsd*-gnu | x86_64-*-kfreebsd*-gnu) - tmake_file="$tmake_file i386/t-kfreebsd" -Index: b/gcc/config/riscv/t-linux -=================================================================== ---- a/gcc/config/riscv/t-linux -+++ b/gcc/config/riscv/t-linux -@@ -1,3 +1,5 @@ - # Only XLEN and ABI affect Linux multilib dir names, e.g. /lib32/ilp32d/ - MULTILIB_DIRNAMES := $(patsubst rv32%,lib32,$(patsubst rv64%,lib64,$(MULTILIB_DIRNAMES))) - MULTILIB_OSDIRNAMES := $(patsubst lib%,../lib%,$(MULTILIB_DIRNAMES)) -+ -+MULTIARCH_DIRNAME := $(call if_multiarch,$(firstword $(subst -, ,$(target)))-linux-gnu) -Index: b/gcc/Makefile.in -=================================================================== ---- a/gcc/Makefile.in -+++ b/gcc/Makefile.in -@@ -553,7 +553,7 @@ BUILD_SYSTEM_HEADER_DIR = `echo @BUILD_S - STMP_FIXINC = @STMP_FIXINC@ - - # Test to see whether exists in the system header files. --LIMITS_H_TEST = [ -f $(BUILD_SYSTEM_HEADER_DIR)/limits.h ] -+LIMITS_H_TEST = [ -f $(BUILD_SYSTEM_HEADER_DIR)/limits.h -o -f $(BUILD_SYSTEM_HEADER_DIR)/$(MULTIARCH_DIRNAME)/limits.h ] - - # Directory for prefix to system directories, for - # each of $(system_prefix)/usr/include, $(system_prefix)/usr/lib, etc. -Index: b/gcc/config/aarch64/t-aarch64-linux -=================================================================== ---- a/gcc/config/aarch64/t-aarch64-linux -+++ b/gcc/config/aarch64/t-aarch64-linux -@@ -22,7 +22,7 @@ LIB1ASMSRC = aarch64/lib1funcs.asm - LIB1ASMFUNCS = _aarch64_sync_cache_range - - AARCH_BE = $(if $(findstring TARGET_BIG_ENDIAN_DEFAULT=1, $(tm_defines)),_be) --MULTILIB_OSDIRNAMES = mabi.lp64=../lib64$(call if_multiarch,:aarch64$(AARCH_BE)-linux-gnu) -+MULTILIB_OSDIRNAMES = mabi.lp64=../lib$(call if_multiarch,:aarch64$(AARCH_BE)-linux-gnu) - MULTIARCH_DIRNAME = $(call if_multiarch,aarch64$(AARCH_BE)-linux-gnu) - - MULTILIB_OSDIRNAMES += mabi.ilp32=../libilp32$(call if_multiarch,:aarch64$(AARCH_BE)-linux-gnu_ilp32) -Index: b/gcc/config/arc/t-multilib-linux -=================================================================== ---- a/gcc/config/arc/t-multilib-linux -+++ b/gcc/config/arc/t-multilib-linux -@@ -23,3 +23,6 @@ MULTILIB_DIRNAMES = hs archs hs38 hs38_l - # Aliases: - MULTILIB_MATCHES += mcpu?arc700=mA7 - MULTILIB_MATCHES += mcpu?arc700=mARC700 -+ -+MULTILIB_OSDIRNAMES = -+MULTIARCH_DIRNAME = $(call if_multiarch,arc-linux-gnu) diff --git a/build/pkgs/gcc/patches/gcc-multilib-multiarch.patch b/build/pkgs/gcc/patches/gcc-multilib-multiarch.patch deleted file mode 100644 index af5580055e8..00000000000 --- a/build/pkgs/gcc/patches/gcc-multilib-multiarch.patch +++ /dev/null @@ -1,126 +0,0 @@ -# DP: Don't auto-detect multilib osdirnames. - -Index: b/gcc/config/sparc/t-linux64 -=================================================================== ---- a/gcc/config/sparc/t-linux64 -+++ b/gcc/config/sparc/t-linux64 -@@ -25,7 +25,12 @@ - - MULTILIB_OPTIONS = m64/m32 - MULTILIB_DIRNAMES = 64 32 -+ifneq (,$(findstring sparc64,$(target))) -+MULTILIB_OSDIRNAMES = ../lib$(call if_multiarch,:sparc64-linux-gnu) -+MULTILIB_OSDIRNAMES += ../lib32$(call if_multiarch,:sparc-linux-gnu) -+else - MULTILIB_OSDIRNAMES = ../lib64$(call if_multiarch,:sparc64-linux-gnu) --MULTILIB_OSDIRNAMES += $(if $(wildcard $(shell echo $(SYSTEM_HEADER_DIR))/../../usr/lib32),../lib32,../lib)$(call if_multiarch,:sparc-linux-gnu) -+MULTILIB_OSDIRNAMES += ../lib$(call if_multiarch,:sparc-linux-gnu) -+endif - - MULTIARCH_DIRNAME = $(call if_multiarch,sparc$(if $(findstring 64,$(target)),64)-linux-gnu) -Index: b/gcc/config/s390/t-linux64 -=================================================================== ---- a/gcc/config/s390/t-linux64 -+++ b/gcc/config/s390/t-linux64 -@@ -7,7 +7,12 @@ - - MULTILIB_OPTIONS = m64/m31 - MULTILIB_DIRNAMES = 64 32 -+ifneq (,$(findstring s390x,$(target))) -+MULTILIB_OSDIRNAMES = ../lib$(call if_multiarch,:s390x-linux-gnu) -+MULTILIB_OSDIRNAMES += ../lib32$(call if_multiarch,:s390-linux-gnu) -+else - MULTILIB_OSDIRNAMES = ../lib64$(call if_multiarch,:s390x-linux-gnu) --MULTILIB_OSDIRNAMES += $(if $(wildcard $(shell echo $(SYSTEM_HEADER_DIR))/../../usr/lib32),../lib32,../lib)$(call if_multiarch,:s390-linux-gnu) -+MULTILIB_OSDIRNAMES += ../lib$(call if_multiarch,:s390-linux-gnu) -+endif - - MULTIARCH_DIRNAME = $(call if_multiarch,s390$(if $(findstring s390x,$(target)),x)-linux-gnu) -Index: b/gcc/config/rs6000/t-linux64 -=================================================================== ---- a/gcc/config/rs6000/t-linux64 -+++ b/gcc/config/rs6000/t-linux64 -@@ -28,8 +28,13 @@ - MULTILIB_OPTIONS := m64/m32 - MULTILIB_DIRNAMES := 64 32 - MULTILIB_EXTRA_OPTS := -+ifneq (,$(findstring powerpc64,$(target))) -+MULTILIB_OSDIRNAMES := m64=../lib$(call if_multiarch,:powerpc64-linux-gnu) -+MULTILIB_OSDIRNAMES += m32=../lib32$(call if_multiarch,:powerpc-linux-gnu) -+else - MULTILIB_OSDIRNAMES := m64=../lib64$(call if_multiarch,:powerpc64-linux-gnu) --MULTILIB_OSDIRNAMES += m32=$(if $(wildcard $(shell echo $(SYSTEM_HEADER_DIR))/../../usr/lib32),../lib32,../lib)$(call if_multiarch,:powerpc-linux-gnu) -+MULTILIB_OSDIRNAMES += m32=../lib$(call if_multiarch,:powerpc-linux-gnu) -+endif - - MULTIARCH_DIRNAME = $(call if_multiarch,powerpc$(if $(findstring 64,$(target)),64)-linux-gnu) - -Index: b/gcc/config/i386/t-linux64 -=================================================================== ---- a/gcc/config/i386/t-linux64 -+++ b/gcc/config/i386/t-linux64 -@@ -33,9 +33,19 @@ - comma=, - MULTILIB_OPTIONS = $(subst $(comma),/,$(TM_MULTILIB_CONFIG)) - MULTILIB_DIRNAMES = $(patsubst m%, %, $(subst /, ,$(MULTILIB_OPTIONS))) -+ifneq (,$(findstring gnux32,$(target))) - MULTILIB_OSDIRNAMES = m64=../lib64$(call if_multiarch,:x86_64-linux-gnu) --MULTILIB_OSDIRNAMES+= m32=$(if $(wildcard $(shell echo $(SYSTEM_HEADER_DIR))/../../usr/lib32),../lib32,../lib)$(call if_multiarch,:i386-linux-gnu) -+MULTILIB_OSDIRNAMES+= m32=../lib32$(call if_multiarch,:i386-linux-gnu) -+MULTILIB_OSDIRNAMES+= mx32=../lib$(call if_multiarch,:x86_64-linux-gnux32) -+else ifneq (,$(findstring x86_64,$(target))) -+MULTILIB_OSDIRNAMES = m64=../lib$(call if_multiarch,:x86_64-linux-gnu) -+MULTILIB_OSDIRNAMES+= m32=../lib32$(call if_multiarch,:i386-linux-gnu) - MULTILIB_OSDIRNAMES+= mx32=../libx32$(call if_multiarch,:x86_64-linux-gnux32) -+else -+MULTILIB_OSDIRNAMES = m64=../lib64$(call if_multiarch,:x86_64-linux-gnu) -+MULTILIB_OSDIRNAMES+= m32=../lib$(call if_multiarch,:i386-linux-gnu) -+MULTILIB_OSDIRNAMES+= mx32=../libx32$(call if_multiarch,:x86_64-linux-gnux32) -+endif - - ifneq (,$(findstring x86_64,$(target))) - ifneq (,$(findstring biarchx32.h,$(tm_include_list))) -Index: b/gcc/config/rs6000/t-linux -=================================================================== ---- a/gcc/config/rs6000/t-linux -+++ b/gcc/config/rs6000/t-linux -@@ -2,7 +2,7 @@ - # or soft-float. - ifeq (,$(filter $(with_cpu),$(SOFT_FLOAT_CPUS))$(findstring soft,$(with_float))) - ifneq (,$(findstring powerpc64,$(target))) --MULTILIB_OSDIRNAMES := .=../lib64$(call if_multiarch,:powerpc64-linux-gnu) -+MULTILIB_OSDIRNAMES := .=../lib$(call if_multiarch,:powerpc64-linux-gnu) - else - MULTIARCH_DIRNAME := $(call if_multiarch,powerpc-linux-gnu) - endif -Index: b/gcc/config/loongarch/t-linux -=================================================================== ---- a/gcc/config/loongarch/t-linux -+++ b/gcc/config/loongarch/t-linux -@@ -32,22 +32,19 @@ ifneq ($(call if_multiarch,yes),yes) - else - # Only define MULTIARCH_DIRNAME when multiarch is enabled, - # or it would always introduce ${target} into the search path. -- MULTIARCH_DIRNAME = $(LA_MULTIARCH_TRIPLET) -+ MULTIARCH_DIRNAME = $(call if_multiarch,loongarch64-linux-gnu) - endif - - # Don't define MULTILIB_OSDIRNAMES if multilib is disabled. - ifeq ($(filter LA_DISABLE_MULTILIB,$(tm_defines)),) - - MULTILIB_OSDIRNAMES = \ -- mabi.lp64d=../lib64$\ -- $(call if_multiarch,:loongarch64-linux-gnu) -+ mabi.lp64d=../lib$(call if_multiarch,:loongarch64-linux-gnu) - - MULTILIB_OSDIRNAMES += \ -- mabi.lp64f=../lib64/f32$\ -- $(call if_multiarch,:loongarch64-linux-gnuf32) -+ mabi.lp64f=../lib/f32$(call if_multiarch,:loongarch64-linux-gnuf32) - - MULTILIB_OSDIRNAMES += \ -- mabi.lp64s=../lib64/sf$\ -- $(call if_multiarch,:loongarch64-linux-gnusf) -+ mabi.lp64s=../lib/sf$(call if_multiarch,:loongarch64-linux-gnusf) - - endif From 9eb5edfa1967f28a30cdfd1a74d768d34c98182d Mon Sep 17 00:00:00 2001 From: Giorgos Mousa Date: Sat, 2 Nov 2024 19:37:08 +0200 Subject: [PATCH 401/537] Format function headers around `=` and `,` --- .../fermionic_ghosts_lie_conformal_algebra.py | 2 +- src/sage/algebras/orlik_terao.py | 8 +- .../algebras/steenrod/steenrod_algebra.py | 2 +- .../steenrod/steenrod_algebra_bases.py | 2 +- .../steenrod/steenrod_algebra_mult.py | 10 +- src/sage/arith/misc.py | 2 +- src/sage/arith/multi_modular.pyx | 4 +- src/sage/calculus/integration.pyx | 4 +- src/sage/calculus/ode.pxd | 4 +- src/sage/calculus/ode.pyx | 4 +- src/sage/calculus/riemann.pyx | 4 +- src/sage/calculus/tests.py | 2 +- src/sage/calculus/transforms/dwt.pyx | 4 +- src/sage/calculus/var.pyx | 2 +- src/sage/categories/category.py | 2 +- src/sage/categories/category_with_axiom.py | 2 +- src/sage/categories/classical_crystals.py | 4 +- src/sage/categories/crystals.py | 2 +- src/sage/categories/discrete_valuation.py | 4 +- ...distributive_magmas_and_additive_magmas.py | 2 +- src/sage/categories/fields.py | 2 +- .../finite_dimensional_modules_with_basis.py | 4 +- ...itely_generated_lambda_bracket_algebras.py | 2 +- src/sage/categories/group_algebras.py | 6 +- .../categories/magmas_and_additive_magmas.py | 2 +- src/sage/categories/modules_with_basis.py | 6 +- src/sage/categories/morphism.pyx | 2 +- src/sage/categories/regular_crystals.py | 10 +- src/sage/categories/semirings.py | 4 +- src/sage/categories/sets_cat.py | 4 +- src/sage/categories/supercrystals.py | 2 +- src/sage/coding/code_bounds.py | 8 +- src/sage/coding/code_constructions.py | 14 +- src/sage/coding/codecan/codecan.pyx | 2 +- src/sage/coding/guruswami_sudan/gs_decoder.py | 2 +- src/sage/coding/linear_code.py | 2 +- .../combinat/cluster_algebra_quiver/quiver.py | 2 +- src/sage/combinat/combination.py | 2 +- src/sage/combinat/crystals/fast_crystals.py | 2 +- .../fully_commutative_stable_grothendieck.py | 2 +- .../combinat/crystals/infinity_crystals.py | 2 +- src/sage/combinat/crystals/littelmann_path.py | 2 +- src/sage/combinat/crystals/star_crystal.py | 6 +- .../crystals/tensor_product_element.pyx | 2 +- src/sage/combinat/designs/bibd.py | 12 +- src/sage/combinat/designs/database.py | 6 +- src/sage/combinat/designs/designs_pyx.pyx | 14 +- .../combinat/designs/difference_family.py | 6 +- .../combinat/designs/difference_matrices.py | 2 +- .../designs/evenly_distributed_sets.pyx | 2 +- src/sage/combinat/designs/latin_squares.py | 4 +- .../combinat/designs/orthogonal_arrays.py | 32 +- .../orthogonal_arrays_build_recursive.py | 20 +- .../orthogonal_arrays_find_recursive.pyx | 24 +- src/sage/combinat/designs/resolvable_bibd.py | 10 +- .../designs/steiner_quadruple_systems.py | 2 +- .../combinat/designs/subhypergraph_search.pyx | 10 +- .../combinat/enumeration_mod_permgroup.pyx | 2 +- src/sage/combinat/gray_codes.py | 8 +- src/sage/combinat/k_tableau.py | 2 +- src/sage/combinat/knutson_tao_puzzles.py | 2 +- src/sage/combinat/misc.py | 2 +- .../multiset_partition_into_sets_ordered.py | 2 +- src/sage/combinat/ncsf_qsym/combinatorics.py | 4 +- src/sage/combinat/partition_tuple.py | 14 +- .../combinat/path_tableaux/path_tableau.py | 4 +- .../combinat/path_tableaux/semistandard.py | 2 +- .../combinat/root_system/ambient_space.py | 2 +- .../combinat/root_system/branching_rules.py | 2 +- .../root_system/extended_affine_weyl_group.py | 12 +- .../hecke_algebra_representation.py | 2 +- .../combinat/root_system/pieri_factors.py | 2 +- .../root_system/reflection_group_complex.py | 8 +- .../combinat/root_system/weyl_characters.py | 4 +- src/sage/combinat/sf/k_dual.py | 4 +- src/sage/combinat/sf/sf.py | 2 +- src/sage/combinat/sf/sfa.py | 2 +- src/sage/combinat/similarity_class_type.py | 2 +- src/sage/combinat/sloane_functions.py | 2 +- src/sage/combinat/subset.py | 4 +- src/sage/combinat/subsets_pairwise.py | 12 +- src/sage/combinat/tutorial.py | 2 +- src/sage/combinat/words/word_generators.py | 12 +- src/sage/crypto/boolean_function.pyx | 4 +- src/sage/crypto/stream.py | 4 +- src/sage/data_structures/bitset.pxd | 2 +- .../bounded_integer_sequences.pyx | 2 +- src/sage/databases/cremona.py | 2 +- src/sage/databases/findstat.py | 2 +- src/sage/databases/sql_db.py | 4 +- src/sage/doctest/sources.py | 2 +- .../arithmetic_dynamics/projective_ds.py | 4 +- .../dynamics/arithmetic_dynamics/wehlerK3.py | 6 +- src/sage/games/quantumino.py | 4 +- src/sage/geometry/cone.py | 2 +- src/sage/geometry/cone_catalog.py | 6 +- src/sage/geometry/cone_critical_angles.py | 2 +- .../double_description_inhomogeneous.py | 6 +- .../modules/formal_polyhedra_module.py | 6 +- .../parametrized_surface3d.py | 6 +- .../geometry/triangulation/triangulations.cc | 4 +- src/sage/graphs/base/static_dense_graph.pxd | 2 +- src/sage/graphs/convexity_properties.pxd | 2 +- src/sage/graphs/generic_graph_pyx.pyx | 2 +- src/sage/graphs/strongly_regular_db.pyx | 2 +- src/sage/groups/group_semidirect_product.py | 24 +- src/sage/groups/matrix_gps/isometries.py | 2 +- .../perm_gps/partn_ref/data_structures.pyx | 2 +- .../perm_gps/partn_ref/refinement_python.pyx | 20 +- src/sage/interfaces/mathematica.py | 2 +- src/sage/interfaces/mathics.py | 2 +- src/sage/interfaces/maxima.py | 8 +- src/sage/interfaces/tides.py | 2 +- src/sage/libs/gap/element.pyx | 2 +- src/sage/libs/giac/__init__.py | 2 +- src/sage/libs/giac/auto-methods.pxi | 5836 ++++++++--------- src/sage/libs/giac/giac.pyx | 24 +- src/sage/libs/gsl/array.pyx | 2 +- src/sage/libs/gsl/errno.pxd | 4 +- src/sage/libs/lcalc/lcalc_Lfunction.pxd | 6 +- src/sage/libs/lcalc/lcalc_Lfunction.pyx | 26 +- .../libs/linkages/padics/unram_shared.pxi | 4 +- src/sage/libs/mpmath/utils.pyx | 2 +- src/sage/libs/ntl/ntl_GF2X.pyx | 2 +- src/sage/libs/ntl/ntl_ZZ_pE.pyx | 2 +- src/sage/libs/ntl/ntl_ZZ_pEContext.pyx | 6 +- src/sage/libs/ntl/ntl_ZZ_pEX.pyx | 6 +- src/sage/libs/ntl/ntl_mat_GF2.pyx | 2 +- src/sage/libs/ntl/ntl_mat_GF2E.pyx | 4 +- src/sage/libs/ntl/ntlwrap_impl.h | 4 +- src/sage/libs/singular/decl.pxd | 2 +- src/sage/libs/singular/function.pxd | 2 +- src/sage/libs/singular/function.pyx | 6 +- src/sage/libs/singular/polynomial.pyx | 4 +- src/sage/libs/singular/singular.pxd | 4 +- .../differentiable/affine_connection.py | 2 +- .../differentiable/integrated_curve.py | 2 +- .../differentiable/levi_civita_connection.py | 2 +- src/sage/manifolds/differentiable/metric.py | 2 +- .../differentiable/vectorfield_module.py | 2 +- src/sage/matrix/benchmark.py | 4 +- src/sage/matrix/matrix0.pyx | 2 +- src/sage/matrix/matrix_double_dense.pyx | 12 +- src/sage/matrix/matrix_gf2e_dense.pyx | 2 +- src/sage/matrix/matrix_integer_dense.pyx | 10 +- .../matrix/matrix_modn_dense_template.pxi | 4 +- src/sage/matrix/matrix_polynomial_dense.pyx | 4 +- src/sage/matrix/matrix_rational_dense.pyx | 2 +- src/sage/matrix/matrix_sparse.pyx | 2 +- src/sage/matrix/misc.pyx | 4 +- src/sage/matrix/special.py | 2 +- src/sage/matrix/strassen.pyx | 2 +- src/sage/matroids/lean_matrix.pyx | 6 +- src/sage/matroids/linear_matroid.pyx | 10 +- src/sage/matroids/matroid.pxd | 6 +- src/sage/matroids/matroid.pyx | 6 +- src/sage/misc/binary_tree.pyx | 2 +- src/sage/misc/c3.pyx | 2 +- src/sage/misc/c3_controlled.pyx | 2 +- src/sage/misc/cachefunc.pyx | 40 +- src/sage/misc/decorators.py | 6 +- src/sage/misc/fpickle.pyx | 4 +- src/sage/misc/function_mangling.pyx | 16 +- src/sage/misc/parser.pyx | 2 +- src/sage/misc/persist.pyx | 6 +- src/sage/misc/sageinspect.py | 24 +- .../modular/arithgroup/arithgroup_perm.py | 12 +- src/sage/modular/arithgroup/congroup_gamma.py | 4 +- .../modular/arithgroup/congroup_gamma0.py | 2 +- .../modular/arithgroup/congroup_gamma1.py | 2 +- .../modular/arithgroup/congroup_generic.py | 4 +- src/sage/modular/arithgroup/congroup_sl2z.py | 2 +- .../modular/btquotients/pautomorphicform.py | 8 +- src/sage/modular/hecke/module.py | 2 +- src/sage/modular/local_comp/local_comp.py | 2 +- src/sage/modular/modform/ambient_R.py | 2 +- src/sage/modular/modsym/manin_symbol.pyx | 2 +- .../modular/overconvergent/hecke_series.py | 6 +- src/sage/modular/pollack_stevens/modsym.py | 2 +- src/sage/modules/free_module_element.pyx | 8 +- src/sage/modules/vector_integer_dense.pyx | 2 +- src/sage/modules/vector_numpy_dense.pyx | 2 +- src/sage/modules/with_basis/invariant.py | 24 +- src/sage/modules/with_basis/morphism.py | 8 +- src/sage/monoids/automatic_semigroup.py | 4 +- .../numerical/backends/cvxopt_backend.pyx | 10 +- src/sage/numerical/backends/glpk_backend.pyx | 4 +- .../numerical/backends/glpk_exact_backend.pyx | 2 +- .../numerical/backends/glpk_graph_backend.pxd | 2 +- .../numerical/backends/glpk_graph_backend.pyx | 2 +- .../backends/interactivelp_backend.pyx | 2 +- src/sage/numerical/backends/ppl_backend.pyx | 2 +- src/sage/numerical/mip.pyx | 18 +- src/sage/numerical/optimize.py | 2 +- src/sage/numerical/sdp.pyx | 4 +- src/sage/parallel/decorate.py | 6 +- src/sage/parallel/reference.py | 2 +- src/sage/plot/animate.py | 2 +- src/sage/plot/contour_plot.py | 48 +- src/sage/plot/density_plot.py | 4 +- src/sage/plot/matrix_plot.py | 2 +- src/sage/plot/plot.py | 4 +- src/sage/plot/plot3d/index_face_set.pyx | 20 +- src/sage/plot/plot3d/parametric_plot3d.py | 16 +- src/sage/plot/plot3d/parametric_surface.pyx | 44 +- src/sage/plot/plot3d/plot3d.py | 18 +- src/sage/plot/plot3d/revolution_plot3d.py | 4 +- src/sage/plot/plot3d/tachyon.py | 12 +- src/sage/plot/plot3d/tri_plot.py | 10 +- .../quadratic_form__ternary_Tornaria.py | 2 +- src/sage/rings/bernmm.pyx | 2 +- src/sage/rings/complex_double.pyx | 2 +- src/sage/rings/complex_interval.pyx | 2 +- src/sage/rings/finite_rings/element_base.pyx | 8 +- .../rings/finite_rings/finite_field_base.pyx | 2 +- src/sage/rings/finite_rings/integer_mod.pyx | 2 +- src/sage/rings/finite_rings/residue_field.pyx | 2 +- src/sage/rings/fraction_field_element.pyx | 2 +- src/sage/rings/function_field/constructor.py | 6 +- src/sage/rings/function_field/divisor.py | 2 +- .../rings/function_field/order_polymod.py | 2 +- src/sage/rings/integer.pxd | 4 +- src/sage/rings/integer.pyx | 14 +- src/sage/rings/integer_ring.pyx | 4 +- src/sage/rings/invariants/invariant_theory.py | 4 +- src/sage/rings/multi_power_series_ring.py | 8 +- .../rings/multi_power_series_ring_element.py | 4 +- src/sage/rings/number_field/selmer_group.py | 2 +- src/sage/rings/padics/CA_template.pxi | 2 +- src/sage/rings/padics/CR_template.pxi | 2 +- src/sage/rings/padics/FM_template.pxi | 2 +- src/sage/rings/padics/FP_template.pxi | 2 +- .../rings/padics/local_generic_element.pyx | 4 +- src/sage/rings/padics/morphism.pyx | 4 +- .../rings/padics/padic_ZZ_pX_CA_element.pyx | 10 +- .../rings/padics/padic_ZZ_pX_CR_element.pyx | 16 +- .../rings/padics/padic_ZZ_pX_FM_element.pyx | 8 +- src/sage/rings/padics/padic_ZZ_pX_element.pyx | 4 +- .../rings/padics/padic_extension_generic.py | 4 +- src/sage/rings/padics/padic_generic.py | 2 +- .../rings/padics/padic_generic_element.pyx | 8 +- src/sage/rings/padics/padic_printing.pyx | 16 +- .../rings/padics/padic_template_element.pxi | 4 +- src/sage/rings/padics/pow_computer.pyx | 2 +- src/sage/rings/padics/pow_computer_ext.pyx | 18 +- src/sage/rings/padics/pow_computer_flint.pyx | 2 +- .../rings/polynomial/multi_polynomial.pyx | 4 +- .../polynomial/multi_polynomial_element.py | 4 +- .../polynomial/multi_polynomial_ideal.py | 6 +- .../multi_polynomial_libsingular.pyx | 14 +- .../polynomial/multi_polynomial_ring_base.pyx | 8 +- .../polynomial/multi_polynomial_sequence.py | 2 +- src/sage/rings/polynomial/plural.pyx | 10 +- .../rings/polynomial/polynomial_element.pyx | 12 +- .../polynomial/polynomial_rational_flint.pyx | 2 +- src/sage/rings/polynomial/real_roots.pyx | 2 +- .../skew_polynomial_finite_field.pyx | 2 +- .../skew_polynomial_finite_order.pyx | 2 +- src/sage/rings/polynomial/term_order.py | 28 +- src/sage/rings/power_series_poly.pyx | 2 +- src/sage/rings/power_series_ring_element.pyx | 4 +- src/sage/rings/quotient_ring.py | 4 +- src/sage/rings/ring.pyx | 2 +- src/sage/rings/ring_extension_element.pyx | 8 +- src/sage/schemes/elliptic_curves/cm.py | 2 +- .../schemes/elliptic_curves/constructor.py | 2 +- .../elliptic_curves/ell_number_field.py | 4 +- src/sage/schemes/elliptic_curves/ell_point.py | 2 +- .../elliptic_curves/ell_rational_field.py | 6 +- src/sage/schemes/elliptic_curves/ell_wp.py | 2 +- src/sage/schemes/elliptic_curves/gal_reps.py | 20 +- .../elliptic_curves/gal_reps_number_field.py | 4 +- src/sage/schemes/elliptic_curves/heegner.py | 6 +- src/sage/schemes/elliptic_curves/kraus.py | 2 +- .../schemes/elliptic_curves/padic_lseries.py | 6 +- src/sage/schemes/generic/divisor.py | 2 +- src/sage/schemes/generic/morphism.py | 2 +- .../hyperelliptic_curves/jacobian_morphism.py | 6 +- .../schemes/projective/projective_point.py | 2 +- src/sage/schemes/toric/divisor.py | 4 +- src/sage/sets/set_from_iterator.py | 4 +- src/sage/stats/time_series.pyx | 4 +- src/sage/structure/category_object.pyx | 4 +- src/sage/structure/element.pyx | 2 +- src/sage/structure/parent_base.pyx | 2 +- src/sage/structure/unique_representation.py | 8 +- src/sage/symbolic/benchmark.py | 4 +- src/sage/symbolic/expression.pyx | 6 +- src/sage/symbolic/function.pyx | 2 +- src/sage/symbolic/function_factory.py | 2 +- src/sage/symbolic/ring.pyx | 4 +- .../tensor/modules/tensor_with_indices.py | 2 +- .../book_schilling_zabrocki_kschur_primer.py | 4 +- src/sage/tests/book_stein_ent.py | 8 +- .../combinat_doctest.py | 2 +- .../float_doctest.py | 12 +- .../graphique_doctest.py | 2 +- .../integration_doctest.py | 4 +- .../linsolve_doctest.py | 10 +- .../numbertheory_doctest.py | 2 +- .../recequadiff_doctest.py | 4 +- .../sol/float_doctest.py | 2 +- .../sol/graphique_doctest.py | 4 +- .../sol/graphtheory_doctest.py | 6 +- .../sol/nonlinear_doctest.py | 2 +- .../sol/numbertheory_doctest.py | 2 +- 306 files changed, 3761 insertions(+), 3761 deletions(-) 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 004718d4a5f..6c4418e4751 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 @@ -72,7 +72,7 @@ class FermionicGhostsLieConformalAlgebra(GradedLieConformalAlgebra): sage: R.structure_coefficients() Finite family {('a', 'c'): ((0, K),), ('b', 'd'): ((0, K),), ('c', 'a'): ((0, K),), ('d', 'b'): ((0, K),)} """ - def __init__(self,R,ngens=2,names=None,index_set=None): + def __init__(self, R, ngens=2, names=None, index_set=None): """ Initialize ``self``. diff --git a/src/sage/algebras/orlik_terao.py b/src/sage/algebras/orlik_terao.py index 60c3c60e6db..26b3c49b443 100644 --- a/src/sage/algebras/orlik_terao.py +++ b/src/sage/algebras/orlik_terao.py @@ -557,7 +557,7 @@ class OrlikTeraoInvariantAlgebra(FiniteDimensionalInvariantModule): defines the action we want, but since the groundset is `\{0,1,2\}` we first add `1` and then subtract `1`:: - sage: def on_groundset(g,x): + sage: def on_groundset(g, x): ....: return g(x+1)-1 Now that we have defined an action we can create the invariant, and @@ -625,7 +625,7 @@ def __init__(self, R, M, G, action_on_groundset=None, *args, **kwargs): ....: [0,0,-1,0,-1,-1]]) sage: M = Matroid(A); sage: G = SymmetricGroup(6) - sage: def on_groundset(g,x): return g(x+1)-1 + sage: def on_groundset(g, x): return g(x+1)-1 sage: import __main__; __main__.on_groundset = on_groundset sage: OTG = M.orlik_terao_algebra(QQ, invariant = (G,on_groundset)) sage: TestSuite(OTG).run() @@ -687,7 +687,7 @@ def construction(self): sage: A = matrix([[1,1,0],[-1,0,1],[0,-1,-1]]) sage: M = Matroid(A) sage: G = SymmetricGroup(3) - sage: def on_groundset(g,x): + sage: def on_groundset(g, x): ....: return g(x+1)-1 sage: OTG = M.orlik_terao_algebra(QQ, invariant=(G,on_groundset)) sage: OTG.construction() is None @@ -718,7 +718,7 @@ def _basis_action(self, g, f): sage: M.groundset() frozenset({0, 1, 2}) sage: G = SymmetricGroup(3) - sage: def on_groundset(g,x): + sage: def on_groundset(g, x): ....: return g(x+1)-1 sage: OTG = M.orlik_terao_algebra(QQ, invariant=(G,on_groundset)) sage: def act(g): diff --git a/src/sage/algebras/steenrod/steenrod_algebra.py b/src/sage/algebras/steenrod/steenrod_algebra.py index 7e4c3dc014f..540cb6ee92d 100644 --- a/src/sage/algebras/steenrod/steenrod_algebra.py +++ b/src/sage/algebras/steenrod/steenrod_algebra.py @@ -2533,7 +2533,7 @@ def an_element(self): return self.monomial(((1, 2),)) return self.term(((), (((1,2), 1),)), GF(p)(p-1)) - def pst(self,s,t): + def pst(self, s, t): r""" The Margolis element `P^s_t`. diff --git a/src/sage/algebras/steenrod/steenrod_algebra_bases.py b/src/sage/algebras/steenrod/steenrod_algebra_bases.py index 06f9a5b87ad..9d37290ef3e 100644 --- a/src/sage/algebras/steenrod/steenrod_algebra_bases.py +++ b/src/sage/algebras/steenrod/steenrod_algebra_bases.py @@ -887,7 +887,7 @@ def degree_dictionary(n, basis): deg = 2**s * (2**t - 1) return dict - def sorting_pair(s,t,basis): # pair used for sorting the basis + def sorting_pair(s, t, basis): # pair used for sorting the basis if basis.find('wood') >= 0 and basis.find('z') >= 0: return (-s-t,-s) elif basis.find('wood') >= 0 or basis.find('wall') >= 0 or \ diff --git a/src/sage/algebras/steenrod/steenrod_algebra_mult.py b/src/sage/algebras/steenrod/steenrod_algebra_mult.py index 053290bc5ed..c3ae7c181f9 100644 --- a/src/sage/algebras/steenrod/steenrod_algebra_mult.py +++ b/src/sage/algebras/steenrod/steenrod_algebra_mult.py @@ -204,7 +204,7 @@ # Milnor, p=2 -def milnor_multiplication(r,s): +def milnor_multiplication(r, s): r""" Product of Milnor basis elements r and s at the prime 2. @@ -372,7 +372,7 @@ def multinomial(list): # Milnor, p odd -def milnor_multiplication_odd(m1,m2,p): +def milnor_multiplication_odd(m1, m2, p): r""" Product of Milnor basis elements defined by m1 and m2 at the odd prime p. @@ -568,7 +568,7 @@ def milnor_multiplication_odd(m1,m2,p): return result -def multinomial_odd(list,p): +def multinomial_odd(list, p): r""" Multinomial coefficient of list, mod p. @@ -635,7 +635,7 @@ def multinomial_odd(list,p): # Adem relations, Serre-Cartan basis, admissible sequences -def binomial_mod2(n,k): +def binomial_mod2(n, k): r""" The binomial coefficient `\binom{n}{k}`, computed mod 2. @@ -665,7 +665,7 @@ def binomial_mod2(n,k): return 0 -def binomial_modp(n,k,p): +def binomial_modp(n, k, p): r""" The binomial coefficient `\binom{n}{k}`, computed mod `p`. diff --git a/src/sage/arith/misc.py b/src/sage/arith/misc.py index 745d5fcbbe7..14fe466ccd9 100644 --- a/src/sage/arith/misc.py +++ b/src/sage/arith/misc.py @@ -4171,7 +4171,7 @@ def multinomial_coefficients(m, n): return r -def kronecker_symbol(x,y): +def kronecker_symbol(x, y): """ The Kronecker symbol `(x|y)`. diff --git a/src/sage/arith/multi_modular.pyx b/src/sage/arith/multi_modular.pyx index 1d5e9a46221..6488eb22761 100644 --- a/src/sage/arith/multi_modular.pyx +++ b/src/sage/arith/multi_modular.pyx @@ -196,11 +196,11 @@ cdef class MultiModularBasis_base(): while True: if len(known_primes) >= self._num_primes: raise RuntimeError("there are not enough primes in the interval [%s, %s] to complete this multimodular computation" % (self._l_bound, self._u_bound)) - p = random_prime(self._u_bound, lbound =self._l_bound) + p = random_prime(self._u_bound, lbound=self._l_bound) if p not in known_primes: return p - def extend_with_primes(self, plist, partial_products = None, check=True): + def extend_with_primes(self, plist, partial_products=None, check=True): """ Extend the stored list of moduli with the given primes in ``plist``. diff --git a/src/sage/calculus/integration.pyx b/src/sage/calculus/integration.pyx index f746f8aa04a..179e5751894 100644 --- a/src/sage/calculus/integration.pyx +++ b/src/sage/calculus/integration.pyx @@ -498,7 +498,7 @@ def monte_carlo_integral(func, xl, xu, size_t calls, algorithm='plain', (4.0, 0.0) sage: monte_carlo_integral(lambda u,v: u*v, [0,0], [2,2], 10000) # abs tol 0.1 (4.0, 0.0) - sage: def f(x1,x2,x3,x4): return x1*x2*x3*x4 + sage: def f(x1, x2, x3, x4): return x1*x2*x3*x4 sage: monte_carlo_integral(f, [0,0], [2,2], 1000, params=[0.6,2]) # abs tol 0.2 (4.8, 0.0) @@ -522,7 +522,7 @@ def monte_carlo_integral(func, xl, xu, size_t calls, algorithm='plain', ValueError: The function to be integrated depends on 2 variables (x, y), and so cannot be integrated in 3 dimensions. Please fix additional variables with the 'params' argument - sage: def f(x,y): return x*y + sage: def f(x, y): return x*y sage: monte_carlo_integral(f, [0,0,0], [2,2,2], 100) Traceback (most recent call last): ... diff --git a/src/sage/calculus/ode.pxd b/src/sage/calculus/ode.pxd index 2de37b91764..fad66432a9e 100644 --- a/src/sage/calculus/ode.pxd +++ b/src/sage/calculus/ode.pxd @@ -1,4 +1,4 @@ cdef class ode_system: - cdef int c_j(self,double , double *, double *,double *) noexcept + cdef int c_j(self, double , double *, double *, double *) noexcept - cdef int c_f(self,double t, double* , double* ) noexcept + cdef int c_f(self, double t, double* , double* ) noexcept diff --git a/src/sage/calculus/ode.pyx b/src/sage/calculus/ode.pyx index 646b937e2e4..2addf3e7f81 100644 --- a/src/sage/calculus/ode.pyx +++ b/src/sage/calculus/ode.pyx @@ -313,11 +313,11 @@ class ode_solver(): from sage.libs.gsl.all cimport * cdef class van_der_pol(sage.calculus.ode.ode_system): - cdef int c_f(self,double t, double *y,double *dydt): + cdef int c_f(self, double t, double *y, double *dydt): dydt[0]=y[1] dydt[1]=-y[0]-1000*y[1]*(y[0]*y[0]-1) return GSL_SUCCESS - cdef int c_j(self, double t,double *y,double *dfdy,double *dfdt): + cdef int c_j(self, double t, double *y, double *dfdy, double *dfdt): dfdy[0]=0 dfdy[1]=1.0 dfdy[2]=-2.0*1000*y[0]*y[1]-1.0 diff --git a/src/sage/calculus/riemann.pyx b/src/sage/calculus/riemann.pyx index 385aa7a09f8..455567371eb 100644 --- a/src/sage/calculus/riemann.pyx +++ b/src/sage/calculus/riemann.pyx @@ -65,7 +65,7 @@ ctypedef np.complex128_t COMPLEX_T cdef FLOAT_T PI = pi cdef FLOAT_T TWOPI = 2*PI -cdef COMPLEX_T I = complex(0,1) +cdef COMPLEX_T I = complex(0, 1) cdef class Riemann_Map: r""" @@ -1263,7 +1263,7 @@ cpdef complex_to_spiderweb(np.ndarray[COMPLEX_T, ndim = 2] z_values, return rgb -cpdef complex_to_rgb(np.ndarray[COMPLEX_T, ndim = 2] z_values): +cpdef complex_to_rgb(np.ndarray[COMPLEX_T, ndim=2] z_values): r""" Convert from a (Numpy) array of complex numbers to its corresponding matrix of RGB values. For internal use of :meth:`~Riemann_Map.plot_colored` diff --git a/src/sage/calculus/tests.py b/src/sage/calculus/tests.py index ac76b5e4f70..2879dda115d 100644 --- a/src/sage/calculus/tests.py +++ b/src/sage/calculus/tests.py @@ -16,7 +16,7 @@ :: - sage: def christoffel(i,j,k,vars,g): + sage: def christoffel(i, j, k, vars, g): ....: s = 0 ....: ginv = g^(-1) ....: for l in range(g.nrows()): diff --git a/src/sage/calculus/transforms/dwt.pyx b/src/sage/calculus/transforms/dwt.pyx index fdb68153a8b..c004b00715c 100644 --- a/src/sage/calculus/transforms/dwt.pyx +++ b/src/sage/calculus/transforms/dwt.pyx @@ -103,11 +103,11 @@ cdef class DiscreteWaveletTransform(GSLDoubleArray): """ Discrete wavelet transform class. """ - def __cinit__(self,size_t n,size_t stride, wavelet_type, size_t wavelet_k): + def __cinit__(self, size_t n, size_t stride, wavelet_type, size_t wavelet_k): self.wavelet = NULL self.workspace = NULL - def __init__(self,size_t n,size_t stride, wavelet_type, size_t wavelet_k): + def __init__(self, size_t n, size_t stride, wavelet_type, size_t wavelet_k): if not is2pow(n): raise NotImplementedError("discrete wavelet transform only implemented when n is a 2-power") GSLDoubleArray.__init__(self,n,stride) diff --git a/src/sage/calculus/var.pyx b/src/sage/calculus/var.pyx index 4967bb9bd9a..853c5c493ff 100644 --- a/src/sage/calculus/var.pyx +++ b/src/sage/calculus/var.pyx @@ -255,7 +255,7 @@ def function(s, **kwds): sage: foo(x).conjugate() 2*x - sage: def deriv(self, *args,**kwds): print("{} {}".format(args, kwds)); return args[kwds['diff_param']]^2 + sage: def deriv(self, *args, **kwds): print("{} {}".format(args, kwds)); return args[kwds['diff_param']]^2 sage: foo = function("foo", nargs=2, derivative_func=deriv) sage: foo(x,y).derivative(y) (x, y) {'diff_param': 1} diff --git a/src/sage/categories/category.py b/src/sage/categories/category.py index b534f7be794..feb1b2cb393 100644 --- a/src/sage/categories/category.py +++ b/src/sage/categories/category.py @@ -173,7 +173,7 @@ class Category(UniqueRepresentation, SageObject): ....: pass ....: ....: class ElementMethods:# holds the generic operations on elements - ....: def gcd(x,y): + ....: def gcd(x, y): ....: # Euclid algorithms ....: pass ....: diff --git a/src/sage/categories/category_with_axiom.py b/src/sage/categories/category_with_axiom.py index 766ec9b64cb..014ac68d369 100644 --- a/src/sage/categories/category_with_axiom.py +++ b/src/sage/categories/category_with_axiom.py @@ -1695,7 +1695,7 @@ class ``Sets.Finite``), or in a separate file (typically in a class ) -def uncamelcase(s,separator=" "): +def uncamelcase(s, separator=" "): """ EXAMPLES:: diff --git a/src/sage/categories/classical_crystals.py b/src/sage/categories/classical_crystals.py index 42dc02bdb2f..b8b05f17b55 100644 --- a/src/sage/categories/classical_crystals.py +++ b/src/sage/categories/classical_crystals.py @@ -328,11 +328,11 @@ def __iter__(self): sage: fb4 = lambda a,b,c,d: crystals.Tableaux(['B',4],shape=[a+b+c+d,b+c+d,c+d,d]) sage: fd4 = lambda a,b,c,d: crystals.Tableaux(['D',4],shape=[a+b+c+d,b+c+d,c+d,d]) sage: fd5 = lambda a,b,c,d,e: crystals.Tableaux(['D',5],shape=[a+b+c+d+e,b+c+d+e,c+d+e,d+e,e]) - sage: def fd4spinplus(a,b,c,d): + sage: def fd4spinplus(a, b, c, d): ....: C = crystals.Tableaux(['D',4],shape=[a+b+c+d,b+c+d,c+d,d]) ....: D = crystals.SpinsPlus(['D',4]) ....: return crystals.TensorProduct(C,D,generators=[[C[0],D[0]]]) - sage: def fb3spin(a,b,c): + sage: def fb3spin(a, b, c): ....: C = crystals.Tableaux(['B',3],shape=[a+b+c,b+c,c]) ....: D = crystals.Spins(['B',3]) ....: return crystals.TensorProduct(C,D,generators=[[C[0],D[0]]]) diff --git a/src/sage/categories/crystals.py b/src/sage/categories/crystals.py index c822bbd50fc..ddcdf6bb44d 100644 --- a/src/sage/categories/crystals.py +++ b/src/sage/categories/crystals.py @@ -1177,7 +1177,7 @@ def plot(self, **options): sage: print(C.plot()) Graphics object consisting of 17 graphics primitives """ - return self.digraph().plot(edge_labels=True,vertex_size=0,**options) + return self.digraph().plot(edge_labels=True, vertex_size=0, **options) def plot3d(self, **options): """ diff --git a/src/sage/categories/discrete_valuation.py b/src/sage/categories/discrete_valuation.py index 77267664bb2..39ed8ae8148 100644 --- a/src/sage/categories/discrete_valuation.py +++ b/src/sage/categories/discrete_valuation.py @@ -196,7 +196,7 @@ def is_unit(self): """ return self.valuation() == 0 - def gcd(self,other): + def gcd(self, other): """ Return the greatest common divisor of ``self`` and ``other``, normalized so that it is a power of the distinguished @@ -209,7 +209,7 @@ def gcd(self,other): else: return self.parent().uniformizer() ** val - def lcm(self,other): + def lcm(self, other): """ Return the least common multiple of ``self`` and ``other``, normalized so that it is a power of the distinguished diff --git a/src/sage/categories/distributive_magmas_and_additive_magmas.py b/src/sage/categories/distributive_magmas_and_additive_magmas.py index 830c6c77c8c..cd736a5d15c 100644 --- a/src/sage/categories/distributive_magmas_and_additive_magmas.py +++ b/src/sage/categories/distributive_magmas_and_additive_magmas.py @@ -16,7 +16,7 @@ class DistributiveMagmasAndAdditiveMagmas(CategoryWithAxiom): """ - The category of sets `(S,+,*)` with `*` distributing on `+`. + The category of sets `(S, +, *)` with `*` distributing on `+`. This is similar to a ring, but `+` and `*` are only required to be (additive) magmas. diff --git a/src/sage/categories/fields.py b/src/sage/categories/fields.py index dafa795f94f..61e8d138c58 100644 --- a/src/sage/categories/fields.py +++ b/src/sage/categories/fields.py @@ -602,7 +602,7 @@ def is_unit( self ): # Of course, in general gcd and lcm in a field are not very interesting. # However, they should be implemented! @coerce_binop - def gcd(self,other): + def gcd(self, other): """ Greatest common divisor. diff --git a/src/sage/categories/finite_dimensional_modules_with_basis.py b/src/sage/categories/finite_dimensional_modules_with_basis.py index ee5b6490346..4b91c642074 100644 --- a/src/sage/categories/finite_dimensional_modules_with_basis.py +++ b/src/sage/categories/finite_dimensional_modules_with_basis.py @@ -212,7 +212,7 @@ def annihilator_basis(self, S, action=operator.mul, side='right'): sage: # needs sage.graphs sage.modules sage: x,y,a,b = F.basis() - sage: def scalar(u,v): + sage: def scalar(u, v): ....: return vector([sum(u[i]*v[i] for i in F.basis().keys())]) sage: F.annihilator_basis([x + y, a + b], scalar) (x - y, a - b) @@ -496,7 +496,7 @@ def twisted_invariant_module(self, G, chi, sage: # needs sage.combinat sage.groups sage.modules sage: M = CombinatorialFreeModule(QQ, [1,2,3]) sage: G = SymmetricGroup(3) - sage: def action(g,x): return(M.term(g(x))) # permute coordinates + sage: def action(g, x): return(M.term(g(x))) # permute coordinates sage: T = M.twisted_invariant_module(G, [2,0,-1], ....: action_on_basis=action) sage: import __main__; __main__.action = action diff --git a/src/sage/categories/finitely_generated_lambda_bracket_algebras.py b/src/sage/categories/finitely_generated_lambda_bracket_algebras.py index 7d028630658..4a7ca22d50f 100644 --- a/src/sage/categories/finitely_generated_lambda_bracket_algebras.py +++ b/src/sage/categories/finitely_generated_lambda_bracket_algebras.py @@ -51,7 +51,7 @@ def ngens(self): """ return len(self.gens()) - def gen(self,i): + def gen(self, i): r""" The ``i``-th generator of this Lie conformal algebra. diff --git a/src/sage/categories/group_algebras.py b/src/sage/categories/group_algebras.py index e83de9263d3..72f3dd7251b 100644 --- a/src/sage/categories/group_algebras.py +++ b/src/sage/categories/group_algebras.py @@ -238,7 +238,7 @@ def coproduct_on_basis(self, g): g = self.term(g) return tensor([g, g]) - def antipode_on_basis(self,g): + def antipode_on_basis(self, g): r""" Return the antipode of the element ``g`` of the basis. @@ -263,7 +263,7 @@ def antipode_on_basis(self,g): """ return self.term(~g) - def counit_on_basis(self,g): + def counit_on_basis(self, g): r""" Return the counit of the element ``g`` of the basis. @@ -283,7 +283,7 @@ def counit_on_basis(self,g): """ return self.base_ring().one() - def counit(self,x): + def counit(self, x): r""" Return the counit of the element ``x`` of the group algebra. diff --git a/src/sage/categories/magmas_and_additive_magmas.py b/src/sage/categories/magmas_and_additive_magmas.py index 4b612606aee..24a6955abac 100644 --- a/src/sage/categories/magmas_and_additive_magmas.py +++ b/src/sage/categories/magmas_and_additive_magmas.py @@ -19,7 +19,7 @@ class MagmasAndAdditiveMagmas(Category_singleton): """ - The category of sets `(S,+,*)` with an additive operation '+' and + The category of sets `(S, +, *)` with an additive operation '+' and a multiplicative operation `*` EXAMPLES:: diff --git a/src/sage/categories/modules_with_basis.py b/src/sage/categories/modules_with_basis.py index 7b51d82c7ba..489f2f97dbb 100644 --- a/src/sage/categories/modules_with_basis.py +++ b/src/sage/categories/modules_with_basis.py @@ -1395,7 +1395,7 @@ def random_element(self, n=2): we can find a random element in a trivial module:: sage: class Foo(CombinatorialFreeModule): # needs sage.modules - ....: def _element_constructor_(self,x): + ....: def _element_constructor_(self, x): ....: if x in self: ....: return x ....: else: @@ -2535,7 +2535,7 @@ def apply_multilinear_morphism(self, f, codomain=None): and `f` the bilinear morphism `(a,b) \mapsto b \otimes a` from `A \times B` to `B \otimes A`:: - sage: def f(a,b): + sage: def f(a, b): ....: return tensor([b,a]) Now, calling applying `f` on `a \otimes b` returns the same @@ -2564,7 +2564,7 @@ def apply_multilinear_morphism(self, f, codomain=None): Mind the `0` in the sums above; otherwise `f` would not return `0` in `\ZZ`:: - sage: def f(a,b): + sage: def f(a, b): ....: return sum(a.coefficients()) * sum(b.coefficients()) sage: type(f(A.zero(), B.zero())) # needs sage.modules <... 'int'> diff --git a/src/sage/categories/morphism.pyx b/src/sage/categories/morphism.pyx index 34bcd1ca5f5..28e89a36299 100644 --- a/src/sage/categories/morphism.pyx +++ b/src/sage/categories/morphism.pyx @@ -619,7 +619,7 @@ cdef class SetMorphism(Morphism): sage: from sage.categories.morphism import SetMorphism sage: R. = QQ[] - sage: def foo(x,*args,**kwds): + sage: def foo(x, *args, **kwds): ....: print('foo called with {} {}'.format(args, kwds)) ....: return x sage: f = SetMorphism(Hom(R,R,Rings()), foo) diff --git a/src/sage/categories/regular_crystals.py b/src/sage/categories/regular_crystals.py index 506be6ba4ec..0459c0e0695 100644 --- a/src/sage/categories/regular_crystals.py +++ b/src/sage/categories/regular_crystals.py @@ -587,7 +587,7 @@ def demazure_operator_simple(self, i, ring=None): l.append(element) return - C.sum_of_monomials(l) - def stembridgeDelta_depth(self,i,j): + def stembridgeDelta_depth(self, i, j): r""" Return the difference in the `j`-depth of ``self`` and `e_i` of ``self``, where `i` and `j` are in the index set of the @@ -610,7 +610,7 @@ def stembridgeDelta_depth(self,i,j): return 0 return -self.e(i).epsilon(j) + self.epsilon(j) - def stembridgeDelta_rise(self,i,j): + def stembridgeDelta_rise(self, i, j): r""" Return the difference in the `j`-rise of ``self`` and `e_i` of ``self``, where `i` and `j` are in the index set of the @@ -633,7 +633,7 @@ def stembridgeDelta_rise(self,i,j): return 0 return self.e(i).phi(j) - self.phi(j) - def stembridgeDel_depth(self,i,j): + def stembridgeDel_depth(self, i, j): r""" Return the difference in the `j`-depth of ``self`` and `f_i` of ``self``, where `i` and `j` are in the index set of the @@ -656,7 +656,7 @@ def stembridgeDel_depth(self,i,j): return 0 return -self.epsilon(j) + self.f(i).epsilon(j) - def stembridgeDel_rise(self,i,j): + def stembridgeDel_rise(self, i, j): r""" Return the difference in the `j`-rise of ``self`` and `f_i` of ``self``, where `i` and `j` are in the index set of the @@ -679,7 +679,7 @@ def stembridgeDel_rise(self,i,j): return 0 return self.phi(j)-self.f(i).phi(j) - def stembridgeTriple(self,i,j): + def stembridgeTriple(self, i, j): r""" Let `A` be the Cartan matrix of the crystal, `x` a crystal element, and let `i` and `j` be in the index set of the crystal. diff --git a/src/sage/categories/semirings.py b/src/sage/categories/semirings.py index 624a867608a..6ba7dbec342 100644 --- a/src/sage/categories/semirings.py +++ b/src/sage/categories/semirings.py @@ -17,10 +17,10 @@ class Semirings(CategoryWithAxiom): """ The category of semirings. - A semiring `(S,+,*)` is similar to a ring, but without the + A semiring `(S, +, *)` is similar to a ring, but without the requirement that each element must have an additive inverse. In other words, it is a combination of a commutative additive monoid - `(S,+)` and a multiplicative monoid `(S,*)`, where `*` distributes + `(S, +)` and a multiplicative monoid `(S, *)`, where `*` distributes over `+`. .. SEEALSO:: diff --git a/src/sage/categories/sets_cat.py b/src/sage/categories/sets_cat.py index 9d63ac2fa30..ba13c6bc9a4 100644 --- a/src/sage/categories/sets_cat.py +++ b/src/sage/categories/sets_cat.py @@ -1750,8 +1750,8 @@ def _sympy_(self): class ElementMethods: ## Should eventually contain the basic operations which are no math ## latex, hash, ... - ##def equal(x,y): - ##def =(x,y): + ##def equal(x, y): + ##def =(x, y): # Used by Element._test_category _dummy_attribute = None diff --git a/src/sage/categories/supercrystals.py b/src/sage/categories/supercrystals.py index 09b924e0ad6..59fbf9241df 100644 --- a/src/sage/categories/supercrystals.py +++ b/src/sage/categories/supercrystals.py @@ -54,7 +54,7 @@ def tensor(self, *crystals, **options): Crystal of BKK tableaux of shape [2, 1] of gl(2|3)] sage: G = T.digraph() sage: H = S.digraph() - sage: G.is_isomorphic(H, edge_labels= True) + sage: G.is_isomorphic(H, edge_labels=True) True """ cartan_type = self.cartan_type() diff --git a/src/sage/coding/code_bounds.py b/src/sage/coding/code_bounds.py index 4bb33d9565f..892445c75bc 100644 --- a/src/sage/coding/code_bounds.py +++ b/src/sage/coding/code_bounds.py @@ -361,7 +361,7 @@ def gilbert_lower_bound(n, q, d): return ans -def plotkin_upper_bound(n,q,d, algorithm=None): +def plotkin_upper_bound(n, q, d, algorithm=None): r""" Return the Plotkin upper bound. @@ -400,7 +400,7 @@ def plotkin_upper_bound(n,q,d, algorithm=None): return int(d/( d - t * fact)) * q**(n - fact) -def griesmer_upper_bound(n,q,d,algorithm=None): +def griesmer_upper_bound(n, q, d, algorithm=None): r""" Return the Griesmer upper bound. @@ -456,7 +456,7 @@ def griesmer_upper_bound(n,q,d,algorithm=None): return q**(k-1) -def elias_upper_bound(n,q,d,algorithm=None): +def elias_upper_bound(n, q, d, algorithm=None): r""" Return the Elias upper bound. @@ -486,7 +486,7 @@ def ff(n, d, w, q): return int(bnd) -def hamming_upper_bound(n,q,d): +def hamming_upper_bound(n, q, d): r""" Return the Hamming upper bound. diff --git a/src/sage/coding/code_constructions.py b/src/sage/coding/code_constructions.py index be1c087c280..ecee1cd349f 100644 --- a/src/sage/coding/code_constructions.py +++ b/src/sage/coding/code_constructions.py @@ -329,7 +329,7 @@ def walsh_matrix(m0): ##################### main constructions ##################### -def DuadicCodeEvenPair(F,S1,S2): +def DuadicCodeEvenPair(F, S1, S2): r""" Construct the "even pair" of duadic codes associated to the "splitting" (see the docstring for ``_is_a_splitting`` @@ -379,7 +379,7 @@ def DuadicCodeEvenPair(F,S1,S2): return C1,C2 -def DuadicCodeOddPair(F,S1,S2): +def DuadicCodeOddPair(F, S1, S2): """ Construct the "odd pair" of duadic codes associated to the "splitting" S1, S2 of n. @@ -435,7 +435,7 @@ def DuadicCodeOddPair(F,S1,S2): return C1,C2 -def ExtendedQuadraticResidueCode(n,F): +def ExtendedQuadraticResidueCode(n, F): r""" The extended quadratic residue code (or XQR code) is obtained from a QR code by adding a check bit to the last coordinate. (These @@ -500,7 +500,7 @@ def from_parity_check_matrix(H): return Cd.dual_code() -def QuadraticResidueCode(n,F): +def QuadraticResidueCode(n, F): r""" A quadratic residue code (or QR code) is a cyclic code whose generator polynomial is the product of the polynomials @@ -544,7 +544,7 @@ def QuadraticResidueCode(n,F): return QuadraticResidueCodeOddPair(n,F)[0] -def QuadraticResidueCodeEvenPair(n,F): +def QuadraticResidueCodeEvenPair(n, F): r""" Quadratic residue codes of a given odd prime length and base ring either don't exist at all or occur as 4-tuples - a pair of @@ -610,7 +610,7 @@ def QuadraticResidueCodeEvenPair(n,F): return DuadicCodeEvenPair(F,Q,N) -def QuadraticResidueCodeOddPair(n,F): +def QuadraticResidueCodeOddPair(n, F): r""" Quadratic residue codes of a given odd prime length and base ring either don't exist at all or occur as 4-tuples - a pair of @@ -696,7 +696,7 @@ def random_linear_code(F, length, dimension): return LinearCode(G) -def ToricCode(P,F): +def ToricCode(P, F): r""" Let `P` denote a list of lattice points in `\ZZ^d` and let `T` denote the set of all diff --git a/src/sage/coding/codecan/codecan.pyx b/src/sage/coding/codecan/codecan.pyx index 47311e16260..ceb197f7890 100644 --- a/src/sage/coding/codecan/codecan.pyx +++ b/src/sage/coding/codecan/codecan.pyx @@ -619,7 +619,7 @@ cdef class PartitionRefinementLinearCode(PartitionRefinement_generic): S = SemimonomialTransformationGroup(self._matrix.base_ring(), self._n) S_n = SymmetricGroup(self._n) - self._transporter = S(perm= S_n(self._to_best.sage())) + self._transporter = S(perm=S_n(self._to_best.sage())) self._transporter, self._best_candidate, remaining_inner_group = self._compute_group_element(self._transporter, algorithm_type) # compute the other components of the automorphism group generators diff --git a/src/sage/coding/guruswami_sudan/gs_decoder.py b/src/sage/coding/guruswami_sudan/gs_decoder.py index 54a624375bd..a5bf1cf345f 100644 --- a/src/sage/coding/guruswami_sudan/gs_decoder.py +++ b/src/sage/coding/guruswami_sudan/gs_decoder.py @@ -375,7 +375,7 @@ def guruswami_sudan_decoding_radius(C=None, n_k=None, l=None, s=None): """ n,k = n_k_params(C, n_k) - def get_tau(s,l): + def get_tau(s, l): "Return the decoding radius given this s and l" if s <= 0 or l <= 0: return -1 diff --git a/src/sage/coding/linear_code.py b/src/sage/coding/linear_code.py index a9e3813b474..3e9d388c434 100644 --- a/src/sage/coding/linear_code.py +++ b/src/sage/coding/linear_code.py @@ -1261,7 +1261,7 @@ def genus(self): gammaC = n+1-k-d return gammaC - def is_permutation_equivalent(self,other,algorithm=None): + def is_permutation_equivalent(self, other, algorithm=None): """ Return ``True`` if ``self`` and ``other`` are permutation equivalent codes and ``False`` otherwise. diff --git a/src/sage/combinat/cluster_algebra_quiver/quiver.py b/src/sage/combinat/cluster_algebra_quiver/quiver.py index 7e07835b935..d9b73e655a9 100644 --- a/src/sage/combinat/cluster_algebra_quiver/quiver.py +++ b/src/sage/combinat/cluster_algebra_quiver/quiver.py @@ -1533,7 +1533,7 @@ def mutation_sequence(self, sequence, show_sequence=False, fig_size=1.2 ): from sage.plot.plot import Graphics from sage.plot.text import text - def _plot_arrow( v, k, center=(0,0) ): + def _plot_arrow( v, k, center=(0, 0) ): return text(r"$\longleftrightarrow$",(center[0],center[1]), fontsize=25) + text(r"$\mu_"+str(v)+"$",(center[0],center[1]+0.15), fontsize=15) \ + text("$"+str(k)+"$",(center[0],center[1]-0.2), fontsize=15) diff --git a/src/sage/combinat/combination.py b/src/sage/combinat/combination.py index 49de0da4ab7..c3597e86611 100644 --- a/src/sage/combinat/combination.py +++ b/src/sage/combinat/combination.py @@ -642,7 +642,7 @@ def from_rank(r, n, k): TESTS:: sage: from sage.combinat.combination import from_rank - sage: def _comb_largest(a,b,x): + sage: def _comb_largest(a, b, x): ....: w = a - 1 ....: while binomial(w,b) > x: ....: w -= 1 diff --git a/src/sage/combinat/crystals/fast_crystals.py b/src/sage/combinat/crystals/fast_crystals.py index e427c6b48aa..5f4ca47249f 100644 --- a/src/sage/combinat/crystals/fast_crystals.py +++ b/src/sage/combinat/crystals/fast_crystals.py @@ -271,7 +271,7 @@ def digraph(self): """ return self._digraph - def cmp_elements(self, x,y): + def cmp_elements(self, x, y): r""" Return ``True`` if and only if there is a path from `x` to `y` in the crystal graph. diff --git a/src/sage/combinat/crystals/fully_commutative_stable_grothendieck.py b/src/sage/combinat/crystals/fully_commutative_stable_grothendieck.py index 9ba9e3c1e0a..4afc713c225 100644 --- a/src/sage/combinat/crystals/fully_commutative_stable_grothendieck.py +++ b/src/sage/combinat/crystals/fully_commutative_stable_grothendieck.py @@ -222,7 +222,7 @@ def __eq__(self, other): """ return isinstance(self, type(other)) and self.value == other.value - def __lt__(self,other): + def __lt__(self, other): """ Return ``True`` if ``self`` comes before ``other`` and ``False`` otherwise. diff --git a/src/sage/combinat/crystals/infinity_crystals.py b/src/sage/combinat/crystals/infinity_crystals.py index a7f98a369fb..c6331093d87 100644 --- a/src/sage/combinat/crystals/infinity_crystals.py +++ b/src/sage/combinat/crystals/infinity_crystals.py @@ -296,7 +296,7 @@ class Element(InfinityCrystalOfTableauxElement): Elements in `\mathcal{B}(\infty)` crystal of tableaux. """ - def phi(self,i): + def phi(self, i): r""" Return `\varphi_i` of ``self``. diff --git a/src/sage/combinat/crystals/littelmann_path.py b/src/sage/combinat/crystals/littelmann_path.py index c9fa7cb7933..7e2f9fe5aca 100644 --- a/src/sage/combinat/crystals/littelmann_path.py +++ b/src/sage/combinat/crystals/littelmann_path.py @@ -1455,7 +1455,7 @@ def weight(self): alpha = WLR.simple_roots() return -WLR.sum(alpha[i] for i in self.to_highest_weight()[1]) - def phi(self,i): + def phi(self, i): r""" Return `\varphi_i` of ``self``. diff --git a/src/sage/combinat/crystals/star_crystal.py b/src/sage/combinat/crystals/star_crystal.py index 02427149ed4..bc80a7a650c 100644 --- a/src/sage/combinat/crystals/star_crystal.py +++ b/src/sage/combinat/crystals/star_crystal.py @@ -61,7 +61,7 @@ class StarCrystal(UniqueRepresentation, Parent): is the highest weight vector in `B(\infty)`; - if `\Psi_i(b) = f_i^mb_i(0) \otimes b_0`, then - `\Psi_i(f_i^*b) =f_i^{m+1}b_i(0) \otimes b_0` + `\Psi_i(f_i^*b) = f_i^{m+1}b_i(0) \otimes b_0` and `\varepsilon_i(b^*) = m`; - the image of `\Psi_i` is `\{f_i^mb_i(0)\otimes b : @@ -124,7 +124,7 @@ def _repr_(self): class Element(ElementWrapper): - def e(self,i): + def e(self, i): r""" Return the action of `e_i^*` on ``self``. @@ -152,7 +152,7 @@ def e(self,i): return None return P(P._pullback[i]( P._tens[i](image[0].e(i),image[1]) )) - def f(self,i): + def f(self, i): r""" Return the action of `f_i^*` on ``self``. diff --git a/src/sage/combinat/crystals/tensor_product_element.pyx b/src/sage/combinat/crystals/tensor_product_element.pyx index 607dcc2a8dc..05b17350004 100644 --- a/src/sage/combinat/crystals/tensor_product_element.pyx +++ b/src/sage/combinat/crystals/tensor_product_element.pyx @@ -998,7 +998,7 @@ cdef class CrystalOfTableauxElement(TensorProductOfRegularCrystalsElement): return crystal(self.to_tableau().promotion_inverse(cartan_type.rank())) cdef class InfinityCrystalOfTableauxElement(CrystalOfTableauxElement): - def e(self,i): + def e(self, i): r""" Return the action of `\widetilde{e}_i` on ``self``. diff --git a/src/sage/combinat/designs/bibd.py b/src/sage/combinat/designs/bibd.py index 49c930ccb38..09785c3d1da 100644 --- a/src/sage/combinat/designs/bibd.py +++ b/src/sage/combinat/designs/bibd.py @@ -521,7 +521,7 @@ def steiner_triple_system(n): return BIBD(n, sts, name=name,check=False) -def BIBD_from_TD(v,k,existence=False): +def BIBD_from_TD(v, k, existence=False): r""" Return a BIBD through TD-based constructions. @@ -894,7 +894,7 @@ def BIBD_from_PBD(PBD, v, k, check=True, base_cases=None): return bibd -def _relabel_bibd(B,n,p=None): +def _relabel_bibd(B, n, p=None): r""" Relabel the BIBD on `n` points and blocks of size k such that `\{0,...,k-2,n-1\},\{k-1,...,2k-3,n-1\},...,\{n-k,...,n-2,n-1\}` are blocks @@ -1223,7 +1223,7 @@ def _get_r_s_t_u(v): return r,s,t,u -def PBD_from_TD(k,t,u): +def PBD_from_TD(k, t, u): r""" Return a `(kt,\{k,t\})`-PBD if `u=0` and a `(kt+u,\{k,k+1,t,u\})`-PBD otherwise. @@ -1294,7 +1294,7 @@ def BIBD_5q_5_for_q_prime_power(q): return B -def BIBD_from_arc_in_desarguesian_projective_plane(n,k,existence=False): +def BIBD_from_arc_in_desarguesian_projective_plane(n, k, existence=False): r""" Return a `(n,k,1)`-BIBD from a maximal arc in a projective plane. @@ -1430,7 +1430,7 @@ class PairwiseBalancedDesign(GroupDivisibleDesign): modified in place (each block is sorted, and the whole list is sorted). Your ``blocks`` object will become the instance's internal data. """ - def __init__(self, points, blocks, K=None, lambd=1, check=True, copy=True,**kwds): + def __init__(self, points, blocks, K=None, lambd=1, check=True, copy=True, **kwds): r""" Constructor. @@ -1498,7 +1498,7 @@ class BalancedIncompleteBlockDesign(PairwiseBalancedDesign): sage: b=designs.balanced_incomplete_block_design(9,3); b (9,3,1)-Balanced Incomplete Block Design """ - def __init__(self, points, blocks, k=None, lambd=1, check=True, copy=True,**kwds): + def __init__(self, points, blocks, k=None, lambd=1, check=True, copy=True, **kwds): r""" Constructor. diff --git a/src/sage/combinat/designs/database.py b/src/sage/combinat/designs/database.py index 19eb9d26165..ad86c612e86 100644 --- a/src/sage/combinat/designs/database.py +++ b/src/sage/combinat/designs/database.py @@ -69,7 +69,7 @@ cyclic_shift = lambda l,i : l[-i:]+l[:-i] -def _MOLS_from_string(s,k): +def _MOLS_from_string(s, k): r""" Return MOLS from a string. @@ -3829,13 +3829,13 @@ def DM_52_6_1(): from itertools import product - def t1(i,R): + def t1(i, R): if i > 1: return t1(1,t1(i-1,R)) ((x1,y1),(x2,y2),(x3,y3),(x4,y4),(x5,y5),(x6,y6)) = R return [(z*x3, 3*y3), (z*x1, 3*y1), (z*x2, 3*y2), (z*x6, 3*y6), (z*x4, 3*y4), (z*x5, 3*y5)] - def t2(i,R): + def t2(i, R): if i > 1: return t2(1,t2(i-1,R)) ((x1,y1),(x2,y2),(x3,y3),(x4,y4),(x5,y5),(x6,y6)) = R diff --git a/src/sage/combinat/designs/designs_pyx.pyx b/src/sage/combinat/designs/designs_pyx.pyx index c862821330e..790111d4326 100644 --- a/src/sage/combinat/designs/designs_pyx.pyx +++ b/src/sage/combinat/designs/designs_pyx.pyx @@ -350,7 +350,7 @@ def is_orthogonal_array(OA, int k, int n, int t=2, verbose=False, terminology='O return True -def is_group_divisible_design(groups,blocks,v,G=None,K=None,lambd=1,verbose=False): +def is_group_divisible_design(groups, blocks, v, G=None, K=None, lambd=1, verbose=False): r""" Check that input is a Group Divisible Design on `\{0, \ldots, v-1\}`. @@ -469,7 +469,7 @@ def is_group_divisible_design(groups,blocks,v,G=None,K=None,lambd=1,verbose=Fals print("{} does not belong to [0,...,{}]".format(x, n-1)) return False - cdef unsigned short * matrix = sig_calloc(n*n,sizeof(unsigned short)) + cdef unsigned short * matrix = sig_calloc(n*n, sizeof(unsigned short)) if matrix is NULL: raise MemoryError @@ -534,7 +534,7 @@ def is_group_divisible_design(groups,blocks,v,G=None,K=None,lambd=1,verbose=Fals return True if not guess_groups else (True, groups) -def is_pairwise_balanced_design(blocks,v,K=None,lambd=1,verbose=False): +def is_pairwise_balanced_design(blocks, v, K=None, lambd=1, verbose=False): r""" Check that input is a Pairwise Balanced Design (PBD) on `\{0, \ldots, v-1\}`. @@ -663,7 +663,7 @@ def is_projective_plane(blocks, verbose=False): verbose=verbose) -def is_difference_matrix(M,G,k,lmbda=1,verbose=False): +def is_difference_matrix(M, G, k, lmbda=1, verbose=False): r""" Test if `M` is a `(G,k,\lambda)`-difference matrix. @@ -728,7 +728,7 @@ def is_difference_matrix(M,G,k,lmbda=1,verbose=False): return is_quasi_difference_matrix(M,G,k,lmbda=lmbda,mu=lmbda,u=0,verbose=verbose) -def is_quasi_difference_matrix(M,G,int k,int lmbda,int mu,int u,verbose=False): +def is_quasi_difference_matrix(M, G, int k, int lmbda, int mu, int u, verbose=False): r""" Test if the matrix is a `(G,k;\lambda,\mu;u)`-quasi-difference matrix. @@ -987,7 +987,7 @@ cpdef _OA_cache_set(int k, int n, truth_value): else: _OA_cache[n].min_false = k if k<_OA_cache[n].min_false else _OA_cache[n].min_false -cpdef _OA_cache_get(int k,int n): +cpdef _OA_cache_get(int k, int n): r""" Get a value from the OA cache of existence results. @@ -1006,7 +1006,7 @@ cpdef _OA_cache_get(int k,int n): return None -cpdef _OA_cache_construction_available(int k,int n): +cpdef _OA_cache_construction_available(int k, int n): r""" Test if a construction is implemented using the cache's information. diff --git a/src/sage/combinat/designs/difference_family.py b/src/sage/combinat/designs/difference_family.py index 49b25c12dd0..a74634d32cf 100644 --- a/src/sage/combinat/designs/difference_family.py +++ b/src/sage/combinat/designs/difference_family.py @@ -330,7 +330,7 @@ def is_difference_family(G, D, v=None, k=None, l=None, verbose=False): return True -def singer_difference_set(q,d): +def singer_difference_set(q, d): r""" Return a difference set associated to the set of hyperplanes in a projective space of dimension `d` over `GF(q)`. @@ -641,7 +641,7 @@ def radical_difference_set(K, k, l=1, existence=False, check=True): return D -def one_cyclic_tiling(A,n): +def one_cyclic_tiling(A, n): r""" Given a subset ``A`` of the cyclic additive group `G = Z / nZ` return another subset `B` so that `A + B = G` and `|A| |B| = n` (i.e. any element @@ -3532,7 +3532,7 @@ def difference_family(v, k, l=1, existence=False, explain_construction=False, ch For `k=6,7` we look at the set of small prime powers for which a construction is available:: - sage: def prime_power_mod(r,m): + sage: def prime_power_mod(r, m): ....: k = m+r ....: while True: ....: if is_prime_power(k): diff --git a/src/sage/combinat/designs/difference_matrices.py b/src/sage/combinat/designs/difference_matrices.py index 11fe16bb8d5..0e90358c234 100644 --- a/src/sage/combinat/designs/difference_matrices.py +++ b/src/sage/combinat/designs/difference_matrices.py @@ -124,7 +124,7 @@ def difference_matrix_product(k, M1, G1, lmbda1, M2, G2, lmbda2, check=True): return G,M -def difference_matrix(g,k,lmbda=1,existence=False,check=True): +def difference_matrix(g, k, lmbda=1, existence=False, check=True): r""" Return a `(g,k,\lambda)`-difference matrix. diff --git a/src/sage/combinat/designs/evenly_distributed_sets.pyx b/src/sage/combinat/designs/evenly_distributed_sets.pyx index 1d1a7acb8ec..8fdf10c0bf1 100644 --- a/src/sage/combinat/designs/evenly_distributed_sets.pyx +++ b/src/sage/combinat/designs/evenly_distributed_sets.pyx @@ -433,7 +433,7 @@ cdef class EvenlyDistributedSetsBacktracker: will be called only once. """ cdef unsigned int i,j,k,tmp1,tmp2,verify - cdef list B = [self.B[i] for i in range(1,self.k)] + cdef list B = [self.B[i] for i in range(1, self.k)] B.append(self.q-1) cdef list BB = [None]*self.k cdef set relabs = set([tuple(B)]) diff --git a/src/sage/combinat/designs/latin_squares.py b/src/sage/combinat/designs/latin_squares.py index c8b61827e90..b117f76b8e0 100644 --- a/src/sage/combinat/designs/latin_squares.py +++ b/src/sage/combinat/designs/latin_squares.py @@ -449,12 +449,12 @@ def latin_square_product(M, N, *others): P = Matrix(D) if others: - return latin_square_product(P, others[0],*others[1:]) + return latin_square_product(P, others[0], *others[1:]) else: return P -def MOLS_table(start,stop=None,compare=False,width=None): +def MOLS_table(start, stop=None, compare=False, width=None): r""" Print the MOLS table that Sage can produce. diff --git a/src/sage/combinat/designs/orthogonal_arrays.py b/src/sage/combinat/designs/orthogonal_arrays.py index daac0f322cf..5d4498cc5a3 100644 --- a/src/sage/combinat/designs/orthogonal_arrays.py +++ b/src/sage/combinat/designs/orthogonal_arrays.py @@ -392,7 +392,7 @@ class TransversalDesign(GroupDivisibleDesign): sage: designs.transversal_design(None,36) Transversal Design TD(10,36) """ - def __init__(self, blocks, k=None,n=None,check=True,**kwds): + def __init__(self, blocks, k=None, n=None, check=True, **kwds): r""" Constructor of the class. @@ -473,7 +473,7 @@ def is_transversal_design(B, k, n, verbose=False): return is_orthogonal_array([[x % n for x in R] for R in B],k,n,verbose=verbose) -def wilson_construction(OA,k,r,m,u,check=True,explain_construction=False): +def wilson_construction(OA, k, r, m, u, check=True, explain_construction=False): r""" Return a `OA(k,rm+\sum_i u_i)` from a truncated `OA(k+s,r)` by Wilson's construction. @@ -678,7 +678,7 @@ def wilson_construction(OA,k,r,m,u,check=True,explain_construction=False): return OA -def TD_product(k,TD1,n1,TD2,n2, check=True): +def TD_product(k, TD1, n1, TD2, n2, check=True): r""" Return the product of two transversal designs. @@ -726,7 +726,7 @@ def TD_product(k,TD1,n1,TD2,n2, check=True): return TD -def orthogonal_array(k,n,t=2,resolvable=False, check=True,existence=False,explain_construction=False): +def orthogonal_array(k, n, t=2, resolvable=False, check=True, existence=False, explain_construction=False): r""" Return an orthogonal array of parameters `k,n,t`. @@ -1055,7 +1055,7 @@ def largest_available_k(n, t=2): return k -def incomplete_orthogonal_array(k,n,holes,resolvable=False, existence=False): +def incomplete_orthogonal_array(k, n, holes, resolvable=False, existence=False): r""" Return an `OA(k,n)-\sum_{1\leq i\leq x} OA(k,s_i)`. @@ -1582,7 +1582,7 @@ def OA_standard_label(OA): return [[mapping[element] for element in row] for row in OA] -def OA_n_times_2_pow_c_from_matrix(k,c,G,A,Y,check=True): +def OA_n_times_2_pow_c_from_matrix(k, c, G, A, Y, check=True): r""" Return an `OA(k, |G| \cdot 2^c)` from a constrained `(G,k-1,2)`-difference matrix. @@ -1740,7 +1740,7 @@ def OA_n_times_2_pow_c_from_matrix(k,c,G,A,Y,check=True): return OA_from_quasi_difference_matrix(list(zip(*Mb)),GG,add_col=True) -def OA_from_quasi_difference_matrix(M,G,add_col=True,fill_hole=True): +def OA_from_quasi_difference_matrix(M, G, add_col=True, fill_hole=True): r""" Return an Orthogonal Array from a Quasi-Difference matrix. @@ -1860,7 +1860,7 @@ def OA_from_quasi_difference_matrix(M,G,add_col=True,fill_hole=True): return new_M -def OA_from_Vmt(m,t,V): +def OA_from_Vmt(m, t, V): r""" Return an Orthogonal Array from a `V(m,t)`. @@ -1884,7 +1884,7 @@ def OA_from_Vmt(m,t,V): return OA_from_quasi_difference_matrix(M,Fq,add_col=False) -def QDM_from_Vmt(m,t,V): +def QDM_from_Vmt(m, t, V): r""" Return a QDM from a `V(m,t)`. @@ -1948,7 +1948,7 @@ def QDM_from_Vmt(m,t,V): return Fq, M -def OA_from_PBD(k,n,PBD, check=True): +def OA_from_PBD(k, n, PBD, check=True): r""" Return an `OA(k,n)` from a PBD. @@ -2031,7 +2031,7 @@ def OA_from_PBD(k,n,PBD, check=True): return OA -def OA_from_wider_OA(OA,k): +def OA_from_wider_OA(OA, k): r""" Return the first `k` columns of `OA`. @@ -2116,7 +2116,7 @@ class OAMainFunctions: ... NotImplementedError: I don't know how to build an OA(12,20)! """ - def __init__(self,*args,**kwds): + def __init__(self, *args, **kwds): r""" There is nothing here. @@ -2132,7 +2132,7 @@ def __init__(self,*args,**kwds): largest_available_k = staticmethod(largest_available_k) @staticmethod - def explain_construction(k,n,t=2): + def explain_construction(k, n, t=2): r""" Return a string describing how to builds an `OA(k,n)`. @@ -2150,7 +2150,7 @@ def explain_construction(k,n,t=2): return orthogonal_array(k,n,t,explain_construction=True) @staticmethod - def build(k,n,t=2,resolvable=False): + def build(k, n, t=2, resolvable=False): r""" Return an `OA(k,n)` of strength `t`. @@ -2191,7 +2191,7 @@ def build(k,n,t=2,resolvable=False): return orthogonal_array(k,n,t,resolvable=resolvable) @staticmethod - def exists(k,n,t=2): + def exists(k, n, t=2): r""" Return the existence status of an `OA(k,n)`. @@ -2220,7 +2220,7 @@ def exists(k,n,t=2): return orthogonal_array(k,n,t,existence=True) @staticmethod - def is_available(k,n,t=2): + def is_available(k, n, t=2): r""" Return whether Sage can build an `OA(k,n)`. diff --git a/src/sage/combinat/designs/orthogonal_arrays_build_recursive.py b/src/sage/combinat/designs/orthogonal_arrays_build_recursive.py index 937076ebb07..2bfd385492c 100644 --- a/src/sage/combinat/designs/orthogonal_arrays_build_recursive.py +++ b/src/sage/combinat/designs/orthogonal_arrays_build_recursive.py @@ -35,7 +35,7 @@ from .orthogonal_arrays import orthogonal_array, wilson_construction, is_orthogonal_array -def construction_3_3(k,n,m,i,explain_construction=False): +def construction_3_3(k, n, m, i, explain_construction=False): r""" Return an `OA(k,nm+i)`. @@ -97,7 +97,7 @@ def construction_3_3(k,n,m,i,explain_construction=False): return OA -def construction_3_4(k,n,m,r,s,explain_construction=False): +def construction_3_4(k, n, m, r, s, explain_construction=False): r""" Return a `OA(k,nm+rs)`. @@ -180,7 +180,7 @@ def construction_3_4(k,n,m,r,s,explain_construction=False): return OA -def construction_3_5(k,n,m,r,s,t,explain_construction=False): +def construction_3_5(k, n, m, r, s, t, explain_construction=False): r""" Return an `OA(k,nm+r+s+t)`. @@ -275,7 +275,7 @@ def construction_3_5(k,n,m,r,s,t,explain_construction=False): return OA -def construction_3_6(k,n,m,i,explain_construction=False): +def construction_3_6(k, n, m, i, explain_construction=False): r""" Return a `OA(k,nm+i)`. @@ -578,7 +578,7 @@ def construction_q_x(k, q, x, check=True, explain_construction=False): return OA -def thwart_lemma_3_5(k,n,m,a,b,c,d=0,complement=False,explain_construction=False): +def thwart_lemma_3_5(k, n, m, a, b, c, d=0, complement=False, explain_construction=False): r""" Return an `OA(k,nm+a+b+c+d)`. @@ -757,7 +757,7 @@ def thwart_lemma_3_5(k,n,m,a,b,c,d=0,complement=False,explain_construction=False return wilson_construction(OA,k,n,m,sizes, check=False) -def thwart_lemma_4_1(k,n,m,explain_construction=False): +def thwart_lemma_4_1(k, n, m, explain_construction=False): r""" Return an `OA(k,nm+4(n-2))`. @@ -886,7 +886,7 @@ def thwart_lemma_4_1(k,n,m,explain_construction=False): return wilson_construction(OA,k,n,m,[n-2,]*4,check=False) -def three_factor_product(k,n1,n2,n3,check=False,explain_construction=False): +def three_factor_product(k, n1, n2, n3, check=False, explain_construction=False): r""" Return an `OA(k+1,n_1n_2n_3)`. @@ -1010,7 +1010,7 @@ def three_factor_product(k,n1,n2,n3,check=False,explain_construction=False): " A three-factor product construction for mutually orthogonal latin squares,\n" + " https://arxiv.org/abs/1401.1466").format(n1, n2, n3) - def assert_c_partition(classs,k,n,c): + def assert_c_partition(classs, k, n, c): r""" Makes sure that ``classs`` contains blocks `B` of size `k` such that the list of ``B[i]`` covers `[n]` exactly `c` times for every index `i`. @@ -1021,7 +1021,7 @@ def assert_c_partition(classs,k,n,c): for p in zip(*classs): assert all(x == i//c for i,x in enumerate(sorted(p))), "A class is not c(={})-parallel".format(c) - def product_with_parallel_classes(OA1,k,g1,g2,g1_parall,parall,check=True): + def product_with_parallel_classes(OA1, k, g1, g2, g1_parall, parall, check=True): r""" Return the product of two OA while keeping track of parallel classes. @@ -1203,7 +1203,7 @@ def _reorder_matrix(matrix): return list(zip(*matrix)) -def brouwer_separable_design(k,t,q,x,check=False,verbose=False,explain_construction=False): +def brouwer_separable_design(k, t, q, x, check=False, verbose=False, explain_construction=False): r""" Return a `OA(k,t(q^2+q+1)+x)` using Brouwer's result on separable designs. diff --git a/src/sage/combinat/designs/orthogonal_arrays_find_recursive.pyx b/src/sage/combinat/designs/orthogonal_arrays_find_recursive.pyx index f7f3502548b..dc9c278cd72 100644 --- a/src/sage/combinat/designs/orthogonal_arrays_find_recursive.pyx +++ b/src/sage/combinat/designs/orthogonal_arrays_find_recursive.pyx @@ -116,7 +116,7 @@ def find_recursive_construction(k, n): return False -cpdef find_product_decomposition(int k,int n): +cpdef find_product_decomposition(int k, int n): r""" Find `n_1n_2=n` to obtain an `OA(k,n)` by the product construction. @@ -157,7 +157,7 @@ cpdef find_product_decomposition(int k,int n): return wilson_construction, (None,k,n1,n2,(),False) return False -cpdef find_wilson_decomposition_with_one_truncated_group(int k,int n): +cpdef find_wilson_decomposition_with_one_truncated_group(int k, int n): r""" Find `rm+u=n` to obtain an `OA(k,n)` by Wilson's construction with one truncated column. @@ -206,7 +206,7 @@ cpdef find_wilson_decomposition_with_one_truncated_group(int k,int n): return False -cpdef find_wilson_decomposition_with_two_truncated_groups(int k,int n): +cpdef find_wilson_decomposition_with_two_truncated_groups(int k, int n): r""" Find `rm+r_1+r_2=n` to obtain an `OA(k,n)` by Wilson's construction with two truncated columns. @@ -268,7 +268,7 @@ cpdef find_wilson_decomposition_with_two_truncated_groups(int k,int n): return wilson_construction, (None,k,r,m,(r1,r2),False) return False -cpdef find_construction_3_3(int k,int n): +cpdef find_construction_3_3(int k, int n): r""" Find a decomposition for construction 3.3 from [AC07]_. @@ -398,7 +398,7 @@ cpdef find_construction_3_5(int k, int n): from sage.combinat.designs.orthogonal_arrays_build_recursive import construction_3_5 return construction_3_5, (k,nn,mm,r,s,t) -cpdef find_construction_3_6(int k,int n): +cpdef find_construction_3_6(int k, int n): r""" Find a decomposition for construction 3.6 from [AC07]_. @@ -439,7 +439,7 @@ cpdef find_construction_3_6(int k,int n): from sage.combinat.designs.orthogonal_arrays_build_recursive import construction_3_6 return construction_3_6, (k,nn,mm,i) -cpdef find_q_x(int k,int n): +cpdef find_q_x(int k, int n): r""" Find integers `q,x` such that the `q-x` construction yields an `OA(k,n)`. @@ -492,7 +492,7 @@ cpdef find_q_x(int k,int n): return construction_q_x, (k,q,x) return False -cpdef find_thwart_lemma_3_5(int k,int N): +cpdef find_thwart_lemma_3_5(int k, int N): r""" Find the values on which Lemma 3.5 from [Thwarts]_ applies. @@ -613,7 +613,7 @@ cpdef find_thwart_lemma_3_5(int k,int N): return False -cpdef find_thwart_lemma_4_1(int k,int n): +cpdef find_thwart_lemma_4_1(int k, int n): r""" Find a decomposition for Lemma 4.1 from [Thwarts]_. @@ -662,7 +662,7 @@ cpdef find_thwart_lemma_4_1(int k,int n): return False -cpdef find_three_factor_product(int k,int n): +cpdef find_three_factor_product(int k, int n): r""" Find `n_1n_2n_3=n` to obtain an `OA(k,n)` by the three-factor product from [DukesLing14]_. @@ -707,7 +707,7 @@ cpdef find_three_factor_product(int k,int n): return False -cpdef find_brouwer_separable_design(int k,int n): +cpdef find_brouwer_separable_design(int k, int n): r""" Find `t(q^2+q+1)+x=n` to obtain an `OA(k,n)` by Brouwer's separable design construction. @@ -878,7 +878,7 @@ def int_as_sum(int value, list S, int k_max): return None -cpdef find_brouwer_van_rees_with_one_truncated_column(int k,int n): +cpdef find_brouwer_van_rees_with_one_truncated_column(int k, int n): r""" Find `rm+x_1+...+x_c=n` such that the Brouwer-van Rees constructions yields a `OA(k,n)`. @@ -947,7 +947,7 @@ cpdef find_brouwer_van_rees_with_one_truncated_column(int k,int n): return False from sage.combinat.designs.designs_pyx cimport _OA_cache, _OA_cache_size -cdef int is_available(int k,int n) except -1: +cdef int is_available(int k, int n) except -1: r""" Return whether Sage can build an OA(k,n) diff --git a/src/sage/combinat/designs/resolvable_bibd.py b/src/sage/combinat/designs/resolvable_bibd.py index ccc11176d54..c6e0bbee33b 100644 --- a/src/sage/combinat/designs/resolvable_bibd.py +++ b/src/sage/combinat/designs/resolvable_bibd.py @@ -56,7 +56,7 @@ from sage.misc.unknown import Unknown -def resolvable_balanced_incomplete_block_design(v,k,existence=False): +def resolvable_balanced_incomplete_block_design(v, k, existence=False): r""" Return a resolvable BIBD of parameters `v,k`. @@ -141,7 +141,7 @@ def resolvable_balanced_incomplete_block_design(v,k,existence=False): raise NotImplementedError("I don't know how to build a ({},{},1)-RBIBD!".format(v,3)) -def kirkman_triple_system(v,existence=False): +def kirkman_triple_system(v, existence=False): r""" Return a Kirkman Triple System on `v` points. @@ -368,7 +368,7 @@ def kirkman_triple_system(v,existence=False): return KTS -def v_4_1_rbibd(v,existence=False): +def v_4_1_rbibd(v, existence=False): r""" Return a `(v,4,1)`-RBIBD. @@ -439,7 +439,7 @@ def v_4_1_rbibd(v,existence=False): return BIBD -def PBD_4_7(v,check=True, existence=False): +def PBD_4_7(v, check=True, existence=False): r""" Return a `(v,\{4,7\})`-PBD. @@ -686,7 +686,7 @@ def PBD_4_7(v,check=True, existence=False): copy=False) -def PBD_4_7_from_Y(gdd,check=True): +def PBD_4_7_from_Y(gdd, check=True): r""" Return a `(3v+1,\{4,7\})`-PBD from a `(v,\{4,5,7\},\NN-\{3,6,10\})`-GDD. diff --git a/src/sage/combinat/designs/steiner_quadruple_systems.py b/src/sage/combinat/designs/steiner_quadruple_systems.py index 9576ae5f5aa..af60e00b63e 100644 --- a/src/sage/combinat/designs/steiner_quadruple_systems.py +++ b/src/sage/combinat/designs/steiner_quadruple_systems.py @@ -540,7 +540,7 @@ def P(alpha, m): return pairs -def _missing_pair(n,l): +def _missing_pair(n, l): r""" Return the smallest `(x,x+1)` that is not contained in `l`. diff --git a/src/sage/combinat/designs/subhypergraph_search.pyx b/src/sage/combinat/designs/subhypergraph_search.pyx index 8de300efe2a..82be44dcd13 100644 --- a/src/sage/combinat/designs/subhypergraph_search.pyx +++ b/src/sage/combinat/designs/subhypergraph_search.pyx @@ -172,7 +172,7 @@ cdef void h_free(hypergraph h) noexcept: h.set_space = NULL h.sets = NULL -cdef hypergraph h_init(int n,list H) noexcept: +cdef hypergraph h_init(int n, list H) noexcept: r""" Build a C hypergraph from a list `H` of sets on `\{0,...,n-1\}`. """ @@ -210,7 +210,7 @@ cdef hypergraph h_init(int n,list H) noexcept: return h -cdef inline void permute(hypergraph * h,int n1,int n2) noexcept: +cdef inline void permute(hypergraph * h, int n1, int n2) noexcept: r""" Permutes two points of h inplace. @@ -265,7 +265,7 @@ cdef void trace_hypergraph64(hypergraph * h, int n, hypergraph * tmp) noexcept: tmp.limbs = 1 -cdef int is_subhypergraph_admissible(hypergraph h1,hypergraph * h2_trace,int n,hypergraph tmp1) noexcept: +cdef int is_subhypergraph_admissible(hypergraph h1, hypergraph * h2_trace, int n, hypergraph tmp1) noexcept: r""" If there are `c` sets of size `k` containing `S\subseteq \{0,...,n-1\}` in `h2`, then there must be `>=c` sets of size `k` containing `S` in h1. This @@ -308,7 +308,7 @@ cdef int cmp_128_bits(const void * a, const void * b) noexcept nogil: else: return -1 -cdef int is_induced_admissible64(hypergraph h1,hypergraph * h2_induced,int n,hypergraph tmp1) noexcept: +cdef int is_induced_admissible64(hypergraph h1, hypergraph * h2_induced, int n, hypergraph tmp1) noexcept: r""" Test if the hypergraph induced in h1 by 0,...,n-1 is equal to the hypergraph induced in h2 by 0,...,n-1. @@ -344,7 +344,7 @@ cdef class SubHypergraphSearch: cdef hypergraph * h2_traces cdef hypergraph * h2_induced - def __cinit__(self,H1,H2,induced): + def __cinit__(self, H1, H2, induced): r""" See the documentation's class. diff --git a/src/sage/combinat/enumeration_mod_permgroup.pyx b/src/sage/combinat/enumeration_mod_permgroup.pyx index b2f713228ed..bcc3236205b 100644 --- a/src/sage/combinat/enumeration_mod_permgroup.pyx +++ b/src/sage/combinat/enumeration_mod_permgroup.pyx @@ -121,7 +121,7 @@ cpdef int lex_cmp(ClonableIntArray v1, ClonableIntArray v2) noexcept: 1 """ cdef int i - cdef int step = min(v1._len,v2._len) + cdef int step = min(v1._len, v2._len) for i in range(step): if v1._list[i] != v2._list[i]: break diff --git a/src/sage/combinat/gray_codes.py b/src/sage/combinat/gray_codes.py index 63e366c2cb5..db1539d2376 100644 --- a/src/sage/combinat/gray_codes.py +++ b/src/sage/combinat/gray_codes.py @@ -103,7 +103,7 @@ def product(m): j = f[0] -def combinations(n,t): +def combinations(n, t): r""" Iterator through the switches of the revolving door algorithm. @@ -177,7 +177,7 @@ def combinations(n,t): TESTS:: - sage: def check_sets_from_iter(n,k): + sage: def check_sets_from_iter(n, k): ....: l = [] ....: s = set(range(k)) ....: l.append(frozenset(s)) @@ -209,7 +209,7 @@ def combinations(n,t): return _revolving_door_even(n,t) -def _revolving_door_odd(n,t): +def _revolving_door_odd(n, t): r""" Revolving door switch for odd `t`. @@ -255,7 +255,7 @@ def _revolving_door_odd(n,t): break -def _revolving_door_even(n,t): +def _revolving_door_even(n, t): r""" Revolving door algorithm for even `t`. diff --git a/src/sage/combinat/k_tableau.py b/src/sage/combinat/k_tableau.py index 2c048fe38fc..de6b783f15b 100644 --- a/src/sage/combinat/k_tableau.py +++ b/src/sage/combinat/k_tableau.py @@ -4179,7 +4179,7 @@ def add_marking( cls, unmarkedT, marking, k, weight ): sage: StrongTableaux.add_marking([], [], 2, []) [] """ - def msgn(c,v): + def msgn(c, v): if c in marking: return -v else: diff --git a/src/sage/combinat/knutson_tao_puzzles.py b/src/sage/combinat/knutson_tao_puzzles.py index f7a7c513c52..7e226bffee3 100644 --- a/src/sage/combinat/knutson_tao_puzzles.py +++ b/src/sage/combinat/knutson_tao_puzzles.py @@ -2092,7 +2092,7 @@ def _fill_strip(self, nw_labels, ne_label, pieces, final_pieces=None): [[0/\0 0\/0, 0/0\0]] sage: sorted(ps._fill_strip(('0',), '0', ps._rhombus_pieces), key=str) [[0/\0 0\/0], [0/\0 1\/10]] - sage: sorted(ps._fill_strip(('0','1'), '0', ps._rhombus_pieces), key =str) + sage: sorted(ps._fill_strip(('0','1'), '0', ps._rhombus_pieces), key=str) [[1/\0 0\/1, 0/\0 0\/0], [1/\0 0\/1, 0/\0 1\/10]] TESTS:: diff --git a/src/sage/combinat/misc.py b/src/sage/combinat/misc.py index d04b615be80..55a4b891bd2 100644 --- a/src/sage/combinat/misc.py +++ b/src/sage/combinat/misc.py @@ -127,7 +127,7 @@ def hide(self, i): self.next_value[self.prev_value[i]] = self.next_value[i] self.prev_value[self.next_value[i]] = self.prev_value[i] - def unhide(self,i): + def unhide(self, i): """ TESTS:: diff --git a/src/sage/combinat/multiset_partition_into_sets_ordered.py b/src/sage/combinat/multiset_partition_into_sets_ordered.py index aae1cd569a2..eaccf0cd142 100755 --- a/src/sage/combinat/multiset_partition_into_sets_ordered.py +++ b/src/sage/combinat/multiset_partition_into_sets_ordered.py @@ -3520,7 +3520,7 @@ def e(self, i): w = w.e(i) return P.element_class(P, (w, breaks)) - def f(self,i): + def f(self, i): r""" Return `f_i` on ``self``. diff --git a/src/sage/combinat/ncsf_qsym/combinatorics.py b/src/sage/combinat/ncsf_qsym/combinatorics.py index ef930596ab8..605ad56aa12 100644 --- a/src/sage/combinat/ncsf_qsym/combinatorics.py +++ b/src/sage/combinat/ncsf_qsym/combinatorics.py @@ -51,7 +51,7 @@ def coeff_pi(J, I): return prod(prod(K.partial_sums()) for K in J.refinement_splitting(I)) -def coeff_lp(J,I): +def coeff_lp(J, I): r""" Return the coefficient `lp_{J,I}` as defined in [NCSF]_. @@ -73,7 +73,7 @@ def coeff_lp(J,I): return prod(K[-1] for K in J.refinement_splitting(I)) -def coeff_ell(J,I): +def coeff_ell(J, I): r""" Return the coefficient `\ell_{J,I}` as defined in [NCSF]_. diff --git a/src/sage/combinat/partition_tuple.py b/src/sage/combinat/partition_tuple.py index 0e0e8e4aae9..527df5a2728 100644 --- a/src/sage/combinat/partition_tuple.py +++ b/src/sage/combinat/partition_tuple.py @@ -944,7 +944,7 @@ def cells(self): """ return [(c,a,b) for c in range(len(self)) for (a,b) in self[c].cells()] - def content(self, k,r,c, multicharge): + def content(self, k, r, c, multicharge): r""" Return the content of the cell. @@ -977,7 +977,7 @@ def content(self, k,r,c, multicharge): """ return multicharge[k]-r+c - def content_tableau(self,multicharge): + def content_tableau(self, multicharge): """ Return the tableau which has (k,r,c)th entry equal to the content ``multicharge[k]-r+c`` of this cell. @@ -1191,7 +1191,7 @@ def garnir_tableau(self, *cell): g._garnir_cell = (comp,row,col) return g - def top_garnir_tableau(self,e,cell): + def top_garnir_tableau(self, e, cell): r""" Return the most dominant *standard* tableau which dominates the corresponding Garnir tableau and has the same residue that has shape @@ -1268,7 +1268,7 @@ def top_garnir_tableau(self,e,cell): from .tableau_tuple import StandardTableauTuple return StandardTableauTuple(t) - def arm_length(self, k,r,c): + def arm_length(self, k, r, c): """ Return the length of the arm of cell ``(k, r, c)`` in ``self``. @@ -1298,7 +1298,7 @@ def arm_length(self, k,r,c): except IndexError: raise ValueError("The cell %s is not in the diagram" % ((k,r,c),)) - def leg_length(self, k,r,c): + def leg_length(self, k, r, c): """ Return the length of the leg of cell ``(k, r, c)`` in ``self``. @@ -1343,7 +1343,7 @@ def contains(self, mu): """ return mu.level() <= self.level() and all(self[c].contains(mu[c]) for c in range(len(mu))) - def hook_length(self, k,r,c): + def hook_length(self, k, r, c): r""" Return the length of the hook of cell ``(k, r, c)`` in the partition. @@ -1509,7 +1509,7 @@ def young_subgroup_generators(self): return gens @cached_method - def _initial_degree(self,e,multicharge): + def _initial_degree(self, e, multicharge): r""" Return the Brundan-Kleshchev-Wang degree of the initial tableau of shape ``self``. diff --git a/src/sage/combinat/path_tableaux/path_tableau.py b/src/sage/combinat/path_tableaux/path_tableau.py index 9d9177ee355..8d25be4a128 100644 --- a/src/sage/combinat/path_tableaux/path_tableau.py +++ b/src/sage/combinat/path_tableaux/path_tableau.py @@ -52,7 +52,7 @@ class PathTableau(ClonableArray, metaclass=InheritComparisonClasscallMetaclass): This is the abstract base class for a path tableau. """ @abstract_method - def local_rule(self,i): + def local_rule(self, i): r""" This is the abstract local rule defined in any coboundary category. @@ -216,7 +216,7 @@ def commutor(self, other, verbose=False): return (P(path[:m]), P(path[m-1:])) - def cactus(self,i,j): + def cactus(self, i, j): r""" Return the action of the generator `s_{i,j}` of the cactus group on ``self``. diff --git a/src/sage/combinat/path_tableaux/semistandard.py b/src/sage/combinat/path_tableaux/semistandard.py index 368caf54145..51ac4e4cbf8 100644 --- a/src/sage/combinat/path_tableaux/semistandard.py +++ b/src/sage/combinat/path_tableaux/semistandard.py @@ -173,7 +173,7 @@ def __init__(self, parent, st, check=True): elif isinstance(st, GelfandTsetlinPattern): w = list(st) w.reverse() - w = [(),*w] + w = [(), *w] elif isinstance(st, (Tableau,SkewTableau)): w = st.to_chain() diff --git a/src/sage/combinat/root_system/ambient_space.py b/src/sage/combinat/root_system/ambient_space.py index 0d00c45273f..d9afa05c169 100644 --- a/src/sage/combinat/root_system/ambient_space.py +++ b/src/sage/combinat/root_system/ambient_space.py @@ -197,7 +197,7 @@ def __call__(self, v): else: return CombinatorialFreeModule.__call__(self, v) - def __getitem__(self,i): + def __getitem__(self, i): """ Note that indexing starts at 1. diff --git a/src/sage/combinat/root_system/branching_rules.py b/src/sage/combinat/root_system/branching_rules.py index 91876ee8dd3..cf6b0012c85 100644 --- a/src/sage/combinat/root_system/branching_rules.py +++ b/src/sage/combinat/root_system/branching_rules.py @@ -136,7 +136,7 @@ def branch_weyl_character(chi, R, S, rule='default'): sage: B4 = WeylCharacterRing("B4", style='coroots') sage: A6 = WeylCharacterRing("A6", style='coroots') sage: A7 = WeylCharacterRing("A7", style='coroots') - sage: def try_default_rule(R,S): return [R(f).branch(S) for f in R.fundamental_weights()] + sage: def try_default_rule(R, S): return [R(f).branch(S) for f in R.fundamental_weights()] sage: try_default_rule(A2,A1) [A1(0) + A1(1), A1(0) + A1(1)] sage: try_default_rule(D4,B3) diff --git a/src/sage/combinat/root_system/extended_affine_weyl_group.py b/src/sage/combinat/root_system/extended_affine_weyl_group.py index b1d35c86f7a..9e72863e5bf 100644 --- a/src/sage/combinat/root_system/extended_affine_weyl_group.py +++ b/src/sage/combinat/root_system/extended_affine_weyl_group.py @@ -2035,7 +2035,7 @@ def __init__(self, E): """ # note that we have to use the multiplicative version of the translation lattice # and change the twist to deal with this - def twist(w,l): + def twist(w, l): return E.exp_lattice()(w.action(l.value)) GroupSemidirectProduct.__init__(self, E.exp_lattice(), E.classical_weyl(), twist=twist, act_to_right=False, prefix0=E._prefixt, print_tuple=E._print_tuple, category=E.Realizations()) @@ -2220,7 +2220,7 @@ def __init__(self, E): sage: W0P = ExtendedAffineWeylGroup(['D',3,2]).W0P() sage: TestSuite(W0P).run() """ - def twist(w,l): + def twist(w, l): return E.exp_lattice()(w.action(l.value)) GroupSemidirectProduct.__init__(self, E.classical_weyl(), E.exp_lattice(), twist=twist, act_to_right=True, prefix1=E._prefixt, print_tuple=E._print_tuple, category=E.Realizations()) @@ -2418,7 +2418,7 @@ def __init__(self, E): sage: WF = ExtendedAffineWeylGroup(['D',3,2]).WF() sage: TestSuite(WF).run() """ - def twist(g,w): + def twist(g, w): return g.act_on_affine_weyl(w) GroupSemidirectProduct.__init__(self, E.affine_weyl(), E.fundamental_group(), twist=twist, act_to_right=False, print_tuple=E._print_tuple, category=E.Realizations()) @@ -2579,7 +2579,7 @@ def __init__(self, E): sage: FW = ExtendedAffineWeylGroup(['D',3,2]).FW() sage: TestSuite(FW).run() """ - def twist(g,w): + def twist(g, w): return g.act_on_affine_weyl(w) GroupSemidirectProduct.__init__(self, E.fundamental_group(), E.affine_weyl(), twist=twist, act_to_right=True, print_tuple=E._print_tuple, category=E.Realizations()) @@ -2753,7 +2753,7 @@ def __init__(self, E): """ # note that we have to use the multiplicative version of the translation lattice # and change the twist to deal with this - def twist(w,l): + def twist(w, l): return E.exp_dual_lattice()(w.action(l.value)) GroupSemidirectProduct.__init__(self, E.exp_dual_lattice(), E.dual_classical_weyl(), twist=twist, act_to_right=False, prefix0=E._prefixt, print_tuple=E._print_tuple, category=E.Realizations()) @@ -2924,7 +2924,7 @@ def __init__(self, E): """ # note that we have to use the multiplicative version of the translation lattice # and change the twist to deal with this - def twist(w,l): + def twist(w, l): return E.exp_dual_lattice()(w.action(l.value)) GroupSemidirectProduct.__init__(self, E.dual_classical_weyl(), E.exp_dual_lattice(), twist=twist, act_to_right=True, prefix1=E._prefixt, print_tuple=E._print_tuple, category=E.Realizations()) diff --git a/src/sage/combinat/root_system/hecke_algebra_representation.py b/src/sage/combinat/root_system/hecke_algebra_representation.py index fd40907d33e..a2a5d4421dc 100644 --- a/src/sage/combinat/root_system/hecke_algebra_representation.py +++ b/src/sage/combinat/root_system/hecke_algebra_representation.py @@ -464,7 +464,7 @@ def _test_relations(self, **options): q2 = self._q2 T = self - def Ti(x,i,c): + def Ti(x, i, c): return T[i](x)+c*x try: diff --git a/src/sage/combinat/root_system/pieri_factors.py b/src/sage/combinat/root_system/pieri_factors.py index 36dc4a332f2..fa97defb73e 100644 --- a/src/sage/combinat/root_system/pieri_factors.py +++ b/src/sage/combinat/root_system/pieri_factors.py @@ -427,7 +427,7 @@ def maximal_elements_combinatorial(self): """ return [self.W.from_reduced_word(range(self.W.cartan_type().n, 0, -1))] - def stanley_symm_poly_weight(self,w): + def stanley_symm_poly_weight(self, w): r""" EXAMPLES:: diff --git a/src/sage/combinat/root_system/reflection_group_complex.py b/src/sage/combinat/root_system/reflection_group_complex.py index 32f57d5da95..1d2641d0c65 100644 --- a/src/sage/combinat/root_system/reflection_group_complex.py +++ b/src/sage/combinat/root_system/reflection_group_complex.py @@ -323,7 +323,7 @@ def __init__(self, W_types, index_set=None, hyperplane_index_set=None, reflectio raise ValueError("the given reflection index set (= %s) does not have the right size" % self._index_set.values()) self._reflection_index_set_inverse = {i: ii for ii,i in enumerate(self._reflection_index_set)} - def _irrcomp_repr_(self,W_type): + def _irrcomp_repr_(self, W_type): r""" Return the string representation of an irreducible component of ``self``. @@ -703,7 +703,7 @@ def reflections(self): return Family(self._reflection_index_set, lambda i: T[self._reflection_index_set_inverse[i]]) - def reflection(self,i): + def reflection(self, i): r""" Return the ``i``-th reflection of ``self``. @@ -1725,7 +1725,7 @@ def action_on_root(w, beta): return beta * w.to_matrix() @cached_function - def invariant_value(i,j): + def invariant_value(i, j): if i > j: return invariant_value(j,i).conjugate() val = sum(action_on_root(w, Delta[i]) * action_on_root(w, Delta[j]).conjugate() @@ -1782,7 +1782,7 @@ def invariant_form_standardization(self): """ return self.invariant_form().principal_square_root() - def set_reflection_representation(self,refl_repr=None): + def set_reflection_representation(self, refl_repr=None): r""" Set the reflection representation of ``self``. diff --git a/src/sage/combinat/root_system/weyl_characters.py b/src/sage/combinat/root_system/weyl_characters.py index d7f87d6f494..c8c44224741 100644 --- a/src/sage/combinat/root_system/weyl_characters.py +++ b/src/sage/combinat/root_system/weyl_characters.py @@ -2205,8 +2205,8 @@ def demazure_lusztig(self, i, v): sage: P. = PolynomialRing(QQ) sage: B2 = WeylCharacterRing("B2",style='coroots',base_ring=P); b2 = B2.ambient() - sage: def T1(f): return f.demazure_lusztig(1,v) - sage: def T2(f): return f.demazure_lusztig(2,v) + sage: def T1(f): return f.demazure_lusztig(1, v) + sage: def T2(f): return f.demazure_lusztig(2, v) sage: T1(T2(T1(T2(b2(1,-1))))) (v^2-v)*b2(0,-1) + v^2*b2(-1,1) sage: [T1(T1(f))==(v-1)*T1(f)+v*f for f in [b2(0,0), b2(1,0), b2(2,3)]] diff --git a/src/sage/combinat/sf/k_dual.py b/src/sage/combinat/sf/k_dual.py index ad7471ec001..6d8151c00ac 100644 --- a/src/sage/combinat/sf/k_dual.py +++ b/src/sage/combinat/sf/k_dual.py @@ -378,7 +378,7 @@ def one(self): """ return self.a_realization().one() - def retract(self,la): + def retract(self, la): r""" Give the retract map from the symmetric functions to the quotient ring of `k`-bounded symmetric functions. This method is here to make the TestSuite run @@ -492,7 +492,7 @@ def super_categories(self): class ParentMethods: - def retract(self,la): + def retract(self, la): r""" Give the retract map from the symmetric functions to the quotient ring of `k`-bounded symmetric functions. This method is here to make the TestSuite run diff --git a/src/sage/combinat/sf/sf.py b/src/sage/combinat/sf/sf.py index 9f15dd18fea..546a3d22367 100644 --- a/src/sage/combinat/sf/sf.py +++ b/src/sage/combinat/sf/sf.py @@ -1604,7 +1604,7 @@ def __init__(self, t, domain, codomain): sage: Sym = SymmetricFunctions(QQ['x']) sage: p = Sym.p(); s = Sym.s() - sage: def t(x) : [(p,c)] = x; return [ (p,2*c), (p.conjugate(), c) ] + sage: def t(x) : [(p, c)] = x; return [ (p, 2*c), (p.conjugate(), c) ] sage: f = sage.combinat.sf.sf.SymmetricaConversionOnBasis(t, p, s) sage: f(Partition([3,1])) s[2, 1, 1] + 2*s[3, 1] diff --git a/src/sage/combinat/sf/sfa.py b/src/sage/combinat/sf/sfa.py index 794f7a0cb42..8d911087b24 100644 --- a/src/sage/combinat/sf/sfa.py +++ b/src/sage/combinat/sf/sfa.py @@ -3783,7 +3783,7 @@ def omega(self): omega_involution = omega - def theta(self,a): + def theta(self, a): r""" Return the image of ``self`` under the theta endomorphism which sends `p_k` to `a \cdot p_k` for every positive integer `k`. diff --git a/src/sage/combinat/similarity_class_type.py b/src/sage/combinat/similarity_class_type.py index caa691ac559..de3ce6f7989 100644 --- a/src/sage/combinat/similarity_class_type.py +++ b/src/sage/combinat/similarity_class_type.py @@ -101,7 +101,7 @@ class type, it is also possible to compute the number of classes of that type sage: from sage.combinat.similarity_class_type import order_of_general_linear_group, centralizer_algebra_dim sage: q = ZZ['q'].gen() - sage: def simultaneous_similarity_classes(n,k): + sage: def simultaneous_similarity_classes(n, k): ....: return SimilarityClassTypes(n).sum(lambda la: q**(k*centralizer_algebra_dim(la)), invertible = True)/order_of_general_linear_group(n) sage: simultaneous_similarity_classes(3, 2) q^10 + q^8 + 2*q^7 + 2*q^6 + 2*q^5 + q^4 diff --git a/src/sage/combinat/sloane_functions.py b/src/sage/combinat/sloane_functions.py index 08897c8b6da..b9651829109 100644 --- a/src/sage/combinat/sloane_functions.py +++ b/src/sage/combinat/sloane_functions.py @@ -6366,7 +6366,7 @@ def _repr_(self): """ return "Linear second order recurrence. A051959." - def g(self,k): + def g(self, k): """ EXAMPLES:: diff --git a/src/sage/combinat/subset.py b/src/sage/combinat/subset.py index 6c8d923ce9f..d6cc38c5cd4 100644 --- a/src/sage/combinat/subset.py +++ b/src/sage/combinat/subset.py @@ -506,7 +506,7 @@ def __call__(self, el): else: return Parent.__call__(self, el) - def _element_constructor_(self,X): + def _element_constructor_(self, X): """ TESTS:: @@ -1148,7 +1148,7 @@ def __call__(self, el): else: return Parent.__call__(self, el) - def _element_constructor_(self,X): + def _element_constructor_(self, X): """ TESTS:: diff --git a/src/sage/combinat/subsets_pairwise.py b/src/sage/combinat/subsets_pairwise.py index d8fec5c1a0c..18f6e13a5a9 100644 --- a/src/sage/combinat/subsets_pairwise.py +++ b/src/sage/combinat/subsets_pairwise.py @@ -39,7 +39,7 @@ class PairwiseCompatibleSubsets(RecursivelyEnumeratedSet_forest): elements are pairwise relatively prime:: sage: from sage.combinat.subsets_pairwise import PairwiseCompatibleSubsets - sage: def predicate(x,y): return gcd(x,y) == 1 + sage: def predicate(x, y): return gcd(x, y) == 1 sage: P = PairwiseCompatibleSubsets( [4,5,6,8,9], predicate); P An enumerated set with a forest structure sage: P.list() @@ -91,7 +91,7 @@ def __init__(self, ambient, predicate, maximal=False, element_class=Set_object_e TESTS:: sage: from sage.combinat.subsets_pairwise import PairwiseCompatibleSubsets - sage: def predicate(x,y): return gcd(x,y) == 1 + sage: def predicate(x, y): return gcd(x, y) == 1 sage: P = PairwiseCompatibleSubsets( [4,5,6,8,9], predicate); P An enumerated set with a forest structure sage: import __main__; __main__.predicate = predicate @@ -113,7 +113,7 @@ def __eq__(self, other): TESTS:: sage: from sage.combinat.subsets_pairwise import PairwiseCompatibleSubsets - sage: def predicate(x,y): return gcd(x,y) == 1 + sage: def predicate(x, y): return gcd(x, y) == 1 sage: P = PairwiseCompatibleSubsets( [4,5,6,8,9], predicate); P An enumerated set with a forest structure sage: P == P @@ -131,7 +131,7 @@ def __contains__(self, subset): EXAMPLES:: sage: from sage.combinat.subsets_pairwise import PairwiseCompatibleSubsets - sage: def predicate(x,y): return gcd(x,y) == 1 + sage: def predicate(x, y): return gcd(x, y) == 1 sage: P = PairwiseCompatibleSubsets( [4,5,6,8,9], predicate); P An enumerated set with a forest structure sage: Set([5,8,9]) in P @@ -150,7 +150,7 @@ def post_process(self, subset_rest): TESTS:: sage: from sage.combinat.subsets_pairwise import PairwiseCompatibleSubsets - sage: def predicate(x,y): return gcd(x,y) == 1 + sage: def predicate(x, y): return gcd(x, y) == 1 sage: P = PairwiseCompatibleSubsets( [4,5,6,8,9], predicate); P An enumerated set with a forest structure sage: P.post_process( ((4,5), (9)) ) @@ -167,7 +167,7 @@ def children(self, subset_rest): TESTS:: sage: from sage.combinat.subsets_pairwise import PairwiseCompatibleSubsets - sage: def predicate(x,y): return gcd(x,y) == 1 + sage: def predicate(x, y): return gcd(x, y) == 1 sage: P = PairwiseCompatibleSubsets( [3,5,7,11,14], predicate); P An enumerated set with a forest structure sage: list(P.children( ((3,5), [14,11,7]) )) diff --git a/src/sage/combinat/tutorial.py b/src/sage/combinat/tutorial.py index ef77bf66d4e..c8d18942181 100644 --- a/src/sage/combinat/tutorial.py +++ b/src/sage/combinat/tutorial.py @@ -1314,7 +1314,7 @@ combinatorics, especially when combined with recursion. Here is how to generate all words of a given length on a given alphabet:: - sage: def words(alphabet,l): + sage: def words(alphabet, l): ....: if l == 0: ....: yield [] ....: else: diff --git a/src/sage/combinat/words/word_generators.py b/src/sage/combinat/words/word_generators.py index 5803709ba5b..05ccb242508 100644 --- a/src/sage/combinat/words/word_generators.py +++ b/src/sage/combinat/words/word_generators.py @@ -589,7 +589,7 @@ def FibonacciWord(self, alphabet=(0, 1), construction_method='recursive'): else: raise NotImplementedError - def _FibonacciWord_RecursiveConstructionIterator(self,alphabet=(0,1)): + def _FibonacciWord_RecursiveConstructionIterator(self, alphabet=(0, 1)): r""" Iterate over the symbols of the Fibonacci word, as defined by the following recursive construction: the Fibonacci word is the @@ -659,7 +659,7 @@ def FixedPointOfMorphism(self, morphism, first_letter): """ return WordMorphism(morphism).fixed_point(letter=first_letter) - def CodingOfRotationWord(self, alpha, beta, x=0, alphabet=(0,1)): + def CodingOfRotationWord(self, alpha, beta, x=0, alphabet=(0, 1)): r""" Return the infinite word obtained from the coding of rotation of parameters `(\alpha,\beta, x)` over the given two-letter alphabet. @@ -695,7 +695,7 @@ def CodingOfRotationWord(self, alpha, beta, x=0, alphabet=(0,1)): w = InfiniteWords(alphabet)(f, datatype='callable') return w - def _CodingOfRotationWord_function(self, n, alpha, beta, x=0, alphabet=(0,1)): + def _CodingOfRotationWord_function(self, n, alpha, beta, x=0, alphabet=(0, 1)): r""" Internal function that returns the symbol in position `n` of the coding of rotation word corresponding to the parameters `\alpha`, @@ -901,7 +901,7 @@ def CharacteristicSturmianWord(self, slope, alphabet=(0, 1), bits=None): datatype='iter') return w - def _CharacteristicSturmianWord_LetterIterator(self, cf, alphabet=(0,1)): + def _CharacteristicSturmianWord_LetterIterator(self, cf, alphabet=(0, 1)): r""" Return an iterator over the symbols of the characteristic Sturmian word of slope ``cf``. @@ -967,7 +967,7 @@ def _CharacteristicSturmianWord_LetterIterator(self, cf, alphabet=(0,1)): except StopIteration: return - def KolakoskiWord(self, alphabet=(1,2)): + def KolakoskiWord(self, alphabet=(1, 2)): r""" Return the Kolakoski word over the given alphabet and starting with the first letter of the alphabet. @@ -1392,7 +1392,7 @@ def RandomWord(self, n, m=2, alphabet=None): ChristoffelWord = LowerChristoffelWord - def UpperChristoffelWord(self, p, q, alphabet=(0,1)): + def UpperChristoffelWord(self, p, q, alphabet=(0, 1)): r""" Return the upper Christoffel word of slope `p/q`, where `p` and `q` are relatively prime nonnegative diff --git a/src/sage/crypto/boolean_function.pyx b/src/sage/crypto/boolean_function.pyx index 7f8f4b4fba0..1716c78f2d9 100644 --- a/src/sage/crypto/boolean_function.pyx +++ b/src/sage/crypto/boolean_function.pyx @@ -983,7 +983,7 @@ cdef class BooleanFunction(SageObject): self._sum_of_square_indicator = sum(a**2 for a in D) return self._sum_of_square_indicator - def annihilator(self,d, dim = False): + def annihilator(self, d, dim=False): r""" Return (if it exists) an annihilator of the boolean function of degree at most `d`, that is a Boolean polynomial `g` such that @@ -1054,7 +1054,7 @@ cdef class BooleanFunction(SageObject): else: return res - def algebraic_immunity(self, annihilator = False): + def algebraic_immunity(self, annihilator=False): """ Return the algebraic immunity of the Boolean function. diff --git a/src/sage/crypto/stream.py b/src/sage/crypto/stream.py index a9e94d63b24..1462295774e 100644 --- a/src/sage/crypto/stream.py +++ b/src/sage/crypto/stream.py @@ -95,7 +95,7 @@ def _repr_(self): """ return "LFSR cryptosystem over %s" % self._field - def encoding(self,M): + def encoding(self, M): S = self.cipher_domain() try: return S.encoding(M) @@ -160,7 +160,7 @@ def _repr_(self): """ return "Shrinking generator cryptosystem over %s" % self._field - def encoding(self,M): + def encoding(self, M): S = self.cipher_domain() try: return S.encoding(M) diff --git a/src/sage/data_structures/bitset.pxd b/src/sage/data_structures/bitset.pxd index 35343fa28ae..db627b294cd 100644 --- a/src/sage/data_structures/bitset.pxd +++ b/src/sage/data_structures/bitset.pxd @@ -12,7 +12,7 @@ from sage.data_structures.bitset_base cimport bitset_t # Python layer over bitset_t cdef class FrozenBitset: cdef bitset_t _bitset - cdef FrozenBitset _new(self,long int capacity) + cdef FrozenBitset _new(self, long int capacity) cpdef FrozenBitset _larger_capacity_(self, long size) cpdef long capacity(self) noexcept cpdef bint isempty(self) noexcept diff --git a/src/sage/data_structures/bounded_integer_sequences.pyx b/src/sage/data_structures/bounded_integer_sequences.pyx index 44635ad2364..96dd83b4f8e 100644 --- a/src/sage/data_structures/bounded_integer_sequences.pyx +++ b/src/sage/data_structures/bounded_integer_sequences.pyx @@ -1380,7 +1380,7 @@ def _biseq_stresstest(): cdef int branch cdef Py_ssize_t x, y, z from sage.misc.prandom import randint - cdef list L = [BoundedIntegerSequence(6, [randint(0,5) for z in range(randint(4,10))]) for y in range(100)] + cdef list L = [BoundedIntegerSequence(6, [randint(0, 5) for z in range(randint(4, 10))]) for y in range(100)] cdef BoundedIntegerSequence S, T while True: branch = randint(0,4) diff --git a/src/sage/databases/cremona.py b/src/sage/databases/cremona.py index 44c8fbcdc7f..ca859214155 100644 --- a/src/sage/databases/cremona.py +++ b/src/sage/databases/cremona.py @@ -1651,7 +1651,7 @@ def _init_allgens(self, ftpdata, largest_conductor=0): _db = None -def CremonaDatabase(name=None,mini=None,set_global=None): +def CremonaDatabase(name=None, mini=None, set_global=None): """ Initialize the Cremona database with name ``name``. If ``name`` is ``None`` it instead initializes large Cremona database (named 'cremona'), diff --git a/src/sage/databases/findstat.py b/src/sage/databases/findstat.py index 811a190db8f..1285569805e 100644 --- a/src/sage/databases/findstat.py +++ b/src/sage/databases/findstat.py @@ -1784,7 +1784,7 @@ def set_sage_code(self, value): EXAMPLES:: sage: q = findstat([(d, randint(1,1000)) for d in DyckWords(4)]) # optional -- internet - sage: q.set_sage_code("def statistic(x):\n return randint(1,1000)") # optional -- internet + sage: q.set_sage_code("def statistic(x):\n return randint(1, 1000)") # optional -- internet sage: print(q.sage_code()) # optional -- internet def statistic(x): return randint(1,1000) diff --git a/src/sage/databases/sql_db.py b/src/sage/databases/sql_db.py index fad05a0add9..3ee328c6cf9 100644 --- a/src/sage/databases/sql_db.py +++ b/src/sage/databases/sql_db.py @@ -296,7 +296,7 @@ def _create_print_table(cur, col_titles, **kwds): plot should be drawn by the object generated by a data slice. Note that plot kwds are permitted. The dictionary format is:: - {'column_name':((lambda x: plot_function(x)),**kwds)} + {'column_name':((lambda x: plot_function(x)), **kwds)} - ``relabel_cols`` -- dictionary to specify a relabeling of column headers. The dictionary format is:: @@ -629,7 +629,7 @@ def show(self, **kwds): plot should be drawn by the object generated by a data slice. Note that plot kwds are permitted. The dictionary format is:: - {'column_name':((lambda x: plot_function(x)),**kwds)} + {'column_name':((lambda x: plot_function(x)), **kwds)} - ``relabel_cols`` -- dictionary to specify a relabeling of column headers. The dictionary format is:: diff --git a/src/sage/doctest/sources.py b/src/sage/doctest/sources.py index 78c45195970..7589f62922b 100644 --- a/src/sage/doctest/sources.py +++ b/src/sage/doctest/sources.py @@ -1013,7 +1013,7 @@ def _update_quotetype(self, line): sage: print(FDS.quotetype) None """ - def _update_parens(start,end=None): + def _update_parens(start, end=None): self.paren_count += line.count("(",start,end) - line.count(")",start,end) self.bracket_count += line.count("[",start,end) - line.count("]",start,end) self.curly_count += line.count("{",start,end) - line.count("}",start,end) diff --git a/src/sage/dynamics/arithmetic_dynamics/projective_ds.py b/src/sage/dynamics/arithmetic_dynamics/projective_ds.py index a74efd9129a..cf8948913a7 100644 --- a/src/sage/dynamics/arithmetic_dynamics/projective_ds.py +++ b/src/sage/dynamics/arithmetic_dynamics/projective_ds.py @@ -2811,7 +2811,7 @@ def nth_preimage_tree(self, Q, n, **kwds): display_complex = True kwds["embed"] = embed else: - field_def = self.field_of_definition_preimage(Q,n) + field_def = self.field_of_definition_preimage(Q, n) fbar = self.change_ring(field_def) if display_complex: embed = field_def.embeddings(ComplexField())[0] @@ -2819,7 +2819,7 @@ def nth_preimage_tree(self, Q, n, **kwds): elif base_ring in FiniteFields(): if numerical: raise ValueError("can't solve numerically over a finite field, no embedding into CC") - field_def = self.field_of_definition_preimage(Q,n) + field_def = self.field_of_definition_preimage(Q, n) fbar = self.change_ring(field_def) # No embedding from finite field into C kwds["display_complex"] = False diff --git a/src/sage/dynamics/arithmetic_dynamics/wehlerK3.py b/src/sage/dynamics/arithmetic_dynamics/wehlerK3.py index 3ef9877e782..766dff990e0 100644 --- a/src/sage/dynamics/arithmetic_dynamics/wehlerK3.py +++ b/src/sage/dynamics/arithmetic_dynamics/wehlerK3.py @@ -1299,7 +1299,7 @@ def sigmaX(self, P, **kwds): return Point return self.point(Point, False) - def sigmaY(self,P, **kwds): + def sigmaY(self, P, **kwds): r""" Return the involution on the Wehler K3 surfaces induced by the double covers. @@ -1579,7 +1579,7 @@ def phi(self, a, **kwds): kwds.update({"check":False}) return self.sigmaY(A, **kwds) - def psi(self,a, **kwds): + def psi(self, a, **kwds): r""" Evaluates the function `\psi = \sigma_x \circ \sigma_y`. @@ -2448,7 +2448,7 @@ def is_isomorphic(self, right): """ return self.defining_ideal() == right.defining_ideal() - def is_symmetric_orbit(self,orbit): + def is_symmetric_orbit(self, orbit): r""" Check to see if the orbit is symmetric (i.e. if one of the points on the orbit is fixed by '\sigma_x' or '\sigma_y'). diff --git a/src/sage/games/quantumino.py b/src/sage/games/quantumino.py index e40dc47f407..555f6901f4a 100644 --- a/src/sage/games/quantumino.py +++ b/src/sage/games/quantumino.py @@ -205,7 +205,7 @@ pentaminos.append(Polyomino([(0,0,0), (0,1,0), (1,1,0), (1,2,0), (1,2,1)], color='purple')) pentaminos.append(Polyomino([(0,1,0), (1,0,0), (1,1,0), (1,1,1), (1,2,0)], color='gray')) -def show_pentaminos(box=(5,8,2)): +def show_pentaminos(box=(5, 8, 2)): r""" Show the 17 3-D pentaminos included in the game and the `5 \times 8 \times 2` box where 16 of them must fit. @@ -278,7 +278,7 @@ class QuantuminoState(SageObject): Quantumino state where the following pentamino is put aside : Polyomino: [(0, 0, 0), (0, 1, 0), (0, 2, 0), (1, 0, 0), (1, 0, 1)], Color: green """ - def __init__(self, pentos, aside, box=(5,8,2)): + def __init__(self, pentos, aside, box=(5, 8, 2)): r""" EXAMPLES:: diff --git a/src/sage/geometry/cone.py b/src/sage/geometry/cone.py index c4b308adbfa..edb5aa3a3af 100644 --- a/src/sage/geometry/cone.py +++ b/src/sage/geometry/cone.py @@ -6796,7 +6796,7 @@ def random_cone(lattice=None, min_ambient_dim=0, max_ambient_dim=None, # Same thing, except when we're given a lattice. max_rays = 2*(lattice.dimension() - 1) - def random_min_max(l,u): + def random_min_max(l, u): r""" We need to handle two cases for the upper bounds, and we need to do the same thing for max_ambient_dim/max_rays. So we consolidate diff --git a/src/sage/geometry/cone_catalog.py b/src/sage/geometry/cone_catalog.py index d58302d5915..27a308193cf 100644 --- a/src/sage/geometry/cone_catalog.py +++ b/src/sage/geometry/cone_catalog.py @@ -530,7 +530,7 @@ def rearrangement(p, ambient_dim=None, lattice=None): cone should sum to a nonnegative number. In other words, the generators really are what we think they are:: - sage: def _has_rearrangement_property(v,p): + sage: def _has_rearrangement_property(v, p): ....: return sum( sorted(v)[0:p] ) >= 0 sage: all( ....: _has_rearrangement_property( @@ -713,7 +713,7 @@ def schur(ambient_dim=None, lattice=None): sage: ambient_dim = ZZ.random_element(10) sage: V = VectorSpace(QQ, ambient_dim) sage: rearrange = lambda z: V(sorted(z.list(),reverse=True)) - sage: def majorized_by(x,y): + sage: def majorized_by(x, y): ....: x = rearrange(x) ....: y = rearrange(y) ....: return (all(sum(x[0:i]) <= sum(y[0:i]) @@ -755,7 +755,7 @@ def schur(ambient_dim=None, lattice=None): ambient_dim, lattice = _preprocess_args(ambient_dim, lattice) - def _f(i,j): + def _f(i, j): if i == j: return 1 elif j - i == 1: diff --git a/src/sage/geometry/cone_critical_angles.py b/src/sage/geometry/cone_critical_angles.py index 9e5252a4bf9..964280e6205 100644 --- a/src/sage/geometry/cone_critical_angles.py +++ b/src/sage/geometry/cone_critical_angles.py @@ -676,7 +676,7 @@ def compute_gevp_M(gs, hs): True sage: G = matrix.column(gs) sage: H = matrix.column(hs) - sage: def _test_indexing(I,J): + sage: def _test_indexing(I, J): ....: G_I = G.matrix_from_columns(I) ....: H_J = H.matrix_from_columns(J) ....: return (G_I.transpose()*H_J == M[I,J] diff --git a/src/sage/geometry/polyhedron/double_description_inhomogeneous.py b/src/sage/geometry/polyhedron/double_description_inhomogeneous.py index 873b3b431ea..bc7d3b76539 100644 --- a/src/sage/geometry/polyhedron/double_description_inhomogeneous.py +++ b/src/sage/geometry/polyhedron/double_description_inhomogeneous.py @@ -7,7 +7,7 @@ H/V-representations of polyhedra. The latter works with cones only. This is sufficient to treat general polyhedra by the following construction: Any polyhedron can be embedded in one dimension higher -in the hyperplane `(1,*,\dots,*)`. The cone over the embedded +in the hyperplane `(1, *, \dots, *)`. The cone over the embedded polyhedron will be called the *homogenized cone* in the following. Conversely, intersecting the homogenized cone with the hyperplane `x_0=1` gives you back the original polyhedron. @@ -268,13 +268,13 @@ def _split_linear_subspace(self): return l1, L0 + [l - l[0] * l1 for l in L1] def _extract_Vrep(self, DD): - """ + r""" Extract the V-representation from the extremal rays of the homogeneous cone. The V-representation is the intersection of the cone generated by the rays `R` and ``self._linear_subspace`` with the - hyperplane `(1,*,*,...,*)`. + hyperplane `(1, *, *, \ldots, *)`. INPUT: diff --git a/src/sage/geometry/polyhedron/modules/formal_polyhedra_module.py b/src/sage/geometry/polyhedron/modules/formal_polyhedra_module.py index b17c2a1ce71..d7ef932a4cf 100644 --- a/src/sage/geometry/polyhedron/modules/formal_polyhedra_module.py +++ b/src/sage/geometry/polyhedron/modules/formal_polyhedra_module.py @@ -26,7 +26,7 @@ class FormalPolyhedraModule(CombinatorialFreeModule): EXAMPLES:: sage: from sage.geometry.polyhedron.modules.formal_polyhedra_module import FormalPolyhedraModule - sage: def closed_interval(a,b): return Polyhedron(vertices=[[a], [b]]) + sage: def closed_interval(a, b): return Polyhedron(vertices=[[a], [b]]) A three-dimensional vector space of polyhedra:: @@ -104,7 +104,7 @@ def __init__(self, base_ring, dimension, basis, category): TESTS:: sage: from sage.geometry.polyhedron.modules.formal_polyhedra_module import FormalPolyhedraModule - sage: def closed_interval(a,b): return Polyhedron(vertices=[[a], [b]]) + sage: def closed_interval(a, b): return Polyhedron(vertices=[[a], [b]]) sage: I01 = closed_interval(0, 1); I01.rename('conv([0], [1])') sage: I11 = closed_interval(1, 1); I11.rename('{[1]}') sage: I12 = closed_interval(1, 2); I12.rename('conv([1], [2])') @@ -125,7 +125,7 @@ def degree_on_basis(self, m): EXAMPLES:: sage: from sage.geometry.polyhedron.modules.formal_polyhedra_module import FormalPolyhedraModule - sage: def closed_interval(a,b): return Polyhedron(vertices=[[a], [b]]) + sage: def closed_interval(a, b): return Polyhedron(vertices=[[a], [b]]) sage: I01 = closed_interval(0, 1); I01.rename('conv([0], [1])') sage: I11 = closed_interval(1, 1); I11.rename('{[1]}') sage: I12 = closed_interval(1, 2); I12.rename('conv([1], [2])') diff --git a/src/sage/geometry/riemannian_manifolds/parametrized_surface3d.py b/src/sage/geometry/riemannian_manifolds/parametrized_surface3d.py index 27940e9a723..17fb5028df1 100644 --- a/src/sage/geometry/riemannian_manifolds/parametrized_surface3d.py +++ b/src/sage/geometry/riemannian_manifolds/parametrized_surface3d.py @@ -789,7 +789,7 @@ def first_fundamental_form_inverse_coefficient(self, index): raise ValueError("Index %s out of bounds." % str(index)) @cached_method - def rotation(self,theta): + def rotation(self, theta): r""" Give the matrix of the rotation operator over a given angle `\theta` with respect to the natural frame. @@ -1185,7 +1185,7 @@ def second_fundamental_form_coefficients(self): self._compute_second_fundamental_form_coefficient(index) return coefficients - def second_fundamental_form(self,vector1,vector2): + def second_fundamental_form(self, vector1, vector2): r""" Evaluates the second fundamental form on two vectors on the surface. If the vectors are given by `v=(v^1,v^2)` and `w=(w^1,w^2)`, the @@ -1569,7 +1569,7 @@ def _create_pt_ode_system(self, curve, t): pt_ode.function = lambda t, v1_v2: [fun1(t, v1_v2[0], v1_v2[1]), fun2(t, v1_v2[0], v1_v2[1])] return pt_ode - def parallel_translation_numerical(self,curve,t,v0,tinterval): + def parallel_translation_numerical(self, curve, t, v0, tinterval): r""" Numerically solve the equations for parallel translation of a vector along a curve on the surface. Explicitly, the equations for parallel diff --git a/src/sage/geometry/triangulation/triangulations.cc b/src/sage/geometry/triangulation/triangulations.cc index 8ea306d8f7c..fa8805c9e9d 100644 --- a/src/sage/geometry/triangulation/triangulations.cc +++ b/src/sage/geometry/triangulation/triangulations.cc @@ -68,9 +68,9 @@ void triangulations::add_neighbours(const simplices & s) { for (flips::const_iterator f=bistellar_flips.begin(); f!=bistellar_flips.end(); ++f) { - goodcircuit goody(s,*f); + goodcircuit goody(s, *f); if (goody.is_good()) { - goody.do_flip(s,*f); + goody.do_flip(s, *f); compact_simplices new_triang=goody.get_neighbor(); add_triang_if_new(new_triang); } diff --git a/src/sage/graphs/base/static_dense_graph.pxd b/src/sage/graphs/base/static_dense_graph.pxd index 0e580a02b57..af3c4db74eb 100644 --- a/src/sage/graphs/base/static_dense_graph.pxd +++ b/src/sage/graphs/base/static_dense_graph.pxd @@ -1,4 +1,4 @@ from sage.data_structures.binary_matrix cimport binary_matrix_t from libc.stdint cimport uint32_t, uint64_t -cdef dict dense_graph_init(binary_matrix_t m, g, translation = ?, force_undirected = ?) +cdef dict dense_graph_init(binary_matrix_t m, g, translation=?, force_undirected=?) diff --git a/src/sage/graphs/convexity_properties.pxd b/src/sage/graphs/convexity_properties.pxd index f6c1b68b6b8..f435ae0aba0 100644 --- a/src/sage/graphs/convexity_properties.pxd +++ b/src/sage/graphs/convexity_properties.pxd @@ -12,4 +12,4 @@ cdef class ConvexityProperties: cdef _bitset_convex_hull(self, bitset_t hull) cpdef hull(self, list vertices) cdef _greedy_increase(self, bitset_t bs) - cpdef hull_number(self, value_only = *, verbose = *) + cpdef hull_number(self, value_only=*, verbose=*) diff --git a/src/sage/graphs/generic_graph_pyx.pyx b/src/sage/graphs/generic_graph_pyx.pyx index a350ceeba86..9f8b90d79ab 100644 --- a/src/sage/graphs/generic_graph_pyx.pyx +++ b/src/sage/graphs/generic_graph_pyx.pyx @@ -390,7 +390,7 @@ cdef inline double sqrt_approx(double x, double y, double xx, double yy) noexcep Assuming that `x > y > 0`, it is a taylor expansion at `x^2`. To see how 'bad' the approximation is:: - sage: def dist(x,y): + sage: def dist(x, y): ....: x = abs(x) ....: y = abs(y) ....: return max(x,y) + min(x,y)**2/(2*max(x,y)) diff --git a/src/sage/graphs/strongly_regular_db.pyx b/src/sage/graphs/strongly_regular_db.pyx index 0fa241ba218..72db0131c59 100644 --- a/src/sage/graphs/strongly_regular_db.pyx +++ b/src/sage/graphs/strongly_regular_db.pyx @@ -1840,7 +1840,7 @@ def eigenmatrix(int v, int k, int l, int mu): return Matrix(ZZ, [[1, k, v-k-1], [1, r, -r-1], [1, s, -s-1]]) -cpdef latin_squares_graph_parameters(int v, int k, int l,int mu): +cpdef latin_squares_graph_parameters(int v, int k, int l, int mu): r""" Check whether (v,k,l,mu)-strongly regular graph has parameters of an `L_g(n)` s.r.g. diff --git a/src/sage/groups/group_semidirect_product.py b/src/sage/groups/group_semidirect_product.py index 7287a79f614..5e06d203172 100644 --- a/src/sage/groups/group_semidirect_product.py +++ b/src/sage/groups/group_semidirect_product.py @@ -31,7 +31,7 @@ def _repr_(self): EXAMPLES:: - sage: def twist(x,y): + sage: def twist(x, y): ....: return y sage: GroupSemidirectProduct(WeylGroup(['A',2],prefix='s'), # indirect doctest ....: WeylGroup(['A',3],prefix='t'), twist) @@ -73,7 +73,7 @@ def __invert__(self): sage: from sage.groups.group_exp import GroupExp sage: EL = GroupExp()(L) sage: W = L.weyl_group(prefix='s') - sage: def twist(w,v): + sage: def twist(w, v): ....: return EL(w.action(v.value)) sage: G = GroupSemidirectProduct(W, EL, twist, prefix1='t') sage: g = G.an_element(); g @@ -105,7 +105,7 @@ def to_opposite(self): sage: W = L.weyl_group(prefix='s'); W Weyl Group of type ['A', 2] (as a matrix group acting on the root lattice) - sage: def twist(w,v): + sage: def twist(w, v): ....: return EL(w.action(v.value)) sage: G = GroupSemidirectProduct(W, EL, twist, prefix1='t'); G Semidirect product of Weyl Group of type ['A', 2] (as a matrix @@ -215,7 +215,7 @@ class GroupSemidirectProduct(CartesianProduct): sage: G = GL(2,QQ) sage: V = QQ^2 sage: EV = GroupExp()(V) # make a multiplicative version of V - sage: def twist(g,v): + sage: def twist(g, v): ....: return EV(g*v.value) sage: H = GroupSemidirectProduct(G, EV, twist=twist, prefix1='t'); H Semidirect product of General Linear Group of degree 2 @@ -229,7 +229,7 @@ class GroupSemidirectProduct(CartesianProduct): sage: # needs sage.rings.number_field sage: cartan_type = CartanType(['A',2]) sage: W = WeylGroup(cartan_type, prefix='s') - sage: def twist(w,v): + sage: def twist(w, v): ....: return w*v*(~w) sage: WW = GroupSemidirectProduct(W, W, twist=twist, print_tuple=True) sage: s = Family(cartan_type.index_set(), lambda i: W.simple_reflection(i)) @@ -252,7 +252,7 @@ def __init__(self, G, H, twist=None, act_to_right=True, prefix0=None, EXAMPLES:: - sage: def twist(x,y): + sage: def twist(x, y): ....: return y sage: import __main__ sage: __main__.twist = twist @@ -297,7 +297,7 @@ def act_to_right(self): EXAMPLES:: - sage: def twist(x,y): + sage: def twist(x, y): ....: return y sage: GroupSemidirectProduct(WeylGroup(['A',2],prefix='s'), ....: WeylGroup(['A',3],prefix='t'), twist).act_to_right() @@ -311,7 +311,7 @@ def _repr_(self): EXAMPLES:: - sage: def twist(x,y): + sage: def twist(x, y): ....: return y sage: GroupSemidirectProduct(WeylGroup(['A',2],prefix='s'), # indirect doctest ....: WeylGroup(['A',3],prefix='t'), twist) @@ -332,7 +332,7 @@ def _element_constructor_(self, x): r""" EXAMPLES:: - sage: def twist(x,y): + sage: def twist(x, y): ....: return y sage: import __main__ sage: __main__.twist = twist @@ -368,7 +368,7 @@ def one(self): sage: G = GL(2,QQ) sage: V = QQ^2 sage: EV = GroupExp()(V) # make a multiplicative version of V - sage: def twist(g,v): + sage: def twist(g, v): ....: return EV(g*v.value) sage: one = GroupSemidirectProduct(G, EV, twist=twist, prefix1='t').one(); one 1 @@ -418,7 +418,7 @@ def product(self, x, y): sage: G = GL(2,QQ) sage: V = QQ^2 sage: EV = GroupExp()(V) # make a multiplicative version of V - sage: def twist(g,v): + sage: def twist(g, v): ....: return EV(g*v.value) sage: S = GroupSemidirectProduct(G, EV, twist=twist, prefix1='t') sage: g = G([[2,1],[3,1]]); g @@ -491,7 +491,7 @@ def construction(self): EXAMPLES:: - sage: def twist(x,y): + sage: def twist(x, y): ....: return y sage: H = GroupSemidirectProduct(WeylGroup(['A',2],prefix='s'), ....: WeylGroup(['A',3],prefix='t'), twist) diff --git a/src/sage/groups/matrix_gps/isometries.py b/src/sage/groups/matrix_gps/isometries.py index 8e0df5f154b..a377066913b 100644 --- a/src/sage/groups/matrix_gps/isometries.py +++ b/src/sage/groups/matrix_gps/isometries.py @@ -288,7 +288,7 @@ class GroupActionOnSubmodule(Action): Echelon basis matrix: [0 1] """ - def __init__(self, MatrixGroup,submodule, is_left=False): + def __init__(self, MatrixGroup, submodule, is_left=False): r""" Initialize the action. diff --git a/src/sage/groups/perm_gps/partn_ref/data_structures.pyx b/src/sage/groups/perm_gps/partn_ref/data_structures.pyx index 28672d00038..127938a5209 100644 --- a/src/sage/groups/perm_gps/partn_ref/data_structures.pyx +++ b/src/sage/groups/perm_gps/partn_ref/data_structures.pyx @@ -1311,7 +1311,7 @@ def SC_test_list_perms(list L, int n, int limit, bint gap, bint limit_complain, sage: def random_perm(x): ....: shuffle(x) ....: return x - sage: def test_stab_chain_fns_6(m,n,k, gap, contains): + sage: def test_stab_chain_fns_6(m, n, k, gap, contains): ....: perms = [] ....: for i in range(k): ....: perm = sum([random_perm(list(range(i*(n//m),min(n,(i+1)*(n//m))))) for i in range(m)], []) diff --git a/src/sage/groups/perm_gps/partn_ref/refinement_python.pyx b/src/sage/groups/perm_gps/partn_ref/refinement_python.pyx index 0623c237b76..b6ed7963b12 100644 --- a/src/sage/groups/perm_gps/partn_ref/refinement_python.pyx +++ b/src/sage/groups/perm_gps/partn_ref/refinement_python.pyx @@ -345,11 +345,11 @@ class PythonObjectWrapper: EXAMPLES:: sage: from sage.groups.perm_gps.partn_ref.refinement_python import PythonObjectWrapper - sage: def acae(a,b): + sage: def acae(a, b): ....: return 0 - sage: def rari(a,b,c): + sage: def rari(a, b, c): ....: return 0 - sage: def cs(a,b,c,d,e): + sage: def cs(a, b, c, d, e): ....: return 0 sage: from sage.groups.perm_gps.partn_ref.refinement_python import PythonObjectWrapper sage: P = PythonObjectWrapper(None, acae, rari, cs, 7) # implicit doctest @@ -434,11 +434,11 @@ def aut_gp_and_can_lab_python(S, partition, n, EXAMPLES:: sage: from sage.groups.perm_gps.partn_ref.refinement_python import aut_gp_and_can_lab_python - sage: def acae(a,b): + sage: def acae(a, b): ....: return 0 - sage: def rari(a,b,c): + sage: def rari(a, b, c): ....: return 0 - sage: def cs(a,b,c,d,e): + sage: def cs(a, b, c, d, e): ....: return 0 sage: aut_gp_and_can_lab_python(None, [[0,1,2,3],[4,5]], 6, acae, rari, cs, True, True, True) ([[0, 1, 3, 2, 4, 5], @@ -513,16 +513,16 @@ def double_coset_python(S1, S2, partition1, ordering2, n, EXAMPLES:: sage: from sage.groups.perm_gps.partn_ref.refinement_python import double_coset_python - sage: def acae(a,b): + sage: def acae(a, b): ....: return 0 - sage: def rari(a,b,c): + sage: def rari(a, b, c): ....: return 0 - sage: def cs(a,b,c,d,e): + sage: def cs(a, b, c, d, e): ....: return 0 sage: double_coset_python(None, None, [[0,1,2,3],[4,5]], [2,3,1,5,0,4], 6, acae, rari, cs) [1, 2, 3, 5, 0, 4] - sage: def compare_lists(p1,p2,l1,l2,deg): + sage: def compare_lists(p1, p2, l1, l2, deg): ....: for i in range(len(l1)): ....: a1 = l1[p1[i]] ....: a2 = l2[p2[i]] diff --git a/src/sage/interfaces/mathematica.py b/src/sage/interfaces/mathematica.py index 71f233746e7..39c3aff9dc2 100644 --- a/src/sage/interfaces/mathematica.py +++ b/src/sage/interfaces/mathematica.py @@ -315,7 +315,7 @@ OTHER Examples:: - sage: def math_bessel_K(nu,x): + sage: def math_bessel_K(nu, x): ....: return mathematica(nu).BesselK(x).N(20) sage: math_bessel_K(2,I) # optional - mathematica -2.59288617549119697817 + 0.18048997206696202663*I diff --git a/src/sage/interfaces/mathics.py b/src/sage/interfaces/mathics.py index 3104fefe665..a6d39ad3c14 100644 --- a/src/sage/interfaces/mathics.py +++ b/src/sage/interfaces/mathics.py @@ -319,7 +319,7 @@ OTHER Examples:: - sage: def math_bessel_K(nu,x): + sage: def math_bessel_K(nu, x): ....: return mathics(nu).BesselK(x).N(20) sage: math_bessel_K(2,I) # optional - mathics -2.5928861754911969782 + 0.18048997206696202663 I diff --git a/src/sage/interfaces/maxima.py b/src/sage/interfaces/maxima.py index 96158d73039..08a8f37f751 100644 --- a/src/sage/interfaces/maxima.py +++ b/src/sage/interfaces/maxima.py @@ -1099,19 +1099,19 @@ def _object_function_class(self): # living in the symbolic ring and return something # that is hopefully coercible into the symbolic ring again. -# def sr_integral(self,*args): +# def sr_integral(self, *args): # return args[0]._maxima_().integrate(*args[1:]) -# def sr_sum(self,expression,v,a,b): +# def sr_sum(self, expression, v, a, b): # sum = "'sum(%s, %s, %s, %s)" % tuple([repr(expr._maxima_()) for expr in (expression, v, a, b)]) # result = self.simplify_sum(sum) # result = result.ratsimp() # return expression.parent()(result) -# def sr_limit(self,ex,*args): +# def sr_limit(self, ex, *args): # return ex._maxima_().limit(*args) -# def sr_tlimit(self,ex,*args): +# def sr_tlimit(self, ex, *args): # return ex._maxima_().tlimit(*args) diff --git a/src/sage/interfaces/tides.py b/src/sage/interfaces/tides.py index c1076496cea..42877ede9ee 100644 --- a/src/sage/interfaces/tides.py +++ b/src/sage/interfaces/tides.py @@ -340,7 +340,7 @@ def remove_repeated(l1, l2): j += 1 -def remove_constants(l1,l2): +def remove_constants(l1, l2): """ Given two lists, remove the entries in the first that are real constants, and also the corresponding elements in the second one. diff --git a/src/sage/libs/gap/element.pyx b/src/sage/libs/gap/element.pyx index 6345c898c66..b654438aad3 100644 --- a/src/sage/libs/gap/element.pyx +++ b/src/sage/libs/gap/element.pyx @@ -3254,7 +3254,7 @@ cdef class GapElement_RecordIterator(): # note the abs: negative values mean the rec keys are not sorted key_index = abs(GET_RNAM_PREC(self.rec.value, i)) key = char_to_str(GAP_CSTR_STRING(NAME_RNAM(key_index))) - cdef Obj result = GET_ELM_PREC(self.rec.value,i) + cdef Obj result = GET_ELM_PREC(self.rec.value, i) val = make_any_gap_element(self.rec.parent(), result) self.i += 1 return (key, val) diff --git a/src/sage/libs/giac/__init__.py b/src/sage/libs/giac/__init__.py index ef2267c4378..ba0be068152 100644 --- a/src/sage/libs/giac/__init__.py +++ b/src/sage/libs/giac/__init__.py @@ -88,7 +88,7 @@ def local_giacsettings(func): EXAMPLES:: - sage: def testf(a,b): + sage: def testf(a, b): ....: giacsettings.proba_epsilon = a/100 ....: giacsettings.threads = b+2 ....: return (giacsettings.proba_epsilon, giacsettings.threads) diff --git a/src/sage/libs/giac/auto-methods.pxi b/src/sage/libs/giac/auto-methods.pxi index 478c9c21bed..a7c214acab9 100644 --- a/src/sage/libs/giac/auto-methods.pxi +++ b/src/sage/libs/giac/auto-methods.pxi @@ -9,7 +9,7 @@ cdef class GiacMethods_base: :class:`Pygen` instead. """ - def Airy_Ai(self,*args): + def Airy_Ai(self, *args): r'''From Giac's documentation: Help for Airy_Ai: Airy_Ai(Real) @@ -18,9 +18,9 @@ cdef class GiacMethods_base: Ex1:Airy_Ai(0) Ex2:Airy_Ai(1.5) ''' - return GiacMethods['Airy_Ai'](self,*args) + return GiacMethods['Airy_Ai'](self, *args) - def Airy_Bi(self,*args): + def Airy_Bi(self, *args): r'''From Giac's documentation: Help for Airy_Bi: Airy_Bi(Real) @@ -29,9 +29,9 @@ cdef class GiacMethods_base: Ex1:Airy_Bi(1.5) Ex2:Airy_Bi(0) ''' - return GiacMethods['Airy_Bi'](self,*args) + return GiacMethods['Airy_Bi'](self, *args) - def Archive(self,*args): + def Archive(self, *args): r'''From Giac's documentation: Help for Archive: Archive(SeqVar) @@ -39,9 +39,9 @@ cdef class GiacMethods_base: See also: 1/ Unarchiv 2/ archive 3/ unarchive Ex1:Archive(a,b) ''' - return GiacMethods['Archive'](self,*args) + return GiacMethods['Archive'](self, *args) - def BesselJ(self,*args): + def BesselJ(self, *args): r'''From Giac's documentation: Help for BesselJ: BesselJ(Int(p),Real(x)) @@ -50,9 +50,9 @@ cdef class GiacMethods_base: Ex1:BesselJ(2,sqrt(2)) Ex2:BesselJ(-2,sqrt(2)) ''' - return GiacMethods['BesselJ'](self,*args) + return GiacMethods['BesselJ'](self, *args) - def BesselY(self,*args): + def BesselY(self, *args): r'''From Giac's documentation: Help for BesselY: BesselY(Int(p),Real(x)) @@ -61,9 +61,9 @@ cdef class GiacMethods_base: Ex1:BesselY(BesselJ(2,sqrt(2))) Ex2:BesselY(BesselJ(-2,sqrt(2))) ''' - return GiacMethods['BesselY'](self,*args) + return GiacMethods['BesselY'](self, *args) - def Beta(self,*args): + def Beta(self, *args): r'''From Giac's documentation: Help for Beta: Beta(Expr,Expr,[Expr],[1]) @@ -74,9 +74,9 @@ cdef class GiacMethods_base: Ex3:Beta(3,2,0.5) Ex4:Beta(3,2,0.5,1) ''' - return GiacMethods['Beta'](self,*args) + return GiacMethods['Beta'](self, *args) - def BlockDiagonal(self,*args): + def BlockDiagonal(self, *args): r'''From Giac's documentation: Help for BlockDiagonal: BlockDiagonal(Lst(l)||Mtrx(A)) @@ -85,9 +85,9 @@ cdef class GiacMethods_base: Ex1:BlockDiagonal([[1,2],[3,4]]) Ex2:BlockDiagonal([1,2,3]) ''' - return GiacMethods['BlockDiagonal'](self,*args) + return GiacMethods['BlockDiagonal'](self, *args) - def Ci(self,*args): + def Ci(self, *args): r'''From Giac's documentation: Help for Ci: Ci(Expr) @@ -95,9 +95,9 @@ cdef class GiacMethods_base: See also: 1/ Ei 2/ Si 3/ Li Ex1:Ci(1.0) ''' - return GiacMethods['Ci'](self,*args) + return GiacMethods['Ci'](self, *args) - def Circle(self,*args): + def Circle(self, *args): r'''From Giac's documentation: Help for Circle: Circle(Real(xc),Real(yc),Real(r),[Intg(option)]) @@ -107,9 +107,9 @@ cdef class GiacMethods_base: Ex2:Circle(0,1,1,0) Ex3:Circle(0,1,1,1) ''' - return GiacMethods['Circle'](self,*args) + return GiacMethods['Circle'](self, *args) - def Col(self,*args): + def Col(self, *args): r'''From Giac's documentation: Help for Col: Col(NULL) @@ -117,9 +117,9 @@ cdef class GiacMethods_base: See also: 1/ Row Ex1:Col() ''' - return GiacMethods['Col'](self,*args) + return GiacMethods['Col'](self, *args) - def CopyVar(self,*args): + def CopyVar(self, *args): r'''From Giac's documentation: Help for CopyVar: CopyVar(Var(var1),Var(var2)) @@ -127,9 +127,9 @@ cdef class GiacMethods_base: See also: 1/ Ex1:CopyVar(A,B) ''' - return GiacMethods['CopyVar'](self,*args) + return GiacMethods['CopyVar'](self, *args) - def Dirac(self,*args): + def Dirac(self, *args): r'''From Giac's documentation: Help for Dirac: Dirac(Real) @@ -139,9 +139,9 @@ cdef class GiacMethods_base: Ex2:Dirac(-1) Ex3: int(Dirac(x)*(x-1)^2,x,-1,2) ''' - return GiacMethods['Dirac'](self,*args) + return GiacMethods['Dirac'](self, *args) - def Ei(self,*args): + def Ei(self, *args): r'''From Giac's documentation: Help for Ei: Ei(Expr) @@ -149,9 +149,9 @@ cdef class GiacMethods_base: See also: 1/ Si 2/ Ci 3/ Li Ex1:Ei(1.0) ''' - return GiacMethods['Ei'](self,*args) + return GiacMethods['Ei'](self, *args) - def Factor(self,*args): + def Factor(self, *args): r'''From Giac's documentation: Help for Factor: Factor(Expr) @@ -160,9 +160,9 @@ cdef class GiacMethods_base: Ex1:Factor(x^4-1) Ex2:Factor(x^4+12*x^3+54*x^2+108*x+81) ''' - return GiacMethods['Factor'](self,*args) + return GiacMethods['Factor'](self, *args) - def GF(self,*args): + def GF(self, *args): r'''From Giac's documentation: Help for GF: GF(Intg(p), Intg(n)|Minpoly,[Variable],[0|undef|Poly]) @@ -174,9 +174,9 @@ cdef class GiacMethods_base: Ex5:GF(2,8,['a','G']) Ex6: G:=GF(2,a^8+a^6+a^3+a^2+1,['a','G'],undef) ''' - return GiacMethods['GF'](self,*args) + return GiacMethods['GF'](self, *args) - def Gamma(self,*args): + def Gamma(self, *args): r'''From Giac's documentation: Help for Gamma: Gamma(Real(a),[Real(b)]) @@ -187,9 +187,9 @@ cdef class GiacMethods_base: Ex3:Gamma(gamma(-5.1)) Ex4:Gamma(-5.1,2.1) ''' - return GiacMethods['Gamma'](self,*args) + return GiacMethods['Gamma'](self, *args) - def Heaviside(self,*args): + def Heaviside(self, *args): r'''From Giac's documentation: Help for Heaviside: Heaviside(Real) @@ -199,9 +199,9 @@ cdef class GiacMethods_base: Ex2:Heaviside(-1) Ex3:Heaviside(0) ''' - return GiacMethods['Heaviside'](self,*args) + return GiacMethods['Heaviside'](self, *args) - def JordanBlock(self,*args): + def JordanBlock(self, *args): r'''From Giac's documentation: Help for JordanBlock: JordanBlock(Expr(a),Intg(n)) @@ -209,9 +209,9 @@ cdef class GiacMethods_base: See also: 1/ jordan Ex1:JordanBlock(7,3) ''' - return GiacMethods['JordanBlock'](self,*args) + return GiacMethods['JordanBlock'](self, *args) - def LU(self,*args): + def LU(self, *args): r'''From Giac's documentation: Help for LU: LU(Mtrx(A),Var(L),Var(U),Var(P)) @@ -220,9 +220,9 @@ cdef class GiacMethods_base: Ex1:LU([[1,2],[3,4]],L,U,P) Ex2:LU([[6,12,18],[5,14,31],[3,8,18]],L,U,P) ''' - return GiacMethods['LU'](self,*args) + return GiacMethods['LU'](self, *args) - def LambertW(self,*args): + def LambertW(self, *args): r'''From Giac's documentation: Help for LambertW: LambertW(Real(x),[Intg(n)]) @@ -231,9 +231,9 @@ cdef class GiacMethods_base: Ex2:LambertW(ln(4)) Ex3:LambertW(-0.1,-1) ''' - return GiacMethods['LambertW'](self,*args) + return GiacMethods['LambertW'](self, *args) - def Li(self,*args): + def Li(self, *args): r'''From Giac's documentation: Help for Li: Li(Expr) @@ -241,9 +241,9 @@ cdef class GiacMethods_base: See also: 1/ Si 2/ Ci 3/ Ei Ex1:Li(2.0) ''' - return GiacMethods['Li'](self,*args) + return GiacMethods['Li'](self, *args) - def Line(self,*args): + def Line(self, *args): r'''From Giac's documentation: Help for Line: Line(Expr(a),Expr(b),Expr(c),Expr(d)) @@ -251,9 +251,9 @@ cdef class GiacMethods_base: See also: 1/ segment Ex1:Line(-1,-2,1,2) ''' - return GiacMethods['Line'](self,*args) + return GiacMethods['Line'](self, *args) - def LineHorz(self,*args): + def LineHorz(self, *args): r'''From Giac's documentation: Help for LineHorz: LineHorz(Expr(a)) @@ -261,9 +261,9 @@ cdef class GiacMethods_base: See also: 1/ Line 2/ LineVert Ex1:LineHorz(-1) ''' - return GiacMethods['LineHorz'](self,*args) + return GiacMethods['LineHorz'](self, *args) - def LineTan(self,*args): + def LineTan(self, *args): r'''From Giac's documentation: Help for LineTan: LineTan(Expr(f(x)),[Var],Expr(a)) @@ -275,9 +275,9 @@ cdef class GiacMethods_base: Ex4: LineTan x^2-x,1 Ex5: (LineTan sin(t),t,pi/4) ''' - return GiacMethods['LineTan'](self,*args) + return GiacMethods['LineTan'](self, *args) - def LineVert(self,*args): + def LineVert(self, *args): r'''From Giac's documentation: Help for LineVert: LineVert(Expr(a)) @@ -285,9 +285,9 @@ cdef class GiacMethods_base: See also: 1/ Line 2/ LineHorz Ex1:LineVert(2) ''' - return GiacMethods['LineVert'](self,*args) + return GiacMethods['LineVert'](self, *args) - def Phi(self,*args): + def Phi(self, *args): r'''From Giac's documentation: Help for Phi: Phi(Intg(n)) @@ -296,9 +296,9 @@ cdef class GiacMethods_base: Ex1:Phi(11) Ex2:Phi(6) ''' - return GiacMethods['Phi'](self,*args) + return GiacMethods['Phi'](self, *args) - def Pi(self,*args): + def Pi(self, *args): r'''From Giac's documentation: Help for Pi: Pi() @@ -309,9 +309,9 @@ cdef class GiacMethods_base: Ex3: evalf(pi) Ex4: evalf(Pi) ''' - return GiacMethods['Pi'](self,*args) + return GiacMethods['Pi'](self, *args) - def Psi(self,*args): + def Psi(self, *args): r'''From Giac's documentation: Help for Psi: Psi(Real(a),Intg(n)) @@ -319,9 +319,9 @@ cdef class GiacMethods_base: See also: 1/ Gamma Ex1:Psi(3,1) ''' - return GiacMethods['Psi'](self,*args) + return GiacMethods['Psi'](self, *args) - def QR(self,*args): + def QR(self, *args): r'''From Giac's documentation: Help for QR: QR(Mtrx,Var(Q),Var(R),[Real(eps)]) @@ -329,9 +329,9 @@ cdef class GiacMethods_base: See also: 1/ qr 2/ LU Ex1:QR([[1,2],[3,4]],Q,R) ''' - return GiacMethods['QR'](self,*args) + return GiacMethods['QR'](self, *args) - def RandSeed(self,*args): + def RandSeed(self, *args): r'''From Giac's documentation: Help for RandSeed: RandSeed(Intg) @@ -339,9 +339,9 @@ cdef class GiacMethods_base: See also: 1/ srand Ex1:RandSeed(321) ''' - return GiacMethods['RandSeed'](self,*args) + return GiacMethods['RandSeed'](self, *args) - def Row(self,*args): + def Row(self, *args): r'''From Giac's documentation: Help for Row: Row(NULL) @@ -349,9 +349,9 @@ cdef class GiacMethods_base: See also: 1/ Col Ex1:Row() ''' - return GiacMethods['Row'](self,*args) + return GiacMethods['Row'](self, *args) - def SortA(self,*args): + def SortA(self, *args): r'''From Giac's documentation: Help for SortA: SortA(LstReal||Seq||Mtrx) @@ -362,9 +362,9 @@ cdef class GiacMethods_base: Ex3: SortA [3,4,2],[6,4,5] Ex4: SortA [[3,4,2],[6,4,5]] ''' - return GiacMethods['SortA'](self,*args) + return GiacMethods['SortA'](self, *args) - def SortD(self,*args): + def SortD(self, *args): r'''From Giac's documentation: Help for SortD: SortD(LstReal||Seq||Mtrx) @@ -375,9 +375,9 @@ cdef class GiacMethods_base: Ex3: SortD [[3,4,2],[6,4,5]] Ex4: SortD [3,4,2],[6,4,5] ''' - return GiacMethods['SortD'](self,*args) + return GiacMethods['SortD'](self, *args) - def UTPC(self,*args): + def UTPC(self, *args): r'''From Giac's documentation: Help for UTPC: UTPC(Intg(n),Real(x0)) @@ -386,9 +386,9 @@ cdef class GiacMethods_base: Ex1:UTPC(2,6.1) Ex2:UTPC(4,6.1) ''' - return GiacMethods['UTPC'](self,*args) + return GiacMethods['UTPC'](self, *args) - def UTPF(self,*args): + def UTPF(self, *args): r'''From Giac's documentation: Help for UTPF: UTPF(Intg(n),Intg(d),Real(x0)) @@ -397,9 +397,9 @@ cdef class GiacMethods_base: Ex1:UTPF(4,10,3.5) Ex2:UTPF(4,4,2.1) ''' - return GiacMethods['UTPF'](self,*args) + return GiacMethods['UTPF'](self, *args) - def UTPN(self,*args): + def UTPN(self, *args): r'''From Giac's documentation: Help for UTPN: UTPN(Real(mu),Real(v),Real(x0)) @@ -408,9 +408,9 @@ cdef class GiacMethods_base: Ex1:UTPN(1.96) Ex2:UTPN(1,4,2.96)+normal_cdf(1,2,2.96) ''' - return GiacMethods['UTPN'](self,*args) + return GiacMethods['UTPN'](self, *args) - def UTPT(self,*args): + def UTPT(self, *args): r'''From Giac's documentation: Help for UTPT: UTPT(Intg(n),Real(x0)) @@ -419,9 +419,9 @@ cdef class GiacMethods_base: Ex1:UTPT(3,2.35) Ex2:UTPT(3,-2.35) ''' - return GiacMethods['UTPT'](self,*args) + return GiacMethods['UTPT'](self, *args) - def VARS(self,*args): + def VARS(self, *args): r'''From Giac's documentation: Help for VARS: VARS(NULL) @@ -429,9 +429,9 @@ cdef class GiacMethods_base: See also: 1/ lvar Ex1:VARS() ''' - return GiacMethods['VARS'](self,*args) + return GiacMethods['VARS'](self, *args) - def VAS(self,*args): + def VAS(self, *args): r'''From Giac's documentation: Help for VAS: VAS(Poly(P)) @@ -439,9 +439,9 @@ cdef class GiacMethods_base: See also: 1/ VAS_positive 2/ sturmab 3/ realroot Ex1:VAS(x^3-7*x+7) ''' - return GiacMethods['VAS'](self,*args) + return GiacMethods['VAS'](self, *args) - def VAS_positive(self,*args): + def VAS_positive(self, *args): r'''From Giac's documentation: Help for VAS_positive: VAS_positive(Poly(P)) @@ -449,9 +449,9 @@ cdef class GiacMethods_base: See also: 1/ poslbdLMQ 2/ posubLMQ 3/ VAS 4/ realroot Ex1:VAS_positive(x^3-7*x+7) ''' - return GiacMethods['VAS_positive'](self,*args) + return GiacMethods['VAS_positive'](self, *args) - def Zeta(self,*args): + def Zeta(self, *args): r'''From Giac's documentation: Help for Zeta: Zeta(Real(a)) @@ -459,9 +459,9 @@ cdef class GiacMethods_base: See also: 1/ sum Ex1:Zeta(2) ''' - return GiacMethods['Zeta'](self,*args) + return GiacMethods['Zeta'](self, *args) - def a2q(self,*args): + def a2q(self, *args): r'''From Giac's documentation: Help for a2q: a2q(Mtrx,VectVar) @@ -470,9 +470,9 @@ cdef class GiacMethods_base: Ex1:a2q([[1,2],[4,4]],[x,y]) Ex2:a2q([[1,3],[3,4]],[x,y]) ''' - return GiacMethods['a2q'](self,*args) + return GiacMethods['a2q'](self, *args) - def abcuv(self,*args): + def abcuv(self, *args): r'''From Giac's documentation: Help for abcuv: abcuv(Poly(a),Poly(b),Poly(c),[Var]) @@ -484,9 +484,9 @@ cdef class GiacMethods_base: Ex4:abcuv(X^2+2*X+1,X^2-1,X^3+1,X) Ex5:abcuv([1,2,1],[1,0,-1],[1,0,0,1]) ''' - return GiacMethods['abcuv'](self,*args) + return GiacMethods['abcuv'](self, *args) - def about(self,*args): + def about(self, *args): r'''From Giac's documentation: Help for about: about(Var(a)) @@ -495,9 +495,9 @@ cdef class GiacMethods_base: Ex1:about(a) Ex2:about(n) ''' - return GiacMethods['about'](self,*args) + return GiacMethods['about'](self, *args) - def abs(self,*args): + def abs(self, *args): r'''From Giac's documentation: Help for abs: abs(Cplx||LstCplx) @@ -508,9 +508,9 @@ cdef class GiacMethods_base: Ex3:abs((1+2*i)^2) Ex4:abs([-2,1+i,-4]) ''' - return GiacMethods['abs'](self,*args) + return GiacMethods['abs'](self, *args) - def abscissa(self,*args): + def abscissa(self, *args): r'''From Giac's documentation: Help for abscissa: abscissa(Pnt or Vect) @@ -521,9 +521,9 @@ cdef class GiacMethods_base: Ex3:abscissa(-1-i) Ex4:abscissa(point(1,2,3)) ''' - return GiacMethods['abscissa'](self,*args) + return GiacMethods['abscissa'](self, *args) - def accumulate_head_tail(self,*args): + def accumulate_head_tail(self, *args): r'''From Giac's documentation: Help for accumulate_head_tail: accumulate_head_tail(Lst(l),Intg(p),Intg(q)) @@ -531,9 +531,9 @@ cdef class GiacMethods_base: See also: 1/ Ex1:accumulate_head_tail([0,1,2,3,4,5,6,7,8,9],3,2) ''' - return GiacMethods['accumulate_head_tail'](self,*args) + return GiacMethods['accumulate_head_tail'](self, *args) - def acos(self,*args): + def acos(self, *args): r'''From Giac's documentation: Help for acos: acos(Expr) @@ -541,9 +541,9 @@ cdef class GiacMethods_base: See also: 1/ cos 2/ acosh Ex1:acos(0) ''' - return GiacMethods['acos'](self,*args) + return GiacMethods['acos'](self, *args) - def acos2asin(self,*args): + def acos2asin(self, *args): r'''From Giac's documentation: Help for acos2asin: acos2asin(Expr) @@ -552,9 +552,9 @@ cdef class GiacMethods_base: Ex1:acos2asin(acos(x)+asin(x)) Ex2:acos2asin(2*acos(x)) ''' - return GiacMethods['acos2asin'](self,*args) + return GiacMethods['acos2asin'](self, *args) - def acos2atan(self,*args): + def acos2atan(self, *args): r'''From Giac's documentation: Help for acos2atan: acos2atan(Expr) @@ -563,9 +563,9 @@ cdef class GiacMethods_base: Ex1:acos2atan(2*acos(x)) Ex2:acos2atan(acos(sqrt(1-x^2))+acos(x)) ''' - return GiacMethods['acos2atan'](self,*args) + return GiacMethods['acos2atan'](self, *args) - def acosh(self,*args): + def acosh(self, *args): r'''From Giac's documentation: Help for acosh: acosh(Expr) @@ -573,9 +573,9 @@ cdef class GiacMethods_base: See also: 1/ cosh 2/ acos Ex1:acosh(1) ''' - return GiacMethods['acosh'](self,*args) + return GiacMethods['acosh'](self, *args) - def acot(self,*args): + def acot(self, *args): r'''From Giac's documentation: Help for acot: acot(Expr) @@ -583,9 +583,9 @@ cdef class GiacMethods_base: See also: 1/ atan 2/ arccos Ex1:acot(0) ''' - return GiacMethods['acot'](self,*args) + return GiacMethods['acot'](self, *args) - def acsc(self,*args): + def acsc(self, *args): r'''From Giac's documentation: Help for acsc: acsc(Expr) @@ -594,18 +594,18 @@ cdef class GiacMethods_base: Ex1:acsc(1) Ex2:acsc(2) ''' - return GiacMethods['acsc'](self,*args) + return GiacMethods['acsc'](self, *args) - def acyclic(self,*args): + def acyclic(self, *args): r'''From Giac's documentation: Help for acyclic: acyclic(Opt) Option for the random_network command. See also: 1/ random_network ''' - return GiacMethods['acyclic'](self,*args) + return GiacMethods['acyclic'](self, *args) - def add(self,*args): + def add(self, *args): r'''From Giac's documentation: Help for add: add(Expr,Var,VarMin(a),VarMax(b),[VarStep(p)]) @@ -622,9 +622,9 @@ cdef class GiacMethods_base: Ex9:add(1/(x*(x+1)),x) Ex10:add(cos(n*x),n) ''' - return GiacMethods['add'](self,*args) + return GiacMethods['add'](self, *args) - def add_arc(self,*args): + def add_arc(self, *args): r'''From Giac's documentation: Help for add_arc: add_arc(Graph(G),Edge(e)||Trail(T)||Lst(E)) @@ -632,9 +632,9 @@ cdef class GiacMethods_base: See also: 1/ add_edge 2/ delete_arc 3/ digraph 4/ edges 5/ has_arc 6/ trail Ex1:add_arc(digraph(trail(1,2,3,4,5,1)),[[1,3],[2,4]]) ''' - return GiacMethods['add_arc'](self,*args) + return GiacMethods['add_arc'](self, *args) - def add_edge(self,*args): + def add_edge(self, *args): r'''From Giac's documentation: Help for add_edge: add_edge(Graph(G),Edge(e)||Trail(T)||Lst(E)) @@ -642,9 +642,9 @@ cdef class GiacMethods_base: See also: 1/ add_arc 2/ delete_edge 3/ edges 4/ graph 5/ has_edge 6/ trail Ex1:add_edge(graph(trail(1,2,3,4)),[4,1]) ''' - return GiacMethods['add_edge'](self,*args) + return GiacMethods['add_edge'](self, *args) - def add_vertex(self,*args): + def add_vertex(self, *args): r'''From Giac's documentation: Help for add_vertex: add_vertex(Graph(G),Vrtx(v)||Lst(V)) @@ -652,9 +652,9 @@ cdef class GiacMethods_base: See also: 1/ add_arc 2/ add_edge 3/ delete_vertex Ex1:add_vertex(cycle_graph(5),["a","b"]) ''' - return GiacMethods['add_vertex'](self,*args) + return GiacMethods['add_vertex'](self, *args) - def additionally(self,*args): + def additionally(self, *args): r'''From Giac's documentation: Help for additionally: additionally(Expr) @@ -663,9 +663,9 @@ cdef class GiacMethods_base: Ex1: assume(n,integer);additionally(n>5) Ex2: assume(n,integer);assume(n>=2,additionally) ''' - return GiacMethods['additionally'](self,*args) + return GiacMethods['additionally'](self, *args) - def addtable(self,*args): + def addtable(self, *args): r'''From Giac's documentation: Help for addtable: addtable(fourier||laplace,f(x),F(s),Var(x),Var(s)) @@ -673,9 +673,9 @@ cdef class GiacMethods_base: See also: 1/ fourier 2/ laplace Ex1:addtable(fourier,y(x),Y(s),x,s) ''' - return GiacMethods['addtable'](self,*args) + return GiacMethods['addtable'](self, *args) - def adjacency_matrix(self,*args): + def adjacency_matrix(self, *args): r'''From Giac's documentation: Help for adjacency_matrix: adjacency_matrix(Graph(G)) @@ -683,9 +683,9 @@ cdef class GiacMethods_base: See also: 1/ neighbors Ex1:adjacency_matrix(graph(trail(1,2,3,4,2,5,1,3))) ''' - return GiacMethods['adjacency_matrix'](self,*args) + return GiacMethods['adjacency_matrix'](self, *args) - def adjoint_matrix(self,*args): + def adjoint_matrix(self, *args): r'''From Giac's documentation: Help for adjoint_matrix: adjoint_matrix(Mtrx) @@ -693,9 +693,9 @@ cdef class GiacMethods_base: See also: 1/ pcar Ex1:adjoint_matrix([[1,i],[2,3]]) ''' - return GiacMethods['adjoint_matrix'](self,*args) + return GiacMethods['adjoint_matrix'](self, *args) - def affix(self,*args): + def affix(self, *args): r'''From Giac's documentation: Help for affix: affix(Pnt||Vect) @@ -705,9 +705,9 @@ cdef class GiacMethods_base: Ex2:affix(point(i)-point(1+2*i)) Ex3:affix([1,2]) ''' - return GiacMethods['affix'](self,*args) + return GiacMethods['affix'](self, *args) - def algsubs(self,*args): + def algsubs(self, *args): r'''From Giac's documentation: Help for algsubs: algsubs(Equal(Xpr1=Xpr2),Expr(Xpr)) @@ -717,9 +717,9 @@ cdef class GiacMethods_base: Ex2:algsubs(a*b/c=d, 2*a*b^2/c) Ex3:algsubs(2a=p^2-q^2,algsubs(2c=p^2+q^2,c^2-a^2)) ''' - return GiacMethods['algsubs'](self,*args) + return GiacMethods['algsubs'](self, *args) - def algvar(self,*args): + def algvar(self, *args): r'''From Giac's documentation: Help for algvar: algvar(Expr) @@ -727,9 +727,9 @@ cdef class GiacMethods_base: See also: 1/ lvar 2/ lname Ex1:algvar(sqrt(x)+y) ''' - return GiacMethods['algvar'](self,*args) + return GiacMethods['algvar'](self, *args) - def all_trig_solutions(self,*args): + def all_trig_solutions(self, *args): r'''From Giac's documentation: Help for all_trig_solutions: all_trig_solutions(:=Intg(0 or 1)) @@ -738,9 +738,9 @@ cdef class GiacMethods_base: Ex1: all_trig_solutions:=1 Ex2: all_trig_solutions:=0 ''' - return GiacMethods['all_trig_solutions'](self,*args) + return GiacMethods['all_trig_solutions'](self, *args) - def allpairs_distance(self,*args): + def allpairs_distance(self, *args): r'''From Giac's documentation: Help for allpairs_distance: allpairs_distance(Graph(G)) @@ -748,9 +748,9 @@ cdef class GiacMethods_base: See also: 1/ dijkstra 2/ graph_diameter 3/ vertex_distance Ex1:allpairs_distance(graph(%{[1,2],[1,3],[1,4],[1,5],[2,3],[3,4],[4,5],[5,2]%})) ''' - return GiacMethods['allpairs_distance'](self,*args) + return GiacMethods['allpairs_distance'](self, *args) - def alog10(self,*args): + def alog10(self, *args): r'''From Giac's documentation: Help for alog10: alog10(Expr) @@ -758,9 +758,9 @@ cdef class GiacMethods_base: See also: 1/ log10 Ex1:alog10(3) ''' - return GiacMethods['alog10'](self,*args) + return GiacMethods['alog10'](self, *args) - def altitude(self,*args): + def altitude(self, *args): r'''From Giac's documentation: Help for altitude: altitude((Pnt or Cplx),(Pnt or Cplx),(Pnt or Cplx)) @@ -768,9 +768,9 @@ cdef class GiacMethods_base: See also: 1/ perpendicular 2/ orthogonal 3/ orthocenter 4/ common_perpendicular Ex1:altitude(-1,1-i,i) ''' - return GiacMethods['altitude'](self,*args) + return GiacMethods['altitude'](self, *args) - def angle(self,*args): + def angle(self, *args): r'''From Giac's documentation: Help for angle: angle((Pnt or Cplx),(Pnt or Cplx),(Pnt or Cplx)) @@ -782,9 +782,9 @@ cdef class GiacMethods_base: Ex4:angle(0,1,i,"a") Ex5:angle(i,1,1+i,"b") ''' - return GiacMethods['angle'](self,*args) + return GiacMethods['angle'](self, *args) - def angle_radian(self,*args): + def angle_radian(self, *args): r'''From Giac's documentation: Help for angle_radian: angle_radian(:=Intg(0 or 1)) @@ -793,9 +793,9 @@ cdef class GiacMethods_base: Ex1: angle_radian:=1 Ex2: angle_radian:=0 ''' - return GiacMethods['angle_radian'](self,*args) + return GiacMethods['angle_radian'](self, *args) - def angleat(self,*args): + def angleat(self, *args): r'''From Giac's documentation: Help for angleat: angleat(Pnt(A),Pnt(B),Pnt(C),(Pnt or Cplx(z0))) @@ -803,9 +803,9 @@ cdef class GiacMethods_base: See also: 1/ angle 2/ angleatraw 3/ legend Ex1: A:=point(0);B:=point(1);C:=point(i);angleat(A,B,C,-2-i) ''' - return GiacMethods['angleat'](self,*args) + return GiacMethods['angleat'](self, *args) - def angleatraw(self,*args): + def angleatraw(self, *args): r'''From Giac's documentation: Help for angleatraw: angleatraw(Pnt(A)),Pnt(B),Pnt(C),(Pnt or Cplx(z0))) @@ -813,9 +813,9 @@ cdef class GiacMethods_base: See also: 1/ angle 2/ angleat Ex1: A:=point(0);B:=point(1);C:=point(i);angleatraw(A,B,C,-2-i) ''' - return GiacMethods['angleatraw'](self,*args) + return GiacMethods['angleatraw'](self, *args) - def ans(self,*args): + def ans(self, *args): r'''From Giac's documentation: Help for ans: ans(Intg(n)) @@ -825,9 +825,9 @@ cdef class GiacMethods_base: Ex2:ans(2) Ex3:ans(-2) ''' - return GiacMethods['ans'](self,*args) + return GiacMethods['ans'](self, *args) - def antiprism_graph(self,*args): + def antiprism_graph(self, *args): r'''From Giac's documentation: Help for antiprism_graph: antiprism_graph(Intg(n)) @@ -835,9 +835,9 @@ cdef class GiacMethods_base: See also: 1/ prism_graph Ex1:antiprism_graph(5) ''' - return GiacMethods['antiprism_graph'](self,*args) + return GiacMethods['antiprism_graph'](self, *args) - def append(self,*args): + def append(self, *args): r'''From Giac's documentation: Help for append: append((Lst||Set||Str(L),Elem)) @@ -850,9 +850,9 @@ cdef class GiacMethods_base: Ex5: S:=set[1,2,4];S:=append(S,6) Ex6: S:=set[1,2,4];S.append(6) ''' - return GiacMethods['append'](self,*args) + return GiacMethods['append'](self, *args) - def apply(self,*args): + def apply(self, *args): r'''From Giac's documentation: Help for apply: apply(Fnc(f),Lst(l)) @@ -861,9 +861,9 @@ cdef class GiacMethods_base: Ex1:apply(x->x^3,[1,2,3]) Ex2:apply(x->x+1,[[1,2,3],[1,2,3]],matrix) ''' - return GiacMethods['apply'](self,*args) + return GiacMethods['apply'](self, *args) - def approx(self,*args): + def approx(self, *args): r'''From Giac's documentation: Help for approx: approx(Expr,[Int]) @@ -876,9 +876,9 @@ cdef class GiacMethods_base: Ex5:approx(sqrt(2)+pi) Ex6:approx(sqrt(2)+pi,30) ''' - return GiacMethods['approx'](self,*args) + return GiacMethods['approx'](self, *args) - def arc(self,*args): + def arc(self, *args): r'''From Giac's documentation: Help for arc: arc(Pnt, Pnt, Real,[Var(C)],[Var(r)],[Opt(segment)]) @@ -889,9 +889,9 @@ cdef class GiacMethods_base: Ex3:arc(i,1,pi/4,segment) Ex4:arc(i,1,pi/4,segment,affichage=1+rempli) ''' - return GiacMethods['arc'](self,*args) + return GiacMethods['arc'](self, *args) - def arcLen(self,*args): + def arcLen(self, *args): r'''From Giac's documentation: Help for arcLen: arcLen(Expr(Xpr) or Lst([Xpr1,Xpr2]),Var,Real(a),Real(b)) @@ -901,9 +901,9 @@ cdef class GiacMethods_base: Ex2:arcLen([t,t^2],t,1,2) Ex3:arcLen([cos(t),sin(t)],t,1,2) ''' - return GiacMethods['arcLen'](self,*args) + return GiacMethods['arcLen'](self, *args) - def arccos(self,*args): + def arccos(self, *args): r'''From Giac's documentation: Help for arccos: arccos(Expr) @@ -911,9 +911,9 @@ cdef class GiacMethods_base: See also: 1/ cos 2/ acosh Ex1:arccos(0) ''' - return GiacMethods['arccos'](self,*args) + return GiacMethods['arccos'](self, *args) - def arccosh(self,*args): + def arccosh(self, *args): r'''From Giac's documentation: Help for arccosh: arccosh(Expr) @@ -921,9 +921,9 @@ cdef class GiacMethods_base: See also: 1/ cosh 2/ acos Ex1:arccosh(1) ''' - return GiacMethods['arccosh'](self,*args) + return GiacMethods['arccosh'](self, *args) - def arclen(self,*args): + def arclen(self, *args): r'''From Giac's documentation: Help for arclen: arclen(Expr(Xpr) or Lst([Xpr1,Xpr2]),Var,Real(a),Real(b)) @@ -933,9 +933,9 @@ cdef class GiacMethods_base: Ex2:arclen([t,t^2],t,1,2) Ex3:arclen([cos(t),sin(t)],t,1,2) ''' - return GiacMethods['arclen'](self,*args) + return GiacMethods['arclen'](self, *args) - def arcsin(self,*args): + def arcsin(self, *args): r'''From Giac's documentation: Help for arcsin: arcsin(Expr) @@ -943,9 +943,9 @@ cdef class GiacMethods_base: See also: 1/ sin Ex1:arcsin(0) ''' - return GiacMethods['arcsin'](self,*args) + return GiacMethods['arcsin'](self, *args) - def arcsinh(self,*args): + def arcsinh(self, *args): r'''From Giac's documentation: Help for arcsinh: arcsinh(Expr) @@ -953,9 +953,9 @@ cdef class GiacMethods_base: See also: 1/ sinh 2/ asin Ex1:arcsinh(0) ''' - return GiacMethods['arcsinh'](self,*args) + return GiacMethods['arcsinh'](self, *args) - def arctan(self,*args): + def arctan(self, *args): r'''From Giac's documentation: Help for arctan: arctan(Expr) @@ -963,9 +963,9 @@ cdef class GiacMethods_base: See also: 1/ tan 2/ atanh Ex1:arctan(0) ''' - return GiacMethods['arctan'](self,*args) + return GiacMethods['arctan'](self, *args) - def arctanh(self,*args): + def arctanh(self, *args): r'''From Giac's documentation: Help for arctanh: arctanh(Expr) @@ -973,9 +973,9 @@ cdef class GiacMethods_base: See also: 1/ atan 2/ tanh Ex1:arctanh(0) ''' - return GiacMethods['arctanh'](self,*args) + return GiacMethods['arctanh'](self, *args) - def area(self,*args): + def area(self, *args): r'''From Giac's documentation: Help for area: area(Polygone || Expr,x=a..b,[n],[Method]) @@ -989,9 +989,9 @@ cdef class GiacMethods_base: Ex6:area(x^2,x=0..1,5,simpson) Ex7:area(x^2,x=0..1,5,rombergm) ''' - return GiacMethods['area'](self,*args) + return GiacMethods['area'](self, *args) - def areaat(self,*args): + def areaat(self, *args): r'''From Giac's documentation: Help for areaat: areaat(Polygone, Pnt||Cplx(z0)) @@ -1003,9 +1003,9 @@ cdef class GiacMethods_base: Ex4: p:=polygon(0,1,i);areaat(p,1+i) Ex5: A:=point(0);B:=point(1+i);c:=carre(A,B);areaat(c,i) ''' - return GiacMethods['areaat'](self,*args) + return GiacMethods['areaat'](self, *args) - def areaatraw(self,*args): + def areaatraw(self, *args): r'''From Giac's documentation: Help for areaatraw: areaatraw(Polygone, Pnt||Cplx(z0)) @@ -1017,9 +1017,9 @@ cdef class GiacMethods_base: Ex4:areaatraw(polygon(0,1,i),1+i) Ex5: A:=point(0);B:=point(1+i);c:=carre(A,B);areaatraw(c,i) ''' - return GiacMethods['areaatraw'](self,*args) + return GiacMethods['areaatraw'](self, *args) - def areaplot(self,*args): + def areaplot(self, *args): r'''From Giac's documentation: Help for areaplot: areaplot(Expr,x=a..b,[n],[Method]) @@ -1029,9 +1029,9 @@ cdef class GiacMethods_base: Ex2:areaplot(x^2,x=0..1,5,trapezoid) Ex3:areaplot(x^2,x=0..1,5,middle_point) ''' - return GiacMethods['areaplot'](self,*args) + return GiacMethods['areaplot'](self, *args) - def arg(self,*args): + def arg(self, *args): r'''From Giac's documentation: Help for arg: arg(Expr) @@ -1041,9 +1041,9 @@ cdef class GiacMethods_base: Ex2:arg(1+2*i) Ex3:arg((1+2*i)^2) ''' - return GiacMethods['arg'](self,*args) + return GiacMethods['arg'](self, *args) - def array(self,*args): + def array(self, *args): r'''From Giac's documentation: Help for array: array(Opt) @@ -1052,9 +1052,9 @@ cdef class GiacMethods_base: Ex1: A[0..2,0..2]:=1;A[0..1,1..2]:=2;convert(A,array) Ex2: B[0..1,1..2]:=1;B[2,2]:=2;convert(B,array) ''' - return GiacMethods['array'](self,*args) + return GiacMethods['array'](self, *args) - def arrivals(self,*args): + def arrivals(self, *args): r'''From Giac's documentation: Help for arrivals: arrivals(Graph(G),[Vrtx(v)]) @@ -1062,9 +1062,9 @@ cdef class GiacMethods_base: See also: 1/ in_degree Ex1:arrivals(digraph(%{[1,2],[1,3],[2,3]%}),1) ''' - return GiacMethods['arrivals'](self,*args) + return GiacMethods['arrivals'](self, *args) - def articulation_points(self,*args): + def articulation_points(self, *args): r'''From Giac's documentation: Help for articulation_points: articulation_points(Graph(G)) @@ -1073,9 +1073,9 @@ cdef class GiacMethods_base: Ex1:articulation_points(path_graph(5)) Ex2:articulation_points(cycle_graph(5)) ''' - return GiacMethods['articulation_points'](self,*args) + return GiacMethods['articulation_points'](self, *args) - def asin(self,*args): + def asin(self, *args): r'''From Giac's documentation: Help for asin: asin(Expr) @@ -1083,9 +1083,9 @@ cdef class GiacMethods_base: See also: 1/ sin Ex1:asin(0) ''' - return GiacMethods['asin'](self,*args) + return GiacMethods['asin'](self, *args) - def asin2acos(self,*args): + def asin2acos(self, *args): r'''From Giac's documentation: Help for asin2acos: asin2acos(Expr) @@ -1094,9 +1094,9 @@ cdef class GiacMethods_base: Ex1:asin2acos(acos(x)+asin(x)) Ex2:asin2acos(2*asin(x)) ''' - return GiacMethods['asin2acos'](self,*args) + return GiacMethods['asin2acos'](self, *args) - def asin2atan(self,*args): + def asin2atan(self, *args): r'''From Giac's documentation: Help for asin2atan: asin2atan(Expr) @@ -1105,9 +1105,9 @@ cdef class GiacMethods_base: Ex1:asin2atan(2*asin(x)) Ex2:asin2atan(asin(sqrt(1-x^2))+asin(x)) ''' - return GiacMethods['asin2atan'](self,*args) + return GiacMethods['asin2atan'](self, *args) - def asinh(self,*args): + def asinh(self, *args): r'''From Giac's documentation: Help for asinh: asinh(Expr) @@ -1115,9 +1115,9 @@ cdef class GiacMethods_base: See also: 1/ sinh 2/ asin Ex1:asinh(0) ''' - return GiacMethods['asinh'](self,*args) + return GiacMethods['asinh'](self, *args) - def assign_edge_weights(self,*args): + def assign_edge_weights(self, *args): r'''From Giac's documentation: Help for assign_edge_weights: assign_edge_weights(Graph(G),Seq(m,n)||Intrv(a..b)) @@ -1126,9 +1126,9 @@ cdef class GiacMethods_base: Ex1:assign_edge_weights(digraph(trail(1,2,3,4,1)),1,9) Ex2:assign_edge_weights(digraph(trail(1,2,3,4,1)),0..1) ''' - return GiacMethods['assign_edge_weights'](self,*args) + return GiacMethods['assign_edge_weights'](self, *args) - def assume(self,*args): + def assume(self, *args): r'''From Giac's documentation: Help for assume: assume(Expr) @@ -1145,9 +1145,9 @@ cdef class GiacMethods_base: Ex9:assume(a>=2);additionally(a<6) Ex10:assume(a) ''' - return GiacMethods['assume'](self,*args) + return GiacMethods['assume'](self, *args) - def at(self,*args): + def at(self, *args): r'''From Giac's documentation: Help for at: at(Lst(l)||Mtrx(m),Index(j)||Lst([j,k])) @@ -1156,9 +1156,9 @@ cdef class GiacMethods_base: Ex1:at([10,11,12],1) Ex2:at([[1,2],[3,4]],[1,0]) ''' - return GiacMethods['at'](self,*args) + return GiacMethods['at'](self, *args) - def atan(self,*args): + def atan(self, *args): r'''From Giac's documentation: Help for atan: atan(Expr) @@ -1166,27 +1166,27 @@ cdef class GiacMethods_base: See also: 1/ tan 2/ atanh Ex1:atan(0) ''' - return GiacMethods['atan'](self,*args) + return GiacMethods['atan'](self, *args) - def atan2acos(self,*args): + def atan2acos(self, *args): r'''From Giac's documentation: Help for atan2acos: atan2acos(Expr) Replaces arctan(x) by pi/2-arccos(x/sqrt(1+x^2)) in the argument. See also: 1/ atan2acos(atan(x)) ''' - return GiacMethods['atan2acos'](self,*args) + return GiacMethods['atan2acos'](self, *args) - def atan2asin(self,*args): + def atan2asin(self, *args): r'''From Giac's documentation: Help for atan2asin: atan2asin(Expr) Replaces arctan(x) by arcsin(x/sqrt(1+x^2)) in the argument. See also: 1/ atan2asin(atan(x)) ''' - return GiacMethods['atan2asin'](self,*args) + return GiacMethods['atan2asin'](self, *args) - def atanh(self,*args): + def atanh(self, *args): r'''From Giac's documentation: Help for atanh: atanh(Expr) @@ -1194,9 +1194,9 @@ cdef class GiacMethods_base: See also: 1/ atan 2/ tanh Ex1:atanh(0) ''' - return GiacMethods['atanh'](self,*args) + return GiacMethods['atanh'](self, *args) - def atrig2ln(self,*args): + def atrig2ln(self, *args): r'''From Giac's documentation: Help for atrig2ln: atrig2ln(Expr) @@ -1206,9 +1206,9 @@ cdef class GiacMethods_base: Ex2:atrig2ln(asin(x)) Ex3:atrig2ln(acos(x)) ''' - return GiacMethods['atrig2ln'](self,*args) + return GiacMethods['atrig2ln'](self, *args) - def augment(self,*args): + def augment(self, *args): r'''From Giac's documentation: Help for augment: augment(Lst,Lst||Seq,Seq||Str,Str||Mtrx,Mtrx) @@ -1220,9 +1220,9 @@ cdef class GiacMethods_base: Ex4: L:=[1,2];L.concat([3,4,5]) Ex5: S:="abcd";S.concat("efghi") ''' - return GiacMethods['augment'](self,*args) + return GiacMethods['augment'](self, *args) - def auto_correlation(self,*args): + def auto_correlation(self, *args): r'''From Giac's documentation: Help for auto_correlation: auto_correlation(Lst) @@ -1230,9 +1230,9 @@ cdef class GiacMethods_base: See also: 1/ cross_correlation 2/ correlation Ex1:auto_correlation([1,-1,0,2,1]) ''' - return GiacMethods['auto_correlation'](self,*args) + return GiacMethods['auto_correlation'](self, *args) - def autosimplify(self,*args): + def autosimplify(self, *args): r'''From Giac's documentation: Help for autosimplify: autosimplify(Cmds) @@ -1245,9 +1245,9 @@ cdef class GiacMethods_base: Ex5:autosimplify(factor) Ex6:autosimplify(simplify) ''' - return GiacMethods['autosimplify'](self,*args) + return GiacMethods['autosimplify'](self, *args) - def avance(self,*args): + def avance(self, *args): r'''From Giac's documentation: Help for avance: avance(NULL or Real(n)) @@ -1256,9 +1256,9 @@ cdef class GiacMethods_base: Ex1: avance 30 Ex2:avance(30) ''' - return GiacMethods['avance'](self,*args) + return GiacMethods['avance'](self, *args) - def avgRC(self,*args): + def avgRC(self, *args): r'''From Giac's documentation: Help for avgRC: avgRC(Expr(Xpr),Var(Var),[Real(h)]) @@ -1268,9 +1268,9 @@ cdef class GiacMethods_base: Ex2:avgRC(x^2,x,0.1) Ex3:avgRC(x^2,x) ''' - return GiacMethods['avgRC'](self,*args) + return GiacMethods['avgRC'](self, *args) - def axes(self,*args): + def axes(self, *args): r'''From Giac's documentation: Help for axes: axes(Opt) @@ -1279,18 +1279,18 @@ cdef class GiacMethods_base: Ex1: axes=0;segment(0,point(1,1)) Ex2: axes=1;segment(0,point(1,1),epaisseur=5) ''' - return GiacMethods['axes'](self,*args) + return GiacMethods['axes'](self, *args) - def axis(self,*args): + def axis(self, *args): r'''From Giac's documentation: Help for axis: axis(xmin,xmax,ymin,ymax,[zmin,zmaz]) Defines the graphic display Ex1:axis(-2,4,-1,6) ''' - return GiacMethods['axis'](self,*args) + return GiacMethods['axis'](self, *args) - def back(self,*args): + def back(self, *args): r'''From Giac's documentation: Help for back: back(Vect or Seq or Str) @@ -1300,9 +1300,9 @@ cdef class GiacMethods_base: Ex2:back([1,2,3]) Ex3:back("bonjour") ''' - return GiacMethods['back'](self,*args) + return GiacMethods['back'](self, *args) - def backward(self,*args): + def backward(self, *args): r'''From Giac's documentation: Help for backward: backward(NULL or Real(n)) @@ -1311,9 +1311,9 @@ cdef class GiacMethods_base: Ex1: recule 30 Ex2:backward(30) ''' - return GiacMethods['backward'](self,*args) + return GiacMethods['backward'](self, *args) - def baisse_crayon(self,*args): + def baisse_crayon(self, *args): r'''From Giac's documentation: Help for baisse_crayon: baisse_crayon(NULL) @@ -1321,18 +1321,18 @@ cdef class GiacMethods_base: See also: 1/ leve_crayon 2/ crayon Ex1:baisse_crayon() ''' - return GiacMethods['baisse_crayon'](self,*args) + return GiacMethods['baisse_crayon'](self, *args) - def bandwidth(self,*args): + def bandwidth(self, *args): r'''From Giac's documentation: Help for bandwidth: bandwidth(Opt) Option for the kernel_density command. See also: 1/ kernel_density 2/ bins ''' - return GiacMethods['bandwidth'](self,*args) + return GiacMethods['bandwidth'](self, *args) - def bar_plot(self,*args): + def bar_plot(self, *args): r'''From Giac's documentation: Help for bar_plot: bar_plot(Mtrx) @@ -1342,9 +1342,9 @@ cdef class GiacMethods_base: Ex2:bar_plot([3/2,2/3,5/4,4/5,7/6,6/7,9/8,8/9,11/10]) Ex3:bar_plot([[2,"xyz","abc"],["A",2,5],["B",5,6],["C",7,7]]) ''' - return GiacMethods['bar_plot'](self,*args) + return GiacMethods['bar_plot'](self, *args) - def barplot(self,*args): + def barplot(self, *args): r'''From Giac's documentation: Help for barplot: barplot(Mtrx) @@ -1354,9 +1354,9 @@ cdef class GiacMethods_base: Ex2:barplot([3/2,2/3,5/4,4/5,7/6,6/7,9/8,8/9,11/10]) Ex3:barplot([[2,"xyz","abc"],["A",2,5],["B",5,6],["C",7,7]]) ''' - return GiacMethods['barplot'](self,*args) + return GiacMethods['barplot'](self, *args) - def bartlett_hann_window(self,*args): + def bartlett_hann_window(self, *args): r'''From Giac's documentation: Help for bartlett_hann_window: bartlett_hann_window(Lst,[Interval(n1..n2)]) @@ -1364,9 +1364,9 @@ cdef class GiacMethods_base: See also: 1/ blackman_harris_window 2/ blackman_window 3/ bohman_window 4/ cosine_window 5/ gaussian_window 6/ hamming_window 7/ hann_poisson_window 8/ hann_window 9/ parzen_window 10/ poisson_window 11/ riemann_window 12/ triangle_window 13/ tukey_window 14/ welch_window Ex1: scatterplot(bartlett_hann_window(randvector(1000,0..1))) ''' - return GiacMethods['bartlett_hann_window'](self,*args) + return GiacMethods['bartlett_hann_window'](self, *args) - def barycenter(self,*args): + def barycenter(self, *args): r'''From Giac's documentation: Help for barycenter: barycenter([Pnt,Real],[Pnt,Real],[Pnt,Real]) @@ -1376,9 +1376,9 @@ cdef class GiacMethods_base: Ex2:barycenter([[point(-1),1],[point(1+i),2],[point(1-i),1]]) Ex3:barycenter([point(-1),point(1+i),point(1-i)],[1,2,1]) ''' - return GiacMethods['barycenter'](self,*args) + return GiacMethods['barycenter'](self, *args) - def base(self,*args): + def base(self, *args): r'''From Giac's documentation: Help for base: base(Opt) @@ -1388,9 +1388,9 @@ cdef class GiacMethods_base: Ex2: convert([3,7,1],base,8) Ex3: horner(revlist([3,7,1]),8) ''' - return GiacMethods['base'](self,*args) + return GiacMethods['base'](self, *args) - def basis(self,*args): + def basis(self, *args): r'''From Giac's documentation: Help for basis: basis(Lst(vector1,..,vectorn)) @@ -1398,9 +1398,9 @@ cdef class GiacMethods_base: See also: 1/ ker 2/ ibasis Ex1:basis([[1,2,3],[4,5,6],[7,8,9],[10,11,12]]) ''' - return GiacMethods['basis'](self,*args) + return GiacMethods['basis'](self, *args) - def batons(self,*args): + def batons(self, *args): r'''From Giac's documentation: Help for batons: batons(Mtrx) @@ -1410,9 +1410,9 @@ cdef class GiacMethods_base: Ex2:batons([[1,3],[2,5],[3,2]]) Ex3:batons([1,2,3],[3,5,2]) ''' - return GiacMethods['batons'](self,*args) + return GiacMethods['batons'](self, *args) - def bellman_ford(self,*args): + def bellman_ford(self, *args): r'''From Giac's documentation: Help for bellman_ford: bellman_ford(Graph(G),Vrtx(s),Vrtx(t)||Lst(T)) @@ -1420,9 +1420,9 @@ cdef class GiacMethods_base: See also: 1/ dijkstra 2/ shortest_path Ex1:bellman_ford(graph(%{[[1,2],-1],[[2,3],-3],[[3,4],-7],[[4,5],-3],[[5,6],-3],[[1,6],-3]%}),1,4) ''' - return GiacMethods['bellman_ford'](self,*args) + return GiacMethods['bellman_ford'](self, *args) - def bernoulli(self,*args): + def bernoulli(self, *args): r'''From Giac's documentation: Help for bernoulli: bernoulli(Intg||(Intg,Var)) @@ -1431,9 +1431,9 @@ cdef class GiacMethods_base: Ex1:bernoulli(6) Ex2:bernoulli(6,x) ''' - return GiacMethods['bernoulli'](self,*args) + return GiacMethods['bernoulli'](self, *args) - def besselJ(self,*args): + def besselJ(self, *args): r'''From Giac's documentation: Help for besselJ: besselJ(Real(x),Int(p)) @@ -1442,9 +1442,9 @@ cdef class GiacMethods_base: Ex1:besselJ(sqrt(2),2) Ex2:besselJ(sqrt(2),-2) ''' - return GiacMethods['besselJ'](self,*args) + return GiacMethods['besselJ'](self, *args) - def besselY(self,*args): + def besselY(self, *args): r'''From Giac's documentation: Help for besselY: besselY(Real(x),Int(p)) @@ -1453,9 +1453,9 @@ cdef class GiacMethods_base: Ex1:besselY(sqrt(2),2) Ex2:besselY(sqrt(2),-2) ''' - return GiacMethods['besselY'](self,*args) + return GiacMethods['besselY'](self, *args) - def betad(self,*args): + def betad(self, *args): r'''From Giac's documentation: Help for betad: betad(Real(a>0),Real(b>0),Real(0<=x<=1)) @@ -1463,9 +1463,9 @@ cdef class GiacMethods_base: See also: 1/ betad_cdf 2/ betad_icdf Ex1:betad(2.2,1.5,0.8) ''' - return GiacMethods['betad'](self,*args) + return GiacMethods['betad'](self, *args) - def betad_cdf(self,*args): + def betad_cdf(self, *args): r'''From Giac's documentation: Help for betad_cdf: betad_cdf(Real(a>0),Real(b>0),Real(0<=x0<=1),[Real(0<=y0<=1)]) @@ -1474,9 +1474,9 @@ cdef class GiacMethods_base: Ex1:betad_cdf(2,1,0.2) Ex2:betad_cdf(2,1,0.1,0.3) ''' - return GiacMethods['betad_cdf'](self,*args) + return GiacMethods['betad_cdf'](self, *args) - def betad_icdf(self,*args): + def betad_icdf(self, *args): r'''From Giac's documentation: Help for betad_icdf: betad_icdf(Real(a>0),Real(b>0),Real(0<=p<=1)) @@ -1485,9 +1485,9 @@ cdef class GiacMethods_base: Ex1:betad_icdf(2,1,0.95) Ex2:betad_icdf(2,1,0.5) ''' - return GiacMethods['betad_icdf'](self,*args) + return GiacMethods['betad_icdf'](self, *args) - def betavariate(self,*args): + def betavariate(self, *args): r'''From Giac's documentation: Help for betavariate: betavariate(Real(a),Real(b)) @@ -1496,9 +1496,9 @@ cdef class GiacMethods_base: Ex1:betavariate(1,2) Ex2:betavariate(1.5,4) ''' - return GiacMethods['betavariate'](self,*args) + return GiacMethods['betavariate'](self, *args) - def bezier(self,*args): + def bezier(self, *args): r'''From Giac's documentation: Help for bezier: bezier(Lst,[plot]) @@ -1509,9 +1509,9 @@ cdef class GiacMethods_base: Ex3: parameq(bezier(1,1+i,2+i,3-i)) Ex4: parameq(bezier(point([0,0,0]),point([1,1,0]),point([0,1,1]))) ''' - return GiacMethods['bezier'](self,*args) + return GiacMethods['bezier'](self, *args) - def bezout_entiers(self,*args): + def bezout_entiers(self, *args): r'''From Giac's documentation: Help for bezout_entiers: bezout_entiers(Intg,Intg) @@ -1521,9 +1521,9 @@ cdef class GiacMethods_base: Ex2:bezout_entiers(21,28) Ex3:bezout_entiers(30,49) ''' - return GiacMethods['bezout_entiers'](self,*args) + return GiacMethods['bezout_entiers'](self, *args) - def biconnected_components(self,*args): + def biconnected_components(self, *args): r'''From Giac's documentation: Help for biconnected_components: biconnected_components(Graph(G)) @@ -1531,9 +1531,9 @@ cdef class GiacMethods_base: See also: 1/ articulation_points 2/ is_biconnected 3/ is_connected 4/ trail Ex1:biconnected_components(graph(trail(1,2,3,4,2),trail(4,5,6,7,5))) ''' - return GiacMethods['biconnected_components'](self,*args) + return GiacMethods['biconnected_components'](self, *args) - def binomial(self,*args): + def binomial(self, *args): r'''From Giac's documentation: Help for binomial: binomial(Intg(n),Intg(k),[Real(p in 0..1)]) @@ -1547,9 +1547,9 @@ cdef class GiacMethods_base: Ex6: randvector(6,binomial,4,0.2) Ex7: ranm(4,6,binomial,4,0.7) ''' - return GiacMethods['binomial'](self,*args) + return GiacMethods['binomial'](self, *args) - def binomial_cdf(self,*args): + def binomial_cdf(self, *args): r'''From Giac's documentation: Help for binomial_cdf: binomial_cdf(Intg(n),Real(p),Real(x),[Real(y)]) @@ -1559,9 +1559,9 @@ cdef class GiacMethods_base: Ex2:binomial_cdf(4,0.1,2) Ex3:binomial_cdf(4,0.5,2,3) ''' - return GiacMethods['binomial_cdf'](self,*args) + return GiacMethods['binomial_cdf'](self, *args) - def binomial_icdf(self,*args): + def binomial_icdf(self, *args): r'''From Giac's documentation: Help for binomial_icdf: binomial_icdf(Intg(n),Real(p),Real(t)) @@ -1570,27 +1570,27 @@ cdef class GiacMethods_base: Ex1:binomial_icdf(4,0.5,0.68) Ex2:binomial_icdf(4,0.1,0.95) ''' - return GiacMethods['binomial_icdf'](self,*args) + return GiacMethods['binomial_icdf'](self, *args) - def bins(self,*args): + def bins(self, *args): r'''From Giac's documentation: Help for bins: bins(Opt) Option for the kernel_density command. See also: 1/ kernel_density 2/ bandwidth ''' - return GiacMethods['bins'](self,*args) + return GiacMethods['bins'](self, *args) - def bipartite(self,*args): + def bipartite(self, *args): r'''From Giac's documentation: Help for bipartite: bipartite(Opt) Option for the draw_graph command See also: 1/ draw_graph ''' - return GiacMethods['bipartite'](self,*args) + return GiacMethods['bipartite'](self, *args) - def bipartite_matching(self,*args): + def bipartite_matching(self, *args): r'''From Giac's documentation: Help for bipartite_matching: bipartite_matching(Graph(G)) @@ -1598,9 +1598,9 @@ cdef class GiacMethods_base: See also: 1/ is_bipartite 2/ maximum_matching Ex1:bipartite_matching(graph("desargues")) ''' - return GiacMethods['bipartite_matching'](self,*args) + return GiacMethods['bipartite_matching'](self, *args) - def bisection_solver(self,*args): + def bisection_solver(self, *args): r'''From Giac's documentation: Help for bisection_solver: bisection_solver(Opt) @@ -1613,9 +1613,9 @@ cdef class GiacMethods_base: Ex5: fsolve(cos(x)=x,x,0,secant_solver) Ex6: fsolve(cos(x)=x,x,0,steffenson_solver) ''' - return GiacMethods['bisection_solver'](self,*args) + return GiacMethods['bisection_solver'](self, *args) - def bisector(self,*args): + def bisector(self, *args): r'''From Giac's documentation: Help for bisector: bisector((Pnt(A) or Cplx),(Pnt(B) or Cplx),(Pnt(C) or Cplx)) @@ -1623,9 +1623,9 @@ cdef class GiacMethods_base: See also: 1/ angle 2/ exbisector Ex1:bisector(0,1,i) ''' - return GiacMethods['bisector'](self,*args) + return GiacMethods['bisector'](self, *args) - def bit_depth(self,*args): + def bit_depth(self, *args): r'''From Giac's documentation: Help for bit_depth: bit_depth(Lst(clip)) @@ -1633,9 +1633,9 @@ cdef class GiacMethods_base: See also: 1/ channels 2/ channel_data 3/ duration 4/ samplerate Ex1:bit_depth(readwav("/some/file")) ''' - return GiacMethods['bit_depth'](self,*args) + return GiacMethods['bit_depth'](self, *args) - def bitand(self,*args): + def bitand(self, *args): r'''From Giac's documentation: Help for bitand: bitand(Intg,Intg) @@ -1643,9 +1643,9 @@ cdef class GiacMethods_base: See also: 1/ bitxor 2/ bitor Ex1:bitand(0x12,0x38) ''' - return GiacMethods['bitand'](self,*args) + return GiacMethods['bitand'](self, *args) - def bitor(self,*args): + def bitor(self, *args): r'''From Giac's documentation: Help for bitor: bitor(Intg,Intg) @@ -1653,9 +1653,9 @@ cdef class GiacMethods_base: See also: 1/ bitxor 2/ bitand Ex1:bitor(0x12,0x38) ''' - return GiacMethods['bitor'](self,*args) + return GiacMethods['bitor'](self, *args) - def bitxor(self,*args): + def bitxor(self, *args): r'''From Giac's documentation: Help for bitxor: bitxor(Intg,Intg) @@ -1663,9 +1663,9 @@ cdef class GiacMethods_base: See also: 1/ bitor 2/ bitand Ex1:bitxor(0x12,0x38) ''' - return GiacMethods['bitxor'](self,*args) + return GiacMethods['bitxor'](self, *args) - def blackman_harris_window(self,*args): + def blackman_harris_window(self, *args): r'''From Giac's documentation: Help for blackman_harris_window: blackman_harris_window(Lst,[Interval(n1..n2)]) @@ -1673,9 +1673,9 @@ cdef class GiacMethods_base: See also: 1/ bartlett_hann_window 2/ blackman_window 3/ bohman_window 4/ cosine_window 5/ gaussian_window 6/ hamming_window 7/ hann_poisson_window 8/ hann_window 9/ parzen_window 10/ poisson_window 11/ riemann_window 12/ triangle_window 13/ tukey_window 14/ welch_window Ex1: scatterplot(blackman_harris_window(randvector(1000,0..1))) ''' - return GiacMethods['blackman_harris_window'](self,*args) + return GiacMethods['blackman_harris_window'](self, *args) - def blackman_window(self,*args): + def blackman_window(self, *args): r'''From Giac's documentation: Help for blackman_window: blackman_window(Lst,[Real(a)],[Interval(n1..n2)]) @@ -1683,9 +1683,9 @@ cdef class GiacMethods_base: See also: 1/ blackman_harris_window 2/ bartlett_harris_window 3/ bohman_window 4/ cosine_window 5/ gaussian_window 6/ hamming_window 7/ hann_poisson_window 8/ hann_window 9/ parzen_window 10/ poisson_window 11/ riemann_window 12/ triangle_window 13/ tukey_window 14/ welch_window Ex1: scatterplot(blackman_window(randvector(1000,0..1))) ''' - return GiacMethods['blackman_window'](self,*args) + return GiacMethods['blackman_window'](self, *args) - def blockmatrix(self,*args): + def blockmatrix(self, *args): r'''From Giac's documentation: Help for blockmatrix: blockmatrix(Intg(n),Intg(m),Lst) @@ -1694,9 +1694,9 @@ cdef class GiacMethods_base: Ex1:blockmatrix(2,3,[idn(2),idn(2),idn(2),idn(2),idn(2),idn(2)]) Ex2:blockmatrix(2,2,[idn(2),newMat(2,3),newMat(3,2),idn(3)]) ''' - return GiacMethods['blockmatrix'](self,*args) + return GiacMethods['blockmatrix'](self, *args) - def bohman_window(self,*args): + def bohman_window(self, *args): r'''From Giac's documentation: Help for bohman_window: bohman_window(Lst,[Interval(n1..n2)]) @@ -1704,9 +1704,9 @@ cdef class GiacMethods_base: See also: 1/ blackman_harris_window 2/ blackman_window 3/ bartlett_hann_window 4/ cosine_window 5/ gaussian_window 6/ hamming_window 7/ hann_poisson_window 8/ hann_window 9/ parzen_window 10/ poisson_window 11/ riemann_window 12/ triangle_window 13/ tukey_window 14/ welch_window Ex1: scatterplot(bohman_window(randvector(1000,0..1))) ''' - return GiacMethods['bohman_window'](self,*args) + return GiacMethods['bohman_window'](self, *args) - def border(self,*args): + def border(self, *args): r'''From Giac's documentation: Help for border: border(Mtrx(A),Lst(b)) @@ -1715,9 +1715,9 @@ cdef class GiacMethods_base: Ex1:border([[1,2,3,4],[4,5,6,8],[7,8,9,10]],[1,3,5]) Ex2:border([[1,2,3],[4,5,6],[7,8,9]],[1,0,1]) ''' - return GiacMethods['border'](self,*args) + return GiacMethods['border'](self, *args) - def boxcar(self,*args): + def boxcar(self, *args): r'''From Giac's documentation: Help for boxcar: boxcar(Real(a),Real(b),Expr(x)) @@ -1725,9 +1725,9 @@ cdef class GiacMethods_base: See also: 1/ rect 2/ Heaviside Ex1:boxcar(1,2,x) ''' - return GiacMethods['boxcar'](self,*args) + return GiacMethods['boxcar'](self, *args) - def boxwhisker(self,*args): + def boxwhisker(self, *args): r'''From Giac's documentation: Help for boxwhisker: boxwhisker(Lst,[Lst],[x=a..b||y=a..b]) @@ -1738,9 +1738,9 @@ cdef class GiacMethods_base: Ex3:boxwhisker([1,2,3,5,10,4],[1,2,3,1,2,3]) Ex4:boxwhisker([[6,0,1,3,4,2,5],[0,1,3,4,2,5,6],[1,3,4,2,5,6,0],[3,4,2,5,6,0,1],[4,2,5,6,0,1,3],[2,5,6,0,1,3,4]]) ''' - return GiacMethods['boxwhisker'](self,*args) + return GiacMethods['boxwhisker'](self, *args) - def brent_solver(self,*args): + def brent_solver(self, *args): r'''From Giac's documentation: Help for brent_solver: brent_solver(Opt) @@ -1753,9 +1753,9 @@ cdef class GiacMethods_base: Ex5: fsolve(cos(x)=x,x,0,secant_solver) Ex6: fsolve(cos(x)=x,x,0,steffenson_solver) ''' - return GiacMethods['brent_solver'](self,*args) + return GiacMethods['brent_solver'](self, *args) - def bvpsolve(self,*args): + def bvpsolve(self, *args): r'''From Giac's documentation: Help for bvpsolve: bvpsolve(Expr(f(x,y,y')),Lst(x=a..b,y),Lst(y(a),y(b),[y'(1)]),[options]) @@ -1764,9 +1764,9 @@ cdef class GiacMethods_base: Ex1:bvpsolve((32+2x^3-y*diff(y(x),x))/8,[x=1..3,y],[17,43/3],20) Ex2:bvpsolve((x^2*diff(y(x),x)^2-9y^2+4x^6)/x^5,[x=1..2,y],[0,ln(256),1],10,output=spline) ''' - return GiacMethods['bvpsolve'](self,*args) + return GiacMethods['bvpsolve'](self, *args) - def cFactor(self,*args): + def cFactor(self, *args): r'''From Giac's documentation: Help for cFactor: cFactor(Expr) @@ -1776,9 +1776,9 @@ cdef class GiacMethods_base: Ex2:cFactor(x^2*y^2+y^2+4*x^2+4) Ex3:cFactor(x^2*y^2+y^2+2*x^2+2) ''' - return GiacMethods['cFactor'](self,*args) + return GiacMethods['cFactor'](self, *args) - def cSolve(self,*args): + def cSolve(self, *args): r'''From Giac's documentation: Help for cSolve: cSolve(LstEq,LstVar) @@ -1789,9 +1789,9 @@ cdef class GiacMethods_base: Ex3:cSolve(x^4-y^4 and x+y=0 and x^2=2*x,[x,y]) Ex4:cSolve(u*v-u=v and v^2=u,[u,v]) ''' - return GiacMethods['cSolve'](self,*args) + return GiacMethods['cSolve'](self, *args) - def cZeros(self,*args): + def cZeros(self, *args): r'''From Giac's documentation: Help for cZeros: cZeros(Expr(Xpr)||LstExpr, [Var||LstVar]) @@ -1800,9 +1800,9 @@ cdef class GiacMethods_base: Ex1:cZeros(x^2-1) Ex2:cZeros([x^2-1,x^2-y^2],[x,y]) ''' - return GiacMethods['cZeros'](self,*args) + return GiacMethods['cZeros'](self, *args) - def camembert(self,*args): + def camembert(self, *args): r'''From Giac's documentation: Help for camembert: camembert(Mtrx) @@ -1812,9 +1812,9 @@ cdef class GiacMethods_base: Ex2:camembert([3/2,2/3,5/4,4/5,7/6,6/7,9/8,8/9,11/10]) Ex3:camembert([[2,"xyz","abc"],["A",2,5],["B",5,6],["C",7,7]]) ''' - return GiacMethods['camembert'](self,*args) + return GiacMethods['camembert'](self, *args) - def canonical_form(self,*args): + def canonical_form(self, *args): r'''From Giac's documentation: Help for canonical_form: canonical_form(Trinom(a*x^2+b*x+c),[Var]) @@ -1823,9 +1823,9 @@ cdef class GiacMethods_base: Ex1:canonical_form(2*x^2-12*x+1) Ex2:canonical_form(2*a^2-12*a+1,a) ''' - return GiacMethods['canonical_form'](self,*args) + return GiacMethods['canonical_form'](self, *args) - def canonical_labeling(self,*args): + def canonical_labeling(self, *args): r'''From Giac's documentation: Help for canonical_labeling: canonical_labeling(Graph(G)) @@ -1833,9 +1833,9 @@ cdef class GiacMethods_base: See also: 1/ isomorphic_copy 2/ relabel_vertices Ex1:canonical_labeling(graph("petersen")) ''' - return GiacMethods['canonical_labeling'](self,*args) + return GiacMethods['canonical_labeling'](self, *args) - def cartesian_product(self,*args): + def cartesian_product(self, *args): r'''From Giac's documentation: Help for cartesian_product: cartesian_product(Seq(G1,G2,..)) @@ -1843,9 +1843,9 @@ cdef class GiacMethods_base: See also: 1/ tensor_product Ex1:cartesian_product(graph(trail(1,2,3,4,5,2)),star_graph(3)) ''' - return GiacMethods['cartesian_product'](self,*args) + return GiacMethods['cartesian_product'](self, *args) - def cauchy(self,*args): + def cauchy(self, *args): r'''From Giac's documentation: Help for cauchy: cauchy(Real(x0),Real(a),Real(x)) @@ -1853,9 +1853,9 @@ cdef class GiacMethods_base: See also: 1/ cauchy_cdf 2/ cauchy_icdf Ex1:cauchy(0.0,2.0,1.0) ''' - return GiacMethods['cauchy'](self,*args) + return GiacMethods['cauchy'](self, *args) - def cauchy_cdf(self,*args): + def cauchy_cdf(self, *args): r'''From Giac's documentation: Help for cauchy_cdf: cauchy_cdf(Real(x0),Real(a),Real(x),[Real(y)]) @@ -1864,9 +1864,9 @@ cdef class GiacMethods_base: Ex1:cauchy_cdf(0.0,2.0,2.1) Ex2:cauchy_cdf(2,3,-1.9,1.4) ''' - return GiacMethods['cauchy_cdf'](self,*args) + return GiacMethods['cauchy_cdf'](self, *args) - def cauchy_icdf(self,*args): + def cauchy_icdf(self, *args): r'''From Giac's documentation: Help for cauchy_icdf: cauchy_icdf(Real(x0),Real(a),Real(p)) @@ -1874,9 +1874,9 @@ cdef class GiacMethods_base: See also: 1/ cauchy_cdf 2/ cauchy Ex1:cauchy_icdf(0.0,2.0,0.95) ''' - return GiacMethods['cauchy_icdf'](self,*args) + return GiacMethods['cauchy_icdf'](self, *args) - def cauchyd(self,*args): + def cauchyd(self, *args): r'''From Giac's documentation: Help for cauchyd: cauchyd(Real(x0),Real(a),Real(x)) @@ -1884,9 +1884,9 @@ cdef class GiacMethods_base: See also: 1/ cauchy_cdf 2/ cauchy_icdf Ex1:cauchyd(0.0,2.0,1.0) ''' - return GiacMethods['cauchyd'](self,*args) + return GiacMethods['cauchyd'](self, *args) - def cauchyd_cdf(self,*args): + def cauchyd_cdf(self, *args): r'''From Giac's documentation: Help for cauchyd_cdf: cauchyd_cdf(Real(x0),Real(a),Real(x),[Real(y)]) @@ -1895,9 +1895,9 @@ cdef class GiacMethods_base: Ex1:cauchyd_cdf(0.0,2.0,2.1) Ex2:cauchyd_cdf(2,3,-1.9,1.4) ''' - return GiacMethods['cauchyd_cdf'](self,*args) + return GiacMethods['cauchyd_cdf'](self, *args) - def cauchyd_icdf(self,*args): + def cauchyd_icdf(self, *args): r'''From Giac's documentation: Help for cauchyd_icdf: cauchyd_icdf(Real(x0),Real(a),Real(p)) @@ -1905,9 +1905,9 @@ cdef class GiacMethods_base: See also: 1/ cauchy_cdf 2/ cauchy Ex1:cauchyd_icdf(0.0,2.0,0.95) ''' - return GiacMethods['cauchyd_icdf'](self,*args) + return GiacMethods['cauchyd_icdf'](self, *args) - def cdf(self,*args): + def cdf(self, *args): r'''From Giac's documentation: Help for cdf: cdf(Func,FuncParams) @@ -1918,9 +1918,9 @@ cdef class GiacMethods_base: Ex3:cdf([1,3,4,3,5,6],4) Ex4:cdf([1,3,4,3,5,6],plot) ''' - return GiacMethods['cdf'](self,*args) + return GiacMethods['cdf'](self, *args) - def ceil(self,*args): + def ceil(self, *args): r'''From Giac's documentation: Help for ceil: ceil(Real or Cplx) @@ -1929,9 +1929,9 @@ cdef class GiacMethods_base: Ex1:ceil(-4.2) Ex2:ceil(4.3+2.4*i) ''' - return GiacMethods['ceil'](self,*args) + return GiacMethods['ceil'](self, *args) - def ceiling(self,*args): + def ceiling(self, *args): r'''From Giac's documentation: Help for ceiling: ceiling(Real or Cplx) @@ -1940,9 +1940,9 @@ cdef class GiacMethods_base: Ex1:ceiling(-4.2) Ex2:ceiling(4.3+2.4*i) ''' - return GiacMethods['ceiling'](self,*args) + return GiacMethods['ceiling'](self, *args) - def center(self,*args): + def center(self, *args): r'''From Giac's documentation: Help for center: center(Crcle) @@ -1951,9 +1951,9 @@ cdef class GiacMethods_base: Ex1:center(circle(1+i,2)) Ex2:center(circumcircle(0,1,1+i)) ''' - return GiacMethods['center'](self,*args) + return GiacMethods['center'](self, *args) - def center2interval(self,*args): + def center2interval(self, *args): r'''From Giac's documentation: Help for center2interval: center2interval(LstVal(l),[Real(a0)]) @@ -1962,9 +1962,9 @@ cdef class GiacMethods_base: Ex1:center2interval([2,5,9],1) Ex2:center2interval([2,5,8]) ''' - return GiacMethods['center2interval'](self,*args) + return GiacMethods['center2interval'](self, *args) - def centered_cube(self,*args): + def centered_cube(self, *args): r'''From Giac's documentation: Help for centered_cube: centered_cube(Pnt(A),Pnt(B),Pnt(C)) @@ -1973,9 +1973,9 @@ cdef class GiacMethods_base: Ex1:centered_cube([0,0,0],[3,0,0],[0,0,1]) Ex2:centered_cube(evalf([0,0,0],[3,2,4],[1,1,0])) ''' - return GiacMethods['centered_cube'](self,*args) + return GiacMethods['centered_cube'](self, *args) - def centered_tetrahedron(self,*args): + def centered_tetrahedron(self, *args): r'''From Giac's documentation: Help for centered_tetrahedron: centered_tetrahedron(Pnt(A),Pnt(B),Pnt(C)) @@ -1984,9 +1984,9 @@ cdef class GiacMethods_base: Ex1:centered_tetrahedron([0,0,0],[3,0,0],[0,1,0]) Ex2:centered_tetrahedron(evalf([0,0,0],[3,2,4],[1,1,0])) ''' - return GiacMethods['centered_tetrahedron'](self,*args) + return GiacMethods['centered_tetrahedron'](self, *args) - def cfactor(self,*args): + def cfactor(self, *args): r'''From Giac's documentation: Help for cfactor: cfactor(Expr) @@ -1996,9 +1996,9 @@ cdef class GiacMethods_base: Ex2:cfactor(x^2*y^2+y^2+4*x^2+4) Ex3:cfactor(x^2*y^2+y^2+2*x^2+2) ''' - return GiacMethods['cfactor'](self,*args) + return GiacMethods['cfactor'](self, *args) - def cfsolve(self,*args): + def cfsolve(self, *args): r'''From Giac's documentation: Help for cfsolve: cfsolve(Expr,Var,[Guess or Interval],[Method]) @@ -2007,9 +2007,9 @@ cdef class GiacMethods_base: Ex1:cfsolve(cos(x)=2) Ex2:cfsolve([x^2+y+2,x+y^2+2],[x,y]) ''' - return GiacMethods['cfsolve'](self,*args) + return GiacMethods['cfsolve'](self, *args) - def changebase(self,*args): + def changebase(self, *args): r'''From Giac's documentation: Help for changebase: changebase(Mtrx(A),Mtrx(P)) @@ -2018,9 +2018,9 @@ cdef class GiacMethods_base: Ex1:changebase([[1,2],[1,3]],[[1,1],[0,1]]) Ex2:changebase([[1,2],[1,3]],[[1,0],[1,1]]) ''' - return GiacMethods['changebase'](self,*args) + return GiacMethods['changebase'](self, *args) - def channel_data(self,*args): + def channel_data(self, *args): r'''From Giac's documentation: Help for channel_data: channel_data(Lst(clip),[Intg(chn) or matrix],[range=a..b]) @@ -2031,9 +2031,9 @@ cdef class GiacMethods_base: Ex3:channel_data(readwav("/some/file"),2) Ex4:channel_data(readwav("/some/file"),matrix,range=1.0..2.5) ''' - return GiacMethods['channel_data'](self,*args) + return GiacMethods['channel_data'](self, *args) - def channels(self,*args): + def channels(self, *args): r'''From Giac's documentation: Help for channels: channels(Lst(clip)) @@ -2041,9 +2041,9 @@ cdef class GiacMethods_base: See also: 1/ bit_depth 2/ channel_data 3/ duration 4/ samplerate Ex1:channels(readwav("/some/file")) ''' - return GiacMethods['channels'](self,*args) + return GiacMethods['channels'](self, *args) - def char(self,*args): + def char(self, *args): r'''From Giac's documentation: Help for char: char(Intg or Lst(Intg)) @@ -2052,9 +2052,9 @@ cdef class GiacMethods_base: Ex1:char(65) Ex2:char([65,66,67]) ''' - return GiacMethods['char'](self,*args) + return GiacMethods['char'](self, *args) - def charpoly(self,*args): + def charpoly(self, *args): r'''From Giac's documentation: Help for charpoly: charpoly(Mtrx,[Var]) @@ -2065,9 +2065,9 @@ cdef class GiacMethods_base: Ex3:charpoly([[1,2,3],[1,3,6],[2,5,7]]) Ex4:charpoly([[1,2,3],[1,3,6],[2,5,7]],z) ''' - return GiacMethods['charpoly'](self,*args) + return GiacMethods['charpoly'](self, *args) - def chinrem(self,*args): + def chinrem(self, *args): r'''From Giac's documentation: Help for chinrem: chinrem([Lst||Expr,Lst||Expr],[Lst||Expr,Lst||Expr]) @@ -2076,9 +2076,9 @@ cdef class GiacMethods_base: Ex1:chinrem([x+2,x^2+1],[x+1,x^2+x+1]) Ex2:chinrem([[1,2],[1,0,1]],[[1,1],[1,1,1]]) ''' - return GiacMethods['chinrem'](self,*args) + return GiacMethods['chinrem'](self, *args) - def chisquare(self,*args): + def chisquare(self, *args): r'''From Giac's documentation: Help for chisquare: chisquare(Intg(n),Real(x0)) @@ -2089,9 +2089,9 @@ cdef class GiacMethods_base: Ex3: randvector(3,chisquare,2) Ex4: ranm(4,3,chisquare,2) ''' - return GiacMethods['chisquare'](self,*args) + return GiacMethods['chisquare'](self, *args) - def chisquare_cdf(self,*args): + def chisquare_cdf(self, *args): r'''From Giac's documentation: Help for chisquare_cdf: chisquare_cdf(Intg(n),Real(x0)) @@ -2100,9 +2100,9 @@ cdef class GiacMethods_base: Ex1:chisquare_cdf(2,6.1) Ex2:chisquare_cdf(4,6.1) ''' - return GiacMethods['chisquare_cdf'](self,*args) + return GiacMethods['chisquare_cdf'](self, *args) - def chisquare_icdf(self,*args): + def chisquare_icdf(self, *args): r'''From Giac's documentation: Help for chisquare_icdf: chisquare_icdf(Intg(n),Real(p)) @@ -2111,9 +2111,9 @@ cdef class GiacMethods_base: Ex1:chisquare_icdf(2,0.95) Ex2:chisquare_icdf(4,0.05) ''' - return GiacMethods['chisquare_icdf'](self,*args) + return GiacMethods['chisquare_icdf'](self, *args) - def chisquared(self,*args): + def chisquared(self, *args): r'''From Giac's documentation: Help for chisquared: chisquared(Intg(n),Real(x0)) @@ -2124,9 +2124,9 @@ cdef class GiacMethods_base: Ex3: randvector(3,chisquare,2) Ex4: ranm(4,3,chisquare,2) ''' - return GiacMethods['chisquared'](self,*args) + return GiacMethods['chisquared'](self, *args) - def chisquared_cdf(self,*args): + def chisquared_cdf(self, *args): r'''From Giac's documentation: Help for chisquared_cdf: chisquared_cdf(Intg(n),Real(x0)) @@ -2135,9 +2135,9 @@ cdef class GiacMethods_base: Ex1:chisquared_cdf(2,6.1) Ex2:chisquared_cdf(4,6.1) ''' - return GiacMethods['chisquared_cdf'](self,*args) + return GiacMethods['chisquared_cdf'](self, *args) - def chisquared_icdf(self,*args): + def chisquared_icdf(self, *args): r'''From Giac's documentation: Help for chisquared_icdf: chisquared_icdf(Intg(n),Real(p)) @@ -2146,9 +2146,9 @@ cdef class GiacMethods_base: Ex1:chisquared_icdf(2,0.95) Ex2:chisquared_icdf(4,0.05) ''' - return GiacMethods['chisquared_icdf'](self,*args) + return GiacMethods['chisquared_icdf'](self, *args) - def chisquaret(self,*args): + def chisquaret(self, *args): r'''From Giac's documentation: Help for chisquaret: chisquaret(Data,[Func],[FuncParams]) @@ -2164,9 +2164,9 @@ cdef class GiacMethods_base: Ex8:chisquaret([11,16,17,22,14,10],[1/6,1/6,1/6,1/6,1/6,1/6]) Ex9:chisquaret([11,16,17,22,14,10],[(1/6)$6]) ''' - return GiacMethods['chisquaret'](self,*args) + return GiacMethods['chisquaret'](self, *args) - def choice(self,*args): + def choice(self, *args): r'''From Giac's documentation: Help for choice: choice(Lst(L)) @@ -2177,9 +2177,9 @@ cdef class GiacMethods_base: Ex3: L:=[1,2,3,4,5,6];L:=choice(L) Ex4: L:=[1,2,3,4,5,6];L.choice() ''' - return GiacMethods['choice'](self,*args) + return GiacMethods['choice'](self, *args) - def cholesky(self,*args): + def cholesky(self, *args): r'''From Giac's documentation: Help for cholesky: cholesky(Mtrx) @@ -2187,9 +2187,9 @@ cdef class GiacMethods_base: See also: 1/ lu 2/ qr 3/ gauss Ex1:cholesky([[3,1],[1,4]]) ''' - return GiacMethods['cholesky'](self,*args) + return GiacMethods['cholesky'](self, *args) - def chr(self,*args): + def chr(self, *args): r'''From Giac's documentation: Help for chr: chr(Intg or Lst(Intg)) @@ -2198,9 +2198,9 @@ cdef class GiacMethods_base: Ex1:chr(65) Ex2:chr([65,66,67]) ''' - return GiacMethods['chr'](self,*args) + return GiacMethods['chr'](self, *args) - def chrem(self,*args): + def chrem(self, *args): r'''From Giac's documentation: Help for chrem: chrem(LstIntg(a,b,c....),LstIntg(p,q,r,....)) @@ -2212,9 +2212,9 @@ cdef class GiacMethods_base: Ex4:chrem([2,4,6,7],[3,5,7,11]) Ex5:chrem([2*x+1,4*x+2,6*x-1,x+1],[3,5,7,11]) ''' - return GiacMethods['chrem'](self,*args) + return GiacMethods['chrem'](self, *args) - def chromatic_index(self,*args): + def chromatic_index(self, *args): r'''From Giac's documentation: Help for chromatic_index: chromatic_index(Graph(G),[Lst(cols)]) @@ -2223,18 +2223,18 @@ cdef class GiacMethods_base: Ex1:chromatic_index(graph("petersen")) Ex2:chromatic_index(graph("dodecahedron"),colors) ''' - return GiacMethods['chromatic_index'](self,*args) + return GiacMethods['chromatic_index'](self, *args) - def chromatic_number(self,*args): + def chromatic_number(self, *args): r'''From Giac's documentation: Help for chromatic_number: chromatic_number(Graph(G)) Returns the chromatic number of G. Ex1:chromatic_number(graph("petersen")) ''' - return GiacMethods['chromatic_number'](self,*args) + return GiacMethods['chromatic_number'](self, *args) - def chromatic_polynomial(self,*args): + def chromatic_polynomial(self, *args): r'''From Giac's documentation: Help for chromatic_polynomial: chromatic_polynomial(Graph(G),[Var(t)]) @@ -2243,9 +2243,9 @@ cdef class GiacMethods_base: Ex1:chromatic_polynomial(graph("petersen")) Ex2:chromatic_polynomial(graph("petersen"),3) ''' - return GiacMethods['chromatic_polynomial'](self,*args) + return GiacMethods['chromatic_polynomial'](self, *args) - def circle(self,*args): + def circle(self, *args): r'''From Giac's documentation: Help for circle: circle((Pnt(M) or Cplx(M),(Pnt(N) or Cplx(zN)),[Real(a)],[Real(b)],[Var(A)],[Var(B)]) @@ -2260,9 +2260,9 @@ cdef class GiacMethods_base: Ex7:circle(cercle(point([-1,0,0]),point([1,0,0]),point([0,2,0]))) Ex8:circle(cercle([-1,0,0],point([1,0,0]),[0,2,0])) ''' - return GiacMethods['circle'](self,*args) + return GiacMethods['circle'](self, *args) - def circumcircle(self,*args): + def circumcircle(self, *args): r'''From Giac's documentation: Help for circumcircle: circumcircle((Pnt or Cplx),(Pnt or Cplx),((Pnt or Cplx)) @@ -2270,9 +2270,9 @@ cdef class GiacMethods_base: See also: 1/ circle 2/ incircle 3/ excircle Ex1:circumcircle(0,1,1+i) ''' - return GiacMethods['circumcircle'](self,*args) + return GiacMethods['circumcircle'](self, *args) - def classes(self,*args): + def classes(self, *args): r'''From Giac's documentation: Help for classes: classes(Lst(l),[ClassMin],[ClassSize||Lst(Center)]) @@ -2284,9 +2284,9 @@ cdef class GiacMethods_base: Ex4:classes([1,1.2,1.4,1.6,1.8,2,2.5],1,[1.2,1.6,2.2]) Ex5:classes([0,0.5,1,1.5,2,2.5,3,3.5,4],[0..2,2..4,4..6]) ''' - return GiacMethods['classes'](self,*args) + return GiacMethods['classes'](self, *args) - def clear(self,*args): + def clear(self, *args): r'''From Giac's documentation: Help for clear: clear(NULL) @@ -2294,9 +2294,9 @@ cdef class GiacMethods_base: See also: 1/ set_pixel 2/ show_pixels Ex1:clear() ''' - return GiacMethods['clear'](self,*args) + return GiacMethods['clear'](self, *args) - def clique_cover(self,*args): + def clique_cover(self, *args): r'''From Giac's documentation: Help for clique_cover: clique_cover(Graph(G),[Intg(k)]) @@ -2306,9 +2306,9 @@ cdef class GiacMethods_base: Ex2:clique_cover(cycle_graph(5)) Ex3:clique_cover(graph_complement(complete_graph(3,4))) ''' - return GiacMethods['clique_cover'](self,*args) + return GiacMethods['clique_cover'](self, *args) - def clique_cover_number(self,*args): + def clique_cover_number(self, *args): r'''From Giac's documentation: Help for clique_cover_number: clique_cover_number(Graph(G)) @@ -2318,9 +2318,9 @@ cdef class GiacMethods_base: Ex2:clique_cover_number(cycle_graph(5)) Ex3:clique_cover_number(graph_complement(complete_graph(3,4))) ''' - return GiacMethods['clique_cover_number'](self,*args) + return GiacMethods['clique_cover_number'](self, *args) - def clique_number(self,*args): + def clique_number(self, *args): r'''From Giac's documentation: Help for clique_number: clique_number(Graph(G)) @@ -2328,9 +2328,9 @@ cdef class GiacMethods_base: See also: 1/ maximum_clique Ex1:clique_number(graph_complement(complete_graph(3,4))) ''' - return GiacMethods['clique_number'](self,*args) + return GiacMethods['clique_number'](self, *args) - def clique_stats(self,*args): + def clique_stats(self, *args): r'''From Giac's documentation: Help for clique_stats: clique_stats(Graph(G),[Intg(k)||Intrv(m..n)]) @@ -2340,9 +2340,9 @@ cdef class GiacMethods_base: Ex2:clique_stats(random_graph(50,0.5),5) Ex3:clique_stats(random_graph(50,0.5),3..5) ''' - return GiacMethods['clique_stats'](self,*args) + return GiacMethods['clique_stats'](self, *args) - def clustering_coefficient(self,*args): + def clustering_coefficient(self, *args): r'''From Giac's documentation: Help for clustering_coefficient: clustering_coefficient(Graph(G),[Vrtx(v)]) @@ -2351,9 +2351,9 @@ cdef class GiacMethods_base: Ex1:clustering_coefficient(graph(%{[1,2],[2,3],[2,4],[3,4],[4,1]%})) Ex2:clustering_coefficient(graph(%{[1,2],[2,3],[2,4],[3,4],[4,1]%}),2) ''' - return GiacMethods['clustering_coefficient'](self,*args) + return GiacMethods['clustering_coefficient'](self, *args) - def coeff(self,*args): + def coeff(self, *args): r'''From Giac's documentation: Help for coeff: coeff(Expr(P),[Var]) @@ -2363,9 +2363,9 @@ cdef class GiacMethods_base: Ex2:coeff(5*y^2-3,y) Ex3:coeff(5*y^2-3,y,2) ''' - return GiacMethods['coeff'](self,*args) + return GiacMethods['coeff'](self, *args) - def coeffs(self,*args): + def coeffs(self, *args): r'''From Giac's documentation: Help for coeffs: coeffs(Expr(P),[Var]) @@ -2375,9 +2375,9 @@ cdef class GiacMethods_base: Ex2:coeffs(5*y^2-3,y) Ex3:coeffs(5*y^2-3,y,2) ''' - return GiacMethods['coeffs'](self,*args) + return GiacMethods['coeffs'](self, *args) - def col(self,*args): + def col(self, *args): r'''From Giac's documentation: Help for col: col(Mtrx(A),Intg(n)||Interval(n1..n2)) @@ -2387,9 +2387,9 @@ cdef class GiacMethods_base: Ex2:col([[1,2,3],[4,5,6],[7,8,9]],0..1) Ex3: count_eq(3,[[3,2,3],[4,3,2],[3,2,1]],col) ''' - return GiacMethods['col'](self,*args) + return GiacMethods['col'](self, *args) - def colDim(self,*args): + def colDim(self, *args): r'''From Giac's documentation: Help for colDim: colDim(Mtrx) @@ -2398,9 +2398,9 @@ cdef class GiacMethods_base: Ex1:colDim([[1,2,3],[4,5,6]]) Ex2:colDim([[1,2],[3,4],[5,6]]) ''' - return GiacMethods['colDim'](self,*args) + return GiacMethods['colDim'](self, *args) - def colNorm(self,*args): + def colNorm(self, *args): r'''From Giac's documentation: Help for colNorm: colNorm(Vect or Mtrx) @@ -2409,9 +2409,9 @@ cdef class GiacMethods_base: Ex1:colNorm([[1,2],[3,-4]]) Ex2:colNorm([[1,2,3,-4],[-5,3,2,1]]) ''' - return GiacMethods['colNorm'](self,*args) + return GiacMethods['colNorm'](self, *args) - def colSwap(self,*args): + def colSwap(self, *args): r'''From Giac's documentation: Help for colSwap: colSwap(Mtrx(A),Intg(n1),Intg(n2)) @@ -2419,9 +2419,9 @@ cdef class GiacMethods_base: See also: 1/ rowSwap Ex1:colSwap([[1,2],[3,4],[5,6]],0,1) ''' - return GiacMethods['colSwap'](self,*args) + return GiacMethods['colSwap'](self, *args) - def coldim(self,*args): + def coldim(self, *args): r'''From Giac's documentation: Help for coldim: coldim(Mtrx) @@ -2430,9 +2430,9 @@ cdef class GiacMethods_base: Ex1:coldim([[1,2,3],[4,5,6]]) Ex2:coldim([[1,2],[3,4],[5,6]]) ''' - return GiacMethods['coldim'](self,*args) + return GiacMethods['coldim'](self, *args) - def collect(self,*args): + def collect(self, *args): r'''From Giac's documentation: Help for collect: collect(Poly or LstPoly) @@ -2442,9 +2442,9 @@ cdef class GiacMethods_base: Ex2:collect(x^2-2) Ex3:collect([x^2-2,x^2-4]) ''' - return GiacMethods['collect'](self,*args) + return GiacMethods['collect'](self, *args) - def colnorm(self,*args): + def colnorm(self, *args): r'''From Giac's documentation: Help for colnorm: colnorm(Vect or Mtrx) @@ -2453,9 +2453,9 @@ cdef class GiacMethods_base: Ex1:colnorm([[1,2],[3,-4]]) Ex2:colnorm([[1,2,3,-4],[-5,3,2,1]]) ''' - return GiacMethods['colnorm'](self,*args) + return GiacMethods['colnorm'](self, *args) - def color(self,*args): + def color(self, *args): r'''From Giac's documentation: Help for color: color([GeoObj or legende],Intg) @@ -2472,9 +2472,9 @@ cdef class GiacMethods_base: Ex9:color(red);square(0,1); Ex10:color(red+filled);square(0,1); ''' - return GiacMethods['color'](self,*args) + return GiacMethods['color'](self, *args) - def colspace(self,*args): + def colspace(self, *args): r'''From Giac's documentation: Help for colspace: colspace(Mtrx(A), [Var(d)]) @@ -2483,9 +2483,9 @@ cdef class GiacMethods_base: Ex1:colspace([[1,2,3],[1,2,3],[1,2,4],[1,2,5]]) Ex2:colspace([[1,2,3],[1,3,6],[2,5,9]],d) ''' - return GiacMethods['colspace'](self,*args) + return GiacMethods['colspace'](self, *args) - def colswap(self,*args): + def colswap(self, *args): r'''From Giac's documentation: Help for colswap: colswap(Mtrx(A),Intg(n1),Intg(n2)) @@ -2493,9 +2493,9 @@ cdef class GiacMethods_base: See also: 1/ rowSwap Ex1:colswap([[1,2],[3,4],[5,6]],0,1) ''' - return GiacMethods['colswap'](self,*args) + return GiacMethods['colswap'](self, *args) - def comDenom(self,*args): + def comDenom(self, *args): r'''From Giac's documentation: Help for comDenom: comDenom(Expr,[Var(Var)]) @@ -2505,9 +2505,9 @@ cdef class GiacMethods_base: Ex2:comDenom(1/x+1/y^2+1,y) Ex3:comDenom(1/x+1/y^2+1,x) ''' - return GiacMethods['comDenom'](self,*args) + return GiacMethods['comDenom'](self, *args) - def comb(self,*args): + def comb(self, *args): r'''From Giac's documentation: Help for comb: comb(Intg(n),Intg(r)) @@ -2515,9 +2515,9 @@ cdef class GiacMethods_base: See also: 1/ factorial 2/ perm Ex1:comb(4,2) ''' - return GiacMethods['comb'](self,*args) + return GiacMethods['comb'](self, *args) - def combine(self,*args): + def combine(self, *args): r'''From Giac's documentation: Help for combine: combine(Expr(Xpr),Fnc(f).) @@ -2527,9 +2527,9 @@ cdef class GiacMethods_base: Ex2:combine(sin(x)*cos(x),trig) Ex3:combine(ln(x)+ln(y),ln) ''' - return GiacMethods['combine'](self,*args) + return GiacMethods['combine'](self, *args) - def comment(self,*args): + def comment(self, *args): r'''From Giac's documentation: Help for comment: comment(Expr) @@ -2537,9 +2537,9 @@ cdef class GiacMethods_base: See also: 1/ Ex1:comment("my_comment") ''' - return GiacMethods['comment'](self,*args) + return GiacMethods['comment'](self, *args) - def common_perpendicular(self,*args): + def common_perpendicular(self, *args): r'''From Giac's documentation: Help for common_perpendicular: common_perpendicular(Line(D1),Line(D2)) @@ -2547,9 +2547,9 @@ cdef class GiacMethods_base: See also: 1/ altitude 2/ perpendicular Ex1:common_perpendicular(line([0,0,0],[0,5,5]),line([5,0,0],[0,0,5])) ''' - return GiacMethods['common_perpendicular'](self,*args) + return GiacMethods['common_perpendicular'](self, *args) - def companion(self,*args): + def companion(self, *args): r'''From Giac's documentation: Help for companion: companion(Poly,Var) @@ -2558,9 +2558,9 @@ cdef class GiacMethods_base: Ex1:companion(x^2+5x-7,x) Ex2:companion(-pcar([[1,0,1],[0,2,-1],[1,-1,1]],x),x) ''' - return GiacMethods['companion'](self,*args) + return GiacMethods['companion'](self, *args) - def compare(self,*args): + def compare(self, *args): r'''From Giac's documentation: Help for compare: compare(Obj(arg1),Obj(arg2)) @@ -2570,9 +2570,9 @@ cdef class GiacMethods_base: Ex2:compare(1.0,2) Ex3:compare("ab","cd") ''' - return GiacMethods['compare'](self,*args) + return GiacMethods['compare'](self, *args) - def complete_binary_tree(self,*args): + def complete_binary_tree(self, *args): r'''From Giac's documentation: Help for complete_binary_tree: complete_binary_tree(Intg(n)) @@ -2580,9 +2580,9 @@ cdef class GiacMethods_base: See also: 1/ complete_kary_tree 2/ is_tree 3/ random_tree Ex1:complete_binary_tree(3) ''' - return GiacMethods['complete_binary_tree'](self,*args) + return GiacMethods['complete_binary_tree'](self, *args) - def complete_graph(self,*args): + def complete_graph(self, *args): r'''From Giac's documentation: Help for complete_graph: complete_graph(Intg(n)||Lst(V)||Seq(n1,n2,...,nk)) @@ -2592,9 +2592,9 @@ cdef class GiacMethods_base: Ex2:complete_graph(["one","two","three"]) Ex3:complete_graph(2,3,4) ''' - return GiacMethods['complete_graph'](self,*args) + return GiacMethods['complete_graph'](self, *args) - def complete_kary_tree(self,*args): + def complete_kary_tree(self, *args): r'''From Giac's documentation: Help for complete_kary_tree: complete_kary_tree(Intg(n)) @@ -2602,9 +2602,9 @@ cdef class GiacMethods_base: See also: 1/ complete_binary_tree 2/ is_tree 3/ random_tree Ex1:complete_kary_tree(3,3) ''' - return GiacMethods['complete_kary_tree'](self,*args) + return GiacMethods['complete_kary_tree'](self, *args) - def complex(self,*args): + def complex(self, *args): r'''From Giac's documentation: Help for complex: complex(Opt) @@ -2614,9 +2614,9 @@ cdef class GiacMethods_base: Ex2: assume(a,DOM_COMPLEX) Ex3: a:=1+i;type(a) ''' - return GiacMethods['complex'](self,*args) + return GiacMethods['complex'](self, *args) - def complex_variables(self,*args): + def complex_variables(self, *args): r'''From Giac's documentation: Help for complex_variables: complex_variables(:=Intg(0 or 1)) @@ -2625,9 +2625,9 @@ cdef class GiacMethods_base: Ex1: complex_variables:=1 Ex2: complex_variables:=0 ''' - return GiacMethods['complex_variables'](self,*args) + return GiacMethods['complex_variables'](self, *args) - def complexroot(self,*args): + def complexroot(self, *args): r'''From Giac's documentation: Help for complexroot: complexroot(Poly(P),Real(l),[Cplx(a)],[Cplx(b)]) @@ -2638,9 +2638,9 @@ cdef class GiacMethods_base: Ex3:complexroot(x^3+8,1e-5,0,2+2*i) Ex4:complexroot(x^5-2*x^4+x^3+i,0.1,1+0.5*i,1.1+0.7*i) ''' - return GiacMethods['complexroot'](self,*args) + return GiacMethods['complexroot'](self, *args) - def concat(self,*args): + def concat(self, *args): r'''From Giac's documentation: Help for concat: concat(Lst,Lst||Seq,Seq||Str,Str||Mtrx,Mtrx) @@ -2652,9 +2652,9 @@ cdef class GiacMethods_base: Ex4: L:=[1,2];L.concat([3,4,5]) Ex5: S:="abcd";S.concat("efghi") ''' - return GiacMethods['concat'](self,*args) + return GiacMethods['concat'](self, *args) - def cond(self,*args): + def cond(self, *args): r'''From Giac's documentation: Help for cond: cond(Mtrx,[2]||[inf]) @@ -2665,9 +2665,9 @@ cdef class GiacMethods_base: Ex3:cond([[1,2],[1,4]],2) Ex4:cond([[1,2],[1,4]],inf) ''' - return GiacMethods['cond'](self,*args) + return GiacMethods['cond'](self, *args) - def condensation(self,*args): + def condensation(self, *args): r'''From Giac's documentation: Help for condensation: condensation(Graph(G)) @@ -2675,9 +2675,9 @@ cdef class GiacMethods_base: See also: 1/ strongly_connected_components Ex1:condensation(digraph(%{[1,2],[1,3],[3,1],[1,4],[2,3],[4,3],[4,5],[5,3],[5,6],[7,6],[8,6],[8,7]%})) ''' - return GiacMethods['condensation'](self,*args) + return GiacMethods['condensation'](self, *args) - def cone(self,*args): + def cone(self, *args): r'''From Giac's documentation: Help for cone: cone(Pnt(A),Vect(v),Real(t),[Real(h)]) @@ -2686,9 +2686,9 @@ cdef class GiacMethods_base: Ex1:cone([0,0,0],[0,0,1],pi/6) Ex2:cone([0,0,0],[0,1,1],pi/6,4) ''' - return GiacMethods['cone'](self,*args) + return GiacMethods['cone'](self, *args) - def confrac(self,*args): + def confrac(self, *args): r'''From Giac's documentation: Help for confrac: confrac(Opt) @@ -2696,9 +2696,9 @@ cdef class GiacMethods_base: See also: 1/ convert Ex1: convert(sqrt(2),confrac,'L'),L ''' - return GiacMethods['confrac'](self,*args) + return GiacMethods['confrac'](self, *args) - def conic(self,*args): + def conic(self, *args): r'''From Giac's documentation: Help for conic: conic(Expr,[LstVar]) @@ -2709,9 +2709,9 @@ cdef class GiacMethods_base: Ex3:conic(u^2-2*v^2-2*u*v-1,[u,v]) Ex4:conic(y^2-x*y+3,[x,y]) ''' - return GiacMethods['conic'](self,*args) + return GiacMethods['conic'](self, *args) - def conj(self,*args): + def conj(self, *args): r'''From Giac's documentation: Help for conj: conj(Cplx) @@ -2722,9 +2722,9 @@ cdef class GiacMethods_base: Ex3:conj((1+2*i)^2) Ex4:conj([[1+i,2,3],[1,3,6],[2,5,9-i]]) ''' - return GiacMethods['conj'](self,*args) + return GiacMethods['conj'](self, *args) - def conjugate_equation(self,*args): + def conjugate_equation(self, *args): r'''From Giac's documentation: Help for conjugate_equation: conjugate_equation(Expr(y0),Lst(P),Lst(V),Var(x),Real(a)) @@ -2732,9 +2732,9 @@ cdef class GiacMethods_base: See also: 1/ jacobi_equation 2/ euler_lagrange Ex1:conjugate_equation(A*sin(t)+B*cos(t),[A,B],[1,0],t,0) ''' - return GiacMethods['conjugate_equation'](self,*args) + return GiacMethods['conjugate_equation'](self, *args) - def conjugate_gradient(self,*args): + def conjugate_gradient(self, *args): r'''From Giac's documentation: Help for conjugate_gradient: conjugate_gradient(Mtrx(A),Vect(y),[Vect(x0),Real(eps)]) @@ -2745,18 +2745,18 @@ cdef class GiacMethods_base: Ex3:conjugate_gradient([[2,1],[1,5]],[1,0],[0.55,-0.11],1e-2) Ex4:conjugate_gradient([[2,1],[1,5]],[1,0],[0.55,-0.11],1e-10) ''' - return GiacMethods['conjugate_gradient'](self,*args) + return GiacMethods['conjugate_gradient'](self, *args) - def connected(self,*args): + def connected(self, *args): r'''From Giac's documentation: Help for connected: connected(Opt) Option for the random_regular_graph command. See also: 1/ directed 2/ weighted 3/ random_regular_graph ''' - return GiacMethods['connected'](self,*args) + return GiacMethods['connected'](self, *args) - def connected_components(self,*args): + def connected_components(self, *args): r'''From Giac's documentation: Help for connected_components: connected_components(Graph(G)) @@ -2764,9 +2764,9 @@ cdef class GiacMethods_base: See also: 1/ articulation_points 2/ is_biconnected 3/ is_strongly_connected 4/ strongly_connected_components 5/ underlying_graph Ex1:connected_components(graph_complement(cycle_graph(4))) ''' - return GiacMethods['connected_components'](self,*args) + return GiacMethods['connected_components'](self, *args) - def cont(self,*args): + def cont(self, *args): r'''From Giac's documentation: Help for cont: cont(NULL) @@ -2774,9 +2774,9 @@ cdef class GiacMethods_base: See also: 1/ continue Ex1:cont() ''' - return GiacMethods['cont'](self,*args) + return GiacMethods['cont'](self, *args) - def contains(self,*args): + def contains(self, *args): r'''From Giac's documentation: Help for contains: contains((Lst(l) or Set(l)),Elem(e)) @@ -2786,9 +2786,9 @@ cdef class GiacMethods_base: Ex2:contains([0,1,2,3],4) Ex3:contains([1..2],1.5) ''' - return GiacMethods['contains'](self,*args) + return GiacMethods['contains'](self, *args) - def content(self,*args): + def content(self, *args): r'''From Giac's documentation: Help for content: content(Poly(P),[Var]) @@ -2798,9 +2798,9 @@ cdef class GiacMethods_base: Ex2:content([2,10,6]) Ex3:content(2*t^2+10*t+6,t) ''' - return GiacMethods['content'](self,*args) + return GiacMethods['content'](self, *args) - def contourplot(self,*args): + def contourplot(self, *args): r'''From Giac's documentation: Help for contourplot: contourplot(Expr(Xpr),[LstVar],[LstVal]) @@ -2811,9 +2811,9 @@ cdef class GiacMethods_base: Ex3:contourplot(x^2+2*y^2-2,[x,y],[1.0,2.0,3.0]) Ex4:contourplot(x^2-y^2,[x=-4..4,y=-4..4],seq(k,k,-11,11,3),xstep=0.1,ystep=0.1) ''' - return GiacMethods['contourplot'](self,*args) + return GiacMethods['contourplot'](self, *args) - def contract_edge(self,*args): + def contract_edge(self, *args): r'''From Giac's documentation: Help for contract_edge: contract_edge(Graph(G),Edge(e)) @@ -2821,9 +2821,9 @@ cdef class GiacMethods_base: See also: 1/ delete_edge 2/ delete_vertex 3/ foldl Ex1:contract_edge(complete_graph(4),[1,3]) ''' - return GiacMethods['contract_edge'](self,*args) + return GiacMethods['contract_edge'](self, *args) - def convert(self,*args): + def convert(self, *args): r'''From Giac's documentation: Help for convert: convert(Expr(Xpr),Cmd(cmd)) @@ -2847,9 +2847,9 @@ cdef class GiacMethods_base: Ex16: A[2,1]:=1;convert(A,array) Ex17: B[0..1,1..2]:=1;B[2,2]:=2;convert(B,array) ''' - return GiacMethods['convert'](self,*args) + return GiacMethods['convert'](self, *args) - def convertir(self,*args): + def convertir(self, *args): r'''From Giac's documentation: Help for convertir: convertir(Expr(Xpr),Cmd(cmd)) @@ -2873,9 +2873,9 @@ cdef class GiacMethods_base: Ex16: A[2,1]:=1;convert(A,array) Ex17: B[0..1,1..2]:=1;B[2,2]:=2;convert(B,array) ''' - return GiacMethods['convertir'](self,*args) + return GiacMethods['convertir'](self, *args) - def convex(self,*args): + def convex(self, *args): r'''From Giac's documentation: Help for convex: convex(Expr(f),Lst(x,y,..)) @@ -2891,9 +2891,9 @@ cdef class GiacMethods_base: Ex8:convex(sqrt((1+cos(x)^2)/sin(x)),x) Ex9:convex(sqrt((1+(u')^2)/(2*g*u)),u(t)) ''' - return GiacMethods['convex'](self,*args) + return GiacMethods['convex'](self, *args) - def convexhull(self,*args): + def convexhull(self, *args): r'''From Giac's documentation: Help for convexhull: convexhull(Lst) @@ -2903,9 +2903,9 @@ cdef class GiacMethods_base: Ex2:convexhull([0,1,1+i,1+2i,-1-i,1-3i,-2+i]) Ex3: polygon(convexhull(0,1,1+i,1+2i,-1-i,1-3i,-2+i)) ''' - return GiacMethods['convexhull'](self,*args) + return GiacMethods['convexhull'](self, *args) - def convolution(self,*args): + def convolution(self, *args): r'''From Giac's documentation: Help for convolution: convolution(Lst(u),Lst(v)) @@ -2914,9 +2914,9 @@ cdef class GiacMethods_base: Ex1:convolution([1,2,3],[1,-1,1,-1]) Ex2:convolution(25*exp(2*x),x*exp(-3*x),x) ''' - return GiacMethods['convolution'](self,*args) + return GiacMethods['convolution'](self, *args) - def coordinates(self,*args): + def coordinates(self, *args): r'''From Giac's documentation: Help for coordinates: coordinates(Pnt or Cplx or Vect) @@ -2931,9 +2931,9 @@ cdef class GiacMethods_base: Ex7:coordinates(point(1,2,3)) Ex8:coordinates(vecteur([1,2,3],[4,5,6])) ''' - return GiacMethods['coordinates'](self,*args) + return GiacMethods['coordinates'](self, *args) - def copy(self,*args): + def copy(self, *args): r'''From Giac's documentation: Help for copy: copy(Mtrx,Var) @@ -2941,9 +2941,9 @@ cdef class GiacMethods_base: See also: 1/ =< Ex1: A:=copy(B) ''' - return GiacMethods['copy'](self,*args) + return GiacMethods['copy'](self, *args) - def correlation(self,*args): + def correlation(self, *args): r'''From Giac's documentation: Help for correlation: correlation(Lst||Mtrx,[Lst]) @@ -2951,9 +2951,9 @@ cdef class GiacMethods_base: See also: 1/ covariance 2/ covariance_correlation Ex1:correlation([[1,2],[1,1],[4,7]]) ''' - return GiacMethods['correlation'](self,*args) + return GiacMethods['correlation'](self, *args) - def cos(self,*args): + def cos(self, *args): r'''From Giac's documentation: Help for cos: cos(Expr or Opt) @@ -2962,9 +2962,9 @@ cdef class GiacMethods_base: Ex1:cos(0) Ex2: convert(cos(x)^4+sin(x)^2,cos) ''' - return GiacMethods['cos'](self,*args) + return GiacMethods['cos'](self, *args) - def cos2sintan(self,*args): + def cos2sintan(self, *args): r'''From Giac's documentation: Help for cos2sintan: cos2sintan(Expr) @@ -2972,9 +2972,9 @@ cdef class GiacMethods_base: See also: 1/ tan2sincos 2/ sin2costan 3/ tan2sincos2 4/ tan2cossin2 Ex1:cos2sintan(cos(x)) ''' - return GiacMethods['cos2sintan'](self,*args) + return GiacMethods['cos2sintan'](self, *args) - def cosh(self,*args): + def cosh(self, *args): r'''From Giac's documentation: Help for cosh: cosh(Expr) @@ -2982,9 +2982,9 @@ cdef class GiacMethods_base: See also: 1/ acosh Ex1:cosh(0) ''' - return GiacMethods['cosh'](self,*args) + return GiacMethods['cosh'](self, *args) - def cosine_window(self,*args): + def cosine_window(self, *args): r'''From Giac's documentation: Help for cosine_window: cosine_window(Lst,[Real(a)],[Interval(n1..n2)]) @@ -2992,9 +2992,9 @@ cdef class GiacMethods_base: See also: 1/ blackman_harris_window 2/ blackman_window 3/ bohman_window 4/ bartlett_hann_window 5/ gaussian_window 6/ hamming_window 7/ hann_poisson_window 8/ hann_window 9/ parzen_window 10/ poisson_window 11/ riemann_window 12/ triangle_window 13/ tukey_window 14/ welch_window Ex1: scatterplot(cosine_window(randvector(1000,0..1),1.5)) ''' - return GiacMethods['cosine_window'](self,*args) + return GiacMethods['cosine_window'](self, *args) - def cot(self,*args): + def cot(self, *args): r'''From Giac's documentation: Help for cot: cot(Expr) @@ -3002,9 +3002,9 @@ cdef class GiacMethods_base: See also: 1/ acot 2/ tan Ex1:cot(pi/2) ''' - return GiacMethods['cot'](self,*args) + return GiacMethods['cot'](self, *args) - def cote(self,*args): + def cote(self, *args): r'''From Giac's documentation: Help for cote: cote(Vect) @@ -3013,9 +3013,9 @@ cdef class GiacMethods_base: Ex1:cote(point[1,2,3]) Ex2:cote(point(1,2,3)) ''' - return GiacMethods['cote'](self,*args) + return GiacMethods['cote'](self, *args) - def count(self,*args): + def count(self, *args): r'''From Giac's documentation: Help for count: count(Fnc(f)||LstIntg,(Lst||Mtrx)(l),[Opt(row||col)]) @@ -3032,9 +3032,9 @@ cdef class GiacMethods_base: Ex9:count((x)->x>2 && x<4,[[3,9/2],[4,1]]) Ex10:count((x)->x<2 || x>4,[[3,9/2],[4,1]]) ''' - return GiacMethods['count'](self,*args) + return GiacMethods['count'](self, *args) - def count_eq(self,*args): + def count_eq(self, *args): r'''From Giac's documentation: Help for count_eq: count_eq(Real(a),(Lst||Mtrx)(L),[Opt(row||col)]) @@ -3045,9 +3045,9 @@ cdef class GiacMethods_base: Ex3:count_eq(4,[[3,4],[4,1]],row) Ex4:count_eq(4,[[3,4],[4,1]],col) ''' - return GiacMethods['count_eq'](self,*args) + return GiacMethods['count_eq'](self, *args) - def count_inf(self,*args): + def count_inf(self, *args): r'''From Giac's documentation: Help for count_inf: count_inf(Real(a),(Lst||Mtrx)(L),[Opt(row||col)]) @@ -3058,9 +3058,9 @@ cdef class GiacMethods_base: Ex3:count_inf(4,[[3,5],[4,1]],row) Ex4:count_inf(4,[[3,5],[4,1]],col) ''' - return GiacMethods['count_inf'](self,*args) + return GiacMethods['count_inf'](self, *args) - def count_sup(self,*args): + def count_sup(self, *args): r'''From Giac's documentation: Help for count_sup: count_sup(Real(a),(Lst||Mtrx)(L),[Opt(row||col)]) @@ -3071,9 +3071,9 @@ cdef class GiacMethods_base: Ex3:count_sup(3,[[3,5],[4,1]],row) Ex4:count_sup(3,[[3,5],[4,1]],col) ''' - return GiacMethods['count_sup'](self,*args) + return GiacMethods['count_sup'](self, *args) - def courbe_parametrique(self,*args): + def courbe_parametrique(self, *args): r'''From Giac's documentation: Help for courbe_parametrique: courbe_parametrique(Cplx||Lst,Var||Lst(Var)) @@ -3088,9 +3088,9 @@ cdef class GiacMethods_base: Ex7:courbe_parametrique([v*cos(u),v*sin(u),v],[u,v]) Ex8:courbe_parametrique([v*cos(u),v*sin(u),v],[u=0..pi,v=0..3],ustep=0.1,vstep=0.2) ''' - return GiacMethods['courbe_parametrique'](self,*args) + return GiacMethods['courbe_parametrique'](self, *args) - def courbe_polaire(self,*args): + def courbe_polaire(self, *args): r'''From Giac's documentation: Help for courbe_polaire: courbe_polaire(Expr,Var,VarMin,VarMax) @@ -3099,9 +3099,9 @@ cdef class GiacMethods_base: Ex1:courbe_polaire(sin(2*x),x,0,pi) Ex2:courbe_polaire(sin(2*x),x,0,pi,tstep=0.1) ''' - return GiacMethods['courbe_polaire'](self,*args) + return GiacMethods['courbe_polaire'](self, *args) - def covariance(self,*args): + def covariance(self, *args): r'''From Giac's documentation: Help for covariance: covariance(Lst||Mtrx,[Lst]) @@ -3109,9 +3109,9 @@ cdef class GiacMethods_base: See also: 1/ correlation 2/ covariance_correlation Ex1:covariance([[1,2],[1,1],[4,7]]) ''' - return GiacMethods['covariance'](self,*args) + return GiacMethods['covariance'](self, *args) - def covariance_correlation(self,*args): + def covariance_correlation(self, *args): r'''From Giac's documentation: Help for covariance_correlation: covariance_correlation(Lst||Mtrx,[Lst]) @@ -3119,9 +3119,9 @@ cdef class GiacMethods_base: See also: 1/ covariance 2/ correlation Ex1:covariance_correlation([[1,2],[1,1],[4,7]]) ''' - return GiacMethods['covariance_correlation'](self,*args) + return GiacMethods['covariance_correlation'](self, *args) - def cpartfrac(self,*args): + def cpartfrac(self, *args): r'''From Giac's documentation: Help for cpartfrac: cpartfrac(RatFrac) @@ -3131,9 +3131,9 @@ cdef class GiacMethods_base: Ex2:cpartfrac((x^2-2*x+3)/(x^2-3*x+2)) Ex3:cpartfrac(a/(z*(z-b)),z) ''' - return GiacMethods['cpartfrac'](self,*args) + return GiacMethods['cpartfrac'](self, *args) - def crationalroot(self,*args): + def crationalroot(self, *args): r'''From Giac's documentation: Help for crationalroot: crationalroot(Poly(P)) @@ -3141,9 +3141,9 @@ cdef class GiacMethods_base: See also: 1/ proot 2/ froot 3/ complexroot 4/ rationalroot 5/ realroot Ex1:crationalroot(2*x^3+(-5-7*i)*x^2+(-4+14*i)*x+8-4*i) ''' - return GiacMethods['crationalroot'](self,*args) + return GiacMethods['crationalroot'](self, *args) - def crayon(self,*args): + def crayon(self, *args): r'''From Giac's documentation: Help for crayon: crayon(Color) @@ -3154,9 +3154,9 @@ cdef class GiacMethods_base: Ex3:crayon(5) Ex4:crayon(gomme) ''' - return GiacMethods['crayon'](self,*args) + return GiacMethods['crayon'](self, *args) - def createwav(self,*args): + def createwav(self, *args): r'''From Giac's documentation: Help for createwav: createwav(Lst(data),[opts]) @@ -3168,9 +3168,9 @@ cdef class GiacMethods_base: Ex4:createwav(10*sin(2*pi*440*soundsec(2)),normalize=-3) Ex5: t:=soundsec(3):;L,R:=sin(2*pi*440*t),sin(2*pi*445*t):;createwav([L,R]) ''' - return GiacMethods['createwav'](self,*args) + return GiacMethods['createwav'](self, *args) - def cross(self,*args): + def cross(self, *args): r'''From Giac's documentation: Help for cross: cross(Vect(v1),Vect(v2)) @@ -3179,9 +3179,9 @@ cdef class GiacMethods_base: Ex1:cross([1,2],[3,4]) Ex2:cross([1,2,3],[4,5,6]) ''' - return GiacMethods['cross'](self,*args) + return GiacMethods['cross'](self, *args) - def crossP(self,*args): + def crossP(self, *args): r'''From Giac's documentation: Help for crossP: crossP(Vect(v1),Vect(v2)) @@ -3190,9 +3190,9 @@ cdef class GiacMethods_base: Ex1:crossP([1,2],[3,4]) Ex2:crossP([1,2,3],[4,5,6]) ''' - return GiacMethods['crossP'](self,*args) + return GiacMethods['crossP'](self, *args) - def cross_correlation(self,*args): + def cross_correlation(self, *args): r'''From Giac's documentation: Help for cross_correlation: cross_correlation(cross_correlation(Lst(u),Lst(v))) @@ -3200,9 +3200,9 @@ cdef class GiacMethods_base: See also: 1/ auto_correlation 2/ correlation Ex1:cross_correlation([1,2],[3,4,5]) ''' - return GiacMethods['cross_correlation'](self,*args) + return GiacMethods['cross_correlation'](self, *args) - def cross_point(self,*args): + def cross_point(self, *args): r'''From Giac's documentation: Help for cross_point: cross_point(Opt) @@ -3211,9 +3211,9 @@ cdef class GiacMethods_base: Ex1: F:=display(point(2+1.5*i),point_point) Ex2: F:=display(point(2+1.5*i),rhombus_point) ''' - return GiacMethods['cross_point'](self,*args) + return GiacMethods['cross_point'](self, *args) - def cross_ratio(self,*args): + def cross_ratio(self, *args): r'''From Giac's documentation: Help for cross_ratio: cross_ratio(Pnt or Cplx(a),Pnt or Cplx(b),Pnt or Cplx(c),Pnt or Cplx(d)) @@ -3223,9 +3223,9 @@ cdef class GiacMethods_base: Ex2:cross_ratio(0,1+i,1,i) Ex3:cross_ratio(0,1,2,3) ''' - return GiacMethods['cross_ratio'](self,*args) + return GiacMethods['cross_ratio'](self, *args) - def crossproduct(self,*args): + def crossproduct(self, *args): r'''From Giac's documentation: Help for crossproduct: crossproduct(Vect(v1),Vect(v2)) @@ -3234,9 +3234,9 @@ cdef class GiacMethods_base: Ex1:crossproduct([1,2],[3,4]) Ex2:crossproduct([1,2,3],[4,5,6]) ''' - return GiacMethods['crossproduct'](self,*args) + return GiacMethods['crossproduct'](self, *args) - def csc(self,*args): + def csc(self, *args): r'''From Giac's documentation: Help for csc: csc(Expr) @@ -3244,9 +3244,9 @@ cdef class GiacMethods_base: See also: 1/ sin 2/ acsc Ex1:csc(pi/2) ''' - return GiacMethods['csc'](self,*args) + return GiacMethods['csc'](self, *args) - def csolve(self,*args): + def csolve(self, *args): r'''From Giac's documentation: Help for csolve: csolve(LstEq,LstVar) @@ -3257,9 +3257,9 @@ cdef class GiacMethods_base: Ex3:csolve(x^4-y^4 and x+y=0 and x^2=2*x,[x,y]) Ex4:csolve(u*v-u=v and v^2=u,[u,v]) ''' - return GiacMethods['csolve'](self,*args) + return GiacMethods['csolve'](self, *args) - def csv2gen(self,*args): + def csv2gen(self, *args): r'''From Giac's documentation: Help for csv2gen: csv2gen(Strng(filename),Strng(sep),Strng(nl),Strng(decsep),Strng(eof),[string]) @@ -3267,9 +3267,9 @@ cdef class GiacMethods_base: See also: 1/ read Ex1:csv2gen("mat.txt",",",char(10),".") ''' - return GiacMethods['csv2gen'](self,*args) + return GiacMethods['csv2gen'](self, *args) - def cube(self,*args): + def cube(self, *args): r'''From Giac's documentation: Help for cube: cube(Pnt(A),Pnt(B),Pnt(C)) @@ -3281,9 +3281,9 @@ cdef class GiacMethods_base: Ex4: c:=cube([0,0,0],[1,0,0],[0,1,0]);c1,c2,c4,c3,c5,c6,c7,c8:=sommets(c); Ex5: c:=cube([0,0,0],[0,2,0],[0,0,1]);c1,c2,c4,c3,c5,c6,c7,c8:=sommets(c); ''' - return GiacMethods['cube'](self,*args) + return GiacMethods['cube'](self, *args) - def cumSum(self,*args): + def cumSum(self, *args): r'''From Giac's documentation: Help for cumSum: cumSum(Lst(l)||Seq||Str) @@ -3293,9 +3293,9 @@ cdef class GiacMethods_base: Ex2:cumSum(1.2,3,4.5,6) Ex3:cumSum("a","b","c","d") ''' - return GiacMethods['cumSum'](self,*args) + return GiacMethods['cumSum'](self, *args) - def cumsum(self,*args): + def cumsum(self, *args): r'''From Giac's documentation: Help for cumsum: cumsum(Lst(l)||Seq||Str) @@ -3305,9 +3305,9 @@ cdef class GiacMethods_base: Ex2:cumsum(1.2,3,4.5,6) Ex3:cumsum("a","b","c","d") ''' - return GiacMethods['cumsum'](self,*args) + return GiacMethods['cumsum'](self, *args) - def cumulated_frequencies(self,*args): + def cumulated_frequencies(self, *args): r'''From Giac's documentation: Help for cumulated_frequencies: cumulated_frequencies(Lst || Mtrx) @@ -3319,9 +3319,9 @@ cdef class GiacMethods_base: Ex4:cumulated_frequencies([[1..2,0.3],[2..3,0.5],[3..4,0.2]]) Ex5:cumulated_frequencies([[1..2,0.3,0.5],[2..3,0.5,0.2],[3..4,0.2,0.3]]) ''' - return GiacMethods['cumulated_frequencies'](self,*args) + return GiacMethods['cumulated_frequencies'](self, *args) - def curl(self,*args): + def curl(self, *args): r'''From Giac's documentation: Help for curl: curl(Lst(A,B,C),Lst(x,y,z)) @@ -3329,9 +3329,9 @@ cdef class GiacMethods_base: See also: 1/ derive 2/ divergence Ex1:curl([2*x*y,x*z,y*z],[x,y,z]) ''' - return GiacMethods['curl'](self,*args) + return GiacMethods['curl'](self, *args) - def current_sheet(self,*args): + def current_sheet(self, *args): r'''From Giac's documentation: Help for current_sheet: current_sheet([Intg||Inter],[Intg||Letter],[Letter]) @@ -3339,9 +3339,9 @@ cdef class GiacMethods_base: Ex1:current_sheet(1,2) Ex2:current_sheet(A1..A5,B,G) ''' - return GiacMethods['current_sheet'](self,*args) + return GiacMethods['current_sheet'](self, *args) - def curvature(self,*args): + def curvature(self, *args): r'''From Giac's documentation: Help for curvature: curvature(Curve,Point) @@ -3355,18 +3355,18 @@ cdef class GiacMethods_base: Ex6:curvature([3*exp(t/2)*cos(t),3*exp(t/2)*sin(t)],t,7) Ex7: trigcos(curvature([2*cos(t),2*sin(t),3*t],t)) ''' - return GiacMethods['curvature'](self,*args) + return GiacMethods['curvature'](self, *args) - def curve(self,*args): + def curve(self, *args): r'''From Giac's documentation: Help for curve: curve(Expr) Reserved word. See also: 1/ ''' - return GiacMethods['curve'](self,*args) + return GiacMethods['curve'](self, *args) - def cyan(self,*args): + def cyan(self, *args): r'''From Giac's documentation: Help for cyan: cyan(Opt) @@ -3375,9 +3375,9 @@ cdef class GiacMethods_base: Ex1: F:=display(point(2+1.5*i),red) Ex2: F:=display(point(2+1.5*i),point_point+green) ''' - return GiacMethods['cyan'](self,*args) + return GiacMethods['cyan'](self, *args) - def cycle2perm(self,*args): + def cycle2perm(self, *args): r'''From Giac's documentation: Help for cycle2perm: cycle2perm(Cycle) @@ -3385,9 +3385,9 @@ cdef class GiacMethods_base: See also: 1/ cycles2permu 2/ permu2cycles Ex1:cycle2perm([1,3,5]) ''' - return GiacMethods['cycle2perm'](self,*args) + return GiacMethods['cycle2perm'](self, *args) - def cycle_graph(self,*args): + def cycle_graph(self, *args): r'''From Giac's documentation: Help for cycle_graph: cycle_graph(Intg(n)||Lst(V)) @@ -3396,9 +3396,9 @@ cdef class GiacMethods_base: Ex1:cycle_graph(4) Ex2:cycle_graph(["one","two","three","four","five"]) ''' - return GiacMethods['cycle_graph'](self,*args) + return GiacMethods['cycle_graph'](self, *args) - def cycleinv(self,*args): + def cycleinv(self, *args): r'''From Giac's documentation: Help for cycleinv: cycleinv(Cycle(c)) @@ -3406,9 +3406,9 @@ cdef class GiacMethods_base: See also: 1/ perminv Ex1:cycleinv([1,3,5]) ''' - return GiacMethods['cycleinv'](self,*args) + return GiacMethods['cycleinv'](self, *args) - def cycles2permu(self,*args): + def cycles2permu(self, *args): r'''From Giac's documentation: Help for cycles2permu: cycles2permu(Lst(Cycle)) @@ -3416,9 +3416,9 @@ cdef class GiacMethods_base: See also: 1/ permu2cycles 2/ cycle2perm Ex1:cycles2permu([[1,3,5],[3,4]]) ''' - return GiacMethods['cycles2permu'](self,*args) + return GiacMethods['cycles2permu'](self, *args) - def cyclotomic(self,*args): + def cyclotomic(self, *args): r'''From Giac's documentation: Help for cyclotomic: cyclotomic(Expr) @@ -3426,9 +3426,9 @@ cdef class GiacMethods_base: See also: 1/ none Ex1:cyclotomic(20) ''' - return GiacMethods['cyclotomic'](self,*args) + return GiacMethods['cyclotomic'](self, *args) - def cylinder(self,*args): + def cylinder(self, *args): r'''From Giac's documentation: Help for cylinder: cylinder(Pnt(A),Vect(v),Real(r),[Real(h)]) @@ -3437,9 +3437,9 @@ cdef class GiacMethods_base: Ex1:cylinder([0,0,0],[0,1,0],2) Ex2:cylinder([0,0,0],[0,1,0],2,-3) ''' - return GiacMethods['cylinder'](self,*args) + return GiacMethods['cylinder'](self, *args) - def dash_line(self,*args): + def dash_line(self, *args): r'''From Giac's documentation: Help for dash_line: dash_line(Opt) @@ -3448,9 +3448,9 @@ cdef class GiacMethods_base: Ex1: display(line(y=x),green+dash_line+line_width_2) Ex2: d:=display(line(2+i,1),cap_round_line) ''' - return GiacMethods['dash_line'](self,*args) + return GiacMethods['dash_line'](self, *args) - def dashdot_line(self,*args): + def dashdot_line(self, *args): r'''From Giac's documentation: Help for dashdot_line: dashdot_line(Opt) @@ -3459,9 +3459,9 @@ cdef class GiacMethods_base: Ex1: display(line(y=x),green+dash_line+line_width_2) Ex2: d:=display(line(2+i,1),cap_round_line) ''' - return GiacMethods['dashdot_line'](self,*args) + return GiacMethods['dashdot_line'](self, *args) - def dashdotdot_line(self,*args): + def dashdotdot_line(self, *args): r'''From Giac's documentation: Help for dashdotdot_line: dashdotdot_line(Opt) @@ -3470,9 +3470,9 @@ cdef class GiacMethods_base: Ex1: display(line(y=x),green+dash_line+line_width_2) Ex2: d:=display(line(2+i,1),cap_round_line) ''' - return GiacMethods['dashdotdot_line'](self,*args) + return GiacMethods['dashdotdot_line'](self, *args) - def dayofweek(self,*args): + def dayofweek(self, *args): r'''From Giac's documentation: Help for dayofweek: dayofweek(Int,Int,Int) @@ -3480,9 +3480,9 @@ cdef class GiacMethods_base: Ex1:dayofweek(21,4,2014) Ex2:dayofweek(15,10,1582) ''' - return GiacMethods['dayofweek'](self,*args) + return GiacMethods['dayofweek'](self, *args) - def deSolve(self,*args): + def deSolve(self, *args): r'''From Giac's documentation: Help for deSolve: deSolve(Eq,[TimeVar],FncVar) @@ -3505,9 +3505,9 @@ cdef class GiacMethods_base: Ex15:deSolve([z'=[[1,2],[2,1]]*z+[t,t+1],z(0)=[1,2]],t,z) Ex16:deSolve([z'=[[1,2],[2,1]]*z+[t,t+1],z(0)=[1,2]],z(t)) ''' - return GiacMethods['deSolve'](self,*args) + return GiacMethods['deSolve'](self, *args) - def debut_enregistrement(self,*args): + def debut_enregistrement(self, *args): r'''From Giac's documentation: Help for debut_enregistrement: debut_enregistrement(Var(nom_du_dessin)) @@ -3516,9 +3516,9 @@ cdef class GiacMethods_base: Ex1:debut_enregistrement(maison) Ex2:debut_enregistrement(arbre) ''' - return GiacMethods['debut_enregistrement'](self,*args) + return GiacMethods['debut_enregistrement'](self, *args) - def degree(self,*args): + def degree(self, *args): r'''From Giac's documentation: Help for degree: degree(Poly(P),Var(Var)) @@ -3528,9 +3528,9 @@ cdef class GiacMethods_base: Ex2:degree([1,0,1,0]) Ex3:degree(x^3+x*y,y) ''' - return GiacMethods['degree'](self,*args) + return GiacMethods['degree'](self, *args) - def degree_sequence(self,*args): + def degree_sequence(self, *args): r'''From Giac's documentation: Help for degree_sequence: degree_sequence(Graph(G)) @@ -3538,9 +3538,9 @@ cdef class GiacMethods_base: See also: 1/ is_graphic_sequence 2/ is_regular 2/ sequence_graph 3/ vertex_degree Ex1:degree_sequence(graph(trail(1,2,3,4,2))) ''' - return GiacMethods['degree_sequence'](self,*args) + return GiacMethods['degree_sequence'](self, *args) - def delcols(self,*args): + def delcols(self, *args): r'''From Giac's documentation: Help for delcols: delcols(Mtrx(A),Interval(n1..n2)||n1) @@ -3550,9 +3550,9 @@ cdef class GiacMethods_base: Ex2:delcols([[1,2,3],[4,5,6],[7,8,9]],0..1) Ex3:delcols([[1,2,3],[4,5,6],[7,8,9]],1) ''' - return GiacMethods['delcols'](self,*args) + return GiacMethods['delcols'](self, *args) - def delete_arc(self,*args): + def delete_arc(self, *args): r'''From Giac's documentation: Help for delete_arc: delete_arc(Graph(G),Edge(e)||Trail(T)||Lst(E)) @@ -3560,9 +3560,9 @@ cdef class GiacMethods_base: See also: 1/ add_arc 2/ delete_edge 3/ digraph 4/ edges 5/ has_arc 6/ trail Ex1:delete_arc(digraph(trail(1,2,3,4,5,1)),[5,1]) ''' - return GiacMethods['delete_arc'](self,*args) + return GiacMethods['delete_arc'](self, *args) - def delete_edge(self,*args): + def delete_edge(self, *args): r'''From Giac's documentation: Help for delete_edge: delete_edge(Graph(G),Edge(e)||Trail(T)||Lst(E)) @@ -3570,9 +3570,9 @@ cdef class GiacMethods_base: See also: 1/ add_edge 2/ delete_arc 3/ edges 4/ graph 5/ has_edge 6/ trail Ex1:delete_edge(cycle_graph(4),[1,2]) ''' - return GiacMethods['delete_edge'](self,*args) + return GiacMethods['delete_edge'](self, *args) - def delete_vertex(self,*args): + def delete_vertex(self, *args): r'''From Giac's documentation: Help for delete_vertex: delete_vertex(Graph(G),Vrtx(v)||Lst(V)) @@ -3580,9 +3580,9 @@ cdef class GiacMethods_base: See also: 1/ add_vertex 2/ induced_subgraph Ex1:delete_vertex(cycle_graph(5),[1,4]) ''' - return GiacMethods['delete_vertex'](self,*args) + return GiacMethods['delete_vertex'](self, *args) - def delrows(self,*args): + def delrows(self, *args): r'''From Giac's documentation: Help for delrows: delrows(Mtrx(A),Interval(n1..n2)||n1) @@ -3592,9 +3592,9 @@ cdef class GiacMethods_base: Ex2:delrows([[1,2,3],[4,5,6],[7,8,9]],0..1) Ex3:delrows([[1,2,3],[4,5,6],[7,8,9]],1) ''' - return GiacMethods['delrows'](self,*args) + return GiacMethods['delrows'](self, *args) - def deltalist(self,*args): + def deltalist(self, *args): r'''From Giac's documentation: Help for deltalist: deltalist(Lst) @@ -3603,9 +3603,9 @@ cdef class GiacMethods_base: Ex1:deltalist([1,4,8,9]) Ex2:deltalist([1,8,4,9]) ''' - return GiacMethods['deltalist'](self,*args) + return GiacMethods['deltalist'](self, *args) - def denom(self,*args): + def denom(self, *args): r'''From Giac's documentation: Help for denom: denom(Frac(a/b) or RatFrac) @@ -3615,9 +3615,9 @@ cdef class GiacMethods_base: Ex2:denom((x^3-1)/(x^2-1)) Ex3:denom(1+(x^3-1)/x^2) ''' - return GiacMethods['denom'](self,*args) + return GiacMethods['denom'](self, *args) - def densityplot(self,*args): + def densityplot(self, *args): r'''From Giac's documentation: Help for densityplot: densityplot(Expr,[x=xrange,y=yrange],[z],[xstep],[ystep]) @@ -3626,9 +3626,9 @@ cdef class GiacMethods_base: Ex1:densityplot(x^2-y^2,[x=-2..2,y=-2..2],xstep=0.1,ystep=0.1) Ex2:densityplot(x^2-y^2,[x=-2..2,y=-2..2],z=-2..2,xstep=0.1,ystep=0.1) ''' - return GiacMethods['densityplot'](self,*args) + return GiacMethods['densityplot'](self, *args) - def departures(self,*args): + def departures(self, *args): r'''From Giac's documentation: Help for departures: departures(Graph(G),[Vrtx(v)]) @@ -3636,9 +3636,9 @@ cdef class GiacMethods_base: See also: 1/ out_degree Ex1:departures(digraph(%{[1,2],[1,3],[2,3]%}),1) ''' - return GiacMethods['departures'](self,*args) + return GiacMethods['departures'](self, *args) - def derive(self,*args): + def derive(self, *args): r'''From Giac's documentation: Help for derive: derive(Expr or Fnc,[SeqVar or LstVar],[n]) @@ -3653,9 +3653,9 @@ cdef class GiacMethods_base: Ex7:derive(x*y+z*y,[y,z]) Ex8: f(x):=sin(2x);g:=diff(f);h:=diff(diff(f)) ''' - return GiacMethods['derive'](self,*args) + return GiacMethods['derive'](self, *args) - def deriver(self,*args): + def deriver(self, *args): r'''From Giac's documentation: Help for deriver: deriver(Expr or Fnc,[SeqVar or LstVar],[n]) @@ -3670,9 +3670,9 @@ cdef class GiacMethods_base: Ex7:deriver(x*y+z*y,[y,z]) Ex8: f(x):=sin(2x);g:=diff(f);h:=diff(diff(f)) ''' - return GiacMethods['deriver'](self,*args) + return GiacMethods['deriver'](self, *args) - def desolve(self,*args): + def desolve(self, *args): r'''From Giac's documentation: Help for desolve: desolve(Eq,[TimeVar],FncVar) @@ -3695,9 +3695,9 @@ cdef class GiacMethods_base: Ex15:desolve([z'=[[1,2],[2,1]]*z+[t,t+1],z(0)=[1,2]],t,z) Ex16:desolve([z'=[[1,2],[2,1]]*z+[t,t+1],z(0)=[1,2]],z(t)) ''' - return GiacMethods['desolve'](self,*args) + return GiacMethods['desolve'](self, *args) - def dessine_tortue(self,*args): + def dessine_tortue(self, *args): r'''From Giac's documentation: Help for dessine_tortue: dessine_tortue([Intg(n)]) @@ -3707,9 +3707,9 @@ cdef class GiacMethods_base: Ex2:dessine_tortue(0) Ex3:dessine_tortue(1) ''' - return GiacMethods['dessine_tortue'](self,*args) + return GiacMethods['dessine_tortue'](self, *args) - def det(self,*args): + def det(self, *args): r'''From Giac's documentation: Help for det: det(Mtrx) @@ -3718,9 +3718,9 @@ cdef class GiacMethods_base: Ex1:det([[1,2],[3,4]]) Ex2:det([[1,2,3],[1,3,6],[2,5,7]]) ''' - return GiacMethods['det'](self,*args) + return GiacMethods['det'](self, *args) - def det_minor(self,*args): + def det_minor(self, *args): r'''From Giac's documentation: Help for det_minor: det_minor(Mtrx(A)) @@ -3728,9 +3728,9 @@ cdef class GiacMethods_base: See also: 1/ det Ex1:det_minor([[1,2],[3,4]]) ''' - return GiacMethods['det_minor'](self,*args) + return GiacMethods['det_minor'](self, *args) - def developper(self,*args): + def developper(self, *args): r'''From Giac's documentation: Help for developper: developper(Expr) @@ -3742,9 +3742,9 @@ cdef class GiacMethods_base: Ex4:developper((x+3)^4) Ex5:developper((2*x-2*1)*(x^2-3*x+2)+(x^2-2*x+3)*(2*x-3*1)) ''' - return GiacMethods['developper'](self,*args) + return GiacMethods['developper'](self, *args) - def developper_transcendant(self,*args): + def developper_transcendant(self, *args): r'''From Giac's documentation: Help for developper_transcendant: developper_transcendant(Expr) @@ -3754,9 +3754,9 @@ cdef class GiacMethods_base: Ex2:developper_transcendant(cos(x+y)) Ex3:developper_transcendant(cos(3*x)) ''' - return GiacMethods['developper_transcendant'](self,*args) + return GiacMethods['developper_transcendant'](self, *args) - def dfc(self,*args): + def dfc(self, *args): r'''From Giac's documentation: Help for dfc: dfc(Real(x0),Int(n)||Real(eps)) @@ -3768,9 +3768,9 @@ cdef class GiacMethods_base: Ex4: convert(sqrt(2),confrac,'dev');dev Ex5: convert(9976/6961,confrac,'l');l ''' - return GiacMethods['dfc'](self,*args) + return GiacMethods['dfc'](self, *args) - def dfc2f(self,*args): + def dfc2f(self, *args): r'''From Giac's documentation: Help for dfc2f: dfc2f(LstFrac_Cont)) @@ -3779,9 +3779,9 @@ cdef class GiacMethods_base: Ex1:dfc2f([1,1,1]) Ex2:dfc2f([1,2,[2]]) ''' - return GiacMethods['dfc2f'](self,*args) + return GiacMethods['dfc2f'](self, *args) - def diag(self,*args): + def diag(self, *args): r'''From Giac's documentation: Help for diag: diag(Lst(l)||(Mtrx(A),[left||right||lu])||Lst(l),Lst(d),Lst(u)) @@ -3794,9 +3794,9 @@ cdef class GiacMethods_base: Ex5:diag([[1,2],[3,4]],lu) Ex6:diag([1,2],[3,4,5],[6,7]) ''' - return GiacMethods['diag'](self,*args) + return GiacMethods['diag'](self, *args) - def diff(self,*args): + def diff(self, *args): r'''From Giac's documentation: Help for diff: diff(Expr or Fnc,[SeqVar or LstVar],[n]) @@ -3811,9 +3811,9 @@ cdef class GiacMethods_base: Ex7:diff(x*y+z*y,[y,z]) Ex8: f(x):=sin(2x);g:=diff(f);h:=diff(diff(f)) ''' - return GiacMethods['diff'](self,*args) + return GiacMethods['diff'](self, *args) - def digraph(self,*args): + def digraph(self, *args): r'''From Giac's documentation: Help for digraph: digraph([Lst(V)],[Set(E)],[Mtrx(A)],[options]) @@ -3822,9 +3822,9 @@ cdef class GiacMethods_base: Ex1:digraph(%{[1,2],[2,3],[3,4],[4,1]%}) Ex2:digraph([a,b,c,d],%{[[a,b],1.0],[[a,c],2.3],[[b,d],3.1],[[c,d],4]%}) ''' - return GiacMethods['digraph'](self,*args) + return GiacMethods['digraph'](self, *args) - def dijkstra(self,*args): + def dijkstra(self, *args): r'''From Giac's documentation: Help for dijkstra: dijkstra(Graph(G),Vrtx(v),[Vrtx(w)||Lst(W)]) @@ -3832,9 +3832,9 @@ cdef class GiacMethods_base: See also: 1/ allpairs_distance 2/ shortest_path Ex1:dijkstra(graph(%{[[1,2],1],[[2,3],3],[[3,4],7],[[4,5],3],[[5,6],3],[[1,6],3]%}),1,4) ''' - return GiacMethods['dijkstra'](self,*args) + return GiacMethods['dijkstra'](self, *args) - def dim(self,*args): + def dim(self, *args): r'''From Giac's documentation: Help for dim: dim(Mtrx) @@ -3842,18 +3842,18 @@ cdef class GiacMethods_base: See also: 1/ rowdim 2/ coldim 3/ sizes 4/ size Ex1:dim([[1,2,3],[4,5,6]]) ''' - return GiacMethods['dim'](self,*args) + return GiacMethods['dim'](self, *args) - def directed(self,*args): + def directed(self, *args): r'''From Giac's documentation: Help for directed: directed(Opt) Option for graph and digraph commands. See also: 1/ weighted 2/ graph 3/ digraph ''' - return GiacMethods['directed'](self,*args) + return GiacMethods['directed'](self, *args) - def discard_edge_attribute(self,*args): + def discard_edge_attribute(self, *args): r'''From Giac's documentation: Help for discard_edge_attribute: discard_edge_attribute(Graph(G),Edge(e),Seq(tag1=value1,tag2=value2,..)) @@ -3861,9 +3861,9 @@ cdef class GiacMethods_base: See also: 1/ get_edge_attribute 2/ set_edge_attribute 3/ list_edge_attributes Ex1:discard_edge_attribute(cycle_graph(3),[1,2],"cost") ''' - return GiacMethods['discard_edge_attribute'](self,*args) + return GiacMethods['discard_edge_attribute'](self, *args) - def discard_graph_attribute(self,*args): + def discard_graph_attribute(self, *args): r'''From Giac's documentation: Help for discard_graph_attribute: discard_graph_attribute(Graph(G),Seq(tag1=value1,tag2=value2,..)) @@ -3871,9 +3871,9 @@ cdef class GiacMethods_base: See also: 1/ get_graph_attribute 2/ set_graph_attribute 3/ list_graph_attributes Ex1:discard_graph_attribute(cycle_graph(3),"name") ''' - return GiacMethods['discard_graph_attribute'](self,*args) + return GiacMethods['discard_graph_attribute'](self, *args) - def discard_vertex_attribute(self,*args): + def discard_vertex_attribute(self, *args): r'''From Giac's documentation: Help for discard_vertex_attribute: discard_vertex_attribute(Graph(G),Vrtx(v),Seq(tag1=value1,tag2=value2,..)) @@ -3881,9 +3881,9 @@ cdef class GiacMethods_base: See also: 1/ get_vertex_attribute 2/ set_vertex_attribute 3/ list_vertex_attributes Ex1:discard_vertex_attribute(cycle_graph(3),1,"supply") ''' - return GiacMethods['discard_vertex_attribute'](self,*args) + return GiacMethods['discard_vertex_attribute'](self, *args) - def disjoint_union(self,*args): + def disjoint_union(self, *args): r'''From Giac's documentation: Help for disjoint_union: disjoint_union(Seq(G1,G2,...)) @@ -3891,9 +3891,9 @@ cdef class GiacMethods_base: See also: 1/ graph_join 2/ graph_union Ex1:disjoint_union(is_connected(disjoint_union(cycle_graph(5),path_graph(4)))) ''' - return GiacMethods['disjoint_union'](self,*args) + return GiacMethods['disjoint_union'](self, *args) - def display(self,*args): + def display(self, *args): r'''From Giac's documentation: Help for display: display([GeoObj or legende],Intg) @@ -3910,9 +3910,9 @@ cdef class GiacMethods_base: Ex9:display(red);square(0,1); Ex10:display(red+filled);square(0,1); ''' - return GiacMethods['display'](self,*args) + return GiacMethods['display'](self, *args) - def disque(self,*args): + def disque(self, *args): r'''From Giac's documentation: Help for disque: disque(Real(r),[Real(a)],[Real(b)]) @@ -3923,9 +3923,9 @@ cdef class GiacMethods_base: Ex3:disque(40,90) Ex4:disque(40,10,100) ''' - return GiacMethods['disque'](self,*args) + return GiacMethods['disque'](self, *args) - def disque_centre(self,*args): + def disque_centre(self, *args): r'''From Giac's documentation: Help for disque_centre: disque_centre(Real(r),[Real(a)],[Real(b)]) @@ -3936,9 +3936,9 @@ cdef class GiacMethods_base: Ex3:disque_centre(40,90) Ex4:disque_centre(40,10,100) ''' - return GiacMethods['disque_centre'](self,*args) + return GiacMethods['disque_centre'](self, *args) - def distance(self,*args): + def distance(self, *args): r'''From Giac's documentation: Help for distance: distance((Pnt or Cplx),(Pnt or Cplx or Curve)) @@ -3948,9 +3948,9 @@ cdef class GiacMethods_base: Ex2:distance(1+i,segment(1-i,i)) Ex3:distance(0,1+i) ''' - return GiacMethods['distance'](self,*args) + return GiacMethods['distance'](self, *args) - def distance2(self,*args): + def distance2(self, *args): r'''From Giac's documentation: Help for distance2: distance2((Pnt or Cplx),(Pnt or Cplx or Curve)) @@ -3960,9 +3960,9 @@ cdef class GiacMethods_base: Ex2:distance2(1+i,segment(1-i,i)) Ex3:distance2(0,1+i) ''' - return GiacMethods['distance2'](self,*args) + return GiacMethods['distance2'](self, *args) - def distanceat(self,*args): + def distanceat(self, *args): r'''From Giac's documentation: Help for distanceat: distanceat(GeoObj(A),GeoObj(B),(Pnt or Cplx)) @@ -3971,9 +3971,9 @@ cdef class GiacMethods_base: Ex1: A:=point(0);B:=point(1+i);distanceat(A,B,(1+i)/2) Ex2: A:=point(0);s:=segment(1-i,i);distanceat(A,s,1) ''' - return GiacMethods['distanceat'](self,*args) + return GiacMethods['distanceat'](self, *args) - def distanceatraw(self,*args): + def distanceatraw(self, *args): r'''From Giac's documentation: Help for distanceatraw: distanceatraw(GeoObj(A),GeoObj(B),(Pnt or Cplx(z0))) @@ -3982,9 +3982,9 @@ cdef class GiacMethods_base: Ex1: A:=point(0);B:=point(1+i);distanceatraw(A,B,(1+i)/2) Ex2: A:=point(0);s:=segment(1-i,i);distanceatraw(A,s,1) ''' - return GiacMethods['distanceatraw'](self,*args) + return GiacMethods['distanceatraw'](self, *args) - def divergence(self,*args): + def divergence(self, *args): r'''From Giac's documentation: Help for divergence: divergence(Lst(A,B,C),Lst(x,y,z)) @@ -3992,9 +3992,9 @@ cdef class GiacMethods_base: See also: 1/ derive 2/ curl Ex1:divergence([x^2+y,x+z+y,z^3+x^2],[x,y,z]) ''' - return GiacMethods['divergence'](self,*args) + return GiacMethods['divergence'](self, *args) - def divide(self,*args): + def divide(self, *args): r'''From Giac's documentation: Help for divide: divide((Vect or Poly),(Vect or Poly),[Var]) @@ -4005,9 +4005,9 @@ cdef class GiacMethods_base: Ex3:divide(t^3+2t^2+3t+4,-t+2,t) Ex4:divide(t^4-1,(t+1)^2,t) ''' - return GiacMethods['divide'](self,*args) + return GiacMethods['divide'](self, *args) - def divis(self,*args): + def divis(self, *args): r'''From Giac's documentation: Help for divis: divis(Poly(P) or LstPoly) @@ -4020,9 +4020,9 @@ cdef class GiacMethods_base: Ex5:divis([x^4-1,t^2-1]) Ex6:divis(poly2symb([1,0,0,0,-1],x)) ''' - return GiacMethods['divis'](self,*args) + return GiacMethods['divis'](self, *args) - def division_point(self,*args): + def division_point(self, *args): r'''From Giac's documentation: Help for division_point: division_point(Pnt or Cplx(a),Pnt or Cplx(b),Cplx(k)) @@ -4031,9 +4031,9 @@ cdef class GiacMethods_base: Ex1:division_point(i,2+i,3+i) Ex2:division_point(i,2+i,3) ''' - return GiacMethods['division_point'](self,*args) + return GiacMethods['division_point'](self, *args) - def divisors(self,*args): + def divisors(self, *args): r'''From Giac's documentation: Help for divisors: divisors(Intg(a) or LstIntg) @@ -4042,9 +4042,9 @@ cdef class GiacMethods_base: Ex1:divisors(36) Ex2:divisors([36,49]) ''' - return GiacMethods['divisors'](self,*args) + return GiacMethods['divisors'](self, *args) - def divmod(self,*args): + def divmod(self, *args): r'''From Giac's documentation: Help for divmod: divmod(Intg(a),Intg(b)) @@ -4054,9 +4054,9 @@ cdef class GiacMethods_base: Ex2:divmod(125,41) Ex3:divmod(25+12*i,5+7*i) ''' - return GiacMethods['divmod'](self,*args) + return GiacMethods['divmod'](self, *args) - def divpc(self,*args): + def divpc(self, *args): r'''From Giac's documentation: Help for divpc: divpc(Poly,Poly,Intg(n)) @@ -4064,9 +4064,9 @@ cdef class GiacMethods_base: See also: 1/ series 2/ quorem Ex1:divpc(x^4+x+2,x^2+1,5) ''' - return GiacMethods['divpc'](self,*args) + return GiacMethods['divpc'](self, *args) - def dnewton_solver(self,*args): + def dnewton_solver(self, *args): r'''From Giac's documentation: Help for dnewton_solver: dnewton_solver(Opt) @@ -4079,9 +4079,9 @@ cdef class GiacMethods_base: Ex5: fsolve([x^2+y-2,x+y^2-2],[x,y],[2,2],hybridsj_solver) Ex6: fsolve([x^2+y-2,x+y^2-2],[x,y],[2,2],newtonj_solver) ''' - return GiacMethods['dnewton_solver'](self,*args) + return GiacMethods['dnewton_solver'](self, *args) - def dodecahedron(self,*args): + def dodecahedron(self, *args): r'''From Giac's documentation: Help for dodecahedron: dodecahedron(Pnt(A),Pnt(B),Pnt(C)) @@ -4090,9 +4090,9 @@ cdef class GiacMethods_base: Ex1:dodecahedron([0,0,0],[0,2,sqrt(5)/2+3/2],[0,0,1]) Ex2:dodecahedron(evalf([0,0,0],[3,2,4],[1,1,0])) ''' - return GiacMethods['dodecahedron'](self,*args) + return GiacMethods['dodecahedron'](self, *args) - def domain(self,*args): + def domain(self, *args): r'''From Giac's documentation: Help for domain: domain(Expr) @@ -4100,9 +4100,9 @@ cdef class GiacMethods_base: Ex1:domain(log(x+1)) Ex2:domain(log(x)+asin(x)) ''' - return GiacMethods['domain'](self,*args) + return GiacMethods['domain'](self, *args) - def dot(self,*args): + def dot(self, *args): r'''From Giac's documentation: Help for dot: dot(Vect(v1),Vect(v2)) @@ -4112,9 +4112,9 @@ cdef class GiacMethods_base: Ex2:dot([3,2,4],[3,2,4]) Ex3:dot([[1,2],[3,4]],[[3,2],[4,5]]) ''' - return GiacMethods['dot'](self,*args) + return GiacMethods['dot'](self, *args) - def dotP(self,*args): + def dotP(self, *args): r'''From Giac's documentation: Help for dotP: dotP(Vect(v1),Vect(v2)) @@ -4124,9 +4124,9 @@ cdef class GiacMethods_base: Ex2:dotP([3,2,4],[3,2,4]) Ex3:dotP([[1,2],[3,4]],[[3,2],[4,5]]) ''' - return GiacMethods['dotP'](self,*args) + return GiacMethods['dotP'](self, *args) - def dot_paper(self,*args): + def dot_paper(self, *args): r'''From Giac's documentation: Help for dot_paper: dot_paper(Real(ux),Real(uy),Real(t)) @@ -4135,9 +4135,9 @@ cdef class GiacMethods_base: Ex2:dot_paper(1,pi/3,sqrt(3)/2,x=-1..4,y=-2..2) Ex3:dot_paper(0.5,3*pi/4,0.5) ''' - return GiacMethods['dot_paper'](self,*args) + return GiacMethods['dot_paper'](self, *args) - def dotprod(self,*args): + def dotprod(self, *args): r'''From Giac's documentation: Help for dotprod: dotprod(Vect(v1),Vect(v2)) @@ -4147,9 +4147,9 @@ cdef class GiacMethods_base: Ex2:dotprod([3,2,4],[3,2,4]) Ex3:dotprod([[1,2],[3,4]],[[3,2],[4,5]]) ''' - return GiacMethods['dotprod'](self,*args) + return GiacMethods['dotprod'](self, *args) - def draw_arc(self,*args): + def draw_arc(self, *args): r'''From Giac's documentation: Help for draw_arc: draw_arc(Intg(x),Intg(y),Intg(rx),Intg(ry),Real(theta1),Real(theta2),Intg(col)) @@ -4157,9 +4157,9 @@ cdef class GiacMethods_base: See also: 1/ draw_pixel 2/ draw_circle Ex1: clear(); draw_arc(100,80,40,20,0,pi,blue); show_pixels(); ''' - return GiacMethods['draw_arc'](self,*args) + return GiacMethods['draw_arc'](self, *args) - def draw_circle(self,*args): + def draw_circle(self, *args): r'''From Giac's documentation: Help for draw_circle: draw_circle(Intg(x),Intg(y),Intg(r),Intg(col)) @@ -4168,9 +4168,9 @@ cdef class GiacMethods_base: Ex1: clear(); draw_circle(100,60,20,blue); show_pixels(); Ex2: clear(); draw_circle(100,60,20,blue+filled); show_pixels(); ''' - return GiacMethods['draw_circle'](self,*args) + return GiacMethods['draw_circle'](self, *args) - def draw_graph(self,*args): + def draw_graph(self, *args): r'''From Giac's documentation: Help for draw_graph: draw_graph(Graph(G),[opts]) @@ -4182,9 +4182,9 @@ cdef class GiacMethods_base: Ex4:draw_graph(sierpinski_graph(5,3,at_triangle)) Ex5:draw_graph(graph("soccerball")) ''' - return GiacMethods['draw_graph'](self,*args) + return GiacMethods['draw_graph'](self, *args) - def draw_line(self,*args): + def draw_line(self, *args): r'''From Giac's documentation: Help for draw_line: draw_line(Intg(x1),Intg(y1),Intg(x2),Intg(y2),Intg(col)) @@ -4192,9 +4192,9 @@ cdef class GiacMethods_base: See also: 1/ draw_pixel 2/ draw_rectangle 3/ draw_polygon Ex1: clear(); draw_line(10,10,60,60,blue); show_pixels(); ''' - return GiacMethods['draw_line'](self,*args) + return GiacMethods['draw_line'](self, *args) - def draw_pixel(self,*args): + def draw_pixel(self, *args): r'''From Giac's documentation: Help for draw_pixel: draw_pixel(Intg(x),Intg(y),Intg(col)) @@ -4202,9 +4202,9 @@ cdef class GiacMethods_base: See also: 1/ clear 2/ show_pixels 3/ draw_line 4/ draw_rectangle 5/ draw_polygon Ex1: clear(); set_pixel(4); draw_pixel(1,2,red); show_pixels(); ''' - return GiacMethods['draw_pixel'](self,*args) + return GiacMethods['draw_pixel'](self, *args) - def draw_polygon(self,*args): + def draw_polygon(self, *args): r'''From Giac's documentation: Help for draw_polygon: draw_polygon(Lst(l),Intg(col)) @@ -4213,9 +4213,9 @@ cdef class GiacMethods_base: Ex1: clear(); draw_polygon([[50,30],[100,10],[20,70]],red); show_pixels(); Ex2: clear(); draw_polygon([[50,30],[100,10],[20,70]],red+filled); show_pixels(); ''' - return GiacMethods['draw_polygon'](self,*args) + return GiacMethods['draw_polygon'](self, *args) - def draw_rectangle(self,*args): + def draw_rectangle(self, *args): r'''From Giac's documentation: Help for draw_rectangle: draw_rectangle(Intg(x),Intg(y),Intg(w),Intg(h),Intg(col)) @@ -4224,9 +4224,9 @@ cdef class GiacMethods_base: Ex1: clear(); draw_rectangle(10,20,30,40,red); show_pixels(); Ex2: clear(); draw_rectangle(10,20,30,40,red+filled); show_pixels(); ''' - return GiacMethods['draw_rectangle'](self,*args) + return GiacMethods['draw_rectangle'](self, *args) - def droit(self,*args): + def droit(self, *args): r'''From Giac's documentation: Help for droit: droit(Equal(a=b) or Interval(a..b) or Str,Intg) @@ -4237,9 +4237,9 @@ cdef class GiacMethods_base: Ex3:droit(1..5) Ex4:droit("abcdefg",3) ''' - return GiacMethods['droit'](self,*args) + return GiacMethods['droit'](self, *args) - def droite_tangente(self,*args): + def droite_tangente(self, *args): r'''From Giac's documentation: Help for droite_tangente: droite_tangente(Expr(f(x)),[Var],Expr(a)) @@ -4250,9 +4250,9 @@ cdef class GiacMethods_base: Ex3:droite_tangente(sin(t),t,pi/4) Ex4:droite_tangente(x^2-x,1) ''' - return GiacMethods['droite_tangente'](self,*args) + return GiacMethods['droite_tangente'](self, *args) - def dsolve(self,*args): + def dsolve(self, *args): r'''From Giac's documentation: Help for dsolve: dsolve(Eq,[TimeVar],FncVar) @@ -4275,9 +4275,9 @@ cdef class GiacMethods_base: Ex15:dsolve([z'=[[1,2],[2,1]]*z+[t,t+1],z(0)=[1,2]],t,z) Ex16:dsolve([z'=[[1,2],[2,1]]*z+[t,t+1],z(0)=[1,2]],z(t)) ''' - return GiacMethods['dsolve'](self,*args) + return GiacMethods['dsolve'](self, *args) - def duration(self,*args): + def duration(self, *args): r'''From Giac's documentation: Help for duration: duration(Lst(clip)) @@ -4285,9 +4285,9 @@ cdef class GiacMethods_base: See also: 1/ bit_depth 2/ channels 3/ channel_data 4/ samplerate Ex1:duration(readwav("/some/file")) ''' - return GiacMethods['duration'](self,*args) + return GiacMethods['duration'](self, *args) - def e(self,*args): + def e(self, *args): r'''From Giac's documentation: Help for e: e() @@ -4295,9 +4295,9 @@ cdef class GiacMethods_base: See also: 1/ i 2/ pi Ex1: evalf(e) ''' - return GiacMethods['e'](self,*args) + return GiacMethods['e'](self, *args) - def e2r(self,*args): + def e2r(self, *args): r'''From Giac's documentation: Help for e2r: e2r(Expr, LstVar or [Var]) @@ -4310,9 +4310,9 @@ cdef class GiacMethods_base: Ex5:e2r(-x^4+x*3*y+2+y^2*z,[x,y,z]) Ex6:e2r(-x^4+x*3*y+2+y^2*z,[x,y,z]) ''' - return GiacMethods['e2r'](self,*args) + return GiacMethods['e2r'](self, *args) - def ecart_type(self,*args): + def ecart_type(self, *args): r'''From Giac's documentation: Help for ecart_type: ecart_type(Lst||Mtrx,[Lst]) @@ -4322,9 +4322,9 @@ cdef class GiacMethods_base: Ex2:ecart_type([1,2,3],[1,2,1]) Ex3:ecart_type([[1,2,3],[5,6,7]]) ''' - return GiacMethods['ecart_type'](self,*args) + return GiacMethods['ecart_type'](self, *args) - def ecart_type_population(self,*args): + def ecart_type_population(self, *args): r'''From Giac's documentation: Help for ecart_type_population: ecart_type_population(Lst||Mtrx,[Lst]) @@ -4334,18 +4334,18 @@ cdef class GiacMethods_base: Ex2:ecart_type_population([1,2,3],[1,2,1]) Ex3:ecart_type_population([[1,2,3],[5,6,7]]) ''' - return GiacMethods['ecart_type_population'](self,*args) + return GiacMethods['ecart_type_population'](self, *args) - def ecm_factor(self,*args): + def ecm_factor(self, *args): r'''From Giac's documentation: Help for ecm_factor: ecm_factor(Intg(a),[Intg(B1)]) Factorization of integer n by the Elliptic Curve Method algorithm, B1 smoothness optional parameter. Ex1:ecm_factor(1000000000000000003000000000000000000000000000000000031000000000000000093) ''' - return GiacMethods['ecm_factor'](self,*args) + return GiacMethods['ecm_factor'](self, *args) - def edge_connectivity(self,*args): + def edge_connectivity(self, *args): r'''From Giac's documentation: Help for edge_connectivity: edge_connectivity(graph(G)) @@ -4355,9 +4355,9 @@ cdef class GiacMethods_base: Ex2:edge_connectivity(graph("clebsch")) Ex3:edge_connectivity(complete_graph(5)) ''' - return GiacMethods['edge_connectivity'](self,*args) + return GiacMethods['edge_connectivity'](self, *args) - def edges(self,*args): + def edges(self, *args): r'''From Giac's documentation: Help for edges: edges(Graph(G),[weights]) @@ -4365,9 +4365,9 @@ cdef class GiacMethods_base: See also: 1/ add_edge 2/ incident_edges 3/ set_edge_weight 4/ get_edge_weight Ex1:edges(complete_graph(4)) ''' - return GiacMethods['edges'](self,*args) + return GiacMethods['edges'](self, *args) - def egcd(self,*args): + def egcd(self, *args): r'''From Giac's documentation: Help for egcd: egcd((Poly or Lst),(Poly or Lst),[Var]) @@ -4378,9 +4378,9 @@ cdef class GiacMethods_base: Ex3:egcd([1,-2,1],[1,0,0,-1]) Ex4:egcd([1,-2,1],[1,-1,2]) ''' - return GiacMethods['egcd'](self,*args) + return GiacMethods['egcd'](self, *args) - def egv(self,*args): + def egv(self, *args): r'''From Giac's documentation: Help for egv: egv(Mtrx) @@ -4389,9 +4389,9 @@ cdef class GiacMethods_base: Ex1:egv([[-2,-2,1],[-2,1,-2],[1,-2,-2]]) Ex2:egv([[1,1,3],[1,3,1],[3,1,1]]) ''' - return GiacMethods['egv'](self,*args) + return GiacMethods['egv'](self, *args) - def egvl(self,*args): + def egvl(self, *args): r'''From Giac's documentation: Help for egvl: egvl(Mtrx(A)) @@ -4401,9 +4401,9 @@ cdef class GiacMethods_base: Ex2:egvl([[-2,-2,1],[-2,1,-2],[1,-2,-2]]) Ex3:egvl([[1,1,3],[1,3,1],[3,1,1]]) ''' - return GiacMethods['egvl'](self,*args) + return GiacMethods['egvl'](self, *args) - def eigVc(self,*args): + def eigVc(self, *args): r'''From Giac's documentation: Help for eigVc: eigVc(Mtrx) @@ -4412,9 +4412,9 @@ cdef class GiacMethods_base: Ex1:eigVc([[-2,-2,1],[-2,1,-2],[1,-2,-2]]) Ex2:eigVc([[1,1,3],[1,3,1],[3,1,1]]) ''' - return GiacMethods['eigVc'](self,*args) + return GiacMethods['eigVc'](self, *args) - def eigVl(self,*args): + def eigVl(self, *args): r'''From Giac's documentation: Help for eigVl: eigVl(Mtrx(A)) @@ -4424,9 +4424,9 @@ cdef class GiacMethods_base: Ex2:eigVl([[-2,-2,1],[-2,1,-2],[1,-2,-2]]) Ex3:eigVl([[1,1,3],[1,3,1],[3,1,1]]) ''' - return GiacMethods['eigVl'](self,*args) + return GiacMethods['eigVl'](self, *args) - def eigenvals(self,*args): + def eigenvals(self, *args): r'''From Giac's documentation: Help for eigenvals: eigenvals(Mtrx) @@ -4436,9 +4436,9 @@ cdef class GiacMethods_base: Ex2:eigenvals([[1,1,3],[1,3,1],[3,1,1]]) Ex3:eigenvals([[4,1],[-4,0]]) ''' - return GiacMethods['eigenvals'](self,*args) + return GiacMethods['eigenvals'](self, *args) - def eigenvalues(self,*args): + def eigenvalues(self, *args): r'''From Giac's documentation: Help for eigenvalues: eigenvalues(Mtrx) @@ -4448,9 +4448,9 @@ cdef class GiacMethods_base: Ex2:eigenvalues([[1,1,3],[1,3,1],[3,1,1]]) Ex3:eigenvalues([[4,1],[-4,0]]) ''' - return GiacMethods['eigenvalues'](self,*args) + return GiacMethods['eigenvalues'](self, *args) - def eigenvectors(self,*args): + def eigenvectors(self, *args): r'''From Giac's documentation: Help for eigenvectors: eigenvectors(Mtrx) @@ -4459,9 +4459,9 @@ cdef class GiacMethods_base: Ex1:eigenvectors([[-2,-2,1],[-2,1,-2],[1,-2,-2]]) Ex2:eigenvectors([[1,1,3],[1,3,1],[3,1,1]]) ''' - return GiacMethods['eigenvectors'](self,*args) + return GiacMethods['eigenvectors'](self, *args) - def eigenvects(self,*args): + def eigenvects(self, *args): r'''From Giac's documentation: Help for eigenvects: eigenvects(Mtrx) @@ -4470,9 +4470,9 @@ cdef class GiacMethods_base: Ex1:eigenvects([[-2,-2,1],[-2,1,-2],[1,-2,-2]]) Ex2:eigenvects([[1,1,3],[1,3,1],[3,1,1]]) ''' - return GiacMethods['eigenvects'](self,*args) + return GiacMethods['eigenvects'](self, *args) - def element(self,*args): + def element(self, *args): r'''From Giac's documentation: Help for element: element((Curve or Real_interval),[Val]) @@ -4485,9 +4485,9 @@ cdef class GiacMethods_base: Ex5: M:=element(circle(i,1)) Ex6: N:=element(circle(i,1),pi/2) ''' - return GiacMethods['element'](self,*args) + return GiacMethods['element'](self, *args) - def eliminate(self,*args): + def eliminate(self, *args): r'''From Giac's documentation: Help for eliminate: eliminate(LstEq(eqs),LstVar(vars)) @@ -4495,9 +4495,9 @@ cdef class GiacMethods_base: Ex1:eliminate([x=v0*t,y=y0-g*t^2],t) Ex2:eliminate([x+y+z+t-2,x*y*t=1,x^2+t^2=z^2],[x,z]) ''' - return GiacMethods['eliminate'](self,*args) + return GiacMethods['eliminate'](self, *args) - def ellipse(self,*args): + def ellipse(self, *args): r'''From Giac's documentation: Help for ellipse: ellipse(Pnt(F1),Pnt(F2),(Pnt(M) or Real(a))) @@ -4509,9 +4509,9 @@ cdef class GiacMethods_base: Ex4:ellipse(point(-1,0,0),point(1,0,0),point(1,1,1)) Ex5:ellipse(x^2+2y^2-y-2) ''' - return GiacMethods['ellipse'](self,*args) + return GiacMethods['ellipse'](self, *args) - def entry(self,*args): + def entry(self, *args): r'''From Giac's documentation: Help for entry: entry(Intg(n)) @@ -4521,9 +4521,9 @@ cdef class GiacMethods_base: Ex2:entry(2) Ex3:entry(-2) ''' - return GiacMethods['entry'](self,*args) + return GiacMethods['entry'](self, *args) - def envelope(self,*args): + def envelope(self, *args): r'''From Giac's documentation: Help for envelope: envelope(Expr(Xpr),Var(t)||[x,y,t]) @@ -4532,9 +4532,9 @@ cdef class GiacMethods_base: Ex1:envelope(y+x*tan(t)-2*sin(t),t) Ex2:envelope(v+u*tan(t)-3*sin(t),[u,v,t]) ''' - return GiacMethods['envelope'](self,*args) + return GiacMethods['envelope'](self, *args) - def epsilon(self,*args): + def epsilon(self, *args): r'''From Giac's documentation: Help for epsilon: epsilon(NULL) @@ -4542,9 +4542,9 @@ cdef class GiacMethods_base: See also: 1/ epsilon2zero Ex1:epsilon() ''' - return GiacMethods['epsilon'](self,*args) + return GiacMethods['epsilon'](self, *args) - def epsilon2zero(self,*args): + def epsilon2zero(self, *args): r'''From Giac's documentation: Help for epsilon2zero: epsilon2zero(Expr) @@ -4552,9 +4552,9 @@ cdef class GiacMethods_base: See also: 1/ evalf Ex1:epsilon2zero(1e-13+x+5) ''' - return GiacMethods['epsilon2zero'](self,*args) + return GiacMethods['epsilon2zero'](self, *args) - def equal(self,*args): + def equal(self, *args): r'''From Giac's documentation: Help for equal: equal(Expr,Expr) @@ -4564,9 +4564,9 @@ cdef class GiacMethods_base: Ex2:equal(2*x,4) Ex3:equal(x^2-3x+2,0) ''' - return GiacMethods['equal'](self,*args) + return GiacMethods['equal'](self, *args) - def equal2diff(self,*args): + def equal2diff(self, *args): r'''From Giac's documentation: Help for equal2diff: equal2diff(Equal) @@ -4575,9 +4575,9 @@ cdef class GiacMethods_base: Ex1:equal2diff(x=2) Ex2:equal2diff(equal(x,2)) ''' - return GiacMethods['equal2diff'](self,*args) + return GiacMethods['equal2diff'](self, *args) - def equal2list(self,*args): + def equal2list(self, *args): r'''From Giac's documentation: Help for equal2list: equal2list(Equal) @@ -4586,9 +4586,9 @@ cdef class GiacMethods_base: Ex1:equal2list(x=2) Ex2:equal2list(equal(x,2)) ''' - return GiacMethods['equal2list'](self,*args) + return GiacMethods['equal2list'](self, *args) - def equation(self,*args): + def equation(self, *args): r'''From Giac's documentation: Help for equation: equation(GeoObj, VectParam) @@ -4596,9 +4596,9 @@ cdef class GiacMethods_base: See also: 1/ parameq Ex1:equation(line(1-i,i),[x,y]) ''' - return GiacMethods['equation'](self,*args) + return GiacMethods['equation'](self, *args) - def equilateral_triangle(self,*args): + def equilateral_triangle(self, *args): r'''From Giac's documentation: Help for equilateral_triangle: equilateral_triangle((Pnt(A) or Cplx),(Pnt(B) or Cplx),[Pnt(P)],[Var(C)]) @@ -4609,9 +4609,9 @@ cdef class GiacMethods_base: Ex3:equilateral_triangle(point(0,0,0),point(3,3,3),point(0,0,3)) Ex4:equilateral_triangle(point(0,0,0),point(3,3,3),point(0,0,3),C) ''' - return GiacMethods['equilateral_triangle'](self,*args) + return GiacMethods['equilateral_triangle'](self, *args) - def erf(self,*args): + def erf(self, *args): r'''From Giac's documentation: Help for erf: erf(Real(x0)) @@ -4620,9 +4620,9 @@ cdef class GiacMethods_base: Ex1:erf(1) Ex2:erf(1/(sqrt(2)))*1/2 ''' - return GiacMethods['erf'](self,*args) + return GiacMethods['erf'](self, *args) - def erfc(self,*args): + def erfc(self, *args): r'''From Giac's documentation: Help for erfc: erfc(Real(x0)) @@ -4631,9 +4631,9 @@ cdef class GiacMethods_base: Ex1:erfc(1) Ex2:erfc(1/(sqrt(2)))*1/2 ''' - return GiacMethods['erfc'](self,*args) + return GiacMethods['erfc'](self, *args) - def error(self,*args): + def error(self, *args): r'''From Giac's documentation: Help for error: error(Str) @@ -4642,9 +4642,9 @@ cdef class GiacMethods_base: Ex1:error("Argument should be integer") Ex2:error("je provoque une erreur") ''' - return GiacMethods['error'](self,*args) + return GiacMethods['error'](self, *args) - def est_permu(self,*args): + def est_permu(self, *args): r'''From Giac's documentation: Help for est_permu: est_permu(Lst) @@ -4653,9 +4653,9 @@ cdef class GiacMethods_base: Ex1:est_permu([4,2,3,1]) Ex2:est_permu([4,2,3,1,0]) ''' - return GiacMethods['est_permu'](self,*args) + return GiacMethods['est_permu'](self, *args) - def euler(self,*args): + def euler(self, *args): r'''From Giac's documentation: Help for euler: euler(Intg(n)) @@ -4664,18 +4664,18 @@ cdef class GiacMethods_base: Ex1:euler(11) Ex2:euler(6) ''' - return GiacMethods['euler'](self,*args) + return GiacMethods['euler'](self, *args) - def euler_gamma(self,*args): + def euler_gamma(self, *args): r'''From Giac's documentation: Help for euler_gamma: euler_gamma() Euler's constant=euler_gamma=limit(sum(1/k,k,1,n)-ln(n),n,+infinity). Ex1: evalf(euler_gamma) ''' - return GiacMethods['euler_gamma'](self,*args) + return GiacMethods['euler_gamma'](self, *args) - def euler_lagrange(self,*args): + def euler_lagrange(self, *args): r'''From Giac's documentation: Help for euler_lagrange: euler_lagrange(Expr(f),[(Var(x),[Var||Lst(y)]) || y(x) || Lst(y(x))]) @@ -4685,9 +4685,9 @@ cdef class GiacMethods_base: Ex2:euler_lagrange(sqrt(x'^2+y'^2),[x(t),y(t)]) Ex3: assume(y>=0):; euler_lagrange(sqrt((1+y'^2)/y),t,y) ''' - return GiacMethods['euler_lagrange'](self,*args) + return GiacMethods['euler_lagrange'](self, *args) - def eval_level(self,*args): + def eval_level(self, *args): r'''From Giac's documentation: Help for eval_level: eval_level([Intg(n)]) @@ -4698,9 +4698,9 @@ cdef class GiacMethods_base: Ex4: purge(a,b,c);eval_level(2);a:=b+1; b:=c+1;c:=3; Ex5: purge(a,b,c);eval_level(3);a:=b+1; b:=c+1;c:=3; ''' - return GiacMethods['eval_level'](self,*args) + return GiacMethods['eval_level'](self, *args) - def evala(self,*args): + def evala(self, *args): r'''From Giac's documentation: Help for evala: evala(Expr) @@ -4710,9 +4710,9 @@ cdef class GiacMethods_base: Ex2:evala(2*x*2) Ex3:evala((2*x+1)^2) ''' - return GiacMethods['evala'](self,*args) + return GiacMethods['evala'](self, *args) - def evalb(self,*args): + def evalb(self, *args): r'''From Giac's documentation: Help for evalb: evalb(Expr) @@ -4721,9 +4721,9 @@ cdef class GiacMethods_base: Ex1:evalb(a==2) Ex2:evalb(sqrt(2)+pi>a) ''' - return GiacMethods['evalb'](self,*args) + return GiacMethods['evalb'](self, *args) - def evalc(self,*args): + def evalc(self, *args): r'''From Giac's documentation: Help for evalc: evalc(Expr) @@ -4732,9 +4732,9 @@ cdef class GiacMethods_base: Ex1:evalc(-3+4*i+exp(i)) Ex2:evalc(1/(x+y*i)) ''' - return GiacMethods['evalc'](self,*args) + return GiacMethods['evalc'](self, *args) - def evalf(self,*args): + def evalf(self, *args): r'''From Giac's documentation: Help for evalf: evalf(Expr,[Int]) @@ -4747,9 +4747,9 @@ cdef class GiacMethods_base: Ex5:evalf(sqrt(2)+pi) Ex6:evalf(sqrt(2)+pi,30) ''' - return GiacMethods['evalf'](self,*args) + return GiacMethods['evalf'](self, *args) - def evalm(self,*args): + def evalm(self, *args): r'''From Giac's documentation: Help for evalm: evalm(Expr) @@ -4757,9 +4757,9 @@ cdef class GiacMethods_base: See also: 1/ evalf Ex1:evalm(2*sin(pi)) ''' - return GiacMethods['evalm'](self,*args) + return GiacMethods['evalm'](self, *args) - def even(self,*args): + def even(self, *args): r'''From Giac's documentation: Help for even: even(Intg(n)) @@ -4768,9 +4768,9 @@ cdef class GiacMethods_base: Ex1:even(6) Ex2:even(1251) ''' - return GiacMethods['even'](self,*args) + return GiacMethods['even'](self, *args) - def evolute(self,*args): + def evolute(self, *args): r'''From Giac's documentation: Help for evolute: evolute(Curve) @@ -4780,9 +4780,9 @@ cdef class GiacMethods_base: Ex2:evolute([t,t^2],t) Ex3:evolute([3*exp(t/2)*cos(t),3*exp(t/2)*sin(t)],t) ''' - return GiacMethods['evolute'](self,*args) + return GiacMethods['evolute'](self, *args) - def exact(self,*args): + def exact(self, *args): r'''From Giac's documentation: Help for exact: exact(Expr) @@ -4793,9 +4793,9 @@ cdef class GiacMethods_base: Ex3:exact(1.4141) Ex4:exact(0.156381102937) ''' - return GiacMethods['exact'](self,*args) + return GiacMethods['exact'](self, *args) - def exbisector(self,*args): + def exbisector(self, *args): r'''From Giac's documentation: Help for exbisector: exbisector((Pnt(A) or Cplx),(Pnt(B) or Cplx),(Pnt(C) or Cplx)) @@ -4803,9 +4803,9 @@ cdef class GiacMethods_base: See also: 1/ angle 2/ bisector Ex1:exbisector(0,1,i) ''' - return GiacMethods['exbisector'](self,*args) + return GiacMethods['exbisector'](self, *args) - def excircle(self,*args): + def excircle(self, *args): r'''From Giac's documentation: Help for excircle: excircle((Pnt or Cplx),(Pnt or Cplx),(Pnt or Cplx)) @@ -4813,9 +4813,9 @@ cdef class GiacMethods_base: See also: 1/ incircle 2/ circumcircle Ex1:excircle(0,1,1+i) ''' - return GiacMethods['excircle'](self,*args) + return GiacMethods['excircle'](self, *args) - def execute(self,*args): + def execute(self, *args): r'''From Giac's documentation: Help for execute: execute(Str) @@ -4826,9 +4826,9 @@ cdef class GiacMethods_base: Ex3:execute("0123") Ex4:execute(sin,x) ''' - return GiacMethods['execute'](self,*args) + return GiacMethods['execute'](self, *args) - def exp(self,*args): + def exp(self, *args): r'''From Giac's documentation: Help for exp: exp(Expr or Opt) @@ -4837,9 +4837,9 @@ cdef class GiacMethods_base: Ex1:exp(0) Ex2: convert(cos(x),exp) ''' - return GiacMethods['exp'](self,*args) + return GiacMethods['exp'](self, *args) - def exp2list(self,*args): + def exp2list(self, *args): r'''From Giac's documentation: Help for exp2list: exp2list(Expr) @@ -4848,9 +4848,9 @@ cdef class GiacMethods_base: Ex1:exp2list((x=2) or (x=0)) Ex2:exp2list((x=3 and y=9) or (x=-1 and y=1) ) ''' - return GiacMethods['exp2list'](self,*args) + return GiacMethods['exp2list'](self, *args) - def exp2pow(self,*args): + def exp2pow(self, *args): r'''From Giac's documentation: Help for exp2pow: exp2pow(Expr) @@ -4859,9 +4859,9 @@ cdef class GiacMethods_base: Ex1:exp2pow(exp(3*ln(x))) Ex2:exp2pow(exp(x*ln(x))) ''' - return GiacMethods['exp2pow'](self,*args) + return GiacMethods['exp2pow'](self, *args) - def exp2trig(self,*args): + def exp2trig(self, *args): r'''From Giac's documentation: Help for exp2trig: exp2trig(Expr) @@ -4870,9 +4870,9 @@ cdef class GiacMethods_base: Ex1:exp2trig(exp(i*x)) Ex2:exp2trig(exp(-i*x)) ''' - return GiacMethods['exp2trig'](self,*args) + return GiacMethods['exp2trig'](self, *args) - def expand(self,*args): + def expand(self, *args): r'''From Giac's documentation: Help for expand: expand(Expr) @@ -4884,9 +4884,9 @@ cdef class GiacMethods_base: Ex4:expand((x+3)^4) Ex5:expand((2*x-2*1)*(x^2-3*x+2)+(x^2-2*x+3)*(2*x-3*1)) ''' - return GiacMethods['expand'](self,*args) + return GiacMethods['expand'](self, *args) - def expexpand(self,*args): + def expexpand(self, *args): r'''From Giac's documentation: Help for expexpand: expexpand(Expr) @@ -4894,9 +4894,9 @@ cdef class GiacMethods_base: See also: 1/ texpand 2/ lnexpand 3/ trigexpand Ex1:expexpand(exp(3*x)) ''' - return GiacMethods['expexpand'](self,*args) + return GiacMethods['expexpand'](self, *args) - def expln(self,*args): + def expln(self, *args): r'''From Giac's documentation: Help for expln: expln(Opt) @@ -4904,9 +4904,9 @@ cdef class GiacMethods_base: See also: 1/ exp 2/ ln 3/ convert 4/ trig2exp Ex1: convert(cos(x),expln) ''' - return GiacMethods['expln'](self,*args) + return GiacMethods['expln'](self, *args) - def exponential(self,*args): + def exponential(self, *args): r'''From Giac's documentation: Help for exponential: exponential(Real(lambda),Real(x)) @@ -4917,9 +4917,9 @@ cdef class GiacMethods_base: Ex3: randvector(3,exponential,1.2) Ex4: ranm(4,3,exponential,1.2) ''' - return GiacMethods['exponential'](self,*args) + return GiacMethods['exponential'](self, *args) - def exponential_cdf(self,*args): + def exponential_cdf(self, *args): r'''From Giac's documentation: Help for exponential_cdf: exponential_cdf(Real(lambda),Real(x0),[Real(y0)]) @@ -4928,9 +4928,9 @@ cdef class GiacMethods_base: Ex1:exponential_cdf(4.2,2.1) Ex2:exponential_cdf(4.2,2.1,3.2) ''' - return GiacMethods['exponential_cdf'](self,*args) + return GiacMethods['exponential_cdf'](self, *args) - def exponential_icdf(self,*args): + def exponential_icdf(self, *args): r'''From Giac's documentation: Help for exponential_icdf: exponential_icdf(Real(lambda),Real(x0),Real(p)) @@ -4939,9 +4939,9 @@ cdef class GiacMethods_base: Ex1:exponential_icdf(4.2,0.95) Ex2:exponential_icdf(4.2,0.6) ''' - return GiacMethods['exponential_icdf'](self,*args) + return GiacMethods['exponential_icdf'](self, *args) - def exponential_regression(self,*args): + def exponential_regression(self, *args): r'''From Giac's documentation: Help for exponential_regression: exponential_regression(Lst||Mtrx(A),[Lst]) @@ -4950,9 +4950,9 @@ cdef class GiacMethods_base: Ex1:exponential_regression([[1.0,2.0],[0.0,1.0],[4.0,7.0]]) Ex2:exponential_regression([1.0,0.0,4.0],[2.0,1.0,7.0]) ''' - return GiacMethods['exponential_regression'](self,*args) + return GiacMethods['exponential_regression'](self, *args) - def exponential_regression_plot(self,*args): + def exponential_regression_plot(self, *args): r'''From Giac's documentation: Help for exponential_regression_plot: exponential_regression_plot(Lst||Mtrx(A),[Lst]) @@ -4961,9 +4961,9 @@ cdef class GiacMethods_base: Ex1:exponential_regression_plot([[1.0,2.0],[0.0,1.0],[4.0,7.0]]) Ex2:exponential_regression_plot([1.0,0.0,4.0],[2.0,1.0,7.0]) ''' - return GiacMethods['exponential_regression_plot'](self,*args) + return GiacMethods['exponential_regression_plot'](self, *args) - def exponentiald(self,*args): + def exponentiald(self, *args): r'''From Giac's documentation: Help for exponentiald: exponentiald(Real(lambda),Real(x)) @@ -4974,9 +4974,9 @@ cdef class GiacMethods_base: Ex3: randvector(3,exponential,1.2) Ex4: ranm(4,3,exponential,1.2) ''' - return GiacMethods['exponentiald'](self,*args) + return GiacMethods['exponentiald'](self, *args) - def exponentiald_cdf(self,*args): + def exponentiald_cdf(self, *args): r'''From Giac's documentation: Help for exponentiald_cdf: exponentiald_cdf(Real(lambda),Real(x0),[Real(y0)]) @@ -4985,9 +4985,9 @@ cdef class GiacMethods_base: Ex1:exponentiald_cdf(4.2,2.1) Ex2:exponentiald_cdf(4.2,2.1,3.2) ''' - return GiacMethods['exponentiald_cdf'](self,*args) + return GiacMethods['exponentiald_cdf'](self, *args) - def exponentiald_icdf(self,*args): + def exponentiald_icdf(self, *args): r'''From Giac's documentation: Help for exponentiald_icdf: exponentiald_icdf(Real(lambda),Real(x0),Real(p)) @@ -4996,9 +4996,9 @@ cdef class GiacMethods_base: Ex1:exponentiald_icdf(4.2,0.95) Ex2:exponentiald_icdf(4.2,0.6) ''' - return GiacMethods['exponentiald_icdf'](self,*args) + return GiacMethods['exponentiald_icdf'](self, *args) - def export_graph(self,*args): + def export_graph(self, *args): r'''From Giac's documentation: Help for export_graph: export_graph(Graph(G),Str("path/to/graphname")) @@ -5006,9 +5006,9 @@ cdef class GiacMethods_base: See also: 1/ import_graph Ex1:export_graph(complete_graph(5),"K5") ''' - return GiacMethods['export_graph'](self,*args) + return GiacMethods['export_graph'](self, *args) - def export_mathml(self,*args): + def export_mathml(self, *args): r'''From Giac's documentation: Help for export_mathml: export_mathml(Expr,[display||content]) @@ -5018,9 +5018,9 @@ cdef class GiacMethods_base: Ex2:export_mathml(a+2*b,display) Ex3:export_mathml(a+2*b,content) ''' - return GiacMethods['export_mathml'](self,*args) + return GiacMethods['export_mathml'](self, *args) - def expovariate(self,*args): + def expovariate(self, *args): r'''From Giac's documentation: Help for expovariate: expovariate(Real(a)) @@ -5029,9 +5029,9 @@ cdef class GiacMethods_base: Ex1:expovariate(1) Ex2:expovariate(2) ''' - return GiacMethods['expovariate'](self,*args) + return GiacMethods['expovariate'](self, *args) - def expr(self,*args): + def expr(self, *args): r'''From Giac's documentation: Help for expr: expr(Str) @@ -5042,9 +5042,9 @@ cdef class GiacMethods_base: Ex3:expr("0123") Ex4:expr(sin,x) ''' - return GiacMethods['expr'](self,*args) + return GiacMethods['expr'](self, *args) - def extend(self,*args): + def extend(self, *args): r'''From Giac's documentation: Help for extend: extend(Lst,Lst||Seq,Seq||Str,Str||Mtrx,Mtrx) @@ -5056,9 +5056,9 @@ cdef class GiacMethods_base: Ex4: L:=[1,2];L.concat([3,4,5]) Ex5: S:="abcd";S.concat("efghi") ''' - return GiacMethods['extend'](self,*args) + return GiacMethods['extend'](self, *args) - def extract_measure(self,*args): + def extract_measure(self, *args): r'''From Giac's documentation: Help for extract_measure: extract_measure(Var) @@ -5068,9 +5068,9 @@ cdef class GiacMethods_base: Ex2:extract_measure(angleatraw(0,1,1+i,1)) Ex3: A:=point(0);B:=point(1+i);a:=distanceatraw(A,B,(1+i)/2);extract_measure(a) ''' - return GiacMethods['extract_measure'](self,*args) + return GiacMethods['extract_measure'](self, *args) - def extrema(self,*args): + def extrema(self, *args): r'''From Giac's documentation: Help for extrema: extrema(Expr,Var,a,b) @@ -5133,9 +5133,9 @@ cdef class GiacMethods_base: Ex56:extrema((1+y*sinh(x))/(1+y^2+tanh(x)^2),[x,y]) Ex57:extrema((1+y*sinh(x))/(1+y^2+tanh(x)^2),y=x^2,[x,y]) ''' - return GiacMethods['extrema'](self,*args) + return GiacMethods['extrema'](self, *args) - def ezgcd(self,*args): + def ezgcd(self, *args): r'''From Giac's documentation: Help for ezgcd: ezgcd(Poly,Poly) @@ -5145,9 +5145,9 @@ cdef class GiacMethods_base: Ex2:ezgcd((x+1)^4-y^4,(x+1-y)^2) Ex3:ezgcd((x+y-1)*(x+y+1),(x+y+1)^2) ''' - return GiacMethods['ezgcd'](self,*args) + return GiacMethods['ezgcd'](self, *args) - def f2nd(self,*args): + def f2nd(self, *args): r'''From Giac's documentation: Help for f2nd: f2nd(Frac or RatFrac) @@ -5156,9 +5156,9 @@ cdef class GiacMethods_base: Ex1:f2nd(42/12) Ex2:f2nd((x^2+2*x+1)/(x^2-1)) ''' - return GiacMethods['f2nd'](self,*args) + return GiacMethods['f2nd'](self, *args) - def fMax(self,*args): + def fMax(self, *args): r'''From Giac's documentation: Help for fMax: fMax(Expr,[Var]) @@ -5167,9 +5167,9 @@ cdef class GiacMethods_base: Ex1:fMax(-x^2+2*x+1,x) Ex2:fMax(-x^2+2*x+1,x=1..2) ''' - return GiacMethods['fMax'](self,*args) + return GiacMethods['fMax'](self, *args) - def fMin(self,*args): + def fMin(self, *args): r'''From Giac's documentation: Help for fMin: fMin(Expr,[Var]) @@ -5180,9 +5180,9 @@ cdef class GiacMethods_base: Ex3:fMin((x-3)^2+(y-5)^2+1,[],[x,y],[1,1]) Ex4:fMin((x-3)^2+(y-5)^2+1,[x+y^2=1],[x,y],[1,1]) ''' - return GiacMethods['fMin'](self,*args) + return GiacMethods['fMin'](self, *args) - def fPart(self,*args): + def fPart(self, *args): r'''From Giac's documentation: Help for fPart: fPart(Real||LstReal) @@ -5194,9 +5194,9 @@ cdef class GiacMethods_base: Ex4:fPart(-1.2) Ex5:fPart([3.4,sqrt(2)]) ''' - return GiacMethods['fPart'](self,*args) + return GiacMethods['fPart'](self, *args) - def faces(self,*args): + def faces(self, *args): r'''From Giac's documentation: Help for faces: faces(Polygon or Polyedr(P)) @@ -5205,9 +5205,9 @@ cdef class GiacMethods_base: Ex1:faces(polyhedron([0,0,0],[0,5,0],[0,0,5],[1,2,6])) Ex2:faces(polyhedron([0,0,0],[0,5,0],[0,0,5],[1,2,6]))[2] ''' - return GiacMethods['faces'](self,*args) + return GiacMethods['faces'](self, *args) - def facteurs_premiers(self,*args): + def facteurs_premiers(self, *args): r'''From Giac's documentation: Help for facteurs_premiers: facteurs_premiers(Intg(a) or LstIntg) @@ -5216,9 +5216,9 @@ cdef class GiacMethods_base: Ex1:facteurs_premiers(36) Ex2:facteurs_premiers([36,52]) ''' - return GiacMethods['facteurs_premiers'](self,*args) + return GiacMethods['facteurs_premiers'](self, *args) - def factor(self,*args): + def factor(self, *args): r'''From Giac's documentation: Help for factor: factor(Expr) @@ -5228,9 +5228,9 @@ cdef class GiacMethods_base: Ex2:factor(x^4-4,sqrt(2)) Ex3:factor(x^4+12*x^3+54*x^2+108*x+81) ''' - return GiacMethods['factor'](self,*args) + return GiacMethods['factor'](self, *args) - def factor_xn(self,*args): + def factor_xn(self, *args): r'''From Giac's documentation: Help for factor_xn: factor_xn(Poly(P)) @@ -5239,9 +5239,9 @@ cdef class GiacMethods_base: Ex1:factor_xn(x^4-1) Ex2:factor_xn(x^4+12*x^3+54*x^2+108*x+81) ''' - return GiacMethods['factor_xn'](self,*args) + return GiacMethods['factor_xn'](self, *args) - def factorial(self,*args): + def factorial(self, *args): r'''From Giac's documentation: Help for factorial: factorial(Intg(n)|| Real(a)) @@ -5250,9 +5250,9 @@ cdef class GiacMethods_base: Ex1:factorial(4) Ex2:factorial(1.2) ''' - return GiacMethods['factorial'](self,*args) + return GiacMethods['factorial'](self, *args) - def factoriser(self,*args): + def factoriser(self, *args): r'''From Giac's documentation: Help for factoriser: factoriser(Expr) @@ -5262,9 +5262,9 @@ cdef class GiacMethods_base: Ex2:factoriser(x^4-4,sqrt(2)) Ex3:factoriser(x^4+12*x^3+54*x^2+108*x+81) ''' - return GiacMethods['factoriser'](self,*args) + return GiacMethods['factoriser'](self, *args) - def factoriser_entier(self,*args): + def factoriser_entier(self, *args): r'''From Giac's documentation: Help for factoriser_entier: factoriser_entier(Intg(a)) @@ -5273,9 +5273,9 @@ cdef class GiacMethods_base: Ex1:factoriser_entier(50) Ex2:factoriser_entier(123456789) ''' - return GiacMethods['factoriser_entier'](self,*args) + return GiacMethods['factoriser_entier'](self, *args) - def factoriser_sur_C(self,*args): + def factoriser_sur_C(self, *args): r'''From Giac's documentation: Help for factoriser_sur_C: factoriser_sur_C(Expr) @@ -5285,9 +5285,9 @@ cdef class GiacMethods_base: Ex2:factoriser_sur_C(x^2*y^2+y^2+4*x^2+4) Ex3:factoriser_sur_C(x^2*y^2+y^2+2*x^2+2) ''' - return GiacMethods['factoriser_sur_C'](self,*args) + return GiacMethods['factoriser_sur_C'](self, *args) - def factors(self,*args): + def factors(self, *args): r'''From Giac's documentation: Help for factors: factors(Poly or LstPoly) @@ -5296,9 +5296,9 @@ cdef class GiacMethods_base: Ex1:factors(x^4-1) Ex2:factors([x^2,x^2-1]) ''' - return GiacMethods['factors'](self,*args) + return GiacMethods['factors'](self, *args) - def fadeev(self,*args): + def fadeev(self, *args): r'''From Giac's documentation: Help for fadeev: fadeev(Opt) @@ -5306,9 +5306,9 @@ cdef class GiacMethods_base: See also: 1/ pcar Ex1: pcar([[4,1,-2],[1,2,-1],[2,1,0]],fadeev) ''' - return GiacMethods['fadeev'](self,*args) + return GiacMethods['fadeev'](self, *args) - def false(self,*args): + def false(self, *args): r'''From Giac's documentation: Help for false: false() @@ -5316,9 +5316,9 @@ cdef class GiacMethods_base: See also: 1/ true Ex1: a:=false ''' - return GiacMethods['false'](self,*args) + return GiacMethods['false'](self, *args) - def falsepos_solver(self,*args): + def falsepos_solver(self, *args): r'''From Giac's documentation: Help for falsepos_solver: falsepos_solver(Opt) @@ -5331,9 +5331,9 @@ cdef class GiacMethods_base: Ex5: fsolve(cos(x)=x,x,0,secant_solver) Ex6: fsolve(cos(x)=x,x,0,steffenson_solver) ''' - return GiacMethods['falsepos_solver'](self,*args) + return GiacMethods['falsepos_solver'](self, *args) - def fclose(self,*args): + def fclose(self, *args): r'''From Giac's documentation: Help for fclose: fclose(File(f)) @@ -5341,9 +5341,9 @@ cdef class GiacMethods_base: See also: 1/ fprint 2/ fopen Ex1:fclose(f) ''' - return GiacMethods['fclose'](self,*args) + return GiacMethods['fclose'](self, *args) - def fcoeff(self,*args): + def fcoeff(self, *args): r'''From Giac's documentation: Help for fcoeff: fcoeff(Lst(root||pole,order)) @@ -5351,9 +5351,9 @@ cdef class GiacMethods_base: See also: 1/ pcoeff 2/ froot 3/ proot Ex1:fcoeff([1,2,0,1,3,-1]) ''' - return GiacMethods['fcoeff'](self,*args) + return GiacMethods['fcoeff'](self, *args) - def fdistrib(self,*args): + def fdistrib(self, *args): r'''From Giac's documentation: Help for fdistrib: fdistrib(Expr) @@ -5365,9 +5365,9 @@ cdef class GiacMethods_base: Ex4:fdistrib((x+3)^4) Ex5:fdistrib((2*x-2*1)*(x^2-3*x+2)+(x^2-2*x+3)*(2*x-3*1)) ''' - return GiacMethods['fdistrib'](self,*args) + return GiacMethods['fdistrib'](self, *args) - def fft(self,*args): + def fft(self, *args): r'''From Giac's documentation: Help for fft: fft(Vect or (Vect(L),Intg(a),Intg(p)) @@ -5376,9 +5376,9 @@ cdef class GiacMethods_base: Ex1:fft([1,2,3,4,0,0,0,0]) Ex2:fft(ranm(128),22798,35969) ''' - return GiacMethods['fft'](self,*args) + return GiacMethods['fft'](self, *args) - def fieldplot(self,*args): + def fieldplot(self, *args): r'''From Giac's documentation: Help for fieldplot: fieldplot(Expr,VectVar,[Opt]) @@ -5390,9 +5390,9 @@ cdef class GiacMethods_base: Ex4:fieldplot(-t*y,[t,y],normalize,xstep=0.5,ystep=0.5) Ex5:fieldplot(-t*y,[t=-6.868..6.868,y=-6.868..6.868],normalize) ''' - return GiacMethods['fieldplot'](self,*args) + return GiacMethods['fieldplot'](self, *args) - def find(self,*args): + def find(self, *args): r'''From Giac's documentation: Help for find: find(Expr,Vect) @@ -5404,9 +5404,9 @@ cdef class GiacMethods_base: Ex4:find("ab","abracadabrant") Ex5:find(1,%{4,3,1,2%}) ''' - return GiacMethods['find'](self,*args) + return GiacMethods['find'](self, *args) - def find_cycles(self,*args): + def find_cycles(self, *args): r'''From Giac's documentation: Help for find_cycles: find_cycles(Graph(G,[length=k||l..u])) @@ -5416,9 +5416,9 @@ cdef class GiacMethods_base: Ex2:find_cycles(digraph(%{[1,2],[1,3],[3,1],[1,4],[2,3],[4,3],[4,5],[5,3],[5,6],[7,6],[8,6],[8,7]%}),length=3) Ex3:find_cycles(digraph(%{[1,2],[1,3],[3,1],[1,4],[2,3],[4,3],[4,5],[5,3],[5,6],[7,6],[8,6],[8,7]%}),length=3..4) ''' - return GiacMethods['find_cycles'](self,*args) + return GiacMethods['find_cycles'](self, *args) - def findhelp(self,*args): + def findhelp(self, *args): r'''From Giac's documentation: Help for findhelp: findhelp(Cmd) @@ -5426,9 +5426,9 @@ cdef class GiacMethods_base: See also: 1/ ifte 2/ when Ex1:findhelp(ifactor) ''' - return GiacMethods['findhelp'](self,*args) + return GiacMethods['findhelp'](self, *args) - def fisher(self,*args): + def fisher(self, *args): r'''From Giac's documentation: Help for fisher: fisher(Intg(n),Intg(m),Real(x0)) @@ -5439,9 +5439,9 @@ cdef class GiacMethods_base: Ex3: randvector(5,fisher,4,6) Ex4: ranm(2,3,fisher,4,6) ''' - return GiacMethods['fisher'](self,*args) + return GiacMethods['fisher'](self, *args) - def fisher_cdf(self,*args): + def fisher_cdf(self, *args): r'''From Giac's documentation: Help for fisher_cdf: fisher_cdf(Intg(n),Intg(m),Real(x0)) @@ -5450,9 +5450,9 @@ cdef class GiacMethods_base: Ex1:fisher_cdf(4,4,2.1) Ex2:fisher_cdf(4,10,3.5) ''' - return GiacMethods['fisher_cdf'](self,*args) + return GiacMethods['fisher_cdf'](self, *args) - def fisher_icdf(self,*args): + def fisher_icdf(self, *args): r'''From Giac's documentation: Help for fisher_icdf: fisher_icdf(Intg(n),Intg(m),Real(p)) @@ -5461,9 +5461,9 @@ cdef class GiacMethods_base: Ex1:fisher_icdf(4,10,0.95) Ex2:fisher_icdf(4,10,0.05) ''' - return GiacMethods['fisher_icdf'](self,*args) + return GiacMethods['fisher_icdf'](self, *args) - def fisherd(self,*args): + def fisherd(self, *args): r'''From Giac's documentation: Help for fisherd: fisherd(Intg(n),Intg(m),Real(x0)) @@ -5474,9 +5474,9 @@ cdef class GiacMethods_base: Ex3: randvector(5,fisher,4,6) Ex4: ranm(2,3,fisher,4,6) ''' - return GiacMethods['fisherd'](self,*args) + return GiacMethods['fisherd'](self, *args) - def fisherd_cdf(self,*args): + def fisherd_cdf(self, *args): r'''From Giac's documentation: Help for fisherd_cdf: fisherd_cdf(Intg(n),Intg(m),Real(x0)) @@ -5485,9 +5485,9 @@ cdef class GiacMethods_base: Ex1:fisherd_cdf(4,4,2.1) Ex2:fisherd_cdf(4,10,3.5) ''' - return GiacMethods['fisherd_cdf'](self,*args) + return GiacMethods['fisherd_cdf'](self, *args) - def fisherd_icdf(self,*args): + def fisherd_icdf(self, *args): r'''From Giac's documentation: Help for fisherd_icdf: fisherd_icdf(Intg(n),Intg(m),Real(p)) @@ -5496,9 +5496,9 @@ cdef class GiacMethods_base: Ex1:fisherd_icdf(4,10,0.95) Ex2:fisherd_icdf(4,10,0.05) ''' - return GiacMethods['fisherd_icdf'](self,*args) + return GiacMethods['fisherd_icdf'](self, *args) - def fitdistr(self,*args): + def fitdistr(self, *args): r'''From Giac's documentation: Help for fitdistr: fitdistr(Lst(L),Fnc(D)) @@ -5508,9 +5508,9 @@ cdef class GiacMethods_base: Ex2: X:=randvar(normal,stddev=9.5):;Y:=randvar(normal,stddev=1.5):;S:=sample(eval(X/Y,0),1000):;Z:=fitdistr(S,cauchy) Ex3: X:=randvar(normal,mean=5,variance=2):;S:=sample(exp(X),1000):;fitdistr(log(S),normal) ''' - return GiacMethods['fitdistr'](self,*args) + return GiacMethods['fitdistr'](self, *args) - def flatten(self,*args): + def flatten(self, *args): r'''From Giac's documentation: Help for flatten: flatten(Lst) @@ -5518,9 +5518,9 @@ cdef class GiacMethods_base: See also: 1/ mat2list Ex1:flatten([[1,[2,3],4],[5,6]]) ''' - return GiacMethods['flatten'](self,*args) + return GiacMethods['flatten'](self, *args) - def float2rational(self,*args): + def float2rational(self, *args): r'''From Giac's documentation: Help for float2rational: float2rational(Expr) @@ -5531,9 +5531,9 @@ cdef class GiacMethods_base: Ex3:float2rational(1.4141) Ex4:float2rational(0.156381102937) ''' - return GiacMethods['float2rational'](self,*args) + return GiacMethods['float2rational'](self, *args) - def floor(self,*args): + def floor(self, *args): r'''From Giac's documentation: Help for floor: floor(Real or Cplx) @@ -5542,9 +5542,9 @@ cdef class GiacMethods_base: Ex1:floor(-2.5) Ex2:floor(2.5-4.2*i) ''' - return GiacMethods['floor'](self,*args) + return GiacMethods['floor'](self, *args) - def flow_polynomial(self,*args): + def flow_polynomial(self, *args): r'''From Giac's documentation: Help for flow_polynomial: flow_polynomial(Graph(G),[Var(x)]) @@ -5553,18 +5553,18 @@ cdef class GiacMethods_base: Ex1:flow_polynomial(graph("tetrahedron")) Ex2:flow_polynomial(graph("tetrahedron"),5) ''' - return GiacMethods['flow_polynomial'](self,*args) + return GiacMethods['flow_polynomial'](self, *args) - def fmod(self,*args): + def fmod(self, *args): r'''From Giac's documentation: Help for fmod: fmod(Real(a),Real(b)) Returns a mod b for a and b floats. Ex1:fmod(10.0,pi) ''' - return GiacMethods['fmod'](self,*args) + return GiacMethods['fmod'](self, *args) - def foldl(self,*args): + def foldl(self, *args): r'''From Giac's documentation: Help for foldl: foldl(op,id,Seq(r1,r2,...)) @@ -5572,9 +5572,9 @@ cdef class GiacMethods_base: See also: 1/ apply 2/ foldr 3/ map Ex1:foldl(F,init,a,b,c) ''' - return GiacMethods['foldl'](self,*args) + return GiacMethods['foldl'](self, *args) - def foldr(self,*args): + def foldr(self, *args): r'''From Giac's documentation: Help for foldr: foldr(op,id,Seq(r1,r2,...)) @@ -5582,9 +5582,9 @@ cdef class GiacMethods_base: See also: 1/ apply 2/ foldl 3/ map Ex1:foldr(F,init,a,b,c) ''' - return GiacMethods['foldr'](self,*args) + return GiacMethods['foldr'](self, *args) - def fonction_derivee(self,*args): + def fonction_derivee(self, *args): r'''From Giac's documentation: Help for fonction_derivee: fonction_derivee(Fnc(f)) @@ -5596,9 +5596,9 @@ cdef class GiacMethods_base: Ex4:fonction_derivee(ln)([x,y]) Ex5: (function_diff @@3)(ln)('x') ''' - return GiacMethods['fonction_derivee'](self,*args) + return GiacMethods['fonction_derivee'](self, *args) - def forward(self,*args): + def forward(self, *args): r'''From Giac's documentation: Help for forward: forward(NULL or Real(n)) @@ -5607,9 +5607,9 @@ cdef class GiacMethods_base: Ex1: avance 30 Ex2:forward(30) ''' - return GiacMethods['forward'](self,*args) + return GiacMethods['forward'](self, *args) - def fourier(self,*args): + def fourier(self, *args): r'''From Giac's documentation: Help for fourier: fourier(Expr(f(x)),[Var(x),[Var(s)]]) @@ -5632,9 +5632,9 @@ cdef class GiacMethods_base: Ex15:fourier(atan(x/4)/x,x,s) Ex16:fourier(piecewise(x<=-1,exp(x+1),x<=1,1,exp(2-2x)),x,s) ''' - return GiacMethods['fourier'](self,*args) + return GiacMethods['fourier'](self, *args) - def fourier_an(self,*args): + def fourier_an(self, *args): r'''From Giac's documentation: Help for fourier_an: fourier_an(Expr(f(x)),Var(x),Period(T),Intg(n),Real(a)) @@ -5643,9 +5643,9 @@ cdef class GiacMethods_base: Ex1:fourier_an(x^2,x,2,0,-1) Ex2:fourier_an(x^2,x,2,n,-1) ''' - return GiacMethods['fourier_an'](self,*args) + return GiacMethods['fourier_an'](self, *args) - def fourier_bn(self,*args): + def fourier_bn(self, *args): r'''From Giac's documentation: Help for fourier_bn: fourier_bn(Expr(f(x)),Var(x),Period(T),Intg(n),Real(a)) @@ -5654,9 +5654,9 @@ cdef class GiacMethods_base: Ex1:fourier_bn(x^2,x,2,0,-1) Ex2:fourier_bn(x^2,x,2,n,-1) ''' - return GiacMethods['fourier_bn'](self,*args) + return GiacMethods['fourier_bn'](self, *args) - def fourier_cn(self,*args): + def fourier_cn(self, *args): r'''From Giac's documentation: Help for fourier_cn: fourier_cn(Expr(f(x)),Var(x),Period(T),Intg(n),Real(a)) @@ -5665,9 +5665,9 @@ cdef class GiacMethods_base: Ex1:fourier_cn(x^2,x,2,0,-1) Ex2:fourier_cn(x^2,x,2,n,-1) ''' - return GiacMethods['fourier_cn'](self,*args) + return GiacMethods['fourier_cn'](self, *args) - def fprint(self,*args): + def fprint(self, *args): r'''From Giac's documentation: Help for fprint: fprint(File(f),Var,[Var,Var...]) @@ -5677,9 +5677,9 @@ cdef class GiacMethods_base: Ex2:fprint(f,"blabla") Ex3:fprint(f,Unquoted,"blabla") ''' - return GiacMethods['fprint'](self,*args) + return GiacMethods['fprint'](self, *args) - def frac(self,*args): + def frac(self, *args): r'''From Giac's documentation: Help for frac: frac(Real||LstReal) @@ -5691,9 +5691,9 @@ cdef class GiacMethods_base: Ex4:frac(-1.2) Ex5:frac([3.4,sqrt(2)]) ''' - return GiacMethods['frac'](self,*args) + return GiacMethods['frac'](self, *args) - def fracmod(self,*args): + def fracmod(self, *args): r'''From Giac's documentation: Help for fracmod: fracmod(Expr(Xpr),Intg(n)) @@ -5701,9 +5701,9 @@ cdef class GiacMethods_base: See also: 1/ mod 2/ smod Ex1:fracmod(41,121) ''' - return GiacMethods['fracmod'](self,*args) + return GiacMethods['fracmod'](self, *args) - def frame_2d(self,*args): + def frame_2d(self, *args): r'''From Giac's documentation: Help for frame_2d: frame_2d(NULL) @@ -5711,9 +5711,9 @@ cdef class GiacMethods_base: See also: 1/ frame_3d 2/ Ox_2d_unit_vector 3/ Oy_2d_unit_vector Ex1:frame_2d() ''' - return GiacMethods['frame_2d'](self,*args) + return GiacMethods['frame_2d'](self, *args) - def frequencies(self,*args): + def frequencies(self, *args): r'''From Giac's documentation: Help for frequencies: frequencies(Lst) @@ -5722,9 +5722,9 @@ cdef class GiacMethods_base: Ex1:frequencies([1,2,1,1,2,1,2,4,3,3]) Ex2:frequencies([(rand(6)+1)$(k=1..100)]) ''' - return GiacMethods['frequencies'](self,*args) + return GiacMethods['frequencies'](self, *args) - def frobenius_norm(self,*args): + def frobenius_norm(self, *args): r'''From Giac's documentation: Help for frobenius_norm: frobenius_norm(Mtrx) @@ -5732,9 +5732,9 @@ cdef class GiacMethods_base: See also: 1/ l1norm 2/ l2 norm 3/ linfnorm 4/ matrix_norm Ex1:frobenius_norm([[1,2,3],[3,-9,6],[4,5,6]]) ''' - return GiacMethods['frobenius_norm'](self,*args) + return GiacMethods['frobenius_norm'](self, *args) - def froot(self,*args): + def froot(self, *args): r'''From Giac's documentation: Help for froot: froot(RatPoly(F)) @@ -5743,9 +5743,9 @@ cdef class GiacMethods_base: Ex1:froot((x^5-2*x^4+x^3)/(x-3)) Ex2:froot((x^5-2*x^4+x^3)/(x-1)) ''' - return GiacMethods['froot'](self,*args) + return GiacMethods['froot'](self, *args) - def fsolve(self,*args): + def fsolve(self, *args): r'''From Giac's documentation: Help for fsolve: fsolve(Expr,Var,[Guess or Interval],[Method]) @@ -5756,9 +5756,9 @@ cdef class GiacMethods_base: Ex3:fsolve([x^2+y-2,x+y^2-2],[x,y],[0,0],newtonj_solver) Ex4:fsolve([x^2+y-2,x+y^2-2],[x,y]) ''' - return GiacMethods['fsolve'](self,*args) + return GiacMethods['fsolve'](self, *args) - def fullparfrac(self,*args): + def fullparfrac(self, *args): r'''From Giac's documentation: Help for fullparfrac: fullparfrac(Opt) @@ -5767,9 +5767,9 @@ cdef class GiacMethods_base: Ex1: convert(1/(x^2-1),parfrac) Ex2: convert(1/(x^2-1),fullparfrac) ''' - return GiacMethods['fullparfrac'](self,*args) + return GiacMethods['fullparfrac'](self, *args) - def funcplot(self,*args): + def funcplot(self, *args): r'''From Giac's documentation: Help for funcplot: funcplot(Expr,[Var(x) or VectVar] ,[Intg(color)]) @@ -5781,9 +5781,9 @@ cdef class GiacMethods_base: Ex4:funcplot(x^2+y^2,[x=-1..1,y=-2..2],nstep=900) Ex5:funcplot((x+i*y)^2,[x=-1..1,y=-2..2],nstep=900,affichage=rempli) ''' - return GiacMethods['funcplot'](self,*args) + return GiacMethods['funcplot'](self, *args) - def function_diff(self,*args): + def function_diff(self, *args): r'''From Giac's documentation: Help for function_diff: function_diff(Fnc(f)) @@ -5795,9 +5795,9 @@ cdef class GiacMethods_base: Ex4:function_diff(ln)([x,y]) Ex5: (function_diff @@3)(ln)('x') ''' - return GiacMethods['function_diff'](self,*args) + return GiacMethods['function_diff'](self, *args) - def fxnd(self,*args): + def fxnd(self, *args): r'''From Giac's documentation: Help for fxnd: fxnd(Frac or RatFrac) @@ -5806,9 +5806,9 @@ cdef class GiacMethods_base: Ex1:fxnd(42/12) Ex2:fxnd((x^2+2*x+1)/(x^2-1)) ''' - return GiacMethods['fxnd'](self,*args) + return GiacMethods['fxnd'](self, *args) - def gammad(self,*args): + def gammad(self, *args): r'''From Giac's documentation: Help for gammad: gammad(Real(a>0),Real(b>0),Real(x>=0)) @@ -5816,9 +5816,9 @@ cdef class GiacMethods_base: See also: 1/ gammad_cdf; 2/ gammad_icdf Ex1:gammad(2.2,1.5,0.8) ''' - return GiacMethods['gammad'](self,*args) + return GiacMethods['gammad'](self, *args) - def gammad_cdf(self,*args): + def gammad_cdf(self, *args): r'''From Giac's documentation: Help for gammad_cdf: gammad_cdf(Real(a>0),Real(b>0),Real(x0>=0),[Real(y0>=0)]) @@ -5827,9 +5827,9 @@ cdef class GiacMethods_base: Ex1:gammad_cdf(2,1,2.96) Ex2:gammad_cdf(2,1,1.4,2.96) ''' - return GiacMethods['gammad_cdf'](self,*args) + return GiacMethods['gammad_cdf'](self, *args) - def gammad_icdf(self,*args): + def gammad_icdf(self, *args): r'''From Giac's documentation: Help for gammad_icdf: gammad_icdf(Real(a>0),Real(b>0),Real(0<=p<=1)) @@ -5838,9 +5838,9 @@ cdef class GiacMethods_base: Ex1:gammad_icdf(2,1,0.95) Ex2:gammad_icdf(2,1,0.5) ''' - return GiacMethods['gammad_icdf'](self,*args) + return GiacMethods['gammad_icdf'](self, *args) - def gammavariate(self,*args): + def gammavariate(self, *args): r'''From Giac's documentation: Help for gammavariate: gammavariate(Real(a),Real(b)) @@ -5849,9 +5849,9 @@ cdef class GiacMethods_base: Ex1:gammavariate(1,2) Ex2:gammavariate(1.5,4) ''' - return GiacMethods['gammavariate'](self,*args) + return GiacMethods['gammavariate'](self, *args) - def gauss(self,*args): + def gauss(self, *args): r'''From Giac's documentation: Help for gauss: gauss(Expr,VectVar) @@ -5859,9 +5859,9 @@ cdef class GiacMethods_base: See also: 1/ cholesky Ex1:gauss(x^2+2*a*x*y,[x,y]) ''' - return GiacMethods['gauss'](self,*args) + return GiacMethods['gauss'](self, *args) - def gauss15(self,*args): + def gauss15(self, *args): r'''From Giac's documentation: Help for gauss15: gauss15(Opt) @@ -5872,9 +5872,9 @@ cdef class GiacMethods_base: Ex3: area(x^2,x=0..1,5,rombergm) Ex4:gauss15(area(x^2,x=0..1,5,gauss15)) ''' - return GiacMethods['gauss15'](self,*args) + return GiacMethods['gauss15'](self, *args) - def gauss_seidel_linsolve(self,*args): + def gauss_seidel_linsolve(self, *args): r'''From Giac's documentation: Help for gauss_seidel_linsolve: gauss_seidel_linsolve([Real(omega)],Mtrx(A),Vect(b),Real(eps),[Int(maxiter)]) @@ -5885,9 +5885,9 @@ cdef class GiacMethods_base: Ex3: a:=[[100,2],[2,100]];gauss_seidel_linsolve(1.5,a,[0,1],1e-12); Ex4: a:=[[100,2],[2,100]];gauss_seidel_linsolve(1.5,table(a),[0,1],1e-12); ''' - return GiacMethods['gauss_seidel_linsolve'](self,*args) + return GiacMethods['gauss_seidel_linsolve'](self, *args) - def gaussian_window(self,*args): + def gaussian_window(self, *args): r'''From Giac's documentation: Help for gaussian_window: gaussian_window(Lst,[Real(a)],[Interval(n1..n2)]) @@ -5895,9 +5895,9 @@ cdef class GiacMethods_base: See also: 1/ blackman_harris_window 2/ blackman_window 3/ bohman_window 4/ cosine_window 5/ bartlett_hann_window 6/ hamming_window 7/ hann_poisson_window 8/ hann_window 9/ parzen_window 10/ poisson_window 11/ riemann_window 12/ triangle_window 13/ tukey_window 14/ welch_window Ex1: scatterplot(gaussian_window(randvector(1000,0..1),0.4)) ''' - return GiacMethods['gaussian_window'](self,*args) + return GiacMethods['gaussian_window'](self, *args) - def gaussjord(self,*args): + def gaussjord(self, *args): r'''From Giac's documentation: Help for gaussjord: gaussjord(Mtrx(M),[Intg(k)]||Opt) @@ -5908,9 +5908,9 @@ cdef class GiacMethods_base: Ex3:gaussjord([[2,1,1,-1],[1,1,2,-1],[1,2,1,-4]],2) Ex4:gaussjord([[1,1,0,0,-a1],[0,1,1,0,-a2],[0,0,1,1,-a3],[1,0,0,1,-a4]],keep_pivot) ''' - return GiacMethods['gaussjord'](self,*args) + return GiacMethods['gaussjord'](self, *args) - def gaussquad(self,*args): + def gaussquad(self, *args): r'''From Giac's documentation: Help for gaussquad: gaussquad(Expr(f(x)),Var(x),Real(a),Real(b)) @@ -5920,9 +5920,9 @@ cdef class GiacMethods_base: Ex2:gaussquad(x^2,x,0,1) Ex3:gaussquad(exp(-x^2),x,-1,1) ''' - return GiacMethods['gaussquad'](self,*args) + return GiacMethods['gaussquad'](self, *args) - def gbasis(self,*args): + def gbasis(self, *args): r'''From Giac's documentation: Help for gbasis: gbasis(LstPoly,LstVar,[order]) @@ -5934,9 +5934,9 @@ cdef class GiacMethods_base: Ex4:gbasis([x1+x2+x3,x1*x2+x1*x3+x2*x3,x1*x2*x3-1],[x1,x2,x3],plex) Ex5:gbasis([x1+x2+x3,x1*x2+x1*x3+x2*x3,x1*x2*x3-1] mod 29,[x1,x2,x3]) ''' - return GiacMethods['gbasis'](self,*args) + return GiacMethods['gbasis'](self, *args) - def gbasis_max_pairs(self,*args): + def gbasis_max_pairs(self, *args): r'''From Giac's documentation: Help for gbasis_max_pairs: gbasis_max_pairs(Intg) @@ -5945,9 +5945,9 @@ cdef class GiacMethods_base: Ex1:gbasis_max_pairs(4096) Ex2:gbasis_max_pairs(0) ''' - return GiacMethods['gbasis_max_pairs'](self,*args) + return GiacMethods['gbasis_max_pairs'](self, *args) - def gbasis_reinject(self,*args): + def gbasis_reinject(self, *args): r'''From Giac's documentation: Help for gbasis_reinject: gbasis_reinject(Real(a),[Real(b)]) @@ -5956,9 +5956,9 @@ cdef class GiacMethods_base: Ex1:gbasis_reinject(0.1) Ex2:gbasis_reinject(0.1,0.05) ''' - return GiacMethods['gbasis_reinject'](self,*args) + return GiacMethods['gbasis_reinject'](self, *args) - def gbasis_simult_primes(self,*args): + def gbasis_simult_primes(self, *args): r'''From Giac's documentation: Help for gbasis_simult_primes: gbasis_simult_primes(Intg) @@ -5966,9 +5966,9 @@ cdef class GiacMethods_base: See also: 1/ gbasis 2/ gbasis_max_pairs 3/ gbasis_reinject Ex1:gbasis_simult_primes(3) ''' - return GiacMethods['gbasis_simult_primes'](self,*args) + return GiacMethods['gbasis_simult_primes'](self, *args) - def gcd(self,*args): + def gcd(self, *args): r'''From Giac's documentation: Help for gcd: gcd((Intg(a) or Poly),(Intg(b) or Poly)) @@ -5980,9 +5980,9 @@ cdef class GiacMethods_base: Ex4:gcd(t^2-2*t+1,t^2+t-2) Ex5:gcd((x^2-1)*(y^2-1)*z^2,x^3*y^3*z+(-(y^3))*z+x^3*z-z) ''' - return GiacMethods['gcd'](self,*args) + return GiacMethods['gcd'](self, *args) - def gcdex(self,*args): + def gcdex(self, *args): r'''From Giac's documentation: Help for gcdex: gcdex((Poly or Lst),(Poly or Lst),[Var]) @@ -5993,9 +5993,9 @@ cdef class GiacMethods_base: Ex3:gcdex([1,-2,1],[1,0,0,-1]) Ex4:gcdex([1,-2,1],[1,-1,2]) ''' - return GiacMethods['gcdex'](self,*args) + return GiacMethods['gcdex'](self, *args) - def genpoly(self,*args): + def genpoly(self, *args): r'''From Giac's documentation: Help for genpoly: genpoly(Poly(P),Intg(b),Var) @@ -6005,9 +6005,9 @@ cdef class GiacMethods_base: Ex2:genpoly(7*y+5,6,x) Ex3:genpoly(7*y-5*z,10,x) ''' - return GiacMethods['genpoly'](self,*args) + return GiacMethods['genpoly'](self, *args) - def geometric(self,*args): + def geometric(self, *args): r'''From Giac's documentation: Help for geometric: geometric(Real(p),Intg(k)) @@ -6018,9 +6018,9 @@ cdef class GiacMethods_base: Ex3: randvector(3,geometric,0.3) Ex4: ranm(4,3,geometric,0.3) ''' - return GiacMethods['geometric'](self,*args) + return GiacMethods['geometric'](self, *args) - def geometric_cdf(self,*args): + def geometric_cdf(self, *args): r'''From Giac's documentation: Help for geometric_cdf: geometric_cdf(Real(p),Intg(k),[Intg(m)]) @@ -6029,9 +6029,9 @@ cdef class GiacMethods_base: Ex1:geometric_cdf(0.3,4) Ex2:geometric_cdf(0.3,4,5) ''' - return GiacMethods['geometric_cdf'](self,*args) + return GiacMethods['geometric_cdf'](self, *args) - def geometric_icdf(self,*args): + def geometric_icdf(self, *args): r'''From Giac's documentation: Help for geometric_icdf: geometric_icdf(Real(p),Real(x)) @@ -6039,9 +6039,9 @@ cdef class GiacMethods_base: See also: 1/ geometric_cdf 2/ geometric Ex1:geometric_icdf(0.3,0.95) ''' - return GiacMethods['geometric_icdf'](self,*args) + return GiacMethods['geometric_icdf'](self, *args) - def getDenom(self,*args): + def getDenom(self, *args): r'''From Giac's documentation: Help for getDenom: getDenom(Expr) @@ -6051,9 +6051,9 @@ cdef class GiacMethods_base: Ex2:getDenom((x^3-1)/(x^2-1)) Ex3:getDenom(1+(x^3-1)/x^2) ''' - return GiacMethods['getDenom'](self,*args) + return GiacMethods['getDenom'](self, *args) - def getKey(self,*args): + def getKey(self, *args): r'''From Giac's documentation: Help for getKey: getKey(NULL) @@ -6061,9 +6061,9 @@ cdef class GiacMethods_base: See also: 1/ getType Ex1:getKey() ''' - return GiacMethods['getKey'](self,*args) + return GiacMethods['getKey'](self, *args) - def getNum(self,*args): + def getNum(self, *args): r'''From Giac's documentation: Help for getNum: getNum(Expr) @@ -6073,9 +6073,9 @@ cdef class GiacMethods_base: Ex2:getNum((x^3-1)/(x^2-1)) Ex3:getNum(1+(x^3-1)/x^2) ''' - return GiacMethods['getNum'](self,*args) + return GiacMethods['getNum'](self, *args) - def getType(self,*args): + def getType(self, *args): r'''From Giac's documentation: Help for getType: getType(Expr) @@ -6086,9 +6086,9 @@ cdef class GiacMethods_base: Ex3:getType(x->cos(2*x)) Ex4:getType(1.414) ''' - return GiacMethods['getType'](self,*args) + return GiacMethods['getType'](self, *args) - def get_edge_attribute(self,*args): + def get_edge_attribute(self, *args): r'''From Giac's documentation: Help for get_edge_attribute: get_edge_attribute(Graph(G),Edge(e),Seq(tag1=value1,tag2=value2,..)) @@ -6096,9 +6096,9 @@ cdef class GiacMethods_base: See also: 1/ discard_edge_attribute 2/ set_edge_attribute 3/ list_edge_attributes Ex1:get_edge_attribute(cycle_graph(3),[1,2],"cost") ''' - return GiacMethods['get_edge_attribute'](self,*args) + return GiacMethods['get_edge_attribute'](self, *args) - def get_edge_weight(self,*args): + def get_edge_weight(self, *args): r'''From Giac's documentation: Help for get_edge_weight: get_edge_weight(Graph(G),Edge(e)) @@ -6106,9 +6106,9 @@ cdef class GiacMethods_base: See also: 1/ is_weighted 2/ make_weighted 3/ set_edge_weight 4/ weight_matrix Ex1:get_edge_weight(graph(%{[[1,2],5],[[2,3],6]%}),[1,2]) ''' - return GiacMethods['get_edge_weight'](self,*args) + return GiacMethods['get_edge_weight'](self, *args) - def get_graph_attribute(self,*args): + def get_graph_attribute(self, *args): r'''From Giac's documentation: Help for get_graph_attribute: get_graph_attribute(Graph(G),Seq(tag1=value1,tag2=value2,..)) @@ -6116,9 +6116,9 @@ cdef class GiacMethods_base: See also: 1/ discard_graph_attribute 2/ set_graph_attribute 3/ list_graph_attributes Ex1:get_graph_attribute(cycle_graph(3),"name") ''' - return GiacMethods['get_graph_attribute'](self,*args) + return GiacMethods['get_graph_attribute'](self, *args) - def get_vertex_attribute(self,*args): + def get_vertex_attribute(self, *args): r'''From Giac's documentation: Help for get_vertex_attribute: get_vertex_attribute(Graph(G),Vrtx(v),Seq(tag1=value1,tag2=value2,..)) @@ -6126,9 +6126,9 @@ cdef class GiacMethods_base: See also: 1/ discard_vertex_attribute 2/ set_vertex_attribute 3/ list_vertex_attributes Ex1:get_vertex_attribute(cycle_graph(3),1,"supply") ''' - return GiacMethods['get_vertex_attribute'](self,*args) + return GiacMethods['get_vertex_attribute'](self, *args) - def girth(self,*args): + def girth(self, *args): r'''From Giac's documentation: Help for girth: girth(Graph(G)) @@ -6137,9 +6137,9 @@ cdef class GiacMethods_base: Ex1:girth(graph("petersen")) Ex2:girth(hypercube_graph(3)) ''' - return GiacMethods['girth'](self,*args) + return GiacMethods['girth'](self, *args) - def gl_showaxes(self,*args): + def gl_showaxes(self, *args): r'''From Giac's documentation: Help for gl_showaxes: gl_showaxes(Opt=Boolean) @@ -6148,9 +6148,9 @@ cdef class GiacMethods_base: Ex1: gl_showaxes=true;plot(sin(x)) Ex2: gl_showaxes=false;plot(sin(x)) ''' - return GiacMethods['gl_showaxes'](self,*args) + return GiacMethods['gl_showaxes'](self, *args) - def grad(self,*args): + def grad(self, *args): r'''From Giac's documentation: Help for grad: grad(Expr(Xpr),LstVar) @@ -6158,9 +6158,9 @@ cdef class GiacMethods_base: See also: 1/ hessian Ex1:grad(2*x^2*y-x*z^3,[x,y,z]) ''' - return GiacMethods['grad'](self,*args) + return GiacMethods['grad'](self, *args) - def gramschmidt(self,*args): + def gramschmidt(self, *args): r'''From Giac's documentation: Help for gramschmidt: gramschmidt(Basis(B),ScalarProd(Sp)) @@ -6169,9 +6169,9 @@ cdef class GiacMethods_base: Ex1:gramschmidt(-2) Ex2:gramschmidt([1,1+x],(p,q)->integrate(p*q,x,-1,1)) ''' - return GiacMethods['gramschmidt'](self,*args) + return GiacMethods['gramschmidt'](self, *args) - def graph(self,*args): + def graph(self, *args): r'''From Giac's documentation: Help for graph: graph([Lst(V)],[Set(E)],[Mtrx(A)],[options]) @@ -6185,9 +6185,9 @@ cdef class GiacMethods_base: Ex6:graph("petersen") Ex7:graph([[0,1,1,0],[1,0,0,1],[1,0,0,0],[0,1,0,0]]) ''' - return GiacMethods['graph'](self,*args) + return GiacMethods['graph'](self, *args) - def graph_automorphisms(self,*args): + def graph_automorphisms(self, *args): r'''From Giac's documentation: Help for graph_automorphisms: graph_automorphisms(Graph(G)) @@ -6195,9 +6195,9 @@ cdef class GiacMethods_base: See also: 1/ cycles2permu 2/ isomorphic_copy 3/ permute_vertices Ex1:graph_automorphisms(graph("petersen")) ''' - return GiacMethods['graph_automorphisms'](self,*args) + return GiacMethods['graph_automorphisms'](self, *args) - def graph_charpoly(self,*args): + def graph_charpoly(self, *args): r'''From Giac's documentation: Help for graph_charpoly: graph_charpoly(Graph(G),[Var(x)]) @@ -6206,9 +6206,9 @@ cdef class GiacMethods_base: Ex1:graph_charpoly(graph(%{[1,2],[2,3]%})) Ex2:graph_charpoly(graph("shrikhande")) ''' - return GiacMethods['graph_charpoly'](self,*args) + return GiacMethods['graph_charpoly'](self, *args) - def graph_complement(self,*args): + def graph_complement(self, *args): r'''From Giac's documentation: Help for graph_complement: graph_complement(Graph(G)) @@ -6216,9 +6216,9 @@ cdef class GiacMethods_base: See also: 1/ edges Ex1:graph_complement(cycle_graph(5)) ''' - return GiacMethods['graph_complement'](self,*args) + return GiacMethods['graph_complement'](self, *args) - def graph_diameter(self,*args): + def graph_diameter(self, *args): r'''From Giac's documentation: Help for graph_diameter: graph_diameter(Graph(G)) @@ -6226,9 +6226,9 @@ cdef class GiacMethods_base: See also: 1/ allpairs_distance 2/ dijkstra 3/ shortest_path 4/ vertex_distance Ex1:graph_diameter(graph("petersen")) ''' - return GiacMethods['graph_diameter'](self,*args) + return GiacMethods['graph_diameter'](self, *args) - def graph_equal(self,*args): + def graph_equal(self, *args): r'''From Giac's documentation: Help for graph_equal: graph_equal(Graph(G1),Graph(G2)) @@ -6236,9 +6236,9 @@ cdef class GiacMethods_base: See also: 1/ edges 2/ graph_vertices Ex1:graph_equal(graph([1,2,3],%{[1,2],[2,3],[3,1]%}),graph(trail(1,2,3,1))) ''' - return GiacMethods['graph_equal'](self,*args) + return GiacMethods['graph_equal'](self, *args) - def graph_join(self,*args): + def graph_join(self, *args): r'''From Giac's documentation: Help for graph_join: graph_join(Graph(G),Graph(H)) @@ -6246,9 +6246,9 @@ cdef class GiacMethods_base: See also: 1/ disjoint_union 2/ graph_union Ex1:graph_join(edges(graph_join(cycle_graph(3),graph(2)))) ''' - return GiacMethods['graph_join'](self,*args) + return GiacMethods['graph_join'](self, *args) - def graph_power(self,*args): + def graph_power(self, *args): r'''From Giac's documentation: Help for graph_power: graph_power(Graph(G),Intg(k)) @@ -6256,9 +6256,9 @@ cdef class GiacMethods_base: See also: 1/ adjacency matrix 2/ graph_diameter 3/ shortest_path Ex1:graph_power(edges(graph_power(path_graph(5),3))) ''' - return GiacMethods['graph_power'](self,*args) + return GiacMethods['graph_power'](self, *args) - def graph_rank(self,*args): + def graph_rank(self, *args): r'''From Giac's documentation: Help for graph_rank: graph_rank(Graph(G),[Lst(E)]) @@ -6267,9 +6267,9 @@ cdef class GiacMethods_base: Ex1:graph_rank(graph(%{[1,2],[3,4],[4,5]%})) Ex2:graph_rank(graph(%{[1,2],[3,4],[4,5]%}),[[1,2],[3,4]) ''' - return GiacMethods['graph_rank'](self,*args) + return GiacMethods['graph_rank'](self, *args) - def graph_spectrum(self,*args): + def graph_spectrum(self, *args): r'''From Giac's documentation: Help for graph_spectrum: graph_spectrum(Graph(G)) @@ -6277,9 +6277,9 @@ cdef class GiacMethods_base: See also: 1/ graph_charpoly 2/ seidel_spectrum 3/ is_integer_graph Ex1:graph_spectrum(cycle_graph(5)) ''' - return GiacMethods['graph_spectrum'](self,*args) + return GiacMethods['graph_spectrum'](self, *args) - def graph_union(self,*args): + def graph_union(self, *args): r'''From Giac's documentation: Help for graph_union: graph_union(Seq(G1,G2,...)) @@ -6287,9 +6287,9 @@ cdef class GiacMethods_base: See also: 1/ disjoint_union 2/ graph_join Ex1:graph_union(edges(graph_union(cycle_graph(4),path_graph(5)))) ''' - return GiacMethods['graph_union'](self,*args) + return GiacMethods['graph_union'](self, *args) - def graph_vertices(self,*args): + def graph_vertices(self, *args): r'''From Giac's documentation: Help for graph_vertices: graph_vertices(Graph(G)) @@ -6297,9 +6297,9 @@ cdef class GiacMethods_base: See also: 1/ add_vertex 2/ graph 3/ neighbors 4/ permute_vertices 5/ relabel_vertices Ex1:graph_vertices(graph(%{[a,c],[b,c],[a,b]%})) ''' - return GiacMethods['graph_vertices'](self,*args) + return GiacMethods['graph_vertices'](self, *args) - def greduce(self,*args): + def greduce(self, *args): r'''From Giac's documentation: Help for greduce: greduce(Poly,LstPoly,LstVar,[order]) @@ -6309,9 +6309,9 @@ cdef class GiacMethods_base: Ex2:greduce(x1^2*x3^2,[x3^3-1,-x2^2-x2*x3-x3^2,x1+x2+x3],[x1,x2,x3],tdeg) Ex3:greduce(x1^2*x3^2-x2,[x3^3-1,-x2^2-x2*x3-x3^2,x1+x2+x3],[x1,x2,x3]) ''' - return GiacMethods['greduce'](self,*args) + return GiacMethods['greduce'](self, *args) - def greedy_color(self,*args): + def greedy_color(self, *args): r'''From Giac's documentation: Help for greedy_color: greedy_color(Graph(G),[Permu(p)]) @@ -6319,9 +6319,9 @@ cdef class GiacMethods_base: See also: 1/ is_vertex_colorable 2/ chromatic_number Ex1:greedy_color(graph("petersen")) ''' - return GiacMethods['greedy_color'](self,*args) + return GiacMethods['greedy_color'](self, *args) - def grid_graph(self,*args): + def grid_graph(self, *args): r'''From Giac's documentation: Help for grid_graph: grid_graph(Intg(m),Intg(n),[triangle]) @@ -6329,9 +6329,9 @@ cdef class GiacMethods_base: See also: 1/ torus_grid_graph Ex1:grid_graph(5,8) ''' - return GiacMethods['grid_graph'](self,*args) + return GiacMethods['grid_graph'](self, *args) - def groupermu(self,*args): + def groupermu(self, *args): r'''From Giac's documentation: Help for groupermu: groupermu(Permut(a),Permut(b)) @@ -6339,9 +6339,9 @@ cdef class GiacMethods_base: See also: 1/ Ex1:groupermu([1,2,0],[3,1,2,0]) ''' - return GiacMethods['groupermu'](self,*args) + return GiacMethods['groupermu'](self, *args) - def hadamard(self,*args): + def hadamard(self, *args): r'''From Giac's documentation: Help for hadamard: hadamard(Mtrx,Mtrx) @@ -6350,9 +6350,9 @@ cdef class GiacMethods_base: Ex1:hadamard([[1,2],[3,4]]) Ex2:hadamard([[1,2],[3,4]],[[3,4],[5,6]]) ''' - return GiacMethods['hadamard'](self,*args) + return GiacMethods['hadamard'](self, *args) - def half_cone(self,*args): + def half_cone(self, *args): r'''From Giac's documentation: Help for half_cone: half_cone(Pnt(A),Vect(v),Real(t),[Real(h)]) @@ -6361,9 +6361,9 @@ cdef class GiacMethods_base: Ex1:half_cone([0,0,0],[0,0,1],pi/6) Ex2:half_cone([0,0,0],[0,1,1],pi/6,-4) ''' - return GiacMethods['half_cone'](self,*args) + return GiacMethods['half_cone'](self, *args) - def half_line(self,*args): + def half_line(self, *args): r'''From Giac's documentation: Help for half_line: half_line((Pnt or Cplx),(Pnt or Cplx)) @@ -6372,9 +6372,9 @@ cdef class GiacMethods_base: Ex1:half_line(i,1+i) Ex2:half_line(point(i),point(1+i)) ''' - return GiacMethods['half_line'](self,*args) + return GiacMethods['half_line'](self, *args) - def halftan(self,*args): + def halftan(self, *args): r'''From Giac's documentation: Help for halftan: halftan(Expr) @@ -6383,9 +6383,9 @@ cdef class GiacMethods_base: Ex2:halftan(cos(x)) Ex3:halftan(tan(x)) ''' - return GiacMethods['halftan'](self,*args) + return GiacMethods['halftan'](self, *args) - def halftan_hyp2exp(self,*args): + def halftan_hyp2exp(self, *args): r'''From Giac's documentation: Help for halftan_hyp2exp: halftan_hyp2exp(ExprTrig) @@ -6393,9 +6393,9 @@ cdef class GiacMethods_base: See also: 1/ hyp2exp 2/ halftan Ex1:halftan_hyp2exp(sin(x)+sinh(x)) ''' - return GiacMethods['halftan_hyp2exp'](self,*args) + return GiacMethods['halftan_hyp2exp'](self, *args) - def halt(self,*args): + def halt(self, *args): r'''From Giac's documentation: Help for halt: halt(NULL) @@ -6403,18 +6403,18 @@ cdef class GiacMethods_base: See also: 1/ Ex1:halt() ''' - return GiacMethods['halt'](self,*args) + return GiacMethods['halt'](self, *args) - def hamdist(self,*args): + def hamdist(self, *args): r'''From Giac's documentation: Help for hamdist: hamdist(Intg,Intg) Bitwise Hamming distance. Ex1:hamdist(0x12,0x38) ''' - return GiacMethods['hamdist'](self,*args) + return GiacMethods['hamdist'](self, *args) - def hamming_window(self,*args): + def hamming_window(self, *args): r'''From Giac's documentation: Help for hamming_window: hamming_window(Lst,[Interval(n1..n2)]) @@ -6422,9 +6422,9 @@ cdef class GiacMethods_base: See also: 1/ blackman_harris_window 2/ blackman_window 3/ bohman_window 4/ cosine_window 5/ gaussian_window 6/ bartlett_hann_window 7/ hann_poisson_window 8/ hann_window 9/ parzen_window 10/ poisson_window 11/ riemann_window 12/ triangle_window 13/ tukey_window 14/ welch_window Ex1: scatterplot(hamming_window(randvector(1000,0..1))) ''' - return GiacMethods['hamming_window'](self,*args) + return GiacMethods['hamming_window'](self, *args) - def hann_poisson_window(self,*args): + def hann_poisson_window(self, *args): r'''From Giac's documentation: Help for hann_poisson_window: hann_poisson_window(Lst,[Interval(n1..n2)]) @@ -6432,9 +6432,9 @@ cdef class GiacMethods_base: See also: 1/ blackman_harris_window 2/ blackman_window 3/ bohman_window 4/ cosine_window 5/ gaussian_window 6/ hamming_window 7/ bartlett_hann_window 8/ hann_window 9/ parzen_window 10/ poisson_window 11/ riemann_window 12/ triangle_window 13/ tukey_window 14/ welch_window Ex1: scatterplot(hann_poisson_window(randvector(1000,0..1),2)) ''' - return GiacMethods['hann_poisson_window'](self,*args) + return GiacMethods['hann_poisson_window'](self, *args) - def hann_window(self,*args): + def hann_window(self, *args): r'''From Giac's documentation: Help for hann_window: hann_window(Lst,[Interval(n1..n2)]) @@ -6442,9 +6442,9 @@ cdef class GiacMethods_base: See also: 1/ blackman_harris_window 2/ blackman_window 3/ bohman_window 4/ cosine_window 5/ gaussian_window 6/ hamming_window 7/ hann_poisson_window 8/ bartlett_hann_window 9/ parzen_window 10/ poisson_window 11/ riemann_window 12/ triangle_window 13/ tukey_window 14/ welch_window Ex1: scatterplot(hann_window(randvector(1000,0..1))) ''' - return GiacMethods['hann_window'](self,*args) + return GiacMethods['hann_window'](self, *args) - def harmonic_conjugate(self,*args): + def harmonic_conjugate(self, *args): r'''From Giac's documentation: Help for harmonic_conjugate: harmonic_conjugate(Line or Pnt(A),Line or Pnt(B),Line or Pnt(C)) @@ -6455,9 +6455,9 @@ cdef class GiacMethods_base: Ex3:harmonic_conjugate(line(0,1+i),line(0,3+i),line(0,i)) Ex4:harmonic_conjugate(line(0,1+i),line(0,3+i),point(3/2+i)) ''' - return GiacMethods['harmonic_conjugate'](self,*args) + return GiacMethods['harmonic_conjugate'](self, *args) - def harmonic_division(self,*args): + def harmonic_division(self, *args): r'''From Giac's documentation: Help for harmonic_division: harmonic_division(Pnt or Line,Pnt or Line,Pnt or Line,Var) @@ -6468,9 +6468,9 @@ cdef class GiacMethods_base: Ex3:harmonic_division(line(i,0),line(i,1+i),line(i,3+2*i),D) Ex4:harmonic_division(line(0,1+i),line(0,3+i),line(0,i),D) ''' - return GiacMethods['harmonic_division'](self,*args) + return GiacMethods['harmonic_division'](self, *args) - def has(self,*args): + def has(self, *args): r'''From Giac's documentation: Help for has: has(Expr,Var) @@ -6479,9 +6479,9 @@ cdef class GiacMethods_base: Ex1:has(x+y,x) Ex2:has(x+y,n) ''' - return GiacMethods['has'](self,*args) + return GiacMethods['has'](self, *args) - def has_arc(self,*args): + def has_arc(self, *args): r'''From Giac's documentation: Help for has_arc: has_arc(Graph(G),Edge(e)) @@ -6490,9 +6490,9 @@ cdef class GiacMethods_base: Ex1:has_arc(digraph(trail(1,2,3,4,1)),[4,2]) Ex2:has_arc(digraph(trail(1,2,3,4,1)),%{4,2%}) ''' - return GiacMethods['has_arc'](self,*args) + return GiacMethods['has_arc'](self, *args) - def has_edge(self,*args): + def has_edge(self, *args): r'''From Giac's documentation: Help for has_edge: has_edge(Graph(G),Edge(e)) @@ -6500,9 +6500,9 @@ cdef class GiacMethods_base: See also: 1/ edges 2/ has_arc Ex1:has_edge(graph(trail(1,2,3,4,1)),[2,4]) ''' - return GiacMethods['has_edge'](self,*args) + return GiacMethods['has_edge'](self, *args) - def hasard(self,*args): + def hasard(self, *args): r'''From Giac's documentation: Help for hasard: hasard(Intg(n) or Interval(p..n) or NULL,[Intg(b1) or Lst(L)],[Intg(b2)]) @@ -6516,9 +6516,9 @@ cdef class GiacMethods_base: Ex6:hasard(3,1,10) Ex7:hasard(3,["r","r","r","b","n"]) ''' - return GiacMethods['hasard'](self,*args) + return GiacMethods['hasard'](self, *args) - def head(self,*args): + def head(self, *args): r'''From Giac's documentation: Help for head: head(Vect or Seq or Str) @@ -6528,9 +6528,9 @@ cdef class GiacMethods_base: Ex2:head([1,2,3]) Ex3:head("bonjour") ''' - return GiacMethods['head'](self,*args) + return GiacMethods['head'](self, *args) - def heading(self,*args): + def heading(self, *args): r'''From Giac's documentation: Help for heading: heading(NULL or Real) @@ -6540,36 +6540,36 @@ cdef class GiacMethods_base: Ex2:heading() Ex3:heading(cap 90) ''' - return GiacMethods['heading'](self,*args) + return GiacMethods['heading'](self, *args) - def heapify(self,*args): + def heapify(self, *args): r'''From Giac's documentation: Help for heapify: heapify(List) Partial ordering of a list as a heap. See also: 1/ heappush 2/ heappop ''' - return GiacMethods['heapify'](self,*args) + return GiacMethods['heapify'](self, *args) - def heappop(self,*args): + def heappop(self, *args): r'''From Giac's documentation: Help for heappop: heappop(List) Removes and returns the root node of a heap. See also: 1/ heapify 2/ heappush ''' - return GiacMethods['heappop'](self,*args) + return GiacMethods['heappop'](self, *args) - def heappush(self,*args): + def heappush(self, *args): r'''From Giac's documentation: Help for heappush: heappush(List,Object) Adds an object in a heap. See also: 1/ heapify 2/ heappop ''' - return GiacMethods['heappush'](self,*args) + return GiacMethods['heappush'](self, *args) - def hermite(self,*args): + def hermite(self, *args): r'''From Giac's documentation: Help for hermite: hermite(Intg(n)||Matr(A)) @@ -6578,9 +6578,9 @@ cdef class GiacMethods_base: Ex1:hermite(3) Ex2: n:=5; a:=ranm(n,n) % 17; l,u:=hermite(x-a);normal(l*(x-a)-u); ''' - return GiacMethods['hermite'](self,*args) + return GiacMethods['hermite'](self, *args) - def hessenberg(self,*args): + def hessenberg(self, *args): r'''From Giac's documentation: Help for hessenberg: hessenberg(Mtrx(A),[Intg(n)]) @@ -6592,9 +6592,9 @@ cdef class GiacMethods_base: Ex4:hessenberg([[1,2,3],[4,5,6],[7,8,1]],-2) Ex5:hessenberg([[1,2,3],[4,5,6],[7,8,1]],3) ''' - return GiacMethods['hessenberg'](self,*args) + return GiacMethods['hessenberg'](self, *args) - def hessian(self,*args): + def hessian(self, *args): r'''From Giac's documentation: Help for hessian: hessian(Expr(Xpr),LstVar) @@ -6602,9 +6602,9 @@ cdef class GiacMethods_base: See also: 1/ grad Ex1:hessian(2*x^2*y-x*z,[x,y,z]) ''' - return GiacMethods['hessian'](self,*args) + return GiacMethods['hessian'](self, *args) - def heugcd(self,*args): + def heugcd(self, *args): r'''From Giac's documentation: Help for heugcd: heugcd(Poly,Poly) @@ -6612,9 +6612,9 @@ cdef class GiacMethods_base: See also: 1/ gcd 2/ modgcd 3/ ezgcd 4/ psrgcd Ex1:heugcd(x^4-1,(x-1)^2) ''' - return GiacMethods['heugcd'](self,*args) + return GiacMethods['heugcd'](self, *args) - def hexagon(self,*args): + def hexagon(self, *args): r'''From Giac's documentation: Help for hexagon: hexagon(Pnt(A)||Cplx,Pnt(B)||Cplx,[Pnt(P)],[Var(C)],[Var(D)],[Var(E)],[Var(F)]) @@ -6625,9 +6625,9 @@ cdef class GiacMethods_base: Ex3:hexagon(point(0,0,0),point(3,3,3),point(0,0,3)) Ex4:hexagon(point(0,0,0),point(3,3,3),point(0,0,3),C,D,E,F) ''' - return GiacMethods['hexagon'](self,*args) + return GiacMethods['hexagon'](self, *args) - def highlight_edges(self,*args): + def highlight_edges(self, *args): r'''From Giac's documentation: Help for highlight_edges: highlight_edges(Graph(G),Edge(e)||Lst(E),[Color(c)||Lst(C)]) @@ -6635,9 +6635,9 @@ cdef class GiacMethods_base: See also: 1/ highlight_vertex 2/ highlight_subgraph 3/ highlight_trail Ex1: draw_graph(highlight_edges(cycle_graph(3),[1,2])) ''' - return GiacMethods['highlight_edges'](self,*args) + return GiacMethods['highlight_edges'](self, *args) - def highlight_subgraph(self,*args): + def highlight_subgraph(self, *args): r'''From Giac's documentation: Help for highlight_subgraph: highlight_subgraph(Graph(G),Graph(S)||Lst(S1,S2,..),Seq(c1,c2)) @@ -6645,9 +6645,9 @@ cdef class GiacMethods_base: See also: 1/ highlight_edges 2/ highlight_vertex 3/ highlight_trail Ex1: draw_graph(highlight_subgraph(cycle_graph(5),path_graph(3))) ''' - return GiacMethods['highlight_subgraph'](self,*args) + return GiacMethods['highlight_subgraph'](self, *args) - def highlight_trail(self,*args): + def highlight_trail(self, *args): r'''From Giac's documentation: Help for highlight_trail: highlight_trail(Graph(G),Trail(t)||Lst(T),[Color(c)||Lst(C)]) @@ -6655,9 +6655,9 @@ cdef class GiacMethods_base: See also: 1/ highlight_edges 2/ highlight_subgraph 3/ highlight_vertex Ex1: draw_graph(highlight_trail(cycle_graph(5),trail(1,2,3),green) ''' - return GiacMethods['highlight_trail'](self,*args) + return GiacMethods['highlight_trail'](self, *args) - def highlight_vertex(self,*args): + def highlight_vertex(self, *args): r'''From Giac's documentation: Help for highlight_vertex: highlight_vertex(Graph(G),Vrtx(v)||Lst(V),[Color(c)||Lst(C)]) @@ -6665,9 +6665,9 @@ cdef class GiacMethods_base: See also: 1/ highlight_edges 2/ highlight_subgraph 3/ highlight_trail Ex1: draw_graph(highlight_vertex(cycle_graph(3),1)) ''' - return GiacMethods['highlight_vertex'](self,*args) + return GiacMethods['highlight_vertex'](self, *args) - def highpass(self,*args): + def highpass(self, *args): r'''From Giac's documentation: Help for highpass: highpass(Lst(s),Real(c),[Intg(samplerate)]) @@ -6675,9 +6675,9 @@ cdef class GiacMethods_base: See also: 1/ lowpass 2/ moving_average Ex1: f:=unapply(periodic(sign(x),x,-1/880,1/880),x):;s:=createwav(apply(f,soundsec(1))):;playsnd(highpass(s,5000)) ''' - return GiacMethods['highpass'](self,*args) + return GiacMethods['highpass'](self, *args) - def hilbert(self,*args): + def hilbert(self, *args): r'''From Giac's documentation: Help for hilbert: hilbert(Intg(n)) @@ -6685,9 +6685,9 @@ cdef class GiacMethods_base: See also: 1/ Ex1:hilbert(4) ''' - return GiacMethods['hilbert'](self,*args) + return GiacMethods['hilbert'](self, *args) - def histogram(self,*args): + def histogram(self, *args): r'''From Giac's documentation: Help for histogram: histogram(Lst(data),[Lst(eff) || Intg(nc) || Real(classmin)],[Real(classsize)]) @@ -6702,9 +6702,9 @@ cdef class GiacMethods_base: Ex7:histogram(seq(rand(1000),k,0,100),0,100) Ex8:histogram(seq(rand(1000),k,0,100),10) ''' - return GiacMethods['histogram'](self,*args) + return GiacMethods['histogram'](self, *args) - def hold(self,*args): + def hold(self, *args): r'''From Giac's documentation: Help for hold: hold(Expr) @@ -6714,9 +6714,9 @@ cdef class GiacMethods_base: Ex2:hold(1/x+1/(x-1)) Ex3:hold((x+1)*(x-1)) ''' - return GiacMethods['hold'](self,*args) + return GiacMethods['hold'](self, *args) - def homogeneize(self,*args): + def homogeneize(self, *args): r'''From Giac's documentation: Help for homogeneize: homogeneize(Expr(P),[Var(t)]) @@ -6724,9 +6724,9 @@ cdef class GiacMethods_base: Ex1:homogeneize(x^2-1) Ex2:homogeneize(x^2-y,z) ''' - return GiacMethods['homogeneize'](self,*args) + return GiacMethods['homogeneize'](self, *args) - def homothety(self,*args): + def homothety(self, *args): r'''From Giac's documentation: Help for homothety: homothety(Pnt(C),Real(k),Pnt(A)) @@ -6737,9 +6737,9 @@ cdef class GiacMethods_base: Ex3: h:=homothety(1+i,1/3);h(i) Ex4: h:=homothety(point(1,1,1),1/3);h(point(0,1,0)) ''' - return GiacMethods['homothety'](self,*args) + return GiacMethods['homothety'](self, *args) - def horner(self,*args): + def horner(self, *args): r'''From Giac's documentation: Help for horner: horner(Poly(P),Real(a)) @@ -6750,9 +6750,9 @@ cdef class GiacMethods_base: Ex3:horner(x^2+y*x+y^3-1,2,y) Ex4: X:=[0.0,1.0,2.0]; A:=lagrange(X,exp,lagrange); horner(A,X,1.5); ''' - return GiacMethods['horner'](self,*args) + return GiacMethods['horner'](self, *args) - def hybrid_solver(self,*args): + def hybrid_solver(self, *args): r'''From Giac's documentation: Help for hybrid_solver: hybrid_solver(Opt) @@ -6765,9 +6765,9 @@ cdef class GiacMethods_base: Ex5: fsolve([x^2+y-2,x+y^2-2],[x,y],[2,2],hybridsj_solver) Ex6: fsolve([x^2+y-2,x+y^2-2],[x,y],[2,2],newtonj_solver) ''' - return GiacMethods['hybrid_solver'](self,*args) + return GiacMethods['hybrid_solver'](self, *args) - def hybridj_solver(self,*args): + def hybridj_solver(self, *args): r'''From Giac's documentation: Help for hybridj_solver: hybridj_solver(Opt) @@ -6780,9 +6780,9 @@ cdef class GiacMethods_base: Ex5: fsolve([x^2+y-2,x+y^2-2],[x,y],[2,2],hybridsj_solver) Ex6: fsolve([x^2+y-2,x+y^2-2],[x,y],[2,2],newtonj_solver) ''' - return GiacMethods['hybridj_solver'](self,*args) + return GiacMethods['hybridj_solver'](self, *args) - def hybrids_solver(self,*args): + def hybrids_solver(self, *args): r'''From Giac's documentation: Help for hybrids_solver: hybrids_solver(Opt) @@ -6795,9 +6795,9 @@ cdef class GiacMethods_base: Ex5: fsolve([x^2+y-2,x+y^2-2],[x,y],[2,2],hybridsj_solver) Ex6: fsolve([x^2+y-2,x+y^2-2],[x,y],[2,2],newtonj_solver) ''' - return GiacMethods['hybrids_solver'](self,*args) + return GiacMethods['hybrids_solver'](self, *args) - def hybridsj_solver(self,*args): + def hybridsj_solver(self, *args): r'''From Giac's documentation: Help for hybridsj_solver: hybridsj_solver(Opt) @@ -6810,9 +6810,9 @@ cdef class GiacMethods_base: Ex5: fsolve([x^2+y-2,x+y^2-2],[x,y],[2,2],hybridsj_solver) Ex6: fsolve([x^2+y-2,x+y^2-2],[x,y],[2,2],newtonj_solver) ''' - return GiacMethods['hybridsj_solver'](self,*args) + return GiacMethods['hybridsj_solver'](self, *args) - def hyp2exp(self,*args): + def hyp2exp(self, *args): r'''From Giac's documentation: Help for hyp2exp: hyp2exp(ExprHyperb) @@ -6820,9 +6820,9 @@ cdef class GiacMethods_base: See also: 1/ halftan_hyp2exp Ex1:hyp2exp(cosh(x)) ''' - return GiacMethods['hyp2exp'](self,*args) + return GiacMethods['hyp2exp'](self, *args) - def hyperbola(self,*args): + def hyperbola(self, *args): r'''From Giac's documentation: Help for hyperbola: hyperbola(Focus(F1),Focus(F2),(Pnt(M) or Real(a))) @@ -6833,9 +6833,9 @@ cdef class GiacMethods_base: Ex3:hyperbola(point(-1,0,0),point(1,0,0),point(1,1,1)) Ex4:hyperbola(x^2-y^2+y+2) ''' - return GiacMethods['hyperbola'](self,*args) + return GiacMethods['hyperbola'](self, *args) - def hypercube_graph(self,*args): + def hypercube_graph(self, *args): r'''From Giac's documentation: Help for hypercube_graph: hypercube_graph(Intg(n)) @@ -6843,9 +6843,9 @@ cdef class GiacMethods_base: See also: 1/ graph Ex1:hypercube_graph(3) ''' - return GiacMethods['hypercube_graph'](self,*args) + return GiacMethods['hypercube_graph'](self, *args) - def iPart(self,*args): + def iPart(self, *args): r'''From Giac's documentation: Help for iPart: iPart(Real||LstReal) @@ -6855,9 +6855,9 @@ cdef class GiacMethods_base: Ex2:iPart(sqrt(2)) Ex3:iPart(4.3,sqrt(2)) ''' - return GiacMethods['iPart'](self,*args) + return GiacMethods['iPart'](self, *args) - def iabcuv(self,*args): + def iabcuv(self, *args): r'''From Giac's documentation: Help for iabcuv: iabcuv(Intg(a),Intg(b),Intg(c)) @@ -6867,9 +6867,9 @@ cdef class GiacMethods_base: Ex2:iabcuv(21,28,14) Ex3:iabcuv(21,28,1) ''' - return GiacMethods['iabcuv'](self,*args) + return GiacMethods['iabcuv'](self, *args) - def ibasis(self,*args): + def ibasis(self, *args): r'''From Giac's documentation: Help for ibasis: ibasis(Lst(Vect,..,Vect),Lst(Vect,..,Vect)) @@ -6877,9 +6877,9 @@ cdef class GiacMethods_base: See also: 1/ basis Ex1:ibasis([[1,0,0],[0,1,0]],[[1,1,1],[0,0,1]]) ''' - return GiacMethods['ibasis'](self,*args) + return GiacMethods['ibasis'](self, *args) - def ibpdv(self,*args): + def ibpdv(self, *args): r'''From Giac's documentation: Help for ibpdv: ibpdv(Expr(f(x)),Expr(v(x)),[Var(x)],[Real(a)],[Real(b)]) @@ -6891,9 +6891,9 @@ cdef class GiacMethods_base: Ex4:ibpdv([x*ln(x),-1],0) Ex5:ibpdv(ibpdv(ln(x),x,x,2,3),0,x,2,3) ''' - return GiacMethods['ibpdv'](self,*args) + return GiacMethods['ibpdv'](self, *args) - def ibpu(self,*args): + def ibpu(self, *args): r'''From Giac's documentation: Help for ibpu: ibpu(Expr(f(x)),Expr(u(x)),[Var(x)],[Real(a)],[Real(b)]) @@ -6905,9 +6905,9 @@ cdef class GiacMethods_base: Ex4:ibpu([x*ln(x),-1],0) Ex5:ibpu(ibpu(ln(x),ln(x),x,2,3),0,x,2,3) ''' - return GiacMethods['ibpu'](self,*args) + return GiacMethods['ibpu'](self, *args) - def icdf(self,*args): + def icdf(self, *args): r'''From Giac's documentation: Help for icdf: icdf(Func,FuncParams) @@ -6916,9 +6916,9 @@ cdef class GiacMethods_base: Ex1:icdf(binomial,10,0.5,0.6) Ex2:icdf(normald,0.0,1.0,0.975) ''' - return GiacMethods['icdf'](self,*args) + return GiacMethods['icdf'](self, *args) - def ichinrem(self,*args): + def ichinrem(self, *args): r'''From Giac's documentation: Help for ichinrem: ichinrem(LstIntg(a,p),LstIntg(b,q)) @@ -6929,9 +6929,9 @@ cdef class GiacMethods_base: Ex3:ichinrem([2%7,3%5,1%9]) Ex4:ichinrem([(x+1)%2,(x+2)%3,(3*x-1)%5]) ''' - return GiacMethods['ichinrem'](self,*args) + return GiacMethods['ichinrem'](self, *args) - def ichrem(self,*args): + def ichrem(self, *args): r'''From Giac's documentation: Help for ichrem: ichrem(LstIntg(a,p),LstIntg(b,q)) @@ -6942,9 +6942,9 @@ cdef class GiacMethods_base: Ex3:ichrem([2%7,3%5,1%9]) Ex4:ichrem([(x+1)%2,(x+2)%3,(3*x-1)%5]) ''' - return GiacMethods['ichrem'](self,*args) + return GiacMethods['ichrem'](self, *args) - def icomp(self,*args): + def icomp(self, *args): r'''From Giac's documentation: Help for icomp: icomp(Intg(n),Intg(k),[zeros=true||false]) @@ -6953,9 +6953,9 @@ cdef class GiacMethods_base: Ex1:icomp(4,2) Ex2:icomp(6,3,zeros=false) ''' - return GiacMethods['icomp'](self,*args) + return GiacMethods['icomp'](self, *args) - def icontent(self,*args): + def icontent(self, *args): r'''From Giac's documentation: Help for icontent: icontent(Poly,[Var]) @@ -6964,9 +6964,9 @@ cdef class GiacMethods_base: Ex1:icontent(24x^3+6x^2-12x+18) Ex2:icontent(24t^3+6t^2-12t+18,t) ''' - return GiacMethods['icontent'](self,*args) + return GiacMethods['icontent'](self, *args) - def icosahedron(self,*args): + def icosahedron(self, *args): r'''From Giac's documentation: Help for icosahedron: icosahedron(Pnt(A),Pnt(B),Pnt(C)) @@ -6975,9 +6975,9 @@ cdef class GiacMethods_base: Ex1:icosahedron([0,0,0],[sqrt(5),0,0],[1,2,0]) Ex2:icosahedron(evalf([0,0,0],[3,2,4],[1,1,0])) ''' - return GiacMethods['icosahedron'](self,*args) + return GiacMethods['icosahedron'](self, *args) - def id(self,*args): + def id(self, *args): r'''From Giac's documentation: Help for id: id(Seq) @@ -6985,9 +6985,9 @@ cdef class GiacMethods_base: See also: 1/ sq 2/ sqrt Ex1:id(1,2,3) ''' - return GiacMethods['id'](self,*args) + return GiacMethods['id'](self, *args) - def identity(self,*args): + def identity(self, *args): r'''From Giac's documentation: Help for identity: identity(Intg(n)) @@ -6996,9 +6996,9 @@ cdef class GiacMethods_base: Ex1:identity(3) Ex2:identity(5) ''' - return GiacMethods['identity'](self,*args) + return GiacMethods['identity'](self, *args) - def idivis(self,*args): + def idivis(self, *args): r'''From Giac's documentation: Help for idivis: idivis(Intg(a) or LstIntg) @@ -7007,9 +7007,9 @@ cdef class GiacMethods_base: Ex1:idivis(36) Ex2:idivis([36,49]) ''' - return GiacMethods['idivis'](self,*args) + return GiacMethods['idivis'](self, *args) - def idn(self,*args): + def idn(self, *args): r'''From Giac's documentation: Help for idn: idn(Intg(n)) @@ -7018,9 +7018,9 @@ cdef class GiacMethods_base: Ex1:idn(3) Ex2:idn(5) ''' - return GiacMethods['idn'](self,*args) + return GiacMethods['idn'](self, *args) - def iegcd(self,*args): + def iegcd(self, *args): r'''From Giac's documentation: Help for iegcd: iegcd(Intg,Intg) @@ -7030,9 +7030,9 @@ cdef class GiacMethods_base: Ex2:iegcd(21,28) Ex3:iegcd(30,49) ''' - return GiacMethods['iegcd'](self,*args) + return GiacMethods['iegcd'](self, *args) - def ifactor(self,*args): + def ifactor(self, *args): r'''From Giac's documentation: Help for ifactor: ifactor(Intg(a)) @@ -7041,9 +7041,9 @@ cdef class GiacMethods_base: Ex1:ifactor(50) Ex2:ifactor(123456789) ''' - return GiacMethods['ifactor'](self,*args) + return GiacMethods['ifactor'](self, *args) - def ifactors(self,*args): + def ifactors(self, *args): r'''From Giac's documentation: Help for ifactors: ifactors(Intg(a) or LstIntg) @@ -7052,9 +7052,9 @@ cdef class GiacMethods_base: Ex1:ifactors(36) Ex2:ifactors([36,52]) ''' - return GiacMethods['ifactors'](self,*args) + return GiacMethods['ifactors'](self, *args) - def ifourier(self,*args): + def ifourier(self, *args): r'''From Giac's documentation: Help for ifourier: ifourier(Expr(F(s)),[Var(s),[Var(x)]]) @@ -7068,9 +7068,9 @@ cdef class GiacMethods_base: Ex6:ifourier(fourier(exp(-abs(x)),x,s)^2,s,x) Ex7:ifourier(sinc(s),s,x) ''' - return GiacMethods['ifourier'](self,*args) + return GiacMethods['ifourier'](self, *args) - def igamma(self,*args): + def igamma(self, *args): r'''From Giac's documentation: Help for igamma: igamma(Real(a),Real(x),[1]) @@ -7080,9 +7080,9 @@ cdef class GiacMethods_base: Ex2:igamma(-5.1,2.1) Ex3:igamma(5.0,2.0,1) ''' - return GiacMethods['igamma'](self,*args) + return GiacMethods['igamma'](self, *args) - def igcd(self,*args): + def igcd(self, *args): r'''From Giac's documentation: Help for igcd: igcd((Intg(a) or Poly),(Intg(b) or Poly)) @@ -7094,9 +7094,9 @@ cdef class GiacMethods_base: Ex4:igcd(t^2-2*t+1,t^2+t-2) Ex5:igcd((x^2-1)*(y^2-1)*z^2,x^3*y^3*z+(-(y^3))*z+x^3*z-z) ''' - return GiacMethods['igcd'](self,*args) + return GiacMethods['igcd'](self, *args) - def igcdex(self,*args): + def igcdex(self, *args): r'''From Giac's documentation: Help for igcdex: igcdex(Intg,Intg) @@ -7106,9 +7106,9 @@ cdef class GiacMethods_base: Ex2:igcdex(21,28) Ex3:igcdex(30,49) ''' - return GiacMethods['igcdex'](self,*args) + return GiacMethods['igcdex'](self, *args) - def ihermite(self,*args): + def ihermite(self, *args): r'''From Giac's documentation: Help for ihermite: ihermite(Mtrx(A)) @@ -7117,9 +7117,9 @@ cdef class GiacMethods_base: Ex1:ihermite([[9,-36,30], [-36,192,-180], [30,-180,180]]) Ex2:ihermite([[1,2,3],[4,5,6],[7,8,9]]) ''' - return GiacMethods['ihermite'](self,*args) + return GiacMethods['ihermite'](self, *args) - def ilaplace(self,*args): + def ilaplace(self, *args): r'''From Giac's documentation: Help for ilaplace: ilaplace(Expr,[Var],[IlapVar]) @@ -7129,9 +7129,9 @@ cdef class GiacMethods_base: Ex2:ilaplace(s/(s^4-1),s,x) Ex3:ilaplace(exp(-s)/s,s,x) ''' - return GiacMethods['ilaplace'](self,*args) + return GiacMethods['ilaplace'](self, *args) - def im(self,*args): + def im(self, *args): r'''From Giac's documentation: Help for im: im(Cplx) @@ -7141,9 +7141,9 @@ cdef class GiacMethods_base: Ex2:im((1+2*i)^2) Ex3:im([1+2*i,(1+2*i)^2]) ''' - return GiacMethods['im'](self,*args) + return GiacMethods['im'](self, *args) - def imag(self,*args): + def imag(self, *args): r'''From Giac's documentation: Help for imag: imag(Cplx) @@ -7153,9 +7153,9 @@ cdef class GiacMethods_base: Ex2:imag((1+2*i)^2) Ex3:imag([1+2*i,(1+2*i)^2]) ''' - return GiacMethods['imag'](self,*args) + return GiacMethods['imag'](self, *args) - def image(self,*args): + def image(self, *args): r'''From Giac's documentation: Help for image: image(Mtrx(M)) @@ -7164,9 +7164,9 @@ cdef class GiacMethods_base: Ex1:image([[1,2],[3,6]]) Ex2:image([[1,2,3],[1,3,6],[2,5,9]]) ''' - return GiacMethods['image'](self,*args) + return GiacMethods['image'](self, *args) - def implicitdiff(self,*args): + def implicitdiff(self, *args): r'''From Giac's documentation: Help for implicitdiff: implicitdiff(constr,[depvars],y,diffvars) @@ -7191,9 +7191,9 @@ cdef class GiacMethods_base: Ex17:implicitdiff(x*y*z,-2x^3+15x^2*y+11y^3-24y=0,[x,z,y],order=2,[1,-1,0]) Ex18: pd:=implicitdiff(x*y*z,-2x^3+15x^2*y+11y^3-24y=0,[x,z,y],order=4,[0,z,0]);pd[4,0,0] ''' - return GiacMethods['implicitdiff'](self,*args) + return GiacMethods['implicitdiff'](self, *args) - def implicitplot(self,*args): + def implicitplot(self, *args): r'''From Giac's documentation: Help for implicitplot: implicitplot(Expr,Var1,Var2) @@ -7209,18 +7209,18 @@ cdef class GiacMethods_base: Ex8:implicitplot((x+5)^2+(y+4)^2-1,x=-6..-4,y=-5..-3) Ex9:implicitplot((x+5)^2+(y+4)^2-1,[x=-6..-4,y=-5..-3]) ''' - return GiacMethods['implicitplot'](self,*args) + return GiacMethods['implicitplot'](self, *args) - def import_graph(self,*args): + def import_graph(self, *args): r'''From Giac's documentation: Help for import_graph: import_graph(Str("path/to/graphname[.dot]")) Returns the graph constructed from instructions in the file 'path/to/graphname.dot' (in dot format), or "undef" on failure. Ex1:import_graph("K5.dot") ''' - return GiacMethods['import_graph'](self,*args) + return GiacMethods['import_graph'](self, *args) - def inString(self,*args): + def inString(self, *args): r'''From Giac's documentation: Help for inString: inString(Str(l),Elem(e)) @@ -7229,9 +7229,9 @@ cdef class GiacMethods_base: Ex1:inString("abcd","b") Ex2:inString("abcd","e") ''' - return GiacMethods['inString'](self,*args) + return GiacMethods['inString'](self, *args) - def in_ideal(self,*args): + def in_ideal(self, *args): r'''From Giac's documentation: Help for in_ideal: in_ideal(Poly,Lst,LstVar,[order]) @@ -7240,9 +7240,9 @@ cdef class GiacMethods_base: Ex1:in_ideal((x+y)^2,[y^2,x^2+2*x*y],[x,y]) Ex2:in_ideal(x+y,[y^2,x^2+2*x*y],[x,y]) ''' - return GiacMethods['in_ideal'](self,*args) + return GiacMethods['in_ideal'](self, *args) - def incidence_matrix(self,*args): + def incidence_matrix(self, *args): r'''From Giac's documentation: Help for incidence_matrix: incidence_matrix(Graph(G)) @@ -7250,9 +7250,9 @@ cdef class GiacMethods_base: See also: 1/ incident_edges Ex1:incidence_matrix(graph("tetrahedron")) ''' - return GiacMethods['incidence_matrix'](self,*args) + return GiacMethods['incidence_matrix'](self, *args) - def incident_edges(self,*args): + def incident_edges(self, *args): r'''From Giac's documentation: Help for incident_edges: incident_edges(Graph(G),Vrtx(v)) @@ -7260,9 +7260,9 @@ cdef class GiacMethods_base: See also: 1/ adjacency_matrix 2/ vertex_degree 3/ incidence_matrix 4/ neighbors Ex1:incident_edges(cycle_graph(8),[1,5,7]) ''' - return GiacMethods['incident_edges'](self,*args) + return GiacMethods['incident_edges'](self, *args) - def incircle(self,*args): + def incircle(self, *args): r'''From Giac's documentation: Help for incircle: incircle((Pnt or Cplx),(Pnt or Cplx),(Pnt or Cplx)) @@ -7270,9 +7270,9 @@ cdef class GiacMethods_base: See also: 1/ excircle 2/ circumcircle Ex1:incircle(0,1,1+i) ''' - return GiacMethods['incircle'](self,*args) + return GiacMethods['incircle'](self, *args) - def increasing_power(self,*args): + def increasing_power(self, *args): r'''From Giac's documentation: Help for increasing_power: increasing_power(:=Intg(0 or 1)) @@ -7281,9 +7281,9 @@ cdef class GiacMethods_base: Ex1: increasing_power:=1 Ex2: increasing_power:=0 ''' - return GiacMethods['increasing_power'](self,*args) + return GiacMethods['increasing_power'](self, *args) - def independence_number(self,*args): + def independence_number(self, *args): r'''From Giac's documentation: Help for independence_number: independence_number(Graph(G)) @@ -7291,9 +7291,9 @@ cdef class GiacMethods_base: See also: 1/ clique_number 2/ graph_complement 3/ maximum_clique 4/ maximum_independent_set Ex1:independence_number(complete_graph(3,4)) ''' - return GiacMethods['independence_number'](self,*args) + return GiacMethods['independence_number'](self, *args) - def indets(self,*args): + def indets(self, *args): r'''From Giac's documentation: Help for indets: indets(Expr) @@ -7301,9 +7301,9 @@ cdef class GiacMethods_base: See also: 1/ has 2/ lvar Ex1:indets(exp(x)*2*sin(y)) ''' - return GiacMethods['indets'](self,*args) + return GiacMethods['indets'](self, *args) - def index(self,*args): + def index(self, *args): r'''From Giac's documentation: Help for index: index(Vect,Expr) @@ -7314,9 +7314,9 @@ cdef class GiacMethods_base: Ex3:index(%{4,3,1,2%},1) Ex4:index("abracadabrant","c") ''' - return GiacMethods['index'](self,*args) + return GiacMethods['index'](self, *args) - def induced_subgraph(self,*args): + def induced_subgraph(self, *args): r'''From Giac's documentation: Help for induced_subgraph: induced_subgraph(Graph(G),Lst(V)) @@ -7324,9 +7324,9 @@ cdef class GiacMethods_base: See also: 1/ subgraph Ex1:induced_subgraph(cycle_graph(6),[1,2,6]) ''' - return GiacMethods['induced_subgraph'](self,*args) + return GiacMethods['induced_subgraph'](self, *args) - def inequationplot(self,*args): + def inequationplot(self, *args): r'''From Giac's documentation: Help for inequationplot: inequationplot(Expr,[x=xrange,y=yrange],[xstep],[ystep]) @@ -7337,27 +7337,27 @@ cdef class GiacMethods_base: Ex3:inequationplot(3-(x^2-y^2),[x=-2..2,y=-2..2],xstep=0.1,ystep=0.1) Ex4:inequationplot([x+y>3,x^2ifte(x<5,"A","B"),1,10) ''' - return GiacMethods['makelist'](self,*args) + return GiacMethods['makelist'](self, *args) - def makemat(self,*args): + def makemat(self, *args): r'''From Giac's documentation: Help for makemat: makemat(Fnct(f),RowsNumb,ColsNumb) @@ -9669,9 +9669,9 @@ cdef class GiacMethods_base: Ex2:makemat((j,k)->1/(j+k+1),2,3) Ex3:makemat(sqrt(2),2,3) ''' - return GiacMethods['makemat'](self,*args) + return GiacMethods['makemat'](self, *args) - def makesuite(self,*args): + def makesuite(self, *args): r'''From Giac's documentation: Help for makesuite: makesuite(Vect||Lst) @@ -9679,9 +9679,9 @@ cdef class GiacMethods_base: See also: 1/ makevector 2/ op Ex1:makesuite([1,2,3]) ''' - return GiacMethods['makesuite'](self,*args) + return GiacMethods['makesuite'](self, *args) - def makevector(self,*args): + def makevector(self, *args): r'''From Giac's documentation: Help for makevector: makevector(Seq) @@ -9689,9 +9689,9 @@ cdef class GiacMethods_base: See also: 1/ makesuite Ex1:makevector(1,2,3) ''' - return GiacMethods['makevector'](self,*args) + return GiacMethods['makevector'](self, *args) - def map(self,*args): + def map(self, *args): r'''From Giac's documentation: Help for map: map(Lst(l),Fnc(f)) @@ -9701,27 +9701,27 @@ cdef class GiacMethods_base: Ex2:map([1,2,3],unapply(x^3,x)) Ex3:map(%%%{1,[2,0]%%%}+%%%{2,[1,1]%%%},(a,b,c)->a*(b+2*c)) ''' - return GiacMethods['map'](self,*args) + return GiacMethods['map'](self, *args) - def maple2mupad(self,*args): + def maple2mupad(self, *args): r'''From Giac's documentation: Help for maple2mupad: maple2mupad(Str("Name_Maplefile"),Str("Name_Mupadfile")) maple2mupad("file1","file2") translates file1(Maple) to file2(MuPAD). See also: 1/ maple2xcas ''' - return GiacMethods['maple2mupad'](self,*args) + return GiacMethods['maple2mupad'](self, *args) - def maple2xcas(self,*args): + def maple2xcas(self, *args): r'''From Giac's documentation: Help for maple2xcas: maple2xcas(Str("NameMapleFile"),Str("NameXcasFile")) maple2xcas("file1","file2") translates file1(Maple) to file2(Xcas). See also: 1/ maple2mupad ''' - return GiacMethods['maple2xcas'](self,*args) + return GiacMethods['maple2xcas'](self, *args) - def maple_ifactors(self,*args): + def maple_ifactors(self, *args): r'''From Giac's documentation: Help for maple_ifactors: maple_ifactors(Intg(n)) @@ -9729,9 +9729,9 @@ cdef class GiacMethods_base: See also: 1/ ifactors Ex1:maple_ifactors(120) ''' - return GiacMethods['maple_ifactors'](self,*args) + return GiacMethods['maple_ifactors'](self, *args) - def maple_mode(self,*args): + def maple_mode(self, *args): r'''From Giac's documentation: Help for maple_mode: maple_mode(Intg(0) or 1 or 2 or 3) @@ -9740,9 +9740,9 @@ cdef class GiacMethods_base: Ex1:maple_mode(1) Ex2:maple_mode(0) ''' - return GiacMethods['maple_mode'](self,*args) + return GiacMethods['maple_mode'](self, *args) - def markov(self,*args): + def markov(self, *args): r'''From Giac's documentation: Help for markov: markov(Mtrx(M),[Real(eps)]) @@ -9750,9 +9750,9 @@ cdef class GiacMethods_base: See also: 1/ randmarkov 2/ plotproba Ex1:markov([[0,0,1/2,0,1/2],[0,0,1,0,0],[1/4,1/4,0,1/4,1/4],[0,0,1/2,0,1/2],[0,0,0,0,1]]) ''' - return GiacMethods['markov'](self,*args) + return GiacMethods['markov'](self, *args) - def mat2list(self,*args): + def mat2list(self, *args): r'''From Giac's documentation: Help for mat2list: mat2list(Mtrx) @@ -9760,9 +9760,9 @@ cdef class GiacMethods_base: See also: 1/ list2mat 2/ flatten Ex1:mat2list([[1,8],[4,9]]) ''' - return GiacMethods['mat2list'](self,*args) + return GiacMethods['mat2list'](self, *args) - def mathml(self,*args): + def mathml(self, *args): r'''From Giac's documentation: Help for mathml: mathml(Expr) @@ -9770,9 +9770,9 @@ cdef class GiacMethods_base: See also: 1/ export_mathml 2/ latex Ex1:mathml(1/2) ''' - return GiacMethods['mathml'](self,*args) + return GiacMethods['mathml'](self, *args) - def matpow(self,*args): + def matpow(self, *args): r'''From Giac's documentation: Help for matpow: matpow(Mtrx,Intg(n)) @@ -9780,9 +9780,9 @@ cdef class GiacMethods_base: See also: 1/ &^ 2/ ^ Ex1:matpow([[1,2],[3,4]],n) ''' - return GiacMethods['matpow'](self,*args) + return GiacMethods['matpow'](self, *args) - def matrix(self,*args): + def matrix(self, *args): r'''From Giac's documentation: Help for matrix: matrix(Intg(p),Intg(q),(Fnc(f) or Val(a))) @@ -9793,9 +9793,9 @@ cdef class GiacMethods_base: Ex3:matrix(2,3,4) Ex4: A[0..2,0..2]:=1;A[0..1,1..2]:=2;a:=matrix(A) ''' - return GiacMethods['matrix'](self,*args) + return GiacMethods['matrix'](self, *args) - def matrix_norm(self,*args): + def matrix_norm(self, *args): r'''From Giac's documentation: Help for matrix_norm: matrix_norm(Mtrx,[2]||[inf]) @@ -9806,9 +9806,9 @@ cdef class GiacMethods_base: Ex3:matrix_norm([[1,2,3],[3,-9,6],[4,5,6]],2) Ex4:matrix_norm([[1,2,3],[3,-9,6],[4,5,6]],inf) ''' - return GiacMethods['matrix_norm'](self,*args) + return GiacMethods['matrix_norm'](self, *args) - def max(self,*args): + def max(self, *args): r'''From Giac's documentation: Help for max: max(Seq||Lst) @@ -9816,9 +9816,9 @@ cdef class GiacMethods_base: See also: 1/ min Ex1:max(25,35) ''' - return GiacMethods['max'](self,*args) + return GiacMethods['max'](self, *args) - def maxflow(self,*args): + def maxflow(self, *args): r'''From Giac's documentation: Help for maxflow: maxflow(Graph(G),Vrtx(s),Vrtx(t)) @@ -9826,9 +9826,9 @@ cdef class GiacMethods_base: See also: 1/ minimum_cut Ex1:maxflow(digraph(%{[[1,2],2],[[2,3],4],[[3,4],3],[[1,5],3],[[5,2],1],[[5,4],2]%}),1,4) ''' - return GiacMethods['maxflow'](self,*args) + return GiacMethods['maxflow'](self, *args) - def maximal_independent_set(self,*args): + def maximal_independent_set(self, *args): r'''From Giac's documentation: Help for maximal_independent_set: maximal_independent_set(Graph(G)) @@ -9836,9 +9836,9 @@ cdef class GiacMethods_base: See also: 1/ maximum_independent_set Ex1:maximal_independent_set(graph("petersen")) ''' - return GiacMethods['maximal_independent_set'](self,*args) + return GiacMethods['maximal_independent_set'](self, *args) - def maximize(self,*args): + def maximize(self, *args): r'''From Giac's documentation: Help for maximize: maximize(Expr,[Constr],Vars,[Options]) @@ -9852,9 +9852,9 @@ cdef class GiacMethods_base: Ex7:maximize((1+x^2+3y+5x-4*x*y)/(1+x^2+y^2),x^2/4+y^2/3=9,[x,y]) Ex8:maximize(cos(x)^2+cos(y)^2,x+y=pi/4,[x,y],locus) ''' - return GiacMethods['maximize'](self,*args) + return GiacMethods['maximize'](self, *args) - def maximum_clique(self,*args): + def maximum_clique(self, *args): r'''From Giac's documentation: Help for maximum_clique: maximum_clique(Graph(G)) @@ -9862,9 +9862,9 @@ cdef class GiacMethods_base: See also: 1/ clique_number 2/ is_clique 3/ maximum_independent_set Ex1:maximum_clique(graph_complement(complete_graph(3,4))) ''' - return GiacMethods['maximum_clique'](self,*args) + return GiacMethods['maximum_clique'](self, *args) - def maximum_degree(self,*args): + def maximum_degree(self, *args): r'''From Giac's documentation: Help for maximum_degree: maximum_degree(Graph(G)) @@ -9872,9 +9872,9 @@ cdef class GiacMethods_base: See also: 1/ minimum_degree 2/ vertex_degree Ex1:maximum_degree(digraph(trail(1,2,3,4,5,6,4,7,8,2))) ''' - return GiacMethods['maximum_degree'](self,*args) + return GiacMethods['maximum_degree'](self, *args) - def maximum_independent_set(self,*args): + def maximum_independent_set(self, *args): r'''From Giac's documentation: Help for maximum_independent_set: maximum_independent_set(Graph(G)) @@ -9882,9 +9882,9 @@ cdef class GiacMethods_base: See also: 1/ clique_number 2/ graph_complement 3/ independence_number 4/ maximum_clique Ex1:maximum_independent_set(complete_graph(3,4)) ''' - return GiacMethods['maximum_independent_set'](self,*args) + return GiacMethods['maximum_independent_set'](self, *args) - def maximum_matching(self,*args): + def maximum_matching(self, *args): r'''From Giac's documentation: Help for maximum_matching: maximum_matching(Graph(G)) @@ -9892,9 +9892,9 @@ cdef class GiacMethods_base: See also: 1/ maximum_independent_set Ex1: G:=graph("soccerball"); draw_graph(highlight_edges(G,maximum_matching(G))) ''' - return GiacMethods['maximum_matching'](self,*args) + return GiacMethods['maximum_matching'](self, *args) - def maxnorm(self,*args): + def maxnorm(self, *args): r'''From Giac's documentation: Help for maxnorm: maxnorm(Vect or Mtrx) @@ -9904,9 +9904,9 @@ cdef class GiacMethods_base: Ex2:maxnorm([1,2,3,-4]) Ex3:maxnorm([[1,2],[3,-4]]) ''' - return GiacMethods['maxnorm'](self,*args) + return GiacMethods['maxnorm'](self, *args) - def mean(self,*args): + def mean(self, *args): r'''From Giac's documentation: Help for mean: mean(Lst||Mtrx,[Lst]) @@ -9916,9 +9916,9 @@ cdef class GiacMethods_base: Ex2:mean([1,2,3],[1,2,3]) Ex3:mean([[1,2,3],[1,2,3]]) ''' - return GiacMethods['mean'](self,*args) + return GiacMethods['mean'](self, *args) - def median(self,*args): + def median(self, *args): r'''From Giac's documentation: Help for median: median(Lst||Mtrx,[Lst]) @@ -9927,9 +9927,9 @@ cdef class GiacMethods_base: Ex1:median([1,2,3,5,10,4]) Ex2:median([1,2,3,5,10,4],[1,2,3,1,2,3]) ''' - return GiacMethods['median'](self,*args) + return GiacMethods['median'](self, *args) - def median_line(self,*args): + def median_line(self, *args): r'''From Giac's documentation: Help for median_line: median_line((Pnt or Cplx),(Pnt or Cplx),(Pnt or Cplx)) @@ -9937,9 +9937,9 @@ cdef class GiacMethods_base: See also: 1/ midpoint 2/ perpen_bisector Ex1:median_line(-1,1-i,i) ''' - return GiacMethods['median_line'](self,*args) + return GiacMethods['median_line'](self, *args) - def member(self,*args): + def member(self, *args): r'''From Giac's documentation: Help for member: member(Elem(e),(Lst(l) or Set(l))) @@ -9948,9 +9948,9 @@ cdef class GiacMethods_base: Ex1:member(1,[4,3,1,2]) Ex2:member(1,%{4,3,1,2%}) ''' - return GiacMethods['member'](self,*args) + return GiacMethods['member'](self, *args) - def mgf(self,*args): + def mgf(self, *args): r'''From Giac's documentation: Help for mgf: mgf(Func,[Real(Param_1),Real(Param_2)]) @@ -9959,9 +9959,9 @@ cdef class GiacMethods_base: Ex2:mgf(poisson,5) Ex3:mgf(binomial,n,p) ''' - return GiacMethods['mgf'](self,*args) + return GiacMethods['mgf'](self, *args) - def mid(self,*args): + def mid(self, *args): r'''From Giac's documentation: Help for mid: mid(Lst(l) or Str(l),Intg(d),Intg(n)) @@ -9973,9 +9973,9 @@ cdef class GiacMethods_base: Ex4:mid("azertyuiop",2) Ex5:mid([[1,2],[3,4],[5,6]],1) ''' - return GiacMethods['mid'](self,*args) + return GiacMethods['mid'](self, *args) - def middle_point(self,*args): + def middle_point(self, *args): r'''From Giac's documentation: Help for middle_point: middle_point(Opt) @@ -9988,9 +9988,9 @@ cdef class GiacMethods_base: Ex5: area(x^2,x=0..1,5,middle_point) Ex6: area(x^2,x=0..1,5,trapezoid) ''' - return GiacMethods['middle_point'](self,*args) + return GiacMethods['middle_point'](self, *args) - def midpoint(self,*args): + def midpoint(self, *args): r'''From Giac's documentation: Help for midpoint: midpoint((Pnt or Cplx),(Pnt or Cplx)) @@ -9998,9 +9998,9 @@ cdef class GiacMethods_base: See also: 1/ median_line 2/ perpen_bisector Ex1:midpoint(-2,2i) ''' - return GiacMethods['midpoint'](self,*args) + return GiacMethods['midpoint'](self, *args) - def min(self,*args): + def min(self, *args): r'''From Giac's documentation: Help for min: min(Seq||Lst) @@ -10008,9 +10008,9 @@ cdef class GiacMethods_base: See also: 1/ max Ex1:min(25,35) ''' - return GiacMethods['min'](self,*args) + return GiacMethods['min'](self, *args) - def minimal_edge_coloring(self,*args): + def minimal_edge_coloring(self, *args): r'''From Giac's documentation: Help for minimal_edge_coloring: minimal_edge_coloring(Graph(G),[sto]) @@ -10019,9 +10019,9 @@ cdef class GiacMethods_base: Ex1:minimal_edge_coloring(graph("petersen")) Ex2: G:=minimal_edge_coloring(graph("dodecahedron"),sto); draw_graph(G) ''' - return GiacMethods['minimal_edge_coloring'](self,*args) + return GiacMethods['minimal_edge_coloring'](self, *args) - def minimal_spanning_tree(self,*args): + def minimal_spanning_tree(self, *args): r'''From Giac's documentation: Help for minimal_spanning_tree: minimal_spanning_tree(Graph(G)) @@ -10029,9 +10029,9 @@ cdef class GiacMethods_base: See also: 1/ spanning_tree Ex1:minimal_spanning_tree(graph([[0,1,0,4,0,0],[1,0,1,0,4,0],[0,1,0,3,0,1],[4,0,3,0,1,0],[0,4,0,1,0,4],[0,0,1,0,4,0]])) ''' - return GiacMethods['minimal_spanning_tree'](self,*args) + return GiacMethods['minimal_spanning_tree'](self, *args) - def minimal_vertex_coloring(self,*args): + def minimal_vertex_coloring(self, *args): r'''From Giac's documentation: Help for minimal_vertex_coloring: minimal_vertex_coloring(Graph(G),[sto]) @@ -10040,9 +10040,9 @@ cdef class GiacMethods_base: Ex1:minimal_vertex_coloring(graph("petersen")) Ex2: draw_graph(minimal_vertex_coloring(graph("petersen"),sto)) ''' - return GiacMethods['minimal_vertex_coloring'](self,*args) + return GiacMethods['minimal_vertex_coloring'](self, *args) - def minimax(self,*args): + def minimax(self, *args): r'''From Giac's documentation: Help for minimax: minimax(Expr,Var=a..b,n,[Options]) @@ -10058,9 +10058,9 @@ cdef class GiacMethods_base: Ex9:minimax(min(1/cosh(3*sin(x)),sin(9x/10)),x=-3..4,30) Ex10:minimax(when(x==0,0,exp(-1/x^2)),x=-1..1,25) ''' - return GiacMethods['minimax'](self,*args) + return GiacMethods['minimax'](self, *args) - def minimize(self,*args): + def minimize(self, *args): r'''From Giac's documentation: Help for minimize: minimize(Expr,[Constr],Vars,[Options]) @@ -10074,9 +10074,9 @@ cdef class GiacMethods_base: Ex7:minimize((1+x^2+3y+5x-4*x*y)/(1+x^2+y^2),x^2/4+y^2/3=9,[x,y]) Ex8:minimize(cos(x)^2+cos(y)^2,x+y=pi/4,[x,y],locus) ''' - return GiacMethods['minimize'](self,*args) + return GiacMethods['minimize'](self, *args) - def minimum_cut(self,*args): + def minimum_cut(self, *args): r'''From Giac's documentation: Help for minimum_cut: minimum_cut(Graph(G),Vrtx(s),Vrtx(t)) @@ -10084,9 +10084,9 @@ cdef class GiacMethods_base: See also: 1/ maxflow Ex1:minimum_cut(digraph(%{[[1,2],2],[[2,3],4],[[3,4],3],[[1,5],3],[[5,2],1],[[5,4],2]%}),1,4) ''' - return GiacMethods['minimum_cut'](self,*args) + return GiacMethods['minimum_cut'](self, *args) - def minimum_degree(self,*args): + def minimum_degree(self, *args): r'''From Giac's documentation: Help for minimum_degree: minimum_degree(Graph(G)) @@ -10094,9 +10094,9 @@ cdef class GiacMethods_base: See also: 1/ maximum_degree 2/ vertex_degree Ex1:minimum_degree(digraph(trail(1,2,3,4,5,6,4,7,8,2))) ''' - return GiacMethods['minimum_degree'](self,*args) + return GiacMethods['minimum_degree'](self, *args) - def mkisom(self,*args): + def mkisom(self, *args): r'''From Giac's documentation: Help for mkisom: mkisom(Vect,(Sign(1) or -1)) @@ -10106,9 +10106,9 @@ cdef class GiacMethods_base: Ex2:mkisom([[1,0,0],pi/3],-1) Ex3:mkisom(pi,1) ''' - return GiacMethods['mkisom'](self,*args) + return GiacMethods['mkisom'](self, *args) - def mksa(self,*args): + def mksa(self, *args): r'''From Giac's documentation: Help for mksa: mksa(Unit) @@ -10116,9 +10116,9 @@ cdef class GiacMethods_base: See also: 1/ convert 2/ ufactor Ex1:mksa(1_N) ''' - return GiacMethods['mksa'](self,*args) + return GiacMethods['mksa'](self, *args) - def modgcd(self,*args): + def modgcd(self, *args): r'''From Giac's documentation: Help for modgcd: modgcd(Poly,Poly) @@ -10126,9 +10126,9 @@ cdef class GiacMethods_base: See also: 1/ gcd 2/ heugcd 3/ ezgcd 4/ psrgcd Ex1:modgcd(x^4-1,(x-1)^2) ''' - return GiacMethods['modgcd'](self,*args) + return GiacMethods['modgcd'](self, *args) - def mods(self,*args): + def mods(self, *args): r'''From Giac's documentation: Help for mods: mods(Intg,Intg) @@ -10138,18 +10138,18 @@ cdef class GiacMethods_base: Ex2:mods(10,4) Ex3:mods(11,7) ''' - return GiacMethods['mods'](self,*args) + return GiacMethods['mods'](self, *args) - def monotonic(self,*args): + def monotonic(self, *args): r'''From Giac's documentation: Help for monotonic: monotonic() Returns a real that increases as time passes Ex1:monotonic() ''' - return GiacMethods['monotonic'](self,*args) + return GiacMethods['monotonic'](self, *args) - def montre_tortue(self,*args): + def montre_tortue(self, *args): r'''From Giac's documentation: Help for montre_tortue: montre_tortue(NULL) @@ -10157,9 +10157,9 @@ cdef class GiacMethods_base: See also: 1/ cache_tortue Ex1:montre_tortue() ''' - return GiacMethods['montre_tortue'](self,*args) + return GiacMethods['montre_tortue'](self, *args) - def moustache(self,*args): + def moustache(self, *args): r'''From Giac's documentation: Help for moustache: moustache(Lst,[Lst],[x=a..b||y=a..b]) @@ -10170,9 +10170,9 @@ cdef class GiacMethods_base: Ex3:moustache([1,2,3,5,10,4],[1,2,3,1,2,3]) Ex4:moustache([[6,0,1,3,4,2,5],[0,1,3,4,2,5,6],[1,3,4,2,5,6,0],[3,4,2,5,6,0,1],[4,2,5,6,0,1,3],[2,5,6,0,1,3,4]]) ''' - return GiacMethods['moustache'](self,*args) + return GiacMethods['moustache'](self, *args) - def moving_average(self,*args): + def moving_average(self, *args): r'''From Giac's documentation: Help for moving_average: moving_average(Lst(A),Intg(n)) @@ -10180,9 +10180,9 @@ cdef class GiacMethods_base: See also: 1/ lowpass Ex1: snd:=soundsec(2):;data:=0.5*threshold(3*sin(2*pi*220*snd),[-1.0,1.0])+randvector(length(snd),normald,0,0.05):;moving_average(data,25) ''' - return GiacMethods['moving_average'](self,*args) + return GiacMethods['moving_average'](self, *args) - def moyal(self,*args): + def moyal(self, *args): r'''From Giac's documentation: Help for moyal: moyal(Expr,Expr,VectVar) @@ -10190,9 +10190,9 @@ cdef class GiacMethods_base: See also: 1/ Ex1:moyal(x^2+y^4,x^4-y^2,[x,y],5) ''' - return GiacMethods['moyal'](self,*args) + return GiacMethods['moyal'](self, *args) - def moyenne(self,*args): + def moyenne(self, *args): r'''From Giac's documentation: Help for moyenne: moyenne(Lst||Mtrx,[Lst]) @@ -10202,9 +10202,9 @@ cdef class GiacMethods_base: Ex2:moyenne([1,2,3],[1,2,3]) Ex3:moyenne([[1,2,3],[1,2,3]]) ''' - return GiacMethods['moyenne'](self,*args) + return GiacMethods['moyenne'](self, *args) - def mul(self,*args): + def mul(self, *args): r'''From Giac's documentation: Help for mul: mul(Expr||Lst,[Var||Lst],[Intg(a)],[Intg(b)],[Intg(p)]) @@ -10218,9 +10218,9 @@ cdef class GiacMethods_base: Ex6:mul([2,3,4],[5,6,7]) Ex7:mul([[2,3,4],[5,6,7]],[[2,3,4],[5,6,7]]) ''' - return GiacMethods['mul'](self,*args) + return GiacMethods['mul'](self, *args) - def mult_c_conjugate(self,*args): + def mult_c_conjugate(self, *args): r'''From Giac's documentation: Help for mult_c_conjugate: mult_c_conjugate(Expr) @@ -10229,9 +10229,9 @@ cdef class GiacMethods_base: Ex1:mult_c_conjugate(1/(3+i*2)) Ex2:mult_c_conjugate(3+i*2) ''' - return GiacMethods['mult_c_conjugate'](self,*args) + return GiacMethods['mult_c_conjugate'](self, *args) - def mult_conjugate(self,*args): + def mult_conjugate(self, *args): r'''From Giac's documentation: Help for mult_conjugate: mult_conjugate(Expr) @@ -10240,9 +10240,9 @@ cdef class GiacMethods_base: Ex1:mult_conjugate(sqrt(3)-sqrt(2)) Ex2:mult_conjugate(1/(sqrt(3)-sqrt(2))) ''' - return GiacMethods['mult_conjugate'](self,*args) + return GiacMethods['mult_conjugate'](self, *args) - def multinomial(self,*args): + def multinomial(self, *args): r'''From Giac's documentation: Help for multinomial: multinomial(Intg(n),Vect(p),Vect(k)) @@ -10253,9 +10253,9 @@ cdef class GiacMethods_base: Ex3: randvector(3,multinomial,[1/2,1/3,1/6]) Ex4: ranm(4,3,multinomial,[1/2,1/3,1/6]) ''' - return GiacMethods['multinomial'](self,*args) + return GiacMethods['multinomial'](self, *args) - def multiplier_conjugue(self,*args): + def multiplier_conjugue(self, *args): r'''From Giac's documentation: Help for multiplier_conjugue: multiplier_conjugue(Expr) @@ -10264,9 +10264,9 @@ cdef class GiacMethods_base: Ex1:multiplier_conjugue(sqrt(3)-sqrt(2)) Ex2:multiplier_conjugue(1/(sqrt(3)-sqrt(2))) ''' - return GiacMethods['multiplier_conjugue'](self,*args) + return GiacMethods['multiplier_conjugue'](self, *args) - def multiplier_conjugue_complexe(self,*args): + def multiplier_conjugue_complexe(self, *args): r'''From Giac's documentation: Help for multiplier_conjugue_complexe: multiplier_conjugue_complexe(Expr) @@ -10275,9 +10275,9 @@ cdef class GiacMethods_base: Ex1:multiplier_conjugue_complexe(1/(3+i*2)) Ex2:multiplier_conjugue_complexe(3+i*2) ''' - return GiacMethods['multiplier_conjugue_complexe'](self,*args) + return GiacMethods['multiplier_conjugue_complexe'](self, *args) - def multiply(self,*args): + def multiply(self, *args): r'''From Giac's documentation: Help for multiply: multiply(Intg or Lst, Intg or Lst) @@ -10287,27 +10287,27 @@ cdef class GiacMethods_base: Ex2:multiply([4,1],[-4,2]) Ex3:multiply([[4,1],[-4,1]],[[4,1],[-4,1]]) ''' - return GiacMethods['multiply'](self,*args) + return GiacMethods['multiply'](self, *args) - def mupad2maple(self,*args): + def mupad2maple(self, *args): r'''From Giac's documentation: Help for mupad2maple: mupad2maple(Str("NameMupadFile"),Str("NameMapleFile")) mupad2maple("file1","file2") translates file1(MuPAD) to file2(Maple). See also: 1/ mupad2xcas ''' - return GiacMethods['mupad2maple'](self,*args) + return GiacMethods['mupad2maple'](self, *args) - def mupad2xcas(self,*args): + def mupad2xcas(self, *args): r'''From Giac's documentation: Help for mupad2xcas: mupad2xcas(Str("NameMupadFile"),Str("NameXcasFile")) mupad2xcas("file1","file2") translates file1(MuPAD) to file2(Xcas). See also: 1/ mupad2maple ''' - return GiacMethods['mupad2xcas'](self,*args) + return GiacMethods['mupad2xcas'](self, *args) - def mycielski(self,*args): + def mycielski(self, *args): r'''From Giac's documentation: Help for mycielski: mycielski(Graph(G)) @@ -10316,9 +10316,9 @@ cdef class GiacMethods_base: Ex1:mycielski(graph("petersen")) Ex2: is_isomorphic(mycielski(mycielski(path_graph(2))),graph("grotzsch")) ''' - return GiacMethods['mycielski'](self,*args) + return GiacMethods['mycielski'](self, *args) - def nCr(self,*args): + def nCr(self, *args): r'''From Giac's documentation: Help for nCr: nCr(Intg(n),Intg(r)) @@ -10326,9 +10326,9 @@ cdef class GiacMethods_base: See also: 1/ factorial 2/ perm Ex1:nCr(4,2) ''' - return GiacMethods['nCr'](self,*args) + return GiacMethods['nCr'](self, *args) - def nDeriv(self,*args): + def nDeriv(self, *args): r'''From Giac's documentation: Help for nDeriv: nDeriv(Expr(Xpr),Var(Var),[Real(h)]) @@ -10338,9 +10338,9 @@ cdef class GiacMethods_base: Ex2:nDeriv(x^2,x,0.1) Ex3:nDeriv(x^2,x) ''' - return GiacMethods['nDeriv'](self,*args) + return GiacMethods['nDeriv'](self, *args) - def nInt(self,*args): + def nInt(self, *args): r'''From Giac's documentation: Help for nInt: nInt(Expr(f(x)),Var(x),Real(a),Real(b)) @@ -10350,9 +10350,9 @@ cdef class GiacMethods_base: Ex2:nInt(x^2,x,0,1) Ex3:nInt(exp(-x^2),x,-1,1) ''' - return GiacMethods['nInt'](self,*args) + return GiacMethods['nInt'](self, *args) - def nPr(self,*args): + def nPr(self, *args): r'''From Giac's documentation: Help for nPr: nPr(Intg(n),Intg(p)) @@ -10360,9 +10360,9 @@ cdef class GiacMethods_base: See also: 1/ comb 2/ factorial Ex1:nPr(4,2) ''' - return GiacMethods['nPr'](self,*args) + return GiacMethods['nPr'](self, *args) - def nSolve(self,*args): + def nSolve(self, *args): r'''From Giac's documentation: Help for nSolve: nSolve(Expr,Var,[Guess or Interval],[Method]) @@ -10371,9 +10371,9 @@ cdef class GiacMethods_base: Ex1:nSolve(cos(x)=x,x) Ex2:nSolve(cos(x)=x,x=1.3) ''' - return GiacMethods['nSolve'](self,*args) + return GiacMethods['nSolve'](self, *args) - def ncols(self,*args): + def ncols(self, *args): r'''From Giac's documentation: Help for ncols: ncols(Mtrx) @@ -10382,9 +10382,9 @@ cdef class GiacMethods_base: Ex1:ncols([[1,2,3],[4,5,6]]) Ex2:ncols([[1,2],[3,4],[5,6]]) ''' - return GiacMethods['ncols'](self,*args) + return GiacMethods['ncols'](self, *args) - def negbinomial(self,*args): + def negbinomial(self, *args): r'''From Giac's documentation: Help for negbinomial: negbinomial(Intg(n),Intg(k),Real(p in 0..1)) @@ -10394,9 +10394,9 @@ cdef class GiacMethods_base: Ex2:negbinomial(4,2,0.6) Ex3:negbinomial(4,6,0.3) ''' - return GiacMethods['negbinomial'](self,*args) + return GiacMethods['negbinomial'](self, *args) - def negbinomial_cdf(self,*args): + def negbinomial_cdf(self, *args): r'''From Giac's documentation: Help for negbinomial_cdf: negbinomial_cdf(Intg(n),Real(p),Real(x),[Real(y)]) @@ -10406,9 +10406,9 @@ cdef class GiacMethods_base: Ex2:negbinomial_cdf(4,0.1,2) Ex3:negbinomial_cdf(4,0.5,2,3) ''' - return GiacMethods['negbinomial_cdf'](self,*args) + return GiacMethods['negbinomial_cdf'](self, *args) - def negbinomial_icdf(self,*args): + def negbinomial_icdf(self, *args): r'''From Giac's documentation: Help for negbinomial_icdf: negbinomial_icdf(Intg(n),Real(p),Real(t)) @@ -10417,9 +10417,9 @@ cdef class GiacMethods_base: Ex1:negbinomial_icdf(4,0.5,0.68) Ex2:negbinomial_icdf(4,0.1,0.95) ''' - return GiacMethods['negbinomial_icdf'](self,*args) + return GiacMethods['negbinomial_icdf'](self, *args) - def neighbors(self,*args): + def neighbors(self, *args): r'''From Giac's documentation: Help for neighbors: neighbors(Graph(G),[Vrtx(v)]) @@ -10427,9 +10427,9 @@ cdef class GiacMethods_base: See also: 1/ adjacency_matrix 2/ vertex_degree 3/ in_degree 3/ out_degree Ex1:neighbors(digraph(trail(1,2,3,4,5,6,4,7,8,2)),4) ''' - return GiacMethods['neighbors'](self,*args) + return GiacMethods['neighbors'](self, *args) - def network_transitivity(self,*args): + def network_transitivity(self, *args): r'''From Giac's documentation: Help for network_transitivity: network_transitivity(Graph(G)) @@ -10437,9 +10437,9 @@ cdef class GiacMethods_base: See also: 1/ clustering_coefficient 2/ number_of_triangles Ex1:network_transitivity(graph(%{[1,2],[2,3],[2,4],[3,4],[4,1]%})) ''' - return GiacMethods['network_transitivity'](self,*args) + return GiacMethods['network_transitivity'](self, *args) - def newList(self,*args): + def newList(self, *args): r'''From Giac's documentation: Help for newList: newList(Intg(n)) @@ -10447,9 +10447,9 @@ cdef class GiacMethods_base: See also: 1/ newMat 2/ makelist Ex1:newList(4) ''' - return GiacMethods['newList'](self,*args) + return GiacMethods['newList'](self, *args) - def newMat(self,*args): + def newMat(self, *args): r'''From Giac's documentation: Help for newMat: newMat(Intg(n),Intg(p)) @@ -10457,9 +10457,9 @@ cdef class GiacMethods_base: See also: 1/ newList 2/ makemat Ex1:newMat(2,3) ''' - return GiacMethods['newMat'](self,*args) + return GiacMethods['newMat'](self, *args) - def newton(self,*args): + def newton(self, *args): r'''From Giac's documentation: Help for newton: newton(Expr(f(x)),Var(x),[ApproxVal(a),NumIter(p)]) @@ -10470,9 +10470,9 @@ cdef class GiacMethods_base: Ex3:newton(x^2-2,x,-2) Ex4:newton(x^2-2,x,2,5,1e-7) ''' - return GiacMethods['newton'](self,*args) + return GiacMethods['newton'](self, *args) - def newton_solver(self,*args): + def newton_solver(self, *args): r'''From Giac's documentation: Help for newton_solver: newton_solver(Opt) @@ -10485,9 +10485,9 @@ cdef class GiacMethods_base: Ex5: fsolve(cos(x)=x,x,0,secant_solver) Ex6: fsolve(cos(x)=x,x,0,steffenson_solver) ''' - return GiacMethods['newton_solver'](self,*args) + return GiacMethods['newton_solver'](self, *args) - def newtonj_solver(self,*args): + def newtonj_solver(self, *args): r'''From Giac's documentation: Help for newtonj_solver: newtonj_solver(Opt) @@ -10500,9 +10500,9 @@ cdef class GiacMethods_base: Ex5: fsolve([x^2+y-2,x+y^2-2],[x,y],[2,2],hybridsj_solver) Ex6: fsolve([x^2+y-2,x+y^2-2],[x,y],[2,2],newtonj_solver) ''' - return GiacMethods['newtonj_solver'](self,*args) + return GiacMethods['newtonj_solver'](self, *args) - def nextperm(self,*args): + def nextperm(self, *args): r'''From Giac's documentation: Help for nextperm: nextperm(Intg(n)) @@ -10511,9 +10511,9 @@ cdef class GiacMethods_base: Ex1:nextperm([0,2,1,3]) Ex2:nextperm([0,3,2,1]) ''' - return GiacMethods['nextperm'](self,*args) + return GiacMethods['nextperm'](self, *args) - def nextprime(self,*args): + def nextprime(self, *args): r'''From Giac's documentation: Help for nextprime: nextprime(Intg(a)) @@ -10522,9 +10522,9 @@ cdef class GiacMethods_base: Ex1:nextprime(9856989898990) Ex2:nextprime(97160249868928888261606009) ''' - return GiacMethods['nextprime'](self,*args) + return GiacMethods['nextprime'](self, *args) - def nlpsolve(self,*args): + def nlpsolve(self, *args): r'''From Giac's documentation: Help for nlpsolve: nlpsolve(objective, [constr], [bd], [opts]) @@ -10541,18 +10541,18 @@ cdef class GiacMethods_base: Ex9:nlpsolve(w^3*(v-w)^2+(w-x-1)^2+(x-y-2)^2+(y-z-3)^2,[w+x+y+z<=5,3z+2v=3],assume=nlp_nonnegative) Ex10:nlpsolve(sin(x)*Psi(x),x=1..20,nlp_initialpoint=[x=16]) ''' - return GiacMethods['nlpsolve'](self,*args) + return GiacMethods['nlpsolve'](self, *args) - def nodisp(self,*args): + def nodisp(self, *args): r'''From Giac's documentation: Help for nodisp: nodisp(Expr) Displays Done in place of a value. Ex1:nodisp(A:=ranm(50,50)) ''' - return GiacMethods['nodisp'](self,*args) + return GiacMethods['nodisp'](self, *args) - def non_recursive_normal(self,*args): + def non_recursive_normal(self, *args): r'''From Giac's documentation: Help for non_recursive_normal: non_recursive_normal(Expr) @@ -10561,9 +10561,9 @@ cdef class GiacMethods_base: Ex1:non_recursive_normal(sin(x+x)+sin(2*x)+x+x) Ex2:non_recursive_normal(sin(2*x)+sin(2*x)+x+x) ''' - return GiacMethods['non_recursive_normal'](self,*args) + return GiacMethods['non_recursive_normal'](self, *args) - def nop(self,*args): + def nop(self, *args): r'''From Giac's documentation: Help for nop: nop(NULL) @@ -10571,9 +10571,9 @@ cdef class GiacMethods_base: See also: 1/ Ex1:nop() ''' - return GiacMethods['nop'](self,*args) + return GiacMethods['nop'](self, *args) - def nops(self,*args): + def nops(self, *args): r'''From Giac's documentation: Help for nops: nops(Lst or Str or Seq) @@ -10583,9 +10583,9 @@ cdef class GiacMethods_base: Ex2:nops("bonjour") Ex3:nops(1,2,3) ''' - return GiacMethods['nops'](self,*args) + return GiacMethods['nops'](self, *args) - def norm(self,*args): + def norm(self, *args): r'''From Giac's documentation: Help for norm: norm(Vect or Mtrx) @@ -10596,9 +10596,9 @@ cdef class GiacMethods_base: Ex3:norm([[1,2],[3,-4]]) Ex4:norm([[1,2,3],[3,-9,6],[4,5,6]]) ''' - return GiacMethods['norm'](self,*args) + return GiacMethods['norm'](self, *args) - def normal(self,*args): + def normal(self, *args): r'''From Giac's documentation: Help for normal: normal(Expr) @@ -10608,9 +10608,9 @@ cdef class GiacMethods_base: Ex2:normal(2*x*2) Ex3:normal((2*x+1)^2) ''' - return GiacMethods['normal'](self,*args) + return GiacMethods['normal'](self, *args) - def normal_cdf(self,*args): + def normal_cdf(self, *args): r'''From Giac's documentation: Help for normal_cdf: normal_cdf(Real(mu),Real(sigma),Real(x0),[Real(y0)]) @@ -10620,9 +10620,9 @@ cdef class GiacMethods_base: Ex2:normal_cdf(1,2,2.96*sqrt(2)) Ex3:normal_cdf(1,2,1.4*sqrt(2),2.96*sqrt(2)) ''' - return GiacMethods['normal_cdf'](self,*args) + return GiacMethods['normal_cdf'](self, *args) - def normal_icdf(self,*args): + def normal_icdf(self, *args): r'''From Giac's documentation: Help for normal_icdf: normal_icdf(Real(mu),Real(sigma),Real(p)) @@ -10631,9 +10631,9 @@ cdef class GiacMethods_base: Ex1:normal_icdf(0.95) Ex2:normal_icdf(1,2,0.95) ''' - return GiacMethods['normal_icdf'](self,*args) + return GiacMethods['normal_icdf'](self, *args) - def normald(self,*args): + def normald(self, *args): r'''From Giac's documentation: Help for normald: normald(Real(mu),Real(sigma),Real(x0)) @@ -10644,9 +10644,9 @@ cdef class GiacMethods_base: Ex3: randvector(3,normald,1,0.5) Ex4: ranm(4,3,normald,1,0.5) ''' - return GiacMethods['normald'](self,*args) + return GiacMethods['normald'](self, *args) - def normald_cdf(self,*args): + def normald_cdf(self, *args): r'''From Giac's documentation: Help for normald_cdf: normald_cdf(Real(mu),Real(sigma),Real(x0),[Real(y0)]) @@ -10656,9 +10656,9 @@ cdef class GiacMethods_base: Ex2:normald_cdf(1,2,2.96*sqrt(2)) Ex3:normald_cdf(1,2,1.4*sqrt(2),2.96*sqrt(2)) ''' - return GiacMethods['normald_cdf'](self,*args) + return GiacMethods['normald_cdf'](self, *args) - def normald_icdf(self,*args): + def normald_icdf(self, *args): r'''From Giac's documentation: Help for normald_icdf: normald_icdf(Real(mu),Real(sigma),Real(p)) @@ -10667,9 +10667,9 @@ cdef class GiacMethods_base: Ex1:normald_icdf(0.95) Ex2:normald_icdf(1,2,0.95) ''' - return GiacMethods['normald_icdf'](self,*args) + return GiacMethods['normald_icdf'](self, *args) - def normalize(self,*args): + def normalize(self, *args): r'''From Giac's documentation: Help for normalize: normalize(Lst||Cplx) @@ -10680,9 +10680,9 @@ cdef class GiacMethods_base: Ex3: fieldplot(-t*y,[t,y],normalize) Ex4: fieldplot(-t*y,[t,y],normalize,xstep=0.5,ystep=0.5) ''' - return GiacMethods['normalize'](self,*args) + return GiacMethods['normalize'](self, *args) - def normalt(self,*args): + def normalt(self, *args): r'''From Giac's documentation: Help for normalt: normalt(Lst,Real,[Real],Fnc,[Real]) @@ -10691,9 +10691,9 @@ cdef class GiacMethods_base: Ex1:normalt([10,30],.5,.02,'!=',0.1) Ex2:normalt([0.48,50],0.5,0.1,'<') ''' - return GiacMethods['normalt'](self,*args) + return GiacMethods['normalt'](self, *args) - def normalvariate(self,*args): + def normalvariate(self, *args): r'''From Giac's documentation: Help for normalvariate: normalvariate(Real(mu),Real(sigma)) @@ -10702,9 +10702,9 @@ cdef class GiacMethods_base: Ex1:normalvariate(0,1) Ex2:normalvariate(2,1) ''' - return GiacMethods['normalvariate'](self,*args) + return GiacMethods['normalvariate'](self, *args) - def nprimes(self,*args): + def nprimes(self, *args): r'''From Giac's documentation: Help for nprimes: nprimes(Intg(n)) @@ -10712,9 +10712,9 @@ cdef class GiacMethods_base: See also: 1/ ithprime 2/ prevprime 3/ nextprime 4/ isprime Ex1:nprimes(20) ''' - return GiacMethods['nprimes'](self,*args) + return GiacMethods['nprimes'](self, *args) - def nrows(self,*args): + def nrows(self, *args): r'''From Giac's documentation: Help for nrows: nrows(Mtrx) @@ -10723,9 +10723,9 @@ cdef class GiacMethods_base: Ex1:nrows([[1,2,3],[4,5,6]]) Ex2:nrows([[1,2],[3,4],[5,6]]) ''' - return GiacMethods['nrows'](self,*args) + return GiacMethods['nrows'](self, *args) - def nuage_points(self,*args): + def nuage_points(self, *args): r'''From Giac's documentation: Help for nuage_points: nuage_points(Mtrx) @@ -10733,9 +10733,9 @@ cdef class GiacMethods_base: See also: 1/ polygonplot 2/ polygonscatterplot 3/ listplot Ex1:nuage_points([[1,2,3],[2,0,1],[-1,2,3]]) ''' - return GiacMethods['nuage_points'](self,*args) + return GiacMethods['nuage_points'](self, *args) - def nullspace(self,*args): + def nullspace(self, *args): r'''From Giac's documentation: Help for nullspace: nullspace(Mtrx) @@ -10744,9 +10744,9 @@ cdef class GiacMethods_base: Ex1:nullspace([[1,2],[3,6]]) Ex2:nullspace([[1,2,3],[1,3,6],[2,5,9]]) ''' - return GiacMethods['nullspace'](self,*args) + return GiacMethods['nullspace'](self, *args) - def number_of_edges(self,*args): + def number_of_edges(self, *args): r'''From Giac's documentation: Help for number_of_edges: number_of_edges(Graph(G)) @@ -10754,9 +10754,9 @@ cdef class GiacMethods_base: See also: 1/ edges 2/ number_of_vertices Ex1:number_of_edges(complete_graph(5)) ''' - return GiacMethods['number_of_edges'](self,*args) + return GiacMethods['number_of_edges'](self, *args) - def number_of_spanning_trees(self,*args): + def number_of_spanning_trees(self, *args): r'''From Giac's documentation: Help for number_of_spanning_trees: number_of_spanning_trees(Graph(G)) @@ -10765,9 +10765,9 @@ cdef class GiacMethods_base: Ex1:number_of_spanning_trees(complete_graph(4)) Ex2:number_of_spanning_trees(graph(trail(1,2,3,4,1,3))) ''' - return GiacMethods['number_of_spanning_trees'](self,*args) + return GiacMethods['number_of_spanning_trees'](self, *args) - def number_of_triangles(self,*args): + def number_of_triangles(self, *args): r'''From Giac's documentation: Help for number_of_triangles: number_of_triangles(Graph(G)) @@ -10775,9 +10775,9 @@ cdef class GiacMethods_base: See also: 1/ is_clique 2/ maximal_clique Ex1:number_of_triangles(graph("tetrahedron")) ''' - return GiacMethods['number_of_triangles'](self,*args) + return GiacMethods['number_of_triangles'](self, *args) - def number_of_vertices(self,*args): + def number_of_vertices(self, *args): r'''From Giac's documentation: Help for number_of_vertices: number_of_vertices(Graph(G)) @@ -10785,9 +10785,9 @@ cdef class GiacMethods_base: See also: 1/ graph_vertices 2/ number_of_edges Ex1:number_of_vertices(graph("petersen")) ''' - return GiacMethods['number_of_vertices'](self,*args) + return GiacMethods['number_of_vertices'](self, *args) - def numer(self,*args): + def numer(self, *args): r'''From Giac's documentation: Help for numer: numer(Frac(a/b) or RatFrac) @@ -10797,9 +10797,9 @@ cdef class GiacMethods_base: Ex2:numer((x^3-1)/(x^2-1)) Ex3:numer(1+(x^3-1)/x^2) ''' - return GiacMethods['numer'](self,*args) + return GiacMethods['numer'](self, *args) - def octahedron(self,*args): + def octahedron(self, *args): r'''From Giac's documentation: Help for octahedron: octahedron(Pnt(A),Pnt(B),Pnt(C)) @@ -10808,9 +10808,9 @@ cdef class GiacMethods_base: Ex1:octahedron([0,0,0],[0,0,5],[0,5,0]) Ex2:octahedron(evalf([0,0,0],[3,2,4],[1,1,0])) ''' - return GiacMethods['octahedron'](self,*args) + return GiacMethods['octahedron'](self, *args) - def odd(self,*args): + def odd(self, *args): r'''From Giac's documentation: Help for odd: odd(Intg(n)) @@ -10819,9 +10819,9 @@ cdef class GiacMethods_base: Ex1:odd(6) Ex2:odd(1251) ''' - return GiacMethods['odd'](self,*args) + return GiacMethods['odd'](self, *args) - def odd_girth(self,*args): + def odd_girth(self, *args): r'''From Giac's documentation: Help for odd_girth: odd_girth(Graph(G)) @@ -10830,9 +10830,9 @@ cdef class GiacMethods_base: Ex1:odd_girth(graph("petersen")) Ex2:odd_girth(hypercube_graph(3)) ''' - return GiacMethods['odd_girth'](self,*args) + return GiacMethods['odd_girth'](self, *args) - def odd_graph(self,*args): + def odd_graph(self, *args): r'''From Giac's documentation: Help for odd_graph: odd_graph(Intg(n)) @@ -10840,9 +10840,9 @@ cdef class GiacMethods_base: See also: 1/ kneser_graph Ex1:odd_graph(3) ''' - return GiacMethods['odd_graph'](self,*args) + return GiacMethods['odd_graph'](self, *args) - def odeplot(self,*args): + def odeplot(self, *args): r'''From Giac's documentation: Help for odeplot: odeplot(Expr,VectVar,VectInitCond) @@ -10856,9 +10856,9 @@ cdef class GiacMethods_base: Ex6:odeplot([-y+b,-1+(x-a)^2+(y-b)^2],[t=-3..3,x,y],[0,a+1,b+0.5],plan) Ex7:odeplot(5*[-y,x],[t=0..1,x,y],[0,0.3,0.7],tstep=0.05,plan) ''' - return GiacMethods['odeplot'](self,*args) + return GiacMethods['odeplot'](self, *args) - def odesolve(self,*args): + def odesolve(self, *args): r'''From Giac's documentation: Help for odesolve: odesolve(Expr,VectVar,VectInitCond,FinalVal,[tstep=Val,curve]) @@ -10870,9 +10870,9 @@ cdef class GiacMethods_base: Ex4:odesolve(sin(t*y),t=0..2,y,1,tstep=0.5) Ex5:odesolve(sin(t*y),t=0..2,y,1,tstep=0.5,curve) ''' - return GiacMethods['odesolve'](self,*args) + return GiacMethods['odesolve'](self, *args) - def op(self,*args): + def op(self, *args): r'''From Giac's documentation: Help for op: op(Op or Fnc) @@ -10884,9 +10884,9 @@ cdef class GiacMethods_base: Ex4:op([1,2,3]) Ex5:op(set[1,2,3]) ''' - return GiacMethods['op'](self,*args) + return GiacMethods['op'](self, *args) - def open_polygon(self,*args): + def open_polygon(self, *args): r'''From Giac's documentation: Help for open_polygon: open_polygon(LstPnt||LstCplx) @@ -10895,9 +10895,9 @@ cdef class GiacMethods_base: Ex1:open_polygon(i,1+i,2-i,-1,-1+i/2) Ex2:open_polygon(point(0,0,0),point(3,3,3),point(0,0,3),point(3,0,0)) ''' - return GiacMethods['open_polygon'](self,*args) + return GiacMethods['open_polygon'](self, *args) - def ord(self,*args): + def ord(self, *args): r'''From Giac's documentation: Help for ord: ord(Char||LstChar) @@ -10907,9 +10907,9 @@ cdef class GiacMethods_base: Ex2:ord("ABC") Ex3:ord(["a","b","c"]) ''' - return GiacMethods['ord'](self,*args) + return GiacMethods['ord'](self, *args) - def order(self,*args): + def order(self, *args): r'''From Giac's documentation: Help for order: order(g) @@ -10917,9 +10917,9 @@ cdef class GiacMethods_base: Ex1:order(3 % 7) Ex2: GF(3,5,g); order(g^2+g+1); ''' - return GiacMethods['order'](self,*args) + return GiacMethods['order'](self, *args) - def order_size(self,*args): + def order_size(self, *args): r'''From Giac's documentation: Help for order_size: order_size(Expr) @@ -10928,9 +10928,9 @@ cdef class GiacMethods_base: Ex1:order_size(x) Ex2: limit(sqrt(x)*order_size(x),x=0) ''' - return GiacMethods['order_size'](self,*args) + return GiacMethods['order_size'](self, *args) - def ordinate(self,*args): + def ordinate(self, *args): r'''From Giac's documentation: Help for ordinate: ordinate(Pnt or Vect) @@ -10941,9 +10941,9 @@ cdef class GiacMethods_base: Ex3:ordinate(-1-i) Ex4:ordinate(point(1,2,3)) ''' - return GiacMethods['ordinate'](self,*args) + return GiacMethods['ordinate'](self, *args) - def orthocenter(self,*args): + def orthocenter(self, *args): r'''From Giac's documentation: Help for orthocenter: orthocenter((Pnt or Cplx),(Pnt or Cplx),(Pnt or Cplx)) @@ -10953,9 +10953,9 @@ cdef class GiacMethods_base: Ex2:orthocenter(point(1+i),point(2),point(i)) Ex3:orthocenter(triangle(0,1,1+i)) ''' - return GiacMethods['orthocenter'](self,*args) + return GiacMethods['orthocenter'](self, *args) - def orthogonal(self,*args): + def orthogonal(self, *args): r'''From Giac's documentation: Help for orthogonal: orthogonal((Pnt),(Line or Plan)) @@ -10964,9 +10964,9 @@ cdef class GiacMethods_base: Ex1:orthogonal(point(0,0,0),line(point(1,0,0),point(0,1,0))) Ex2:orthogonal(point(0,0,0),plane(point(1,0,0),point(0,1,0),point(0,0,1))) ''' - return GiacMethods['orthogonal'](self,*args) + return GiacMethods['orthogonal'](self, *args) - def osculating_circle(self,*args): + def osculating_circle(self, *args): r'''From Giac's documentation: Help for osculating_circle: osculating_circle(Curve,Point) @@ -10979,9 +10979,9 @@ cdef class GiacMethods_base: Ex5:osculating_circle([3*exp(t/2)*cos(t),3*exp(t/2)*sin(t)],t) Ex6:osculating_circle([3*exp(t/2)*cos(t),3*exp(t/2)*sin(t)],t,7) ''' - return GiacMethods['osculating_circle'](self,*args) + return GiacMethods['osculating_circle'](self, *args) - def p1oc2(self,*args): + def p1oc2(self, *args): r'''From Giac's documentation: Help for p1oc2: p1oc2(Permut,Cycle) @@ -10989,9 +10989,9 @@ cdef class GiacMethods_base: See also: 1/ c1op2 2/ p1op2 Ex1:p1oc2([0,2,1],[2,1,3]) ''' - return GiacMethods['p1oc2'](self,*args) + return GiacMethods['p1oc2'](self, *args) - def p1op2(self,*args): + def p1op2(self, *args): r'''From Giac's documentation: Help for p1op2: p1op2(Permut,Permut) @@ -10999,9 +10999,9 @@ cdef class GiacMethods_base: See also: 1/ c1op2 2/ p1oc2 Ex1:p1op2([0,2,1],[1,0,3,2]) ''' - return GiacMethods['p1op2'](self,*args) + return GiacMethods['p1op2'](self, *args) - def pa2b2(self,*args): + def pa2b2(self, *args): r'''From Giac's documentation: Help for pa2b2: pa2b2(Intg(n)) @@ -11010,9 +11010,9 @@ cdef class GiacMethods_base: Ex2:pa2b2(209) Ex3:pa2b2(229) ''' - return GiacMethods['pa2b2'](self,*args) + return GiacMethods['pa2b2'](self, *args) - def pade(self,*args): + def pade(self, *args): r'''From Giac's documentation: Help for pade: pade(Expr(Xpr), Var(x), (Intg(n) || Poly(N)), Intg(p)) @@ -11020,9 +11020,9 @@ cdef class GiacMethods_base: See also: 1/ taylor 2/ series Ex1:pade(exp(x),x,10,6) ''' - return GiacMethods['pade'](self,*args) + return GiacMethods['pade'](self, *args) - def parabola(self,*args): + def parabola(self, *args): r'''From Giac's documentation: Help for parabola: parabola(Pnt(F)||Pnt(xA+i*yA),Pnt(A)||Real(c),[Pnt(P)]) @@ -11033,9 +11033,9 @@ cdef class GiacMethods_base: Ex3:parabola(point(0,0,0),point(1,0,0),point(1,1,1)) Ex4:parabola(x-y^2+y-2) ''' - return GiacMethods['parabola'](self,*args) + return GiacMethods['parabola'](self, *args) - def parallel(self,*args): + def parallel(self, *args): r'''From Giac's documentation: Help for parallel: parallel(Pnt or Line,Line or Plan,[Line]) @@ -11049,9 +11049,9 @@ cdef class GiacMethods_base: Ex6:parallel([1,0,0],line(x=0,y=0),line(x=y,y=z)) Ex7:parallel(line(x=y,y=z),line(x=0,y=0)) ''' - return GiacMethods['parallel'](self,*args) + return GiacMethods['parallel'](self, *args) - def parallelepiped(self,*args): + def parallelepiped(self, *args): r'''From Giac's documentation: Help for parallelepiped: parallelepiped(Pnt(A),Pnt(B),Pnt(C),Pnt(D)) @@ -11060,9 +11060,9 @@ cdef class GiacMethods_base: Ex1:parallelepiped([0,0,0],[2,0,0],[0,1,0],[0,0,3]) Ex2: p:=parallelepiped([0,0,0],[5,0,0],[0,3,0],[0,0,2]);c1,c2,c3,c4,c5,c6,c7,c8:=sommets(p); ''' - return GiacMethods['parallelepiped'](self,*args) + return GiacMethods['parallelepiped'](self, *args) - def parallelogram(self,*args): + def parallelogram(self, *args): r'''From Giac's documentation: Help for parallelogram: parallelogram(Pnt(A)||Cplx,Pnt(B)||Cplx,Pnt(C)||Cplx,[Var(D)]) @@ -11073,9 +11073,9 @@ cdef class GiacMethods_base: Ex3:parallelogram(point(0,0,0),point(3,3,3),point(0,0,3)) Ex4:parallelogram(point(0,0,0),point(3,3,3),point(0,0,3),D) ''' - return GiacMethods['parallelogram'](self,*args) + return GiacMethods['parallelogram'](self, *args) - def parameq(self,*args): + def parameq(self, *args): r'''From Giac's documentation: Help for parameq: parameq(GeoObj) @@ -11084,18 +11084,18 @@ cdef class GiacMethods_base: Ex1:parameq(circle(0,1)) Ex2:parameq(line(i,1-i)) ''' - return GiacMethods['parameq'](self,*args) + return GiacMethods['parameq'](self, *args) - def parameter(self,*args): + def parameter(self, *args): r'''From Giac's documentation: Help for parameter: parameter() Reserved word. See also: 1/ ''' - return GiacMethods['parameter'](self,*args) + return GiacMethods['parameter'](self, *args) - def paramplot(self,*args): + def paramplot(self, *args): r'''From Giac's documentation: Help for paramplot: paramplot(Cplx||Lst,Var||Lst(Var)) @@ -11110,9 +11110,9 @@ cdef class GiacMethods_base: Ex7:paramplot([v*cos(u),v*sin(u),v],[u,v]) Ex8:paramplot([v*cos(u),v*sin(u),v],[u=0..pi,v=0..3],ustep=0.1,vstep=0.2) ''' - return GiacMethods['paramplot'](self,*args) + return GiacMethods['paramplot'](self, *args) - def parfrac(self,*args): + def parfrac(self, *args): r'''From Giac's documentation: Help for parfrac: parfrac(Opt) @@ -11121,9 +11121,9 @@ cdef class GiacMethods_base: Ex1: convert(1/(x^2-1),parfrac) Ex2: convert(1/(x^2-1),fullparfrac) ''' - return GiacMethods['parfrac'](self,*args) + return GiacMethods['parfrac'](self, *args) - def pari(self,*args): + def pari(self, *args): r'''From Giac's documentation: Help for pari: pari(Str,arguments) @@ -11138,9 +11138,9 @@ cdef class GiacMethods_base: Ex7:pari("isprime",9856989898997789789,1) Ex8:pari("isprime",9856989898997789789,2) ''' - return GiacMethods['pari'](self,*args) + return GiacMethods['pari'](self, *args) - def part(self,*args): + def part(self, *args): r'''From Giac's documentation: Help for part: part(Expr, Intg(n)) @@ -11151,9 +11151,9 @@ cdef class GiacMethods_base: Ex3:part(exp(x)*sin(x),1) Ex4:part(part(exp(x)*sin(x)+cos(x),1),1) ''' - return GiacMethods['part'](self,*args) + return GiacMethods['part'](self, *args) - def partfrac(self,*args): + def partfrac(self, *args): r'''From Giac's documentation: Help for partfrac: partfrac(RatFrac or Opt) @@ -11164,9 +11164,9 @@ cdef class GiacMethods_base: Ex3:partfrac(a/(z*(z-b)),z) Ex4: convert(x/(4-x^2),partfrac) ''' - return GiacMethods['partfrac'](self,*args) + return GiacMethods['partfrac'](self, *args) - def parzen_window(self,*args): + def parzen_window(self, *args): r'''From Giac's documentation: Help for parzen_window: parzen_window(Lst,[Interval(n1..n2)]) @@ -11174,9 +11174,9 @@ cdef class GiacMethods_base: See also: 1/ blackman_harris_window 2/ blackman_window 3/ bohman_window 4/ cosine_window 5/ gaussian_window 6/ hamming_window 7/ hann_poisson_window 8/ hann_window 9/ bartlett_hann_window 10/ poisson_window 11/ riemann_window 12/ triangle_window 13/ tukey_window 14/ welch_window Ex1: scatterplot(parzen_window(randvector(1000,0..1))) ''' - return GiacMethods['parzen_window'](self,*args) + return GiacMethods['parzen_window'](self, *args) - def pas_de_cote(self,*args): + def pas_de_cote(self, *args): r'''From Giac's documentation: Help for pas_de_cote: pas_de_cote(NULL or Real(n)) @@ -11185,9 +11185,9 @@ cdef class GiacMethods_base: Ex1: pas_de_cote 30 Ex2:pas_de_cote(30) ''' - return GiacMethods['pas_de_cote'](self,*args) + return GiacMethods['pas_de_cote'](self, *args) - def path_graph(self,*args): + def path_graph(self, *args): r'''From Giac's documentation: Help for path_graph: path_graph(Intg(n)||Lst(V)) @@ -11195,9 +11195,9 @@ cdef class GiacMethods_base: See also: 1/ cycle_graph 2/ graph 3/ trail Ex1:path_graph(5) ''' - return GiacMethods['path_graph'](self,*args) + return GiacMethods['path_graph'](self, *args) - def pcar(self,*args): + def pcar(self, *args): r'''From Giac's documentation: Help for pcar: pcar(Mtrx,[Var]) @@ -11208,9 +11208,9 @@ cdef class GiacMethods_base: Ex3:pcar([[1,2,3],[1,3,6],[2,5,7]]) Ex4:pcar([[1,2,3],[1,3,6],[2,5,7]],z) ''' - return GiacMethods['pcar'](self,*args) + return GiacMethods['pcar'](self, *args) - def pcar_hessenberg(self,*args): + def pcar_hessenberg(self, *args): r'''From Giac's documentation: Help for pcar_hessenberg: pcar_hessenberg(Mtrx,[Var]) @@ -11220,9 +11220,9 @@ cdef class GiacMethods_base: Ex2:pcar_hessenberg([[1,2],[3,4]],x) Ex3:pcar_hessenberg([[1,2,3],[1,3,6],[2,5,7]]) ''' - return GiacMethods['pcar_hessenberg'](self,*args) + return GiacMethods['pcar_hessenberg'](self, *args) - def pcoef(self,*args): + def pcoef(self, *args): r'''From Giac's documentation: Help for pcoef: pcoef(Vect) @@ -11231,9 +11231,9 @@ cdef class GiacMethods_base: Ex1:pcoef([1,0,0,0,1]) Ex2:pcoef([1,0,-2]) ''' - return GiacMethods['pcoef'](self,*args) + return GiacMethods['pcoef'](self, *args) - def pcoeff(self,*args): + def pcoeff(self, *args): r'''From Giac's documentation: Help for pcoeff: pcoeff(Vect) @@ -11242,9 +11242,9 @@ cdef class GiacMethods_base: Ex1:pcoeff([1,0,0,0,1]) Ex2:pcoeff([1,0,-2]) ''' - return GiacMethods['pcoeff'](self,*args) + return GiacMethods['pcoeff'](self, *args) - def pencolor(self,*args): + def pencolor(self, *args): r'''From Giac's documentation: Help for pencolor: pencolor(Color) @@ -11255,9 +11255,9 @@ cdef class GiacMethods_base: Ex3:pencolor(5) Ex4:pencolor(gomme) ''' - return GiacMethods['pencolor'](self,*args) + return GiacMethods['pencolor'](self, *args) - def pendown(self,*args): + def pendown(self, *args): r'''From Giac's documentation: Help for pendown: pendown(NULL) @@ -11265,9 +11265,9 @@ cdef class GiacMethods_base: See also: 1/ leve_crayon 2/ crayon Ex1:pendown() ''' - return GiacMethods['pendown'](self,*args) + return GiacMethods['pendown'](self, *args) - def penup(self,*args): + def penup(self, *args): r'''From Giac's documentation: Help for penup: penup(NULL) @@ -11275,9 +11275,9 @@ cdef class GiacMethods_base: See also: 1/ baisse_crayon 2/ crayon Ex1:penup() ''' - return GiacMethods['penup'](self,*args) + return GiacMethods['penup'](self, *args) - def perimeter(self,*args): + def perimeter(self, *args): r'''From Giac's documentation: Help for perimeter: perimeter(Polygone) @@ -11288,9 +11288,9 @@ cdef class GiacMethods_base: Ex3:perimeter(circle(0,2)) Ex4:perimeter(0,1,i) ''' - return GiacMethods['perimeter'](self,*args) + return GiacMethods['perimeter'](self, *args) - def perimeterat(self,*args): + def perimeterat(self, *args): r'''From Giac's documentation: Help for perimeterat: perimeterat(Polygone, Pnt||Cplx(z0)) @@ -11302,9 +11302,9 @@ cdef class GiacMethods_base: Ex4: p:=polygon(0,1,i);perimeterat(p,1+i) Ex5: A:=point(0);B:=point(1+i);c:=carre(A,B);perimeterat(c,i) ''' - return GiacMethods['perimeterat'](self,*args) + return GiacMethods['perimeterat'](self, *args) - def perimeteratraw(self,*args): + def perimeteratraw(self, *args): r'''From Giac's documentation: Help for perimeteratraw: perimeteratraw(Polygone, Pnt||Cplx(z0)) @@ -11316,18 +11316,18 @@ cdef class GiacMethods_base: Ex4:perimeteratraw(polygon(0,1,i),1+i) Ex5: A:=point(0);B:=point(1+i);c:=carre(A,B);perimeteratraw(c,i) ''' - return GiacMethods['perimeteratraw'](self,*args) + return GiacMethods['perimeteratraw'](self, *args) - def periodic(self,*args): + def periodic(self, *args): r'''From Giac's documentation: Help for periodic: periodic(Expr,Var,a,b) Makes a periodic expression equal to Expr on a..b, period b-a. Ex1:periodic(x^2,x,-1,1) ''' - return GiacMethods['periodic'](self,*args) + return GiacMethods['periodic'](self, *args) - def perm(self,*args): + def perm(self, *args): r'''From Giac's documentation: Help for perm: perm(Intg(n),Intg(p)) @@ -11335,9 +11335,9 @@ cdef class GiacMethods_base: See also: 1/ comb 2/ factorial Ex1:perm(4,2) ''' - return GiacMethods['perm'](self,*args) + return GiacMethods['perm'](self, *args) - def perminv(self,*args): + def perminv(self, *args): r'''From Giac's documentation: Help for perminv: perminv(Permut(a)) @@ -11345,9 +11345,9 @@ cdef class GiacMethods_base: See also: 1/ cycleinv Ex1:perminv([1,3,2,4,0]) ''' - return GiacMethods['perminv'](self,*args) + return GiacMethods['perminv'](self, *args) - def permu2cycles(self,*args): + def permu2cycles(self, *args): r'''From Giac's documentation: Help for permu2cycles: permu2cycles(Permut) @@ -11356,9 +11356,9 @@ cdef class GiacMethods_base: Ex1:permu2cycles([0,2,1,3,5,4]) Ex2:permu2cycles([0,2,1,4,3,5]) ''' - return GiacMethods['permu2cycles'](self,*args) + return GiacMethods['permu2cycles'](self, *args) - def permu2mat(self,*args): + def permu2mat(self, *args): r'''From Giac's documentation: Help for permu2mat: permu2mat(Permut(p)) @@ -11366,9 +11366,9 @@ cdef class GiacMethods_base: See also: 1/ Ex1:permu2mat([1,3,2,4,0]) ''' - return GiacMethods['permu2mat'](self,*args) + return GiacMethods['permu2mat'](self, *args) - def permuorder(self,*args): + def permuorder(self, *args): r'''From Giac's documentation: Help for permuorder: permuorder(Permut(a)) @@ -11376,9 +11376,9 @@ cdef class GiacMethods_base: See also: 1/ cycles2permu Ex1:permuorder([1,3,2,4,0]) ''' - return GiacMethods['permuorder'](self,*args) + return GiacMethods['permuorder'](self, *args) - def permute_vertices(self,*args): + def permute_vertices(self, *args): r'''From Giac's documentation: Help for permute_vertices: permute_vertices(Graph(G),Lst(V)) @@ -11386,9 +11386,9 @@ cdef class GiacMethods_base: See also: 1/ graph_vertices 2/ isomorphic_copy 3/ relabel_vertices Ex1:permute_vertices(graph([a,b,c]),[a,c,b]) ''' - return GiacMethods['permute_vertices'](self,*args) + return GiacMethods['permute_vertices'](self, *args) - def perpen_bisector(self,*args): + def perpen_bisector(self, *args): r'''From Giac's documentation: Help for perpen_bisector: perpen_bisector((Pnt or Cplx),(Pnt or Cplx)) @@ -11397,9 +11397,9 @@ cdef class GiacMethods_base: Ex1:perpen_bisector(1-i,i) Ex2:perpen_bisector([0,0,0],[5,5,0]) ''' - return GiacMethods['perpen_bisector'](self,*args) + return GiacMethods['perpen_bisector'](self, *args) - def perpendicular(self,*args): + def perpendicular(self, *args): r'''From Giac's documentation: Help for perpendicular: perpendicular((Pnt or Line),(Line or Plan)) @@ -11410,9 +11410,9 @@ cdef class GiacMethods_base: Ex3:perpendicular([0,0,0],line(x=y,y=z)) Ex4:perpendicular(line([0,0,0],[1,1,0]),plane(x+y+z=1)) ''' - return GiacMethods['perpendicular'](self,*args) + return GiacMethods['perpendicular'](self, *args) - def petersen_graph(self,*args): + def petersen_graph(self, *args): r'''From Giac's documentation: Help for petersen_graph: petersen_graph(Intg(n),[Intg(k)]) @@ -11422,9 +11422,9 @@ cdef class GiacMethods_base: Ex2:petersen_graph(6,3) Ex3:petersen_graph(10,2) ''' - return GiacMethods['petersen_graph'](self,*args) + return GiacMethods['petersen_graph'](self, *args) - def peval(self,*args): + def peval(self, *args): r'''From Giac's documentation: Help for peval: peval(Vect,Real(x0)) @@ -11433,9 +11433,9 @@ cdef class GiacMethods_base: Ex1:peval([1,0,-2],1) Ex2:peval([1,2,-25,-26,120],8) ''' - return GiacMethods['peval'](self,*args) + return GiacMethods['peval'](self, *args) - def pi(self,*args): + def pi(self, *args): r'''From Giac's documentation: Help for pi: pi() @@ -11446,9 +11446,9 @@ cdef class GiacMethods_base: Ex3: evalf(pi) Ex4: evalf(Pi) ''' - return GiacMethods['pi'](self,*args) + return GiacMethods['pi'](self, *args) - def pie(self,*args): + def pie(self, *args): r'''From Giac's documentation: Help for pie: pie(Mtrx) @@ -11458,9 +11458,9 @@ cdef class GiacMethods_base: Ex2:pie([3/2,2/3,5/4,4/5,7/6,6/7,9/8,8/9,11/10]) Ex3:pie([[2,"xyz","abc"],["A",2,5],["B",5,6],["C",7,7]]) ''' - return GiacMethods['pie'](self,*args) + return GiacMethods['pie'](self, *args) - def piecewise(self,*args): + def piecewise(self, *args): r'''From Giac's documentation: Help for piecewise: piecewise(Cond1,Expr1,..,Cond2p,Expr2p,[Expr2p+1]) @@ -11469,9 +11469,9 @@ cdef class GiacMethods_base: Ex1:piecewise(x<=-pi,x+2*pi,x<=pi,x,x+2*pi) Ex2:piecewise(x<-2,-2,x<-1,3x+4,x<0,1,x+1) ''' - return GiacMethods['piecewise'](self,*args) + return GiacMethods['piecewise'](self, *args) - def pivot(self,*args): + def pivot(self, *args): r'''From Giac's documentation: Help for pivot: pivot(Mtrx(A),Intg(nl),Intg(nc)) @@ -11480,9 +11480,9 @@ cdef class GiacMethods_base: Ex1:pivot([[1,2],[3,4],[5,6]],0,1) Ex2:pivot([[1,2],[3,4],[5,6]],1,1) ''' - return GiacMethods['pivot'](self,*args) + return GiacMethods['pivot'](self, *args) - def pixoff(self,*args): + def pixoff(self, *args): r'''From Giac's documentation: Help for pixoff: pixoff(Real(x),Real(y)) @@ -11490,9 +11490,9 @@ cdef class GiacMethods_base: See also: 1/ set_pixel 2/ pixon Ex1:pixoff(1,2) ''' - return GiacMethods['pixoff'](self,*args) + return GiacMethods['pixoff'](self, *args) - def pixon(self,*args): + def pixon(self, *args): r'''From Giac's documentation: Help for pixon: pixon(Real(x),Real(y)) @@ -11500,18 +11500,18 @@ cdef class GiacMethods_base: See also: 1/ set_pixel 2/ pixoff Ex1:pixon(1,2) ''' - return GiacMethods['pixon'](self,*args) + return GiacMethods['pixon'](self, *args) - def planar(self,*args): + def planar(self, *args): r'''From Giac's documentation: Help for planar: planar(Opt) Option for the draw_graph command. See also: 1/ spring 2/ tree 3/ draw_graph ''' - return GiacMethods['planar'](self,*args) + return GiacMethods['planar'](self, *args) - def plane(self,*args): + def plane(self, *args): r'''From Giac's documentation: Help for plane: plane(Pnt or Eq, [Pnt or Line],[Pnt]) @@ -11522,9 +11522,9 @@ cdef class GiacMethods_base: Ex3:plane(x+y+z=0) Ex4:plane(2*x+y-2*z-1) ''' - return GiacMethods['plane'](self,*args) + return GiacMethods['plane'](self, *args) - def plane_dual(self,*args): + def plane_dual(self, *args): r'''From Giac's documentation: Help for plane_dual: plane_dual(Graph(G)||Lst(F)) @@ -11532,9 +11532,9 @@ cdef class GiacMethods_base: See also: 1/ is_planar Ex1:plane_dual(hypercube_graph(3)) ''' - return GiacMethods['plane_dual'](self,*args) + return GiacMethods['plane_dual'](self, *args) - def playsnd(self,*args): + def playsnd(self, *args): r'''From Giac's documentation: Help for playsnd: playsnd(Vect) @@ -11542,18 +11542,18 @@ cdef class GiacMethods_base: See also: 1/ readwav 2/ writewav 3/ soundsec Ex1:playsnd(2^14*(sin(2*pi*440*soundsec(1))) ''' - return GiacMethods['playsnd'](self,*args) + return GiacMethods['playsnd'](self, *args) - def plex(self,*args): + def plex(self, *args): r'''From Giac's documentation: Help for plex: plex(Opt) Option of the gbasis or greduce command to specify an order for monomials (=default order=pure lexicographic). See also: 1/ gbasis 2/ greduce ''' - return GiacMethods['plex'](self,*args) + return GiacMethods['plex'](self, *args) - def plot(self,*args): + def plot(self, *args): r'''From Giac's documentation: Help for plot: plot((Expr or LstExpr),Var[=VarMin..VarMax],[color=LstColor]) @@ -11567,9 +11567,9 @@ cdef class GiacMethods_base: Ex6:plot(normald) Ex7:plot(normald(-1,2)) ''' - return GiacMethods['plot'](self,*args) + return GiacMethods['plot'](self, *args) - def plot3d(self,*args): + def plot3d(self, *args): r'''From Giac's documentation: Help for plot3d: plot3d(Expr||Lst(3*Expr),Var,Var) @@ -11581,9 +11581,9 @@ cdef class GiacMethods_base: Ex4:plot3d(f,-1..1,-2..2) Ex5:plot3d([f,g,h],-1..1,-2..2) ''' - return GiacMethods['plot3d'](self,*args) + return GiacMethods['plot3d'](self, *args) - def plotarea(self,*args): + def plotarea(self, *args): r'''From Giac's documentation: Help for plotarea: plotarea(Expr,x=a..b,[n],[Method]) @@ -11593,9 +11593,9 @@ cdef class GiacMethods_base: Ex2:plotarea(x^2,x=0..1,5,trapezoid) Ex3:plotarea(x^2,x=0..1,5,middle_point) ''' - return GiacMethods['plotarea'](self,*args) + return GiacMethods['plotarea'](self, *args) - def plotcdf(self,*args): + def plotcdf(self, *args): r'''From Giac's documentation: Help for plotcdf: plotcdf(Func,FuncParams) @@ -11605,9 +11605,9 @@ cdef class GiacMethods_base: Ex2:plotcdf(normald,0.0,1.0) Ex3:plotcdf([1,3,4,3,5,6]) ''' - return GiacMethods['plotcdf'](self,*args) + return GiacMethods['plotcdf'](self, *args) - def plotcontour(self,*args): + def plotcontour(self, *args): r'''From Giac's documentation: Help for plotcontour: plotcontour(Expr(Xpr),[LstVar],[LstVal]) @@ -11618,9 +11618,9 @@ cdef class GiacMethods_base: Ex3:plotcontour(x^2+2*y^2-2,[x,y],[1.0,2.0,3.0]) Ex4:plotcontour(x^2-y^2,[x=-4..4,y=-4..4],seq(k,k,-11,11,3),xstep=0.1,ystep=0.1) ''' - return GiacMethods['plotcontour'](self,*args) + return GiacMethods['plotcontour'](self, *args) - def plotdensity(self,*args): + def plotdensity(self, *args): r'''From Giac's documentation: Help for plotdensity: plotdensity(Expr,[x=xrange,y=yrange],[z],[xstep],[ystep]) @@ -11629,9 +11629,9 @@ cdef class GiacMethods_base: Ex1:plotdensity(x^2-y^2,[x=-2..2,y=-2..2],xstep=0.1,ystep=0.1) Ex2:plotdensity(x^2-y^2,[x=-2..2,y=-2..2],z=-2..2,xstep=0.1,ystep=0.1) ''' - return GiacMethods['plotdensity'](self,*args) + return GiacMethods['plotdensity'](self, *args) - def plotfield(self,*args): + def plotfield(self, *args): r'''From Giac's documentation: Help for plotfield: plotfield(Expr,VectVar,[Opt]) @@ -11643,9 +11643,9 @@ cdef class GiacMethods_base: Ex4:plotfield(-t*y,[t,y],normalize,xstep=0.5,ystep=0.5) Ex5:plotfield(-t*y,[t=-6.868..6.868,y=-6.868..6.868],normalize) ''' - return GiacMethods['plotfield'](self,*args) + return GiacMethods['plotfield'](self, *args) - def plotfunc(self,*args): + def plotfunc(self, *args): r'''From Giac's documentation: Help for plotfunc: plotfunc(Expr,[Var(x) or VectVar] ,[Intg(color)]) @@ -11657,9 +11657,9 @@ cdef class GiacMethods_base: Ex4:plotfunc(x^2+y^2,[x=-1..1,y=-2..2],nstep=900) Ex5:plotfunc((x+i*y)^2,[x=-1..1,y=-2..2],nstep=900,affichage=rempli) ''' - return GiacMethods['plotfunc'](self,*args) + return GiacMethods['plotfunc'](self, *args) - def plotimplicit(self,*args): + def plotimplicit(self, *args): r'''From Giac's documentation: Help for plotimplicit: plotimplicit(Expr,Var1,Var2) @@ -11675,9 +11675,9 @@ cdef class GiacMethods_base: Ex8:plotimplicit((x+5)^2+(y+4)^2-1,x=-6..-4,y=-5..-3) Ex9:plotimplicit((x+5)^2+(y+4)^2-1,[x=-6..-4,y=-5..-3]) ''' - return GiacMethods['plotimplicit'](self,*args) + return GiacMethods['plotimplicit'](self, *args) - def plotinequation(self,*args): + def plotinequation(self, *args): r'''From Giac's documentation: Help for plotinequation: plotinequation(Expr,[x=xrange,y=yrange],[xstep],[ystep]) @@ -11688,9 +11688,9 @@ cdef class GiacMethods_base: Ex3:plotinequation(3-(x^2-y^2),[x=-2..2,y=-2..2],xstep=0.1,ystep=0.1) Ex4:plotinequation([x+y>3,x^2x>=5,[1,2,6,7]) Ex2:remove(5,[1,2,5,6,7,5]) ''' - return GiacMethods['remove'](self,*args) + return GiacMethods['remove'](self, *args) - def reorder(self,*args): + def reorder(self, *args): r'''From Giac's documentation: Help for reorder: reorder(Expr, LstVar) @@ -13475,9 +13475,9 @@ cdef class GiacMethods_base: Ex1:reorder(-2) Ex2:reorder(x^2+2*x+y^2,[y,x]) ''' - return GiacMethods['reorder'](self,*args) + return GiacMethods['reorder'](self, *args) - def resample(self,*args): + def resample(self, *args): r'''From Giac's documentation: Help for resample: resample(Lst(clip),[Intg(s),[Intg(q)]]) @@ -13486,9 +13486,9 @@ cdef class GiacMethods_base: Ex1:resample(readwav("/some/file"),48000) Ex2:resample(readwav("/some/file"),48000,3) ''' - return GiacMethods['resample'](self,*args) + return GiacMethods['resample'](self, *args) - def residue(self,*args): + def residue(self, *args): r'''From Giac's documentation: Help for residue: residue(Expr,Var(v),Cplx(a)) @@ -13499,9 +13499,9 @@ cdef class GiacMethods_base: Ex3:residue(cos(z)/(z*(z-b)),z,0) Ex4:residue(c/(z*(z-b)),z=b) ''' - return GiacMethods['residue'](self,*args) + return GiacMethods['residue'](self, *args) - def resoudre(self,*args): + def resoudre(self, *args): r'''From Giac's documentation: Help for resoudre: resoudre(Expr,[Var]) @@ -13512,9 +13512,9 @@ cdef class GiacMethods_base: Ex3:resoudre([y-z=0,z-x=0,x-y=0,x-1+y+z=0],[x,y,z]) Ex4:resoudre([x^2-y^2=0,x^2-z^2=0],[x,y,z]) ''' - return GiacMethods['resoudre'](self,*args) + return GiacMethods['resoudre'](self, *args) - def resoudre_dans_C(self,*args): + def resoudre_dans_C(self, *args): r'''From Giac's documentation: Help for resoudre_dans_C: resoudre_dans_C(LstEq,LstVar) @@ -13525,9 +13525,9 @@ cdef class GiacMethods_base: Ex3:resoudre_dans_C(x^4-y^4 and x+y=0 and x^2=2*x,[x,y]) Ex4:resoudre_dans_C(u*v-u=v and v^2=u,[u,v]) ''' - return GiacMethods['resoudre_dans_C'](self,*args) + return GiacMethods['resoudre_dans_C'](self, *args) - def resoudre_systeme_lineaire(self,*args): + def resoudre_systeme_lineaire(self, *args): r'''From Giac's documentation: Help for resoudre_systeme_lineaire: resoudre_systeme_lineaire(LstLinEq,LstVar) @@ -13543,9 +13543,9 @@ cdef class GiacMethods_base: Ex8: p,l,u:=lu([[2,1,1],[1,1,2],[1,2,1]]);linsolve(p,l,u,[1,1,4]) Ex9: a:=[[100,2],[2,100]];linsolve(evalf(a),[0,1]); ''' - return GiacMethods['resoudre_systeme_lineaire'](self,*args) + return GiacMethods['resoudre_systeme_lineaire'](self, *args) - def resultant(self,*args): + def resultant(self, *args): r'''From Giac's documentation: Help for resultant: resultant(Poly,Poly,Var) @@ -13554,9 +13554,9 @@ cdef class GiacMethods_base: Ex1:resultant(x^2-1,x^3-1,x) Ex2:resultant(x^3-p*x+q,3*x^2-p,x) ''' - return GiacMethods['resultant'](self,*args) + return GiacMethods['resultant'](self, *args) - def reverse(self,*args): + def reverse(self, *args): r'''From Giac's documentation: Help for reverse: reverse(Lst(L)) @@ -13566,9 +13566,9 @@ cdef class GiacMethods_base: Ex3: L:=[1,2,3,4];L.revlist() Ex4: L:=[1,2,3,4];L.reverse() ''' - return GiacMethods['reverse'](self,*args) + return GiacMethods['reverse'](self, *args) - def reverse_graph(self,*args): + def reverse_graph(self, *args): r'''From Giac's documentation: Help for reverse_graph: reverse_graph(Graph(G)) @@ -13576,9 +13576,9 @@ cdef class GiacMethods_base: See also: 1/ digraph Ex1:reverse_graph(digraph(%{[1,2],[1,3],[2,3]%})) ''' - return GiacMethods['reverse_graph'](self,*args) + return GiacMethods['reverse_graph'](self, *args) - def reverse_rsolve(self,*args): + def reverse_rsolve(self, *args): r'''From Giac's documentation: Help for reverse_rsolve: reverse_rsolve(Vect(v)) @@ -13586,9 +13586,9 @@ cdef class GiacMethods_base: See also: 1/ rsolve Ex1:reverse_rsolve([1,-1,3,3]) ''' - return GiacMethods['reverse_rsolve'](self,*args) + return GiacMethods['reverse_rsolve'](self, *args) - def revert(self,*args): + def revert(self, *args): r'''From Giac's documentation: Help for revert: revert(Expr) @@ -13596,18 +13596,18 @@ cdef class GiacMethods_base: See also: 1/ series Ex1:revert(x+x^2+x^4) ''' - return GiacMethods['revert'](self,*args) + return GiacMethods['revert'](self, *args) - def revlex(self,*args): + def revlex(self, *args): r'''From Giac's documentation: Help for revlex: revlex(Opt) Option of the gbasis or greduce command to specify an order for monomials (complete degree then inverse lexicographic order). See also: 1/ gbasis 2/ greduce ''' - return GiacMethods['revlex'](self,*args) + return GiacMethods['revlex'](self, *args) - def revlist(self,*args): + def revlist(self, *args): r'''From Giac's documentation: Help for revlist: revlist(Lst(L)) @@ -13617,9 +13617,9 @@ cdef class GiacMethods_base: Ex3: L:=[1,2,3,4];L.revlist() Ex4: L:=[1,2,3,4];L.reverse() ''' - return GiacMethods['revlist'](self,*args) + return GiacMethods['revlist'](self, *args) - def rgb(self,*args): + def rgb(self, *args): r'''From Giac's documentation: Help for rgb: rgb(Opt) @@ -13632,9 +13632,9 @@ cdef class GiacMethods_base: Ex5: F:=display(square(0,2+i),filled+rgb(rand(),rand(),rand())) Ex6: L:=rand(),rand(),rand();affichage(square(0,2+i),rgb(L)+rempli);legend(0.2,[L]) ''' - return GiacMethods['rgb'](self,*args) + return GiacMethods['rgb'](self, *args) - def rhombus(self,*args): + def rhombus(self, *args): r'''From Giac's documentation: Help for rhombus: rhombus(Pnt(A)||Cplx,Pnt(B)||Cplx,Angle(a)||Pnt(P)||Lst(P,a)),[Var(C)],[Var(D)]) @@ -13646,9 +13646,9 @@ cdef class GiacMethods_base: Ex4:rhombus(point(0,0,0),point(3,3,3),point(0,0,3),C,D) Ex5:rhombus(point(0,0,0),point(3,3,3),[point(0,0,3),pi/4],C,D) ''' - return GiacMethods['rhombus'](self,*args) + return GiacMethods['rhombus'](self, *args) - def rhombus_point(self,*args): + def rhombus_point(self, *args): r'''From Giac's documentation: Help for rhombus_point: rhombus_point(Opt) @@ -13657,9 +13657,9 @@ cdef class GiacMethods_base: Ex1: F:=display(point(2+1.5*i),point_point) Ex2: F:=display(point(2+1.5*i),rhombus_point) ''' - return GiacMethods['rhombus_point'](self,*args) + return GiacMethods['rhombus_point'](self, *args) - def rhs(self,*args): + def rhs(self, *args): r'''From Giac's documentation: Help for rhs: rhs(Equal(a=b) or Interval(a..b) or Str,Intg) @@ -13670,9 +13670,9 @@ cdef class GiacMethods_base: Ex3:rhs(1..5) Ex4:rhs("abcdefg",3) ''' - return GiacMethods['rhs'](self,*args) + return GiacMethods['rhs'](self, *args) - def riemann_window(self,*args): + def riemann_window(self, *args): r'''From Giac's documentation: Help for riemann_window: riemann_window(Lst,[Interval(n1..n2)]) @@ -13680,9 +13680,9 @@ cdef class GiacMethods_base: See also: 1/ blackman_harris_window 2/ blackman_window 3/ bohman_window 4/ cosine_window 5/ gaussian_window 6/ hamming_window 7/ hann_poisson_window 8/ hann_window 9/ parzen_window 10/ poisson_window 11/ bartlett_hann_window 12/ triangle_window 13/ tukey_window 14/ welch_window Ex1: scatterplot(riemann_window(randvector(1000,0..1))) ''' - return GiacMethods['riemann_window'](self,*args) + return GiacMethods['riemann_window'](self, *args) - def right(self,*args): + def right(self, *args): r'''From Giac's documentation: Help for right: right(Equal(a=b) or Interval(a..b) or Str,Intg) @@ -13693,9 +13693,9 @@ cdef class GiacMethods_base: Ex3:right(1..5) Ex4:right("abcdefg",3) ''' - return GiacMethods['right'](self,*args) + return GiacMethods['right'](self, *args) - def right_rectangle(self,*args): + def right_rectangle(self, *args): r'''From Giac's documentation: Help for right_rectangle: right_rectangle(Opt) @@ -13708,9 +13708,9 @@ cdef class GiacMethods_base: Ex5: area(x^2,x=0..1,5,middle_point) Ex6: area(x^2,x=0..1,5,trapezoid) ''' - return GiacMethods['right_rectangle'](self,*args) + return GiacMethods['right_rectangle'](self, *args) - def right_triangle(self,*args): + def right_triangle(self, *args): r'''From Giac's documentation: Help for right_triangle: right_triangle((Pnt(A) or Cplx),(Pnt(B) or Cplx),(Real(k) or Pnt(P) or Lst(P,k)),[Var(C)]) @@ -13722,9 +13722,9 @@ cdef class GiacMethods_base: Ex4:right_triangle(point(0,0,0),point(3,3,3),[point(0,0,3),1/2],C) Ex5:right_triangle(point(0,0,0),point(3,3,3),[point(0,0,3),1/2],C) ''' - return GiacMethods['right_triangle'](self,*args) + return GiacMethods['right_triangle'](self, *args) - def risch(self,*args): + def risch(self, *args): r'''From Giac's documentation: Help for risch: risch(Expr,[Var]) @@ -13734,9 +13734,9 @@ cdef class GiacMethods_base: Ex2:risch(ln(x)) Ex3:risch(exp(x^2),x) ''' - return GiacMethods['risch'](self,*args) + return GiacMethods['risch'](self, *args) - def rm_a_z(self,*args): + def rm_a_z(self, *args): r'''From Giac's documentation: Help for rm_a_z: rm_a_z(NULL) @@ -13744,9 +13744,9 @@ cdef class GiacMethods_base: See also: 1/ rm_all_vars Ex1:rm_a_z() ''' - return GiacMethods['rm_a_z'](self,*args) + return GiacMethods['rm_a_z'](self, *args) - def rm_all_vars(self,*args): + def rm_all_vars(self, *args): r'''From Giac's documentation: Help for rm_all_vars: rm_all_vars(NULL) @@ -13754,9 +13754,9 @@ cdef class GiacMethods_base: See also: 1/ rm_a_z Ex1:rm_all_vars() ''' - return GiacMethods['rm_all_vars'](self,*args) + return GiacMethods['rm_all_vars'](self, *args) - def rmbreakpoint(self,*args): + def rmbreakpoint(self, *args): r'''From Giac's documentation: Help for rmbreakpoint: rmbreakpoint(Intg) @@ -13764,9 +13764,9 @@ cdef class GiacMethods_base: See also: 1/ breakpoint Ex1:rmbreakpoint(1) ''' - return GiacMethods['rmbreakpoint'](self,*args) + return GiacMethods['rmbreakpoint'](self, *args) - def rmmod(self,*args): + def rmmod(self, *args): r'''From Giac's documentation: Help for rmmod: rmmod(Str(pwd)) @@ -13774,9 +13774,9 @@ cdef class GiacMethods_base: See also: 1/ lsmod 2/ insmod Ex1:rmmod("/home/parisse/giac/src/libprogfr.so") ''' - return GiacMethods['rmmod'](self,*args) + return GiacMethods['rmmod'](self, *args) - def rmwatch(self,*args): + def rmwatch(self, *args): r'''From Giac's documentation: Help for rmwatch: rmwatch(Var) @@ -13784,9 +13784,9 @@ cdef class GiacMethods_base: See also: 1/ watch Ex1:rmwatch(a) ''' - return GiacMethods['rmwatch'](self,*args) + return GiacMethods['rmwatch'](self, *args) - def romberg(self,*args): + def romberg(self, *args): r'''From Giac's documentation: Help for romberg: romberg(Expr(f(x)),Var(x),Real(a),Real(b)) @@ -13796,9 +13796,9 @@ cdef class GiacMethods_base: Ex2:romberg(x^2,x,0,1) Ex3:romberg(exp(-x^2),x,-1,1) ''' - return GiacMethods['romberg'](self,*args) + return GiacMethods['romberg'](self, *args) - def rombergm(self,*args): + def rombergm(self, *args): r'''From Giac's documentation: Help for rombergm: rombergm(Opt) @@ -13809,9 +13809,9 @@ cdef class GiacMethods_base: Ex3: area(x^2,x=0..1,5,rombergm) Ex4:rombergm(area(x^2,x=0..1,5,gauss15)) ''' - return GiacMethods['rombergm'](self,*args) + return GiacMethods['rombergm'](self, *args) - def rombergt(self,*args): + def rombergt(self, *args): r'''From Giac's documentation: Help for rombergt: rombergt(Opt) @@ -13822,9 +13822,9 @@ cdef class GiacMethods_base: Ex3: area(x^2,x=0..1,5,rombergm) Ex4:rombergt(area(x^2,x=0..1,5,gauss15)) ''' - return GiacMethods['rombergt'](self,*args) + return GiacMethods['rombergt'](self, *args) - def rond(self,*args): + def rond(self, *args): r'''From Giac's documentation: Help for rond: rond(Real(r),[Real(a)],[Real(b)]) @@ -13835,9 +13835,9 @@ cdef class GiacMethods_base: Ex3:rond(40,90) Ex4:rond(40,10,100) ''' - return GiacMethods['rond'](self,*args) + return GiacMethods['rond'](self, *args) - def root(self,*args): + def root(self, *args): r'''From Giac's documentation: Help for root: root(Expr(a),Expr(b)) @@ -13848,9 +13848,9 @@ cdef class GiacMethods_base: Ex3:root(3,1.2) Ex4:root(3.2,1.2) ''' - return GiacMethods['root'](self,*args) + return GiacMethods['root'](self, *args) - def rootof(self,*args): + def rootof(self, *args): r'''From Giac's documentation: Help for rootof: rootof(LstPoly(P),LstPoly(Q)) @@ -13860,9 +13860,9 @@ cdef class GiacMethods_base: Ex2: normal(1/rootof([1,0,0],[1,1,0,-1])) Ex3: rootof(x^4+x+1):='j'; normal(j^5); ''' - return GiacMethods['rootof'](self,*args) + return GiacMethods['rootof'](self, *args) - def roots(self,*args): + def roots(self, *args): r'''From Giac's documentation: Help for roots: roots(Poly,[Var]) @@ -13871,9 +13871,9 @@ cdef class GiacMethods_base: Ex1:roots(t^3-1,t) Ex2:roots(x^5-2*x^4+x^3) ''' - return GiacMethods['roots'](self,*args) + return GiacMethods['roots'](self, *args) - def rotate(self,*args): + def rotate(self, *args): r'''From Giac's documentation: Help for rotate: rotate(Lst||Str(L),[Intg(n)]) @@ -13888,9 +13888,9 @@ cdef class GiacMethods_base: Ex7: L:=[0,1,2,3];L:=rotate([0,1,2,3],2) Ex8: L:=[0,1,2,3];L.rotate(2) ''' - return GiacMethods['rotate'](self,*args) + return GiacMethods['rotate'](self, *args) - def rotation(self,*args): + def rotation(self, *args): r'''From Giac's documentation: Help for rotation: rotation((Pnt(B) or Cplx or Dr3),Angle(a1),(Pnt(A) or Curve)) @@ -13902,9 +13902,9 @@ cdef class GiacMethods_base: Ex4: r:=rotation(1+i,pi/2);r(i) Ex5: r:=rotation(line(x=y,y=z),pi/2);r(point(1,-1,2)) ''' - return GiacMethods['rotation'](self,*args) + return GiacMethods['rotation'](self, *args) - def round(self,*args): + def round(self, *args): r'''From Giac's documentation: Help for round: round(Real or Cplx,[Intg(n)]) @@ -13916,9 +13916,9 @@ cdef class GiacMethods_base: Ex4:round(1.237,2) Ex5:round(sqrt(2)+i*sqrt(5),4) ''' - return GiacMethods['round'](self,*args) + return GiacMethods['round'](self, *args) - def row(self,*args): + def row(self, *args): r'''From Giac's documentation: Help for row: row(Mtrx(A),Intg(n)||Interval(n1..n2)) @@ -13928,9 +13928,9 @@ cdef class GiacMethods_base: Ex2:row([[1,2,3],[4,5,6],[7,8,9]],0..1) Ex3: count_eq(3,[[1,2,3],[4,3,2],[3,2,1]],row) ''' - return GiacMethods['row'](self,*args) + return GiacMethods['row'](self, *args) - def rowAdd(self,*args): + def rowAdd(self, *args): r'''From Giac's documentation: Help for rowAdd: rowAdd(Mtrx(A),Intg(n1),Intg(n2)) @@ -13938,9 +13938,9 @@ cdef class GiacMethods_base: See also: 1/ rowSwap Ex1:rowAdd([[1,2],[3,4],[5,6]],1,2) ''' - return GiacMethods['rowAdd'](self,*args) + return GiacMethods['rowAdd'](self, *args) - def rowDim(self,*args): + def rowDim(self, *args): r'''From Giac's documentation: Help for rowDim: rowDim(Mtrx) @@ -13949,9 +13949,9 @@ cdef class GiacMethods_base: Ex1:rowDim([[1,2,3],[4,5,6]]) Ex2:rowDim([[1,2],[3,4],[5,6]]) ''' - return GiacMethods['rowDim'](self,*args) + return GiacMethods['rowDim'](self, *args) - def rowNorm(self,*args): + def rowNorm(self, *args): r'''From Giac's documentation: Help for rowNorm: rowNorm(Vect or Mtrx) @@ -13960,9 +13960,9 @@ cdef class GiacMethods_base: Ex1:rowNorm([[1,2],[3,-4]]) Ex2:rowNorm([[1,2,3,-4],[-5,3,2,1]]) ''' - return GiacMethods['rowNorm'](self,*args) + return GiacMethods['rowNorm'](self, *args) - def rowSwap(self,*args): + def rowSwap(self, *args): r'''From Giac's documentation: Help for rowSwap: rowSwap(Mtrx(A),Intg(n1),Intg(n2)) @@ -13970,9 +13970,9 @@ cdef class GiacMethods_base: See also: 1/ rowAdd 2/ colSwap Ex1:rowSwap([[1,2],[3,4],[5,6]],1,2) ''' - return GiacMethods['rowSwap'](self,*args) + return GiacMethods['rowSwap'](self, *args) - def rowdim(self,*args): + def rowdim(self, *args): r'''From Giac's documentation: Help for rowdim: rowdim(Mtrx) @@ -13981,9 +13981,9 @@ cdef class GiacMethods_base: Ex1:rowdim([[1,2,3],[4,5,6]]) Ex2:rowdim([[1,2],[3,4],[5,6]]) ''' - return GiacMethods['rowdim'](self,*args) + return GiacMethods['rowdim'](self, *args) - def rownorm(self,*args): + def rownorm(self, *args): r'''From Giac's documentation: Help for rownorm: rownorm(Vect or Mtrx) @@ -13992,9 +13992,9 @@ cdef class GiacMethods_base: Ex1:rownorm([[1,2],[3,-4]]) Ex2:rownorm([[1,2,3,-4],[-5,3,2,1]]) ''' - return GiacMethods['rownorm'](self,*args) + return GiacMethods['rownorm'](self, *args) - def rowspace(self,*args): + def rowspace(self, *args): r'''From Giac's documentation: Help for rowspace: rowspace(Mtrx(A), [Var(d)]) @@ -14003,9 +14003,9 @@ cdef class GiacMethods_base: Ex1:rowspace([[1,2,3],[1,2,3],[1,2,4],[1,2,5]]) Ex2:rowspace([[1,2,3],[1,3,6],[2,5,9]],d) ''' - return GiacMethods['rowspace'](self,*args) + return GiacMethods['rowspace'](self, *args) - def rowswap(self,*args): + def rowswap(self, *args): r'''From Giac's documentation: Help for rowswap: rowswap(Mtrx(A),Intg(n1),Intg(n2)) @@ -14013,9 +14013,9 @@ cdef class GiacMethods_base: See also: 1/ rowAdd 2/ colSwap Ex1:rowswap([[1,2],[3,4],[5,6]],1,2) ''' - return GiacMethods['rowswap'](self,*args) + return GiacMethods['rowswap'](self, *args) - def rref(self,*args): + def rref(self, *args): r'''From Giac's documentation: Help for rref: rref(Mtrx(M),[Intg(k)]||Opt) @@ -14026,9 +14026,9 @@ cdef class GiacMethods_base: Ex3:rref([[2,1,1,-1],[1,1,2,-1],[1,2,1,-4]],2) Ex4:rref([[1,1,0,0,-a1],[0,1,1,0,-a2],[0,0,1,1,-a3],[1,0,0,1,-a4]],keep_pivot) ''' - return GiacMethods['rref'](self,*args) + return GiacMethods['rref'](self, *args) - def rsolve(self,*args): + def rsolve(self, *args): r'''From Giac's documentation: Help for rsolve: rsolve((Expr or LstExpr),(Var or LstVar),(InitVal or LstInitVal)) @@ -14040,9 +14040,9 @@ cdef class GiacMethods_base: Ex4:rsolve(u(n+2)=u(n)+2*u(n+1)+n+1,u(n),[u(0)=0,u(1)=1]) Ex5:rsolve([u(n+1)=3*v(n)+u(n),v(n+1)=v(n)+u(n)],[u(n),v(n)],[u(0)=1,v(0)=2]) ''' - return GiacMethods['rsolve'](self,*args) + return GiacMethods['rsolve'](self, *args) - def same(self,*args): + def same(self, *args): r'''From Giac's documentation: Help for same: same(Expr,Expr) @@ -14051,9 +14051,9 @@ cdef class GiacMethods_base: Ex1:same(a,b) Ex2:same((2-1)^2,2^2-2*2+1) ''' - return GiacMethods['same'](self,*args) + return GiacMethods['same'](self, *args) - def sample(self,*args): + def sample(self, *args): r'''From Giac's documentation: Help for sample: sample(Lst(L),Intg(n)) @@ -14066,9 +14066,9 @@ cdef class GiacMethods_base: Ex5: L:=[1,2,3,4,5,6];L.sample(3) Ex6: ''' - return GiacMethods['sample'](self,*args) + return GiacMethods['sample'](self, *args) - def samplerate(self,*args): + def samplerate(self, *args): r'''From Giac's documentation: Help for samplerate: samplerate(Lst(clip)) @@ -14076,9 +14076,9 @@ cdef class GiacMethods_base: See also: 1/ bit_depth 2/ channels 3/ channel_data 4/ duration Ex1:samplerate(readwav("/some/file")) ''' - return GiacMethods['samplerate'](self,*args) + return GiacMethods['samplerate'](self, *args) - def sans_factoriser(self,*args): + def sans_factoriser(self, *args): r'''From Giac's documentation: Help for sans_factoriser: sans_factoriser(Opt.) @@ -14090,9 +14090,9 @@ cdef class GiacMethods_base: Ex4: plotimplicit(x^2+y^2+z^2-1,[x,y,z],xstep=0.2,ystep=0.2,zstep=0.2,unfactored) Ex5: plotimplicit(x^2+y^2+z^2-1,x=0..1,y=0..1,z=0..1,xstep=0.2,ystep=0.2,zstep=0.2,unfactored) ''' - return GiacMethods['sans_factoriser'](self,*args) + return GiacMethods['sans_factoriser'](self, *args) - def saute(self,*args): + def saute(self, *args): r'''From Giac's documentation: Help for saute: saute(NULL or Real(n)) @@ -14101,9 +14101,9 @@ cdef class GiacMethods_base: Ex1: saute 30 Ex2:saute(30) ''' - return GiacMethods['saute'](self,*args) + return GiacMethods['saute'](self, *args) - def scalarProduct(self,*args): + def scalarProduct(self, *args): r'''From Giac's documentation: Help for scalarProduct: scalarProduct(Vect(v1),Vect(v2)) @@ -14113,9 +14113,9 @@ cdef class GiacMethods_base: Ex2:scalarProduct([3,2,4],[3,2,4]) Ex3:scalarProduct([[1,2],[3,4]],[[3,2],[4,5]]) ''' - return GiacMethods['scalarProduct'](self,*args) + return GiacMethods['scalarProduct'](self, *args) - def scalar_product(self,*args): + def scalar_product(self, *args): r'''From Giac's documentation: Help for scalar_product: scalar_product(Vect(v1),Vect(v2)) @@ -14125,9 +14125,9 @@ cdef class GiacMethods_base: Ex2:scalar_product([3,2,4],[3,2,4]) Ex3:scalar_product([[1,2],[3,4]],[[3,2],[4,5]]) ''' - return GiacMethods['scalar_product'](self,*args) + return GiacMethods['scalar_product'](self, *args) - def scatterplot(self,*args): + def scatterplot(self, *args): r'''From Giac's documentation: Help for scatterplot: scatterplot(Mtrx) @@ -14135,9 +14135,9 @@ cdef class GiacMethods_base: See also: 1/ polygonplot 2/ polygonscatterplot 3/ listplot Ex1:scatterplot([[1,2,3],[2,0,1],[-1,2,3]]) ''' - return GiacMethods['scatterplot'](self,*args) + return GiacMethods['scatterplot'](self, *args) - def schur(self,*args): + def schur(self, *args): r'''From Giac's documentation: Help for schur: schur(Mtrx(A)) @@ -14146,9 +14146,9 @@ cdef class GiacMethods_base: Ex1:schur([[1,2,3],[4,5,6],[7,8,1]]) Ex2:schur([[1,2,3,4],[4,5,6,7],[7,8,9,0],[0,1,2,3]]) ''' - return GiacMethods['schur'](self,*args) + return GiacMethods['schur'](self, *args) - def sec(self,*args): + def sec(self, *args): r'''From Giac's documentation: Help for sec: sec(Expr) @@ -14156,9 +14156,9 @@ cdef class GiacMethods_base: See also: 1/ cos 2/ asec Ex1:sec(pi/3) ''' - return GiacMethods['sec'](self,*args) + return GiacMethods['sec'](self, *args) - def secant_solver(self,*args): + def secant_solver(self, *args): r'''From Giac's documentation: Help for secant_solver: secant_solver(Opt) @@ -14171,9 +14171,9 @@ cdef class GiacMethods_base: Ex5: fsolve(cos(x)=x,x,0,secant_solver) Ex6: fsolve(cos(x)=x,x,0,steffenson_solver) ''' - return GiacMethods['secant_solver'](self,*args) + return GiacMethods['secant_solver'](self, *args) - def segment(self,*args): + def segment(self, *args): r'''From Giac's documentation: Help for segment: segment((Pnt or Cplx or Lst([xM,yM])),(Pnt or Cplx or Lst([xN,yN]),[Var],[Var] or Opt) @@ -14187,9 +14187,9 @@ cdef class GiacMethods_base: Ex6: arc(i,1,pi/4,segment) Ex7: affichage( arc(i,1,pi/4,segment),1+rempli) ''' - return GiacMethods['segment'](self,*args) + return GiacMethods['segment'](self, *args) - def seidel_spectrum(self,*args): + def seidel_spectrum(self, *args): r'''From Giac's documentation: Help for seidel_spectrum: seidel_spectrum(Graph(G)) @@ -14197,9 +14197,9 @@ cdef class GiacMethods_base: See also: 1/ graph_spectrum Ex1:seidel_spectrum(graph("clebsch")) ''' - return GiacMethods['seidel_spectrum'](self,*args) + return GiacMethods['seidel_spectrum'](self, *args) - def seidel_switch(self,*args): + def seidel_switch(self, *args): r'''From Giac's documentation: Help for seidel_switch: seidel_switch(Graph(G),Lst(V)) @@ -14207,9 +14207,9 @@ cdef class GiacMethods_base: See also: 1/ neighbors 2/ graph_complement Ex1:seidel_switch(cycle_graph(5),[1,2]) ''' - return GiacMethods['seidel_switch'](self,*args) + return GiacMethods['seidel_switch'](self, *args) - def select(self,*args): + def select(self, *args): r'''From Giac's documentation: Help for select: select(FncBool(f),Lst(l)) @@ -14218,9 +14218,9 @@ cdef class GiacMethods_base: Ex1:select(x->x>=5,[1,2,6,7]) Ex2:select(x->isprime(x),range(20)).^2 ''' - return GiacMethods['select'](self,*args) + return GiacMethods['select'](self, *args) - def semi_augment(self,*args): + def semi_augment(self, *args): r'''From Giac's documentation: Help for semi_augment: semi_augment(Mtrx(A),Mtrx(B)) @@ -14228,9 +14228,9 @@ cdef class GiacMethods_base: See also: 1/ augment Ex1:semi_augment([[68,-21],[56,59],[1,2]],[[68,-21],[56,59]]) ''' - return GiacMethods['semi_augment'](self,*args) + return GiacMethods['semi_augment'](self, *args) - def seq(self,*args): + def seq(self, *args): r'''From Giac's documentation: Help for seq: seq(Expr(Xpr),Var(Var)=Int(a..b),[Real(p)]||Expr(Xpr),Var(Var),Real(a),Real(b),[Real(p)]) @@ -14248,9 +14248,9 @@ cdef class GiacMethods_base: Ex10: [seq(0.3..2,0.2)] Ex11: a:=(1,2,3);eval(seq(a,4)) ''' - return GiacMethods['seq'](self,*args) + return GiacMethods['seq'](self, *args) - def seqplot(self,*args): + def seqplot(self, *args): r'''From Giac's documentation: Help for seqplot: seqplot(Expr(f(Var)),Var=[a,xm,xM],Intg(p)) @@ -14260,9 +14260,9 @@ cdef class GiacMethods_base: Ex2:seqplot(sqrt(2+t),t=6,5) Ex3:seqplot(sqrt(2+x),x=[6,1,7],5,affichage=epaisseur_ligne_2) ''' - return GiacMethods['seqplot'](self,*args) + return GiacMethods['seqplot'](self, *args) - def seqsolve(self,*args): + def seqsolve(self, *args): r'''From Giac's documentation: Help for seqsolve: seqsolve((Expr or LstExpr),(Var or LstVar),(InitVal or LstInitVal)) @@ -14275,9 +14275,9 @@ cdef class GiacMethods_base: Ex5:seqsolve([x+2*y,n+1+x],[x,y,n],[0,1]) Ex6:seqsolve([x+2*y+n+1,x],[x,y,n],[0,1]) ''' - return GiacMethods['seqsolve'](self,*args) + return GiacMethods['seqsolve'](self, *args) - def sequence_graph(self,*args): + def sequence_graph(self, *args): r'''From Giac's documentation: Help for sequence_graph: sequence_graph(Lst(L)) @@ -14285,9 +14285,9 @@ cdef class GiacMethods_base: See also: 1/ degree_sequence 2/ is_graphic_sequence Ex1:sequence_graph(degree_sequence(sequence_graph([3,2,4,2,3,4,5,7]))) ''' - return GiacMethods['sequence_graph'](self,*args) + return GiacMethods['sequence_graph'](self, *args) - def series(self,*args): + def series(self, *args): r'''From Giac's documentation: Help for series: series(Expr,Equal(var=limit_point),[Order],[Dir(1,0,-1)]) @@ -14307,9 +14307,9 @@ cdef class GiacMethods_base: Ex12:series(subst(sin(x+y)+cos(y*x),[x,y],h*[x,y]),h=0,6,polynom)(h=1) Ex13: truncate(series(sin(x),x=0,6),6) ''' - return GiacMethods['series'](self,*args) + return GiacMethods['series'](self, *args) - def set_edge_attribute(self,*args): + def set_edge_attribute(self, *args): r'''From Giac's documentation: Help for set_edge_attribute: set_edge_attribute(Graph(G),Edge(e),Seq(tag1=value1,tag2=value2,..)) @@ -14317,9 +14317,9 @@ cdef class GiacMethods_base: See also: 1/ discard_edge_attribute 2/ get_edge_attribute 3/ list_edge_attributes Ex1:set_edge_attribute(cycle_graph(3),[1,2],"cost"=12.4) ''' - return GiacMethods['set_edge_attribute'](self,*args) + return GiacMethods['set_edge_attribute'](self, *args) - def set_edge_weight(self,*args): + def set_edge_weight(self, *args): r'''From Giac's documentation: Help for set_edge_weight: set_edge_weight(Graph(G),Edge(e),Real(w)) @@ -14327,9 +14327,9 @@ cdef class GiacMethods_base: See also: 1/ is_weighted 2/ get_edge_weight 3/ make_weighted 4/ weight_matrix Ex1:set_edge_weight(graph(%{[1,2],[2,3]%}),[1,2],5) ''' - return GiacMethods['set_edge_weight'](self,*args) + return GiacMethods['set_edge_weight'](self, *args) - def set_graph_attribute(self,*args): + def set_graph_attribute(self, *args): r'''From Giac's documentation: Help for set_graph_attribute: set_graph_attribute(Graph(G),Seq(tag1=value1,tag2=value2,..)) @@ -14337,9 +14337,9 @@ cdef class GiacMethods_base: See also: 1/ discard_graph_attribute 2/ get_graph_attribute 3/ list_graph_attributes Ex1:set_graph_attribute(cycle_graph(3),"name"="cycle graph") ''' - return GiacMethods['set_graph_attribute'](self,*args) + return GiacMethods['set_graph_attribute'](self, *args) - def set_pixel(self,*args): + def set_pixel(self, *args): r'''From Giac's documentation: Help for set_pixel: set_pixel(Intg(x),Intg(y),Intg(col)) @@ -14347,9 +14347,9 @@ cdef class GiacMethods_base: See also: 1/ clear 2/ show_pixels 3/ draw_line 4/ draw_rectangle 5/ draw_polygon Ex1: clear(); set_pixel(4); draw_pixel(1,2,red); show_pixels(); ''' - return GiacMethods['set_pixel'](self,*args) + return GiacMethods['set_pixel'](self, *args) - def set_vertex_attribute(self,*args): + def set_vertex_attribute(self, *args): r'''From Giac's documentation: Help for set_vertex_attribute: set_vertex_attribute(Graph(G),Vrtx(v),Seq(tag1=value1,tag2=value2,..)) @@ -14357,9 +14357,9 @@ cdef class GiacMethods_base: See also: 1/ discard_vertex_attribute 2/ get_vertex_attribute 3/ list_vertex_attributes Ex1:set_vertex_attribute(cycle_graph(3),1,"supply"=27) ''' - return GiacMethods['set_vertex_attribute'](self,*args) + return GiacMethods['set_vertex_attribute'](self, *args) - def set_vertex_positions(self,*args): + def set_vertex_positions(self, *args): r'''From Giac's documentation: Help for set_vertex_positions: set_vertex_positions(Graph(G),Lst(vp)) @@ -14367,9 +14367,9 @@ cdef class GiacMethods_base: See also: 1/ draw_graph Ex1: G:=graph([1,2,3,4,5,6],%{[1,2],[1,4],[4,5],[2,5],[2,3],[3,6],[5,6]%}); G:=set_vertex_positions(G,[[0,0],[0.5,0],[1,0],[0,0.5],[0.5,0.5],[1,0.5]]) ''' - return GiacMethods['set_vertex_positions'](self,*args) + return GiacMethods['set_vertex_positions'](self, *args) - def shift(self,*args): + def shift(self, *args): r'''From Giac's documentation: Help for shift: shift(Lst,[Intg(n)]) @@ -14381,9 +14381,9 @@ cdef class GiacMethods_base: Ex4: L:=[0,1,2,3];L:=shift(L,2) Ex5: L:=[0,1,2,3];L.shift(2) ''' - return GiacMethods['shift'](self,*args) + return GiacMethods['shift'](self, *args) - def shift_phase(self,*args): + def shift_phase(self, *args): r'''From Giac's documentation: Help for shift_phase: shift_phase(Expr) @@ -14396,9 +14396,9 @@ cdef class GiacMethods_base: Ex5:shift_phase(cos(t)) Ex6:shift_phase(tan(u)) ''' - return GiacMethods['shift_phase'](self,*args) + return GiacMethods['shift_phase'](self, *args) - def shortest_path(self,*args): + def shortest_path(self, *args): r'''From Giac's documentation: Help for shortest_path: shortest_path(Graph(G),Vrtx(s),Vrtx(t)||Lst(T)) @@ -14406,9 +14406,9 @@ cdef class GiacMethods_base: See also: 1/ dijkstra 2/ vertex_distance Ex1:shortest_path(cycle_graph(6),1,5) ''' - return GiacMethods['shortest_path'](self,*args) + return GiacMethods['shortest_path'](self, *args) - def show_pixels(self,*args): + def show_pixels(self, *args): r'''From Giac's documentation: Help for show_pixels: show_pixels(NULL) @@ -14416,9 +14416,9 @@ cdef class GiacMethods_base: See also: 1/ set_pixel 2/ clear Ex1:show_pixels() ''' - return GiacMethods['show_pixels'](self,*args) + return GiacMethods['show_pixels'](self, *args) - def shuffle(self,*args): + def shuffle(self, *args): r'''From Giac's documentation: Help for shuffle: shuffle(Intg(n)||Lst(L)) @@ -14430,9 +14430,9 @@ cdef class GiacMethods_base: Ex4: L:=[1,3,5,7,9];L:=randperm(L) Ex5: L:=[1,3,5,7,9];L.randperm() ''' - return GiacMethods['shuffle'](self,*args) + return GiacMethods['shuffle'](self, *args) - def sierpinski_graph(self,*args): + def sierpinski_graph(self, *args): r'''From Giac's documentation: Help for sierpinski_graph: sierpinski_graph(Intg(n),Intg(k),[triangle]) @@ -14444,9 +14444,9 @@ cdef class GiacMethods_base: Ex4:sierpinski_graph(3,2) Ex5:sierpinski_graph(3,3,at_triangle) ''' - return GiacMethods['sierpinski_graph'](self,*args) + return GiacMethods['sierpinski_graph'](self, *args) - def sign(self,*args): + def sign(self, *args): r'''From Giac's documentation: Help for sign: sign(Expr) @@ -14455,9 +14455,9 @@ cdef class GiacMethods_base: Ex1:sign(-4) Ex2:sign(4-5) ''' - return GiacMethods['sign'](self,*args) + return GiacMethods['sign'](self, *args) - def signature(self,*args): + def signature(self, *args): r'''From Giac's documentation: Help for signature: signature(Permut) @@ -14465,9 +14465,9 @@ cdef class GiacMethods_base: See also: 1/ permu2cycles 2/ is_permu Ex1:signature([1,0,3,4,2]) ''' - return GiacMethods['signature'](self,*args) + return GiacMethods['signature'](self, *args) - def signe(self,*args): + def signe(self, *args): r'''From Giac's documentation: Help for signe: signe(Str(s)) @@ -14476,9 +14476,9 @@ cdef class GiacMethods_base: Ex1:signe("Thomas") Ex2:signe(Thomas) ''' - return GiacMethods['signe'](self,*args) + return GiacMethods['signe'](self, *args) - def similarity(self,*args): + def similarity(self, *args): r'''From Giac's documentation: Help for similarity: similarity(Pnt or Dr3,Real,Angle,Pnt) @@ -14489,9 +14489,9 @@ cdef class GiacMethods_base: Ex3: s:=similarity(1+i,2,pi/3);s(i) Ex4: s:=similarity(line(x=y,y=z),2,pi/3),s(point(-1,2,1)) ''' - return GiacMethods['similarity'](self,*args) + return GiacMethods['similarity'](self, *args) - def simp2(self,*args): + def simp2(self, *args): r'''From Giac's documentation: Help for simp2: simp2(Intg(A) or Poly(A),Intg(B) or Poly(B)) @@ -14500,9 +14500,9 @@ cdef class GiacMethods_base: Ex1:simp2(12,18) Ex2:simp2(x^3-1,x^2-1) ''' - return GiacMethods['simp2'](self,*args) + return GiacMethods['simp2'](self, *args) - def simplex_reduce(self,*args): + def simplex_reduce(self, *args): r'''From Giac's documentation: Help for simplex_reduce: simplex_reduce(Mtrx(A), Vect(b), Vect(c)) @@ -14513,9 +14513,9 @@ cdef class GiacMethods_base: Ex4:simplex_reduce([[-3,2,1,0,3],[1,1,0,1,4],[-1,-2,0,0,0]]) Ex5:simplex_reduce([[2,1,1,1,0,0,2],[1,2,3,0,1,0,5],[2,2,1,0,0,1,6],[-3,-1,-3,1,-1,2,0]]) ''' - return GiacMethods['simplex_reduce'](self,*args) + return GiacMethods['simplex_reduce'](self, *args) - def simplifier(self,*args): + def simplifier(self, *args): r'''From Giac's documentation: Help for simplifier: simplifier(Expr) @@ -14525,9 +14525,9 @@ cdef class GiacMethods_base: Ex2:simplifier(texpand((sin(3*x)+sin(7*x))/sin(5*x))) Ex3:simplifier(texpand((cos(3*x)+cos(7*x))/cos(5*x))) ''' - return GiacMethods['simplifier'](self,*args) + return GiacMethods['simplifier'](self, *args) - def simplify(self,*args): + def simplify(self, *args): r'''From Giac's documentation: Help for simplify: simplify(Expr) @@ -14537,9 +14537,9 @@ cdef class GiacMethods_base: Ex2:simplify(texpand((sin(3*x)+sin(7*x))/sin(5*x))) Ex3:simplify(texpand((cos(3*x)+cos(7*x))/cos(5*x))) ''' - return GiacMethods['simplify'](self,*args) + return GiacMethods['simplify'](self, *args) - def simpson(self,*args): + def simpson(self, *args): r'''From Giac's documentation: Help for simpson: simpson(Opt) @@ -14550,9 +14550,9 @@ cdef class GiacMethods_base: Ex3: area(x^2,x=0..1,5,rombergm) Ex4:simpson(area(x^2,x=0..1,5,gauss15)) ''' - return GiacMethods['simpson'](self,*args) + return GiacMethods['simpson'](self, *args) - def simult(self,*args): + def simult(self, *args): r'''From Giac's documentation: Help for simult: simult(Mtrx(A),Mtrx(B)) @@ -14561,9 +14561,9 @@ cdef class GiacMethods_base: Ex1:simult([[3,1],[3,2]],[[-2],[2]]) Ex2:simult([[3,1],[3,2]],[[-2,1],[2,-1]]) ''' - return GiacMethods['simult'](self,*args) + return GiacMethods['simult'](self, *args) - def sin(self,*args): + def sin(self, *args): r'''From Giac's documentation: Help for sin: sin(Expr or Opt) @@ -14572,9 +14572,9 @@ cdef class GiacMethods_base: Ex1:sin(0) Ex2: convert(cos(x)^4+sin(x)^2,sin) ''' - return GiacMethods['sin'](self,*args) + return GiacMethods['sin'](self, *args) - def sin2costan(self,*args): + def sin2costan(self, *args): r'''From Giac's documentation: Help for sin2costan: sin2costan(Expr) @@ -14582,9 +14582,9 @@ cdef class GiacMethods_base: See also: 1/ tan2sincos 2/ cos2sintan 3/ tan2sincos2 4/ tan2cossin2 Ex1:sin2costan(sin(x)) ''' - return GiacMethods['sin2costan'](self,*args) + return GiacMethods['sin2costan'](self, *args) - def sinc(self,*args): + def sinc(self, *args): r'''From Giac's documentation: Help for sinc: sinc(Expr(x)) @@ -14592,9 +14592,9 @@ cdef class GiacMethods_base: See also: 1/ sin Ex1:sinc(pi*x) ''' - return GiacMethods['sinc'](self,*args) + return GiacMethods['sinc'](self, *args) - def sincos(self,*args): + def sincos(self, *args): r'''From Giac's documentation: Help for sincos: sincos(Expr or Opt) @@ -14604,9 +14604,9 @@ cdef class GiacMethods_base: Ex2:sincos(exp(-i*x)) Ex3: convert(exp(i*x),sincos) ''' - return GiacMethods['sincos'](self,*args) + return GiacMethods['sincos'](self, *args) - def single_inter(self,*args): + def single_inter(self, *args): r'''From Giac's documentation: Help for single_inter: single_inter(Curve,Curve,[Pnt(A)||LstPnt(L)]) @@ -14620,9 +14620,9 @@ cdef class GiacMethods_base: Ex6:single_inter(plane(x=y),plane(y=z)) Ex7:single_inter(line(x=y+1,y=2*z),plane(y=z)) ''' - return GiacMethods['single_inter'](self,*args) + return GiacMethods['single_inter'](self, *args) - def sinh(self,*args): + def sinh(self, *args): r'''From Giac's documentation: Help for sinh: sinh(Expr) @@ -14630,9 +14630,9 @@ cdef class GiacMethods_base: See also: 1/ asinh Ex1:sinh(0) ''' - return GiacMethods['sinh'](self,*args) + return GiacMethods['sinh'](self, *args) - def sizes(self,*args): + def sizes(self, *args): r'''From Giac's documentation: Help for sizes: sizes(Lst or Str or Seq) @@ -14640,9 +14640,9 @@ cdef class GiacMethods_base: See also: 1/ size 2/ dim Ex1:sizes([[1,2,3],[1,2],[1]]) ''' - return GiacMethods['sizes'](self,*args) + return GiacMethods['sizes'](self, *args) - def slope(self,*args): + def slope(self, *args): r'''From Giac's documentation: Help for slope: slope(Line||Pnt||Cplx,[Pnt||Cplx]) @@ -14657,9 +14657,9 @@ cdef class GiacMethods_base: Ex7:slope(LineTan(sin(x),pi/4)) Ex8: line(point(1,2),slope=-1) ''' - return GiacMethods['slope'](self,*args) + return GiacMethods['slope'](self, *args) - def slopeat(self,*args): + def slopeat(self, *args): r'''From Giac's documentation: Help for slopeat: slopeat(Line, Pnt||Cplx(z0)) @@ -14669,9 +14669,9 @@ cdef class GiacMethods_base: Ex2: s:=segment(1-i,i);slopeat(s,point(0.4)) Ex3: t:=tangent(plotfunc(sin(x)),pi/4);slopeat(t,0) ''' - return GiacMethods['slopeat'](self,*args) + return GiacMethods['slopeat'](self, *args) - def slopeatraw(self,*args): + def slopeatraw(self, *args): r'''From Giac's documentation: Help for slopeatraw: slopeatraw(Line, Pnt||Cplx(z0)) @@ -14682,9 +14682,9 @@ cdef class GiacMethods_base: Ex3:slopeatraw(tangent(plotfunc(sin(x)),pi/4),0) Ex4:slopeatraw((LineTan sin(x),pi/4),i) ''' - return GiacMethods['slopeatraw'](self,*args) + return GiacMethods['slopeatraw'](self, *args) - def smith(self,*args): + def smith(self, *args): r'''From Giac's documentation: Help for smith: smith(Mtrx(A)) @@ -14693,9 +14693,9 @@ cdef class GiacMethods_base: Ex1: n:=10; A:=ranm(n,n) % 17; U,D,V:=smith(x*idn(n)-A);normal(U*(x*idn(n)-A)*V-D); diag(D); Ex2: GF(3,5,g); n:=3; A:=ranm(n,n,g); U,D,V:=smith(x*idn(n)-A);normal(U*(x*idn(n)-A)*V-D); diag(D); ''' - return GiacMethods['smith'](self,*args) + return GiacMethods['smith'](self, *args) - def smod(self,*args): + def smod(self, *args): r'''From Giac's documentation: Help for smod: smod(Intg,Intg) @@ -14705,9 +14705,9 @@ cdef class GiacMethods_base: Ex2:smod(10,4) Ex3:smod(11,7) ''' - return GiacMethods['smod'](self,*args) + return GiacMethods['smod'](self, *args) - def snedecor(self,*args): + def snedecor(self, *args): r'''From Giac's documentation: Help for snedecor: snedecor(Intg(n),Intg(m),Real(x0)) @@ -14718,9 +14718,9 @@ cdef class GiacMethods_base: Ex3: randvector(5,fisher,4,6) Ex4: ranm(2,3,fisher,4,6) ''' - return GiacMethods['snedecor'](self,*args) + return GiacMethods['snedecor'](self, *args) - def snedecor_cdf(self,*args): + def snedecor_cdf(self, *args): r'''From Giac's documentation: Help for snedecor_cdf: snedecor_cdf(Intg(n),Intg(m),Real(x0)) @@ -14729,9 +14729,9 @@ cdef class GiacMethods_base: Ex1:snedecor_cdf(4,4,2.1) Ex2:snedecor_cdf(4,10,3.5) ''' - return GiacMethods['snedecor_cdf'](self,*args) + return GiacMethods['snedecor_cdf'](self, *args) - def snedecor_icdf(self,*args): + def snedecor_icdf(self, *args): r'''From Giac's documentation: Help for snedecor_icdf: snedecor_icdf(Intg(n),Intg(m),Real(p)) @@ -14740,9 +14740,9 @@ cdef class GiacMethods_base: Ex1:snedecor_icdf(4,10,0.95) Ex2:snedecor_icdf(4,10,0.05) ''' - return GiacMethods['snedecor_icdf'](self,*args) + return GiacMethods['snedecor_icdf'](self, *args) - def snedecord(self,*args): + def snedecord(self, *args): r'''From Giac's documentation: Help for snedecord: snedecord(Intg(n),Intg(m),Real(x0)) @@ -14753,9 +14753,9 @@ cdef class GiacMethods_base: Ex3: randvector(5,fisher,4,6) Ex4: ranm(2,3,fisher,4,6) ''' - return GiacMethods['snedecord'](self,*args) + return GiacMethods['snedecord'](self, *args) - def snedecord_cdf(self,*args): + def snedecord_cdf(self, *args): r'''From Giac's documentation: Help for snedecord_cdf: snedecord_cdf(Intg(n),Intg(m),Real(x0)) @@ -14764,9 +14764,9 @@ cdef class GiacMethods_base: Ex1:snedecord_cdf(4,4,2.1) Ex2:snedecord_cdf(4,10,3.5) ''' - return GiacMethods['snedecord_cdf'](self,*args) + return GiacMethods['snedecord_cdf'](self, *args) - def snedecord_icdf(self,*args): + def snedecord_icdf(self, *args): r'''From Giac's documentation: Help for snedecord_icdf: snedecord_icdf(Intg(n),Intg(m),Real(p)) @@ -14775,9 +14775,9 @@ cdef class GiacMethods_base: Ex1:snedecord_icdf(4,10,0.95) Ex2:snedecord_icdf(4,10,0.05) ''' - return GiacMethods['snedecord_icdf'](self,*args) + return GiacMethods['snedecord_icdf'](self, *args) - def solid_line(self,*args): + def solid_line(self, *args): r'''From Giac's documentation: Help for solid_line: solid_line(Opt) @@ -14786,9 +14786,9 @@ cdef class GiacMethods_base: Ex1: display(line(y=x),green+dash_line+line_width_2) Ex2: d:=display(line(2+i,1),cap_round_line) ''' - return GiacMethods['solid_line'](self,*args) + return GiacMethods['solid_line'](self, *args) - def solve(self,*args): + def solve(self, *args): r'''From Giac's documentation: Help for solve: solve(Expr,[Var]) @@ -14799,9 +14799,9 @@ cdef class GiacMethods_base: Ex3:solve([y-z=0,z-x=0,x-y=0,x-1+y+z=0],[x,y,z]) Ex4:solve([x^2-y^2=0,x^2-z^2=0],[x,y,z]) ''' - return GiacMethods['solve'](self,*args) + return GiacMethods['solve'](self, *args) - def somme(self,*args): + def somme(self, *args): r'''From Giac's documentation: Help for somme: somme(Expr,Var,VarMin(a),VarMax(b),[VarStep(p)]) @@ -14818,9 +14818,9 @@ cdef class GiacMethods_base: Ex9:somme(1/(x*(x+1)),x) Ex10:somme(cos(n*x),n) ''' - return GiacMethods['somme'](self,*args) + return GiacMethods['somme'](self, *args) - def sommet(self,*args): + def sommet(self, *args): r'''From Giac's documentation: Help for sommet: sommet(Op or Fnct) @@ -14829,9 +14829,9 @@ cdef class GiacMethods_base: Ex1:sommet(quote(gcd(45,123))) Ex2:sommet('gcd(45,123)') ''' - return GiacMethods['sommet'](self,*args) + return GiacMethods['sommet'](self, *args) - def sort(self,*args): + def sort(self, *args): r'''From Giac's documentation: Help for sort: sort(LstReal or Seq [Fnc]) @@ -14843,9 +14843,9 @@ cdef class GiacMethods_base: Ex4:sort([[1,2],[2,3],[4,3]],(x,y)->when(x[1]==y[1],x[0]>y[0],x[1]>y[1])) Ex5:sort(y*x*2+x*y) ''' - return GiacMethods['sort'](self,*args) + return GiacMethods['sort'](self, *args) - def sorta(self,*args): + def sorta(self, *args): r'''From Giac's documentation: Help for sorta: sorta(LstReal||Seq×||Mtrx) @@ -14855,9 +14855,9 @@ cdef class GiacMethods_base: Ex2:sorta([3,4,2]) Ex3:sorta([[3,4,2],[6,4,5]]) ''' - return GiacMethods['sorta'](self,*args) + return GiacMethods['sorta'](self, *args) - def sortd(self,*args): + def sortd(self, *args): r'''From Giac's documentation: Help for sortd: sortd(LstReal||Seq||Mtrx) @@ -14867,9 +14867,9 @@ cdef class GiacMethods_base: Ex2:sortd([3,4,2]) Ex3:sortd([[3,4,2],[6,4,5]]) ''' - return GiacMethods['sortd'](self,*args) + return GiacMethods['sortd'](self, *args) - def sorted(self,*args): + def sorted(self, *args): r'''From Giac's documentation: Help for sorted: sorted(LstReal or Seq [Fnc]) @@ -14881,9 +14881,9 @@ cdef class GiacMethods_base: Ex4:sorted([[1,2],[2,3],[4,3]],(x,y)->when(x[1]==y[1],x[0]>y[0],x[1]>y[1])) Ex5:sorted(y*x*2+x*y) ''' - return GiacMethods['sorted'](self,*args) + return GiacMethods['sorted'](self, *args) - def soundsec(self,*args): + def soundsec(self, *args): r'''From Giac's documentation: Help for soundsec: soundsec(Intg(n),[Intg(N)]) @@ -14892,9 +14892,9 @@ cdef class GiacMethods_base: Ex1:soundsec(1) Ex2:soundsec(1,22100) ''' - return GiacMethods['soundsec'](self,*args) + return GiacMethods['soundsec'](self, *args) - def spanning_tree(self,*args): + def spanning_tree(self, *args): r'''From Giac's documentation: Help for spanning_tree: spanning_tree(Graph(G),[Vrtx(r)]) @@ -14903,9 +14903,9 @@ cdef class GiacMethods_base: Ex1:spanning_tree(graph("petersen")) Ex2:spanning_tree(graph("petersen"),5) ''' - return GiacMethods['spanning_tree'](self,*args) + return GiacMethods['spanning_tree'](self, *args) - def sphere(self,*args): + def sphere(self, *args): r'''From Giac's documentation: Help for sphere: sphere((Pnt or Vect),(Pnt or Real)) @@ -14914,9 +14914,9 @@ cdef class GiacMethods_base: Ex1:sphere([0,0,0],[2,2,2]) Ex2:sphere([1,1,1],1) ''' - return GiacMethods['sphere'](self,*args) + return GiacMethods['sphere'](self, *args) - def spline(self,*args): + def spline(self, *args): r'''From Giac's documentation: Help for spline: spline(Lst(lx),Lst(ly),Var(x),Intg(d)) @@ -14924,9 +14924,9 @@ cdef class GiacMethods_base: See also: 1/ lagrange Ex1:spline([0,1,2],[1,3,0],x,3) ''' - return GiacMethods['spline'](self,*args) + return GiacMethods['spline'](self, *args) - def split(self,*args): + def split(self, *args): r'''From Giac's documentation: Help for split: split(Expr(Xpr),Lst(var1,var2)) @@ -14935,18 +14935,18 @@ cdef class GiacMethods_base: Ex1:split(x^3*y^2-y^2+x^3-1,[x,y]) Ex2:split(x^3*y^2-y^2+x^3+1,[x,y]) ''' - return GiacMethods['split'](self,*args) + return GiacMethods['split'](self, *args) - def spring(self,*args): + def spring(self, *args): r'''From Giac's documentation: Help for spring: spring(Opt) Option for the draw_graph command. See also: 1/ planar 2/ tree 3/ draw_graph ''' - return GiacMethods['spring'](self,*args) + return GiacMethods['spring'](self, *args) - def sq(self,*args): + def sq(self, *args): r'''From Giac's documentation: Help for sq: sq(Seq) @@ -14955,9 +14955,9 @@ cdef class GiacMethods_base: Ex1:sq(5) Ex2:sq(1,2,3) ''' - return GiacMethods['sq'](self,*args) + return GiacMethods['sq'](self, *args) - def sqrfree(self,*args): + def sqrfree(self, *args): r'''From Giac's documentation: Help for sqrfree: sqrfree(Expr) @@ -14966,9 +14966,9 @@ cdef class GiacMethods_base: Ex1:sqrfree(x^4-2*x^2+1) Ex2:sqrfree((x-2)^7*(x+2)^7*(x^4-2*x^2+1)) ''' - return GiacMethods['sqrfree'](self,*args) + return GiacMethods['sqrfree'](self, *args) - def sqrt(self,*args): + def sqrt(self, *args): r'''From Giac's documentation: Help for sqrt: sqrt(Expr) @@ -14977,9 +14977,9 @@ cdef class GiacMethods_base: Ex1:sqrt(50) Ex2:sqrt(x^2) ''' - return GiacMethods['sqrt'](self,*args) + return GiacMethods['sqrt'](self, *args) - def square(self,*args): + def square(self, *args): r'''From Giac's documentation: Help for square: square((Pnt(A) or Cplx),(Pnt(B) or Cplx),[Pnt(P),Var(C),Var(D)]) @@ -14990,9 +14990,9 @@ cdef class GiacMethods_base: Ex3:square(point(0,0,0),point(3,3,3),point(0,0,3)) Ex4:square(point(0,0,0),point(3,3,3),point(0,0,3),C,D) ''' - return GiacMethods['square'](self,*args) + return GiacMethods['square'](self, *args) - def square_point(self,*args): + def square_point(self, *args): r'''From Giac's documentation: Help for square_point: square_point(Opt) @@ -15001,9 +15001,9 @@ cdef class GiacMethods_base: Ex1: F:=display(point(2+1.5*i),point_point) Ex2: F:=display(point(2+1.5*i),rhombus_point) ''' - return GiacMethods['square_point'](self,*args) + return GiacMethods['square_point'](self, *args) - def srand(self,*args): + def srand(self, *args): r'''From Giac's documentation: Help for srand: srand() @@ -15012,9 +15012,9 @@ cdef class GiacMethods_base: Ex1:srand(12) Ex2: srand ''' - return GiacMethods['srand'](self,*args) + return GiacMethods['srand'](self, *args) - def sst(self,*args): + def sst(self, *args): r'''From Giac's documentation: Help for sst: sst(NULL) @@ -15022,9 +15022,9 @@ cdef class GiacMethods_base: See also: 1/ Ex1:sst() ''' - return GiacMethods['sst'](self,*args) + return GiacMethods['sst'](self, *args) - def sst_in(self,*args): + def sst_in(self, *args): r'''From Giac's documentation: Help for sst_in: sst_in(NULL) @@ -15032,9 +15032,9 @@ cdef class GiacMethods_base: See also: 1/ Ex1:sst_in() ''' - return GiacMethods['sst_in'](self,*args) + return GiacMethods['sst_in'](self, *args) - def st_ordering(self,*args): + def st_ordering(self, *args): r'''From Giac's documentation: Help for st_ordering: st_ordering(Graph(G),Vrtx(s),Vrtx(t)) @@ -15042,9 +15042,9 @@ cdef class GiacMethods_base: See also: 1/ is_biconnected Ex1:st_ordering(graph("petersen"),1,2) ''' - return GiacMethods['st_ordering'](self,*args) + return GiacMethods['st_ordering'](self, *args) - def star_graph(self,*args): + def star_graph(self, *args): r'''From Giac's documentation: Help for star_graph: star_graph(Intg(n)) @@ -15052,9 +15052,9 @@ cdef class GiacMethods_base: See also: 1/ complete_graph 2/ wheel_graph Ex1:star_graph(5) ''' - return GiacMethods['star_graph'](self,*args) + return GiacMethods['star_graph'](self, *args) - def star_point(self,*args): + def star_point(self, *args): r'''From Giac's documentation: Help for star_point: star_point(Opt) @@ -15063,9 +15063,9 @@ cdef class GiacMethods_base: Ex1: F:=display(point(2+1.5*i),point_point) Ex2: F:=display(point(2+1.5*i),rhombus_point) ''' - return GiacMethods['star_point'](self,*args) + return GiacMethods['star_point'](self, *args) - def stdDev(self,*args): + def stdDev(self, *args): r'''From Giac's documentation: Help for stdDev: stdDev(Lst||Mtrx,[Lst]) @@ -15075,9 +15075,9 @@ cdef class GiacMethods_base: Ex2:stdDev([1,2,3],[1,2,1]) Ex3:stdDev([[1,2,3],[5,6,7]]) ''' - return GiacMethods['stdDev'](self,*args) + return GiacMethods['stdDev'](self, *args) - def stddev(self,*args): + def stddev(self, *args): r'''From Giac's documentation: Help for stddev: stddev(Lst||Mtrx,[Lst]) @@ -15087,9 +15087,9 @@ cdef class GiacMethods_base: Ex2:stddev([1,2,3],[1,2,1]) Ex3:stddev([[1,2,3],[5,6,7]]) ''' - return GiacMethods['stddev'](self,*args) + return GiacMethods['stddev'](self, *args) - def stddevp(self,*args): + def stddevp(self, *args): r'''From Giac's documentation: Help for stddevp: stddevp(Lst||Mtrx,[Lst]) @@ -15099,9 +15099,9 @@ cdef class GiacMethods_base: Ex2:stddevp([1,2,3],[1,2,1]) Ex3:stddevp([[1,2,3],[5,6,7]]) ''' - return GiacMethods['stddevp'](self,*args) + return GiacMethods['stddevp'](self, *args) - def steffenson_solver(self,*args): + def steffenson_solver(self, *args): r'''From Giac's documentation: Help for steffenson_solver: steffenson_solver(Opt) @@ -15114,9 +15114,9 @@ cdef class GiacMethods_base: Ex5: fsolve(cos(x)=x,x,0,secant_solver) Ex6: fsolve(cos(x)=x,x,0,steffenson_solver) ''' - return GiacMethods['steffenson_solver'](self,*args) + return GiacMethods['steffenson_solver'](self, *args) - def stereo2mono(self,*args): + def stereo2mono(self, *args): r'''From Giac's documentation: Help for stereo2mono: stereo2mono(Lst(clip)) @@ -15124,9 +15124,9 @@ cdef class GiacMethods_base: See also: 1/ channel_data 2/ mean 3/ createwav Ex1:stereo2mono(readwav("/some/file")) ''' - return GiacMethods['stereo2mono'](self,*args) + return GiacMethods['stereo2mono'](self, *args) - def str(self,*args): + def str(self, *args): r'''From Giac's documentation: Help for str: str(Expr or Opt) @@ -15137,9 +15137,9 @@ cdef class GiacMethods_base: Ex3:str(quote(a:=12)) Ex4: convert(quote(a:=12),string) ''' - return GiacMethods['str'](self,*args) + return GiacMethods['str'](self, *args) - def strongly_connected_components(self,*args): + def strongly_connected_components(self, *args): r'''From Giac's documentation: Help for strongly_connected_components: strongly_connected_components(Graph(G)) @@ -15147,9 +15147,9 @@ cdef class GiacMethods_base: See also: 1/ connected_components 2/ is_connected 3/ is_strongly_connected Ex1:strongly_connected_components(digraph([1,2,3],%{[1,2],[1,3],[2,3],[3,2]%})) ''' - return GiacMethods['strongly_connected_components'](self,*args) + return GiacMethods['strongly_connected_components'](self, *args) - def student(self,*args): + def student(self, *args): r'''From Giac's documentation: Help for student: student(Intg(n),Real(x0)) @@ -15158,9 +15158,9 @@ cdef class GiacMethods_base: Ex1:student(3,5.2) Ex2:student(1,5.2) ''' - return GiacMethods['student'](self,*args) + return GiacMethods['student'](self, *args) - def student_cdf(self,*args): + def student_cdf(self, *args): r'''From Giac's documentation: Help for student_cdf: student_cdf(Intg(n),Real(x0)) @@ -15169,9 +15169,9 @@ cdef class GiacMethods_base: Ex1:student_cdf(3,2.35) Ex2:student_cdf(3,-3.2) ''' - return GiacMethods['student_cdf'](self,*args) + return GiacMethods['student_cdf'](self, *args) - def student_icdf(self,*args): + def student_icdf(self, *args): r'''From Giac's documentation: Help for student_icdf: student_icdf(Intg(n),Real(p)) @@ -15180,9 +15180,9 @@ cdef class GiacMethods_base: Ex1:student_icdf(3,0.95) Ex2:student_icdf(3,0.05) ''' - return GiacMethods['student_icdf'](self,*args) + return GiacMethods['student_icdf'](self, *args) - def studentd(self,*args): + def studentd(self, *args): r'''From Giac's documentation: Help for studentd: studentd(Intg(n),Real(x0)) @@ -15191,9 +15191,9 @@ cdef class GiacMethods_base: Ex1:studentd(3,5.2) Ex2:studentd(1,5.2) ''' - return GiacMethods['studentd'](self,*args) + return GiacMethods['studentd'](self, *args) - def studentt(self,*args): + def studentt(self, *args): r'''From Giac's documentation: Help for studentt: studentt(Lst,Real,[Real],Fnc,[Real]) @@ -15202,9 +15202,9 @@ cdef class GiacMethods_base: Ex1:studentt([10,20],.5,.02,'!=',0.1) Ex2:studentt([0.48,20],0.5,0.1,'<') ''' - return GiacMethods['studentt'](self,*args) + return GiacMethods['studentt'](self, *args) - def sturm(self,*args): + def sturm(self, *args): r'''From Giac's documentation: Help for sturm: sturm(Poly,[Var],[Cplx(a)],[Cplx(b)]) @@ -15216,9 +15216,9 @@ cdef class GiacMethods_base: Ex4:sturm(x^5-x^3,x,-2,5) Ex5:sturm(x^3-1,x,-2-i,5+3i) ''' - return GiacMethods['sturm'](self,*args) + return GiacMethods['sturm'](self, *args) - def sturmab(self,*args): + def sturmab(self, *args): r'''From Giac's documentation: Help for sturmab: sturmab(Poly,Var,Cplx(a),Cplx(b)) @@ -15227,9 +15227,9 @@ cdef class GiacMethods_base: Ex1:sturmab(x^3-1,x,-2,5) Ex2:sturmab(x^3-1,x,-2-i,5+3i) ''' - return GiacMethods['sturmab'](self,*args) + return GiacMethods['sturmab'](self, *args) - def sturmseq(self,*args): + def sturmseq(self, *args): r'''From Giac's documentation: Help for sturmseq: sturmseq(Poly,[Var]) @@ -15239,9 +15239,9 @@ cdef class GiacMethods_base: Ex2:sturmseq(x^5-x^3,x) Ex3:sturmseq((x^5-x^3)/(x+2),x) ''' - return GiacMethods['sturmseq'](self,*args) + return GiacMethods['sturmseq'](self, *args) - def style(self,*args): + def style(self, *args): r'''From Giac's documentation: Help for style: style(Opt) @@ -15250,9 +15250,9 @@ cdef class GiacMethods_base: Ex1: segment(0,point(1,1),style=point) Ex2: line(y=x,style=point,display=green+line_width_2) ''' - return GiacMethods['style'](self,*args) + return GiacMethods['style'](self, *args) - def subMat(self,*args): + def subMat(self, *args): r'''From Giac's documentation: Help for subMat: subMat(Mtrx(A),Intg(n1),Intg(n2),Intg(n3),Intg(n4).) @@ -15260,9 +15260,9 @@ cdef class GiacMethods_base: See also: 1/ mid Ex1:subMat([[1,2],[3,4],[5,6]],1,0,2,1) ''' - return GiacMethods['subMat'](self,*args) + return GiacMethods['subMat'](self, *args) - def subdivide_edges(self,*args): + def subdivide_edges(self, *args): r'''From Giac's documentation: Help for subdivide_edges: subdivide_edges(Graph(G),Lst(E),[Intg(r)]) @@ -15270,9 +15270,9 @@ cdef class GiacMethods_base: See also: 1/ edges Ex1:subdivide_edges(complete_graph(2,3),[[1,3],[1,4]],2) ''' - return GiacMethods['subdivide_edges'](self,*args) + return GiacMethods['subdivide_edges'](self, *args) - def subgraph(self,*args): + def subgraph(self, *args): r'''From Giac's documentation: Help for subgraph: subgraph(Graph(G),Lst(E)) @@ -15280,9 +15280,9 @@ cdef class GiacMethods_base: See also: 1/ induced_subgraph 2/ highlight_subgraph Ex1:subgraph(complete_graph(5),[[1,2],[2,3],[3,4],[4,1]]) ''' - return GiacMethods['subgraph'](self,*args) + return GiacMethods['subgraph'](self, *args) - def subs(self,*args): + def subs(self, *args): r'''From Giac's documentation: Help for subs: subs(Expr or Var=value,Var=value or Expr) @@ -15292,9 +15292,9 @@ cdef class GiacMethods_base: Ex2:subs(x=2,1/(4+x^2)) Ex3: f:=1/(4+x^2);f(x=2) ''' - return GiacMethods['subs'](self,*args) + return GiacMethods['subs'](self, *args) - def subsop(self,*args): + def subsop(self, *args): r'''From Giac's documentation: Help for subsop: subsop(Lst||Mtrx,Intg(n)=Expr) @@ -15304,9 +15304,9 @@ cdef class GiacMethods_base: Ex3:subsop([[1,2],[3,4]],1=[10,8]) Ex4:subsop([0,1,2,3],'1=NULL') ''' - return GiacMethods['subsop'](self,*args) + return GiacMethods['subsop'](self, *args) - def subst(self,*args): + def subst(self, *args): r'''From Giac's documentation: Help for subst: subst(Expr,Var(v)=value(a)) @@ -15320,9 +15320,9 @@ cdef class GiacMethods_base: Ex6:subst('sum(x^(n+1)/((n+p+1)*(n+1)),n,0,inf)',n=k-1) Ex7: f:=1/(x^2+y^2;f(x=2,y=3) ''' - return GiacMethods['subst'](self,*args) + return GiacMethods['subst'](self, *args) - def substituer(self,*args): + def substituer(self, *args): r'''From Giac's documentation: Help for substituer: substituer(Expr,Var(v)=value(a)) @@ -15336,9 +15336,9 @@ cdef class GiacMethods_base: Ex6:substituer('sum(x^(n+1)/((n+p+1)*(n+1)),n,0,inf)',n=k-1) Ex7: f:=1/(x^2+y^2;f(x=2,y=3) ''' - return GiacMethods['substituer'](self,*args) + return GiacMethods['substituer'](self, *args) - def subtype(self,*args): + def subtype(self, *args): r'''From Giac's documentation: Help for subtype: subtype(Expr) @@ -15349,9 +15349,9 @@ cdef class GiacMethods_base: Ex3:subtype(poly1[1,2,3]) Ex4:subtype([1,2,3]) ''' - return GiacMethods['subtype'](self,*args) + return GiacMethods['subtype'](self, *args) - def sum(self,*args): + def sum(self, *args): r'''From Giac's documentation: Help for sum: sum(Expr,Var,VarMin(a),VarMax(b),[VarStep(p)]) @@ -15368,9 +15368,9 @@ cdef class GiacMethods_base: Ex9:sum(1/(x*(x+1)),x) Ex10:sum(cos(n*x),n) ''' - return GiacMethods['sum'](self,*args) + return GiacMethods['sum'](self, *args) - def sum_riemann(self,*args): + def sum_riemann(self, *args): r'''From Giac's documentation: Help for sum_riemann: sum_riemann(Expr(Xpr),Lst(var1,var2)) @@ -15380,9 +15380,9 @@ cdef class GiacMethods_base: Ex2:sum_riemann(n/(n^2+k),[n,k]) Ex3:sum_riemann(n/(n^2+k^2),[n,k]) ''' - return GiacMethods['sum_riemann'](self,*args) + return GiacMethods['sum_riemann'](self, *args) - def suppress(self,*args): + def suppress(self, *args): r'''From Giac's documentation: Help for suppress: suppress(Vect(L)||Str(l),Intg(n)) @@ -15393,9 +15393,9 @@ cdef class GiacMethods_base: Ex3: L:=[0,1,2,3];L:=suppress(L,2) Ex4: L:=[0,1,2,3];L.suppress(2) ''' - return GiacMethods['suppress'](self,*args) + return GiacMethods['suppress'](self, *args) - def surd(self,*args): + def surd(self, *args): r'''From Giac's documentation: Help for surd: surd(Expr,Intg(n)) @@ -15404,18 +15404,18 @@ cdef class GiacMethods_base: Ex1:surd(8,3) Ex2:surd(-8,3) ''' - return GiacMethods['surd'](self,*args) + return GiacMethods['surd'](self, *args) - def svd(self,*args): + def svd(self, *args): r'''From Giac's documentation: Help for svd: svd(Mtrx(A)) For a square numerical real matrix A, returns U orthogonal, S vector of singular values, Q orthogonal such that A=U*diag(S)*tran(Q). Ex1:svd([[1,2],[3,4]]) ''' - return GiacMethods['svd'](self,*args) + return GiacMethods['svd'](self, *args) - def swapcol(self,*args): + def swapcol(self, *args): r'''From Giac's documentation: Help for swapcol: swapcol(Mtrx(A),Intg(n1),Intg(n2)) @@ -15423,9 +15423,9 @@ cdef class GiacMethods_base: See also: 1/ rowSwap Ex1:swapcol([[1,2],[3,4],[5,6]],0,1) ''' - return GiacMethods['swapcol'](self,*args) + return GiacMethods['swapcol'](self, *args) - def swaprow(self,*args): + def swaprow(self, *args): r'''From Giac's documentation: Help for swaprow: swaprow(Mtrx(A),Intg(n1),Intg(n2)) @@ -15433,9 +15433,9 @@ cdef class GiacMethods_base: See also: 1/ rowAdd 2/ colSwap Ex1:swaprow([[1,2],[3,4],[5,6]],1,2) ''' - return GiacMethods['swaprow'](self,*args) + return GiacMethods['swaprow'](self, *args) - def switch_axes(self,*args): + def switch_axes(self, *args): r'''From Giac's documentation: Help for switch_axes: switch_axes([Intg(0 or 1)]) @@ -15445,9 +15445,9 @@ cdef class GiacMethods_base: Ex2:switch_axes(0) Ex3:switch_axes(1) ''' - return GiacMethods['switch_axes'](self,*args) + return GiacMethods['switch_axes'](self, *args) - def sylvester(self,*args): + def sylvester(self, *args): r'''From Giac's documentation: Help for sylvester: sylvester(Poly,Poly,Var) @@ -15456,9 +15456,9 @@ cdef class GiacMethods_base: Ex1:sylvester(x^2-1,x^3-1,x) Ex2:sylvester(x^3-p*x+q,3*x^2-p,x) ''' - return GiacMethods['sylvester'](self,*args) + return GiacMethods['sylvester'](self, *args) - def symb2poly(self,*args): + def symb2poly(self, *args): r'''From Giac's documentation: Help for symb2poly: symb2poly(Expr, LstVar or [Var]) @@ -15471,9 +15471,9 @@ cdef class GiacMethods_base: Ex5:symb2poly(-x^4+x*3*y+2+y^2*z,[x,y,z]) Ex6:symb2poly(-x^4+x*3*y+2+y^2*z,[x,y,z]) ''' - return GiacMethods['symb2poly'](self,*args) + return GiacMethods['symb2poly'](self, *args) - def symbol(self,*args): + def symbol(self, *args): r'''From Giac's documentation: Help for symbol: symbol(Opt) @@ -15484,9 +15484,9 @@ cdef class GiacMethods_base: Ex3: a:=sqrt(2);type(a) Ex4: type(2x+1) ''' - return GiacMethods['symbol'](self,*args) + return GiacMethods['symbol'](self, *args) - def syst2mat(self,*args): + def syst2mat(self, *args): r'''From Giac's documentation: Help for syst2mat: syst2mat(LstLinEq,LstVar) @@ -15494,9 +15494,9 @@ cdef class GiacMethods_base: See also: 1/ linsolve 2/ rref Ex1:syst2mat([x-y=1,x+2*y],[x,y]) ''' - return GiacMethods['syst2mat'](self,*args) + return GiacMethods['syst2mat'](self, *args) - def tCollect(self,*args): + def tCollect(self, *args): r'''From Giac's documentation: Help for tCollect: tCollect(Expr) @@ -15504,9 +15504,9 @@ cdef class GiacMethods_base: See also: 1/ texpand 2/ tlin Ex1:tCollect(sin(x)+cos(x)) ''' - return GiacMethods['tCollect'](self,*args) + return GiacMethods['tCollect'](self, *args) - def tExpand(self,*args): + def tExpand(self, *args): r'''From Giac's documentation: Help for tExpand: tExpand(Expr) @@ -15516,9 +15516,9 @@ cdef class GiacMethods_base: Ex2:tExpand(cos(x+y)) Ex3:tExpand(cos(3*x)) ''' - return GiacMethods['tExpand'](self,*args) + return GiacMethods['tExpand'](self, *args) - def table(self,*args): + def table(self, *args): r'''From Giac's documentation: Help for table: table(SeqEqual(index=value)) @@ -15528,9 +15528,9 @@ cdef class GiacMethods_base: Ex2: A:=[[0,1],[2,3]];table(A) Ex3: B:=table([1,2]=12,[2,5]=25);matrix(B) ''' - return GiacMethods['table'](self,*args) + return GiacMethods['table'](self, *args) - def tablefunc(self,*args): + def tablefunc(self, *args): r'''From Giac's documentation: Help for tablefunc: tablefunc(Expr,Var) @@ -15539,9 +15539,9 @@ cdef class GiacMethods_base: Ex1:tablefunc(sin(x),x) Ex2:tablefunc(x^2-x-2,x) ''' - return GiacMethods['tablefunc'](self,*args) + return GiacMethods['tablefunc'](self, *args) - def tableseq(self,*args): + def tableseq(self, *args): r'''From Giac's documentation: Help for tableseq: tableseq(Expr,(Var or LstVar),(InitVal or LstInitVal)) @@ -15550,9 +15550,9 @@ cdef class GiacMethods_base: Ex1:tableseq(cos(x),x,0.0) Ex2:tableseq(x+y,[x,y],[1,1]) ''' - return GiacMethods['tableseq'](self,*args) + return GiacMethods['tableseq'](self, *args) - def tabsign(self,*args): + def tabsign(self, *args): r'''From Giac's documentation: Help for tabsign: tabsign(Expr,Var) @@ -15562,9 +15562,9 @@ cdef class GiacMethods_base: Ex2:tabsign(x^2,x,-3,5) Ex3:tabsign(sin(x),x) ''' - return GiacMethods['tabsign'](self,*args) + return GiacMethods['tabsign'](self, *args) - def tabvar(self,*args): + def tabvar(self, *args): r'''From Giac's documentation: Help for tabvar: tabvar(Expr,Var) @@ -15576,9 +15576,9 @@ cdef class GiacMethods_base: Ex4:tabvar(x^2,x,-3,5) Ex5:tabvar([sin(2t),cos(3t)]) ''' - return GiacMethods['tabvar'](self,*args) + return GiacMethods['tabvar'](self, *args) - def tail(self,*args): + def tail(self, *args): r'''From Giac's documentation: Help for tail: tail(Lst or Seq or Str) @@ -15588,9 +15588,9 @@ cdef class GiacMethods_base: Ex2:tail(3,2,4,1,0) Ex3:tail("bonjour") ''' - return GiacMethods['tail'](self,*args) + return GiacMethods['tail'](self, *args) - def tan(self,*args): + def tan(self, *args): r'''From Giac's documentation: Help for tan: tan(Expr) @@ -15600,9 +15600,9 @@ cdef class GiacMethods_base: Ex2:tan(pi/4) Ex3: convert(tan(x),tan) ''' - return GiacMethods['tan'](self,*args) + return GiacMethods['tan'](self, *args) - def tan2cossin2(self,*args): + def tan2cossin2(self, *args): r'''From Giac's documentation: Help for tan2cossin2: tan2cossin2(Expr) @@ -15610,9 +15610,9 @@ cdef class GiacMethods_base: See also: 1/ tan2sincos2 2/ tan2sincos 3/ sin2costan 4/ cos2sintan Ex1:tan2cossin2(tan(x)) ''' - return GiacMethods['tan2cossin2'](self,*args) + return GiacMethods['tan2cossin2'](self, *args) - def tan2sincos(self,*args): + def tan2sincos(self, *args): r'''From Giac's documentation: Help for tan2sincos: tan2sincos(Expr) @@ -15620,9 +15620,9 @@ cdef class GiacMethods_base: See also: 1/ sin2costan 2/ cos2sintan 3/ tan2sincos2 4/ tan2cossin2 Ex1:tan2sincos(tan(x)) ''' - return GiacMethods['tan2sincos'](self,*args) + return GiacMethods['tan2sincos'](self, *args) - def tan2sincos2(self,*args): + def tan2sincos2(self, *args): r'''From Giac's documentation: Help for tan2sincos2: tan2sincos2(Expr) @@ -15630,9 +15630,9 @@ cdef class GiacMethods_base: See also: 1/ tan2cossin2 2/ tan2sincos 3/ sin2costan 4/ cos2sintan Ex1:tan2sincos2(tan(x)) ''' - return GiacMethods['tan2sincos2'](self,*args) + return GiacMethods['tan2sincos2'](self, *args) - def tangent(self,*args): + def tangent(self, *args): r'''From Giac's documentation: Help for tangent: tangent(Curve(C),Pnt(A)) @@ -15647,9 +15647,9 @@ cdef class GiacMethods_base: Ex7:tangent(plotpolar(3*exp(t/2),t),7) Ex8: equation(tangente([2*cos(t),2*sin(t),3*t],t)) ''' - return GiacMethods['tangent'](self,*args) + return GiacMethods['tangent'](self, *args) - def tangente(self,*args): + def tangente(self, *args): r'''From Giac's documentation: Help for tangente: tangente(Curve(C),Pnt(A)) @@ -15664,9 +15664,9 @@ cdef class GiacMethods_base: Ex7:tangente(plotpolar(3*exp(t/2),t),7) Ex8: equation(tangente([2*cos(t),2*sin(t),3*t],t)) ''' - return GiacMethods['tangente'](self,*args) + return GiacMethods['tangente'](self, *args) - def tanh(self,*args): + def tanh(self, *args): r'''From Giac's documentation: Help for tanh: tanh(Expr) @@ -15675,9 +15675,9 @@ cdef class GiacMethods_base: Ex1:tanh(0) Ex2:tanh(hyp2exp(tanh(1))) ''' - return GiacMethods['tanh'](self,*args) + return GiacMethods['tanh'](self, *args) - def taux_accroissement(self,*args): + def taux_accroissement(self, *args): r'''From Giac's documentation: Help for taux_accroissement: taux_accroissement(Expr,Var,Val1,(Val1+Var or Val2)) @@ -15687,9 +15687,9 @@ cdef class GiacMethods_base: Ex2:taux_accroissement(x^2,1,2) Ex3:taux_accroissement(a^2,a,1,1+h) ''' - return GiacMethods['taux_accroissement'](self,*args) + return GiacMethods['taux_accroissement'](self, *args) - def taylor(self,*args): + def taylor(self, *args): r'''From Giac's documentation: Help for taylor: taylor(Expr,[Var=limit_point],[Order]) @@ -15706,9 +15706,9 @@ cdef class GiacMethods_base: Ex9:taylor(sin((1+h*t)*(pi/2+k*t)),t=0,3,polynom)(t=1) Ex10:taylor((-1+k*t)^2/(1+h*t)^3,t=0,3,polynom)(t=1) ''' - return GiacMethods['taylor'](self,*args) + return GiacMethods['taylor'](self, *args) - def tchebyshev1(self,*args): + def tchebyshev1(self, *args): r'''From Giac's documentation: Help for tchebyshev1: tchebyshev1(Intg(n)) @@ -15716,9 +15716,9 @@ cdef class GiacMethods_base: See also: 1/ tchebyshev2 2/ hermite Ex1:tchebyshev1(3) ''' - return GiacMethods['tchebyshev1'](self,*args) + return GiacMethods['tchebyshev1'](self, *args) - def tchebyshev2(self,*args): + def tchebyshev2(self, *args): r'''From Giac's documentation: Help for tchebyshev2: tchebyshev2(Intg(n)) @@ -15726,9 +15726,9 @@ cdef class GiacMethods_base: See also: 1/ tchebyshev1 2/ hermite Ex1:tchebyshev2(3) ''' - return GiacMethods['tchebyshev2'](self,*args) + return GiacMethods['tchebyshev2'](self, *args) - def tcoeff(self,*args): + def tcoeff(self, *args): r'''From Giac's documentation: Help for tcoeff: tcoeff(Poly||Lst) @@ -15737,9 +15737,9 @@ cdef class GiacMethods_base: Ex1:tcoeff(-2*x^3+x^2+7*x) Ex2:tcoeff([-2,1,7,0]) ''' - return GiacMethods['tcoeff'](self,*args) + return GiacMethods['tcoeff'](self, *args) - def tcollect(self,*args): + def tcollect(self, *args): r'''From Giac's documentation: Help for tcollect: tcollect(Expr) @@ -15747,18 +15747,18 @@ cdef class GiacMethods_base: See also: 1/ texpand 2/ tlin Ex1:tcollect(sin(x)+cos(x)) ''' - return GiacMethods['tcollect'](self,*args) + return GiacMethods['tcollect'](self, *args) - def tdeg(self,*args): + def tdeg(self, *args): r'''From Giac's documentation: Help for tdeg: tdeg(Opt) Option of the gbasis or greduce command to specify an order for monomials (complete degree then lexicographic order). See also: 1/ gbasis 2/ greduce ''' - return GiacMethods['tdeg'](self,*args) + return GiacMethods['tdeg'](self, *args) - def tensor_product(self,*args): + def tensor_product(self, *args): r'''From Giac's documentation: Help for tensor_product: tensor_product(Seq(G1,G2,..)) @@ -15766,9 +15766,9 @@ cdef class GiacMethods_base: See also: 1/ cartesian_product Ex1:tensor_product(graph(trail(1,2,3,4,5,2)),star_graph(3)) ''' - return GiacMethods['tensor_product'](self,*args) + return GiacMethods['tensor_product'](self, *args) - def tetrahedron(self,*args): + def tetrahedron(self, *args): r'''From Giac's documentation: Help for tetrahedron: tetrahedron(Pnt(A),Pnt(B),Pnt(C),[Pnt(D)]) @@ -15777,9 +15777,9 @@ cdef class GiacMethods_base: Ex1:tetrahedron([0,0,0],[3,0,0],[0,1,0]) Ex2:tetrahedron([0,0,0],[3,0,0],[0,3,0],[0,0,4]) ''' - return GiacMethods['tetrahedron'](self,*args) + return GiacMethods['tetrahedron'](self, *args) - def texpand(self,*args): + def texpand(self, *args): r'''From Giac's documentation: Help for texpand: texpand(Expr) @@ -15789,9 +15789,9 @@ cdef class GiacMethods_base: Ex2:texpand(cos(x+y)) Ex3:texpand(cos(3*x)) ''' - return GiacMethods['texpand'](self,*args) + return GiacMethods['texpand'](self, *args) - def thickness(self,*args): + def thickness(self, *args): r'''From Giac's documentation: Help for thickness: thickness(Opt) @@ -15800,9 +15800,9 @@ cdef class GiacMethods_base: Ex1: segment(0,point(1,1),thickness=5) Ex2: segment(0,point(1,1),epaisseur=5) ''' - return GiacMethods['thickness'](self,*args) + return GiacMethods['thickness'](self, *args) - def threshold(self,*args): + def threshold(self, *args): r'''From Giac's documentation: Help for threshold: threshold(Lst,Real(bound)[=Expr(repl)] or Lst[Real(lower)[=Expr(rl)],Real(upper)[=Expr(ru)]],[Fnc(compare)],[abs[=true or false]]) @@ -15811,9 +15811,9 @@ cdef class GiacMethods_base: Ex1:threshold([1,3,2,4,5,4,3,2,3,1],3,'>=') Ex2:threshold([-10,-5,0,5,10],7=a,abs=true) ''' - return GiacMethods['threshold'](self,*args) + return GiacMethods['threshold'](self, *args) - def throw(self,*args): + def throw(self, *args): r'''From Giac's documentation: Help for throw: throw(Str) @@ -15822,9 +15822,9 @@ cdef class GiacMethods_base: Ex1:throw("Argument should be integer") Ex2:throw("je provoque une erreur") ''' - return GiacMethods['throw'](self,*args) + return GiacMethods['throw'](self, *args) - def title(self,*args): + def title(self, *args): r'''From Giac's documentation: Help for title: title(Opt) @@ -15833,9 +15833,9 @@ cdef class GiacMethods_base: Ex1: title="segment";segment(0,point(1,1),epaisseur=5) Ex2: titre="segment";segment(0,point(1,1),epaisseur=5) ''' - return GiacMethods['title'](self,*args) + return GiacMethods['title'](self, *args) - def titre(self,*args): + def titre(self, *args): r'''From Giac's documentation: Help for titre: titre(Opt) @@ -15844,9 +15844,9 @@ cdef class GiacMethods_base: Ex1: title="segment";segment(0,point(1,1),epaisseur=5) Ex2: titre="segment";segment(0,point(1,1),epaisseur=5) ''' - return GiacMethods['titre'](self,*args) + return GiacMethods['titre'](self, *args) - def tlin(self,*args): + def tlin(self, *args): r'''From Giac's documentation: Help for tlin: tlin(ExprTrig) @@ -15855,9 +15855,9 @@ cdef class GiacMethods_base: Ex1:tlin(sin(x)^3) Ex2:tlin(cos(x)*cos(y)) ''' - return GiacMethods['tlin'](self,*args) + return GiacMethods['tlin'](self, *args) - def tonnetz(self,*args): + def tonnetz(self, *args): r'''From Giac's documentation: Help for tonnetz: tonnetz(Intg(a),Intg(b),Intg(c),[Intg(d)]) @@ -15866,9 +15866,9 @@ cdef class GiacMethods_base: Ex1:tonnetz(3,4,5) Ex2:tonnetz(2,3,3,4) ''' - return GiacMethods['tonnetz'](self,*args) + return GiacMethods['tonnetz'](self, *args) - def topologic_sort(self,*args): + def topologic_sort(self, *args): r'''From Giac's documentation: Help for topologic_sort: topologic_sort(Graph(G)) @@ -15876,9 +15876,9 @@ cdef class GiacMethods_base: See also: 1/ digraph 2/ is_acyclic Ex1:topologic_sort(digraph(%{[c,a],[c,b],[c,d],[a,d],[b,d],[a,b]%})) ''' - return GiacMethods['topologic_sort'](self,*args) + return GiacMethods['topologic_sort'](self, *args) - def topological_sort(self,*args): + def topological_sort(self, *args): r'''From Giac's documentation: Help for topological_sort: topological_sort(Graph(G)) @@ -15886,9 +15886,9 @@ cdef class GiacMethods_base: See also: 1/ digraph 2/ is_acyclic Ex1:topological_sort(digraph(%{[c,a],[c,b],[c,d],[a,d],[b,d],[a,b]%})) ''' - return GiacMethods['topological_sort'](self,*args) + return GiacMethods['topological_sort'](self, *args) - def torus_grid_graph(self,*args): + def torus_grid_graph(self, *args): r'''From Giac's documentation: Help for torus_grid_graph: torus_grid_graph(Intg(m),Intg(n)) @@ -15896,9 +15896,9 @@ cdef class GiacMethods_base: See also: 1/ grid_graph Ex1:torus_grid_graph(6,12) ''' - return GiacMethods['torus_grid_graph'](self,*args) + return GiacMethods['torus_grid_graph'](self, *args) - def total_degree(self,*args): + def total_degree(self, *args): r'''From Giac's documentation: Help for total_degree: total_degree(Poly(P),Lst(Vars)) @@ -15906,9 +15906,9 @@ cdef class GiacMethods_base: See also: 1/ valuation 2/ size 3/ degree Ex1:total_degree(x^3*y+x*y,[x,y]) ''' - return GiacMethods['total_degree'](self,*args) + return GiacMethods['total_degree'](self, *args) - def tourne_droite(self,*args): + def tourne_droite(self, *args): r'''From Giac's documentation: Help for tourne_droite: tourne_droite(NULL or Real(n)) @@ -15917,9 +15917,9 @@ cdef class GiacMethods_base: Ex1: tourne_droite 60 Ex2:tourne_droite(60) ''' - return GiacMethods['tourne_droite'](self,*args) + return GiacMethods['tourne_droite'](self, *args) - def tourne_gauche(self,*args): + def tourne_gauche(self, *args): r'''From Giac's documentation: Help for tourne_gauche: tourne_gauche(NULL or Real(n)) @@ -15928,9 +15928,9 @@ cdef class GiacMethods_base: Ex1: tourne_gauche 60 Ex2:tourne_gauche(60) ''' - return GiacMethods['tourne_gauche'](self,*args) + return GiacMethods['tourne_gauche'](self, *args) - def tpsolve(self,*args): + def tpsolve(self, *args): r'''From Giac's documentation: Help for tpsolve: tpsolve(supply,demand,cost_matrix) @@ -15940,9 +15940,9 @@ cdef class GiacMethods_base: Ex3:tpsolve([95,70,165,165],[195,150,30,45,75],[[15,M,45,M,0],[12,40,M,M,0],[0,15,25,25,0],[M,0,M,12,0]]) Ex4:tpsolve([1,1,1,1],[1,1,1,1],[[10,12,9,11],[5,10,7,8],[12,14,13,11],[8,15,11,9]]) ''' - return GiacMethods['tpsolve'](self,*args) + return GiacMethods['tpsolve'](self, *args) - def trace(self,*args): + def trace(self, *args): r'''From Giac's documentation: Help for trace: trace(Mtrx or GeoObj) @@ -15953,9 +15953,9 @@ cdef class GiacMethods_base: Ex3: assume(a=[0.7,-5,5,0.1]);trace(point(a-i*a)) Ex4: assume(a=[0.7,-5,5,0.1]);trace(inter_unique(droite(y=a*x+a),droite(y=2*a*x+1))) ''' - return GiacMethods['trace'](self,*args) + return GiacMethods['trace'](self, *args) - def trail(self,*args): + def trail(self, *args): r'''From Giac's documentation: Help for trail: trail(Seq(V)) @@ -15963,9 +15963,9 @@ cdef class GiacMethods_base: See also: 1/ graph 2/ digraph Ex1:trail(1,2,3,4,1) ''' - return GiacMethods['trail'](self,*args) + return GiacMethods['trail'](self, *args) - def trail2edges(self,*args): + def trail2edges(self, *args): r'''From Giac's documentation: Help for trail2edges: trail2edges(Trail(T)) @@ -15974,9 +15974,9 @@ cdef class GiacMethods_base: Ex1:trail2edges(trail(1,2,3,4,1,3)) Ex2:trail2edges([1,2,3,4,1,3]) ''' - return GiacMethods['trail2edges'](self,*args) + return GiacMethods['trail2edges'](self, *args) - def trames(self,*args): + def trames(self, *args): r'''From Giac's documentation: Help for trames: trames(Opt) @@ -15985,9 +15985,9 @@ cdef class GiacMethods_base: Ex1: animate(sin(x*t),x=-pi..pi,t=-3..3,frames=30) Ex2: animate3d(x^2+t*y^2,[x=-2..2,y=-2..2],t=-3..3,frames=10) ''' - return GiacMethods['trames'](self,*args) + return GiacMethods['trames'](self, *args) - def tran(self,*args): + def tran(self, *args): r'''From Giac's documentation: Help for tran: tran(Mtrx) @@ -15997,9 +15997,9 @@ cdef class GiacMethods_base: Ex2:tran([[1+i,2,3],[1,3,6],[2,5,9-i]]) Ex3:tran(conj([[1+i,2,3],[1,3,6],[2,5,9-i]])) ''' - return GiacMethods['tran'](self,*args) + return GiacMethods['tran'](self, *args) - def transitive_closure(self,*args): + def transitive_closure(self, *args): r'''From Giac's documentation: Help for transitive_closure: transitive_closure(Graph(G),[weighted[=true||false]]) @@ -16007,9 +16007,9 @@ cdef class GiacMethods_base: See also: 1/ allpairs_distance 2/ is_connected 3/ shortest_path 4/ vertex_distance Ex1:transitive_closure(digraph([1,2,3,4,5,6],%{[1,2],[2,3],[2,4],[4,5],[3,5]%}),weighted) ''' - return GiacMethods['transitive_closure'](self,*args) + return GiacMethods['transitive_closure'](self, *args) - def translation(self,*args): + def translation(self, *args): r'''From Giac's documentation: Help for translation: translation(Vect, Pnt(C)) @@ -16020,9 +16020,9 @@ cdef class GiacMethods_base: Ex3: t:=translation(1+i);t(i) Ex4: t:=translation([1,1,1]);t(point([1,2,3])) ''' - return GiacMethods['translation'](self,*args) + return GiacMethods['translation'](self, *args) - def transpose(self,*args): + def transpose(self, *args): r'''From Giac's documentation: Help for transpose: transpose(Mtrx) @@ -16032,9 +16032,9 @@ cdef class GiacMethods_base: Ex2:transpose([[1+i,2,3],[1,3,6],[2,5,9-i]]) Ex3:transpose(conj([[1+i,2,3],[1,3,6],[2,5,9-i]])) ''' - return GiacMethods['transpose'](self,*args) + return GiacMethods['transpose'](self, *args) - def trapeze(self,*args): + def trapeze(self, *args): r'''From Giac's documentation: Help for trapeze: trapeze(Opt) @@ -16047,9 +16047,9 @@ cdef class GiacMethods_base: Ex5: area(x^2,x=0..1,5,middle_point) Ex6: area(x^2,x=0..1,5,trapezoid) ''' - return GiacMethods['trapeze'](self,*args) + return GiacMethods['trapeze'](self, *args) - def trapezoid(self,*args): + def trapezoid(self, *args): r'''From Giac's documentation: Help for trapezoid: trapezoid(Opt) @@ -16062,9 +16062,9 @@ cdef class GiacMethods_base: Ex5: area(x^2,x=0..1,5,middle_point) Ex6: area(x^2,x=0..1,5,trapezoid) ''' - return GiacMethods['trapezoid'](self,*args) + return GiacMethods['trapezoid'](self, *args) - def traveling_salesman(self,*args): + def traveling_salesman(self, *args): r'''From Giac's documentation: Help for traveling_salesman: traveling_salesman(Graph(G),[Mtrx(M)],[opts]) @@ -16076,18 +16076,18 @@ cdef class GiacMethods_base: Ex4: G:=set_vertex_positions(complete_graph(42),[randvector(2,1000)$(k=1..42)]); traveling_salesman(G,vertex_distance) Ex5: G:=set_vertex_positions(complete_graph(120),[randvector(2,1000)$(k=1..120)]); c,T:=traveling_salesman(G,vertex_distance,approx) ''' - return GiacMethods['traveling_salesman'](self,*args) + return GiacMethods['traveling_salesman'](self, *args) - def tree(self,*args): + def tree(self, *args): r'''From Giac's documentation: Help for tree: tree(Opt) Option for the draw_graph command. See also: 1/ planar 2/ spring 3/ draw_graph ''' - return GiacMethods['tree'](self,*args) + return GiacMethods['tree'](self, *args) - def tree_height(self,*args): + def tree_height(self, *args): r'''From Giac's documentation: Help for tree_height: tree_height(Graph(T),Vrtx(r)) @@ -16095,9 +16095,9 @@ cdef class GiacMethods_base: See also: 1/ is_tree 2/ random_tree Ex1:tree_height(graph(%{[1,2],[2,3],[2,4],[4,5]%}),1) ''' - return GiacMethods['tree_height'](self,*args) + return GiacMethods['tree_height'](self, *args) - def tri(self,*args): + def tri(self, *args): r'''From Giac's documentation: Help for tri: tri(Expr(x)) @@ -16105,9 +16105,9 @@ cdef class GiacMethods_base: See also: 1/ rect 2/ Heaviside Ex1:tri(x-1) ''' - return GiacMethods['tri'](self,*args) + return GiacMethods['tri'](self, *args) - def triangle(self,*args): + def triangle(self, *args): r'''From Giac's documentation: Help for triangle: triangle((Pnt or Cplx),(Pnt or Cplx),(Pnt or Cplx)) @@ -16117,9 +16117,9 @@ cdef class GiacMethods_base: Ex2:triangle(0,1,1+i) Ex3:triangle(point(0,0,0),point(3,3,3),point(0,3,3)) ''' - return GiacMethods['triangle'](self,*args) + return GiacMethods['triangle'](self, *args) - def triangle_paper(self,*args): + def triangle_paper(self, *args): r'''From Giac's documentation: Help for triangle_paper: triangle_paper(Real(ux),Real(t),Real(uy),[x=xmin..xmax,y=ymin..ymax]) @@ -16129,9 +16129,9 @@ cdef class GiacMethods_base: Ex3:triangle_paper(papier_triangule(1,pi/3,sqrt(3)/2,x=-2..6,y=-4*sqrt(3)..4*sqrt(3))) Ex4:triangle_paper(0.5,3*pi/4,0.5) ''' - return GiacMethods['triangle_paper'](self,*args) + return GiacMethods['triangle_paper'](self, *args) - def triangle_plein(self,*args): + def triangle_plein(self, *args): r'''From Giac's documentation: Help for triangle_plein: triangle_plein(Real(a),[Real(b)],[Real(t)]) @@ -16142,9 +16142,9 @@ cdef class GiacMethods_base: Ex3:triangle_plein(30,40) Ex4:triangle_plein(30,40,60) ''' - return GiacMethods['triangle_plein'](self,*args) + return GiacMethods['triangle_plein'](self, *args) - def triangle_point(self,*args): + def triangle_point(self, *args): r'''From Giac's documentation: Help for triangle_point: triangle_point(Opt) @@ -16153,9 +16153,9 @@ cdef class GiacMethods_base: Ex1: F:=display(point(2+1.5*i),point_point) Ex2: F:=display(point(2+1.5*i),rhombus_point) ''' - return GiacMethods['triangle_point'](self,*args) + return GiacMethods['triangle_point'](self, *args) - def triangle_window(self,*args): + def triangle_window(self, *args): r'''From Giac's documentation: Help for triangle_window: triangle_window(Lst,[Intg(d)],[Interval(n1..n2)]) @@ -16163,9 +16163,9 @@ cdef class GiacMethods_base: See also: 1/ blackman_harris_window 2/ blackman_window 3/ bohman_window 4/ cosine_window 5/ gaussian_window 6/ hamming_window 7/ hann_poisson_window 8/ hann_window 9/ parzen_window 10/ poisson_window 11/ riemann_window 12/ bartlett_hann_window 13/ tukey_window 14/ welch_window Ex1: scatterplot(triangle_window(randvector(1000,0..1),1)) ''' - return GiacMethods['triangle_window'](self,*args) + return GiacMethods['triangle_window'](self, *args) - def trig2exp(self,*args): + def trig2exp(self, *args): r'''From Giac's documentation: Help for trig2exp: trig2exp(Expr) @@ -16173,9 +16173,9 @@ cdef class GiacMethods_base: See also: 1/ exp2trig 2/ atrig2ln Ex1:trig2exp(sin(x)) ''' - return GiacMethods['trig2exp'](self,*args) + return GiacMethods['trig2exp'](self, *args) - def trigcos(self,*args): + def trigcos(self, *args): r'''From Giac's documentation: Help for trigcos: trigcos(Expr) @@ -16183,9 +16183,9 @@ cdef class GiacMethods_base: See also: 1/ trigsin 2/ trigtan Ex1:trigcos(sin(x)^4+sin(x)^2) ''' - return GiacMethods['trigcos'](self,*args) + return GiacMethods['trigcos'](self, *args) - def trigexpand(self,*args): + def trigexpand(self, *args): r'''From Giac's documentation: Help for trigexpand: trigexpand(Expr) @@ -16193,9 +16193,9 @@ cdef class GiacMethods_base: See also: 1/ texpand 2/ lnexpand 3/ expexpand Ex1:trigexpand(sin(3*x)) ''' - return GiacMethods['trigexpand'](self,*args) + return GiacMethods['trigexpand'](self, *args) - def triginterp(self,*args): + def triginterp(self, *args): r'''From Giac's documentation: Help for triginterp: triginterp(List,Var=xmin..xmax) @@ -16204,9 +16204,9 @@ cdef class GiacMethods_base: Ex1:triginterp([11,10,17,24,32,26,23,19],x=0..21) Ex2:triginterp([11,10,17,24,32,26,23,19],0,21,x) ''' - return GiacMethods['triginterp'](self,*args) + return GiacMethods['triginterp'](self, *args) - def trigsimplify(self,*args): + def trigsimplify(self, *args): r'''From Giac's documentation: Help for trigsimplify: trigsimplify(Expr) @@ -16214,9 +16214,9 @@ cdef class GiacMethods_base: See also: 1/ simplify Ex1:trigsimplify(3*sin(x)-4*sin(x)^3) ''' - return GiacMethods['trigsimplify'](self,*args) + return GiacMethods['trigsimplify'](self, *args) - def trigsin(self,*args): + def trigsin(self, *args): r'''From Giac's documentation: Help for trigsin: trigsin(Expr) @@ -16224,9 +16224,9 @@ cdef class GiacMethods_base: See also: 1/ trigcos 2/ trigtan Ex1:trigsin(cos(x)^4+sin(x)^2) ''' - return GiacMethods['trigsin'](self,*args) + return GiacMethods['trigsin'](self, *args) - def trigtan(self,*args): + def trigtan(self, *args): r'''From Giac's documentation: Help for trigtan: trigtan(Expr) @@ -16234,9 +16234,9 @@ cdef class GiacMethods_base: See also: 1/ trigsin 2/ trigcos Ex1:trigtan(cos(x)^4+sin(x)^2) ''' - return GiacMethods['trigtan'](self,*args) + return GiacMethods['trigtan'](self, *args) - def trn(self,*args): + def trn(self, *args): r'''From Giac's documentation: Help for trn: trn(Mtrx) @@ -16244,9 +16244,9 @@ cdef class GiacMethods_base: See also: 1/ tran 2/ conj Ex1:trn([[1,2+i],[3,4]]) ''' - return GiacMethods['trn'](self,*args) + return GiacMethods['trn'](self, *args) - def true(self,*args): + def true(self, *args): r'''From Giac's documentation: Help for true: true() @@ -16254,9 +16254,9 @@ cdef class GiacMethods_base: See also: 1/ false Ex1: a:=true ''' - return GiacMethods['true'](self,*args) + return GiacMethods['true'](self, *args) - def trunc(self,*args): + def trunc(self, *args): r'''From Giac's documentation: Help for trunc: trunc(Real||LstReal,Int(n)) @@ -16268,9 +16268,9 @@ cdef class GiacMethods_base: Ex4:trunc([4.3333,sqrt(2)],2) Ex5:trunc(sqrt(2)+i*sqrt(5),4) ''' - return GiacMethods['trunc'](self,*args) + return GiacMethods['trunc'](self, *args) - def truncate(self,*args): + def truncate(self, *args): r'''From Giac's documentation: Help for truncate: truncate(Poly(P),Intg(n)) @@ -16278,9 +16278,9 @@ cdef class GiacMethods_base: See also: 1/ series Ex1:truncate((x^2+x)^2,3) ''' - return GiacMethods['truncate'](self,*args) + return GiacMethods['truncate'](self, *args) - def truncate_graph(self,*args): + def truncate_graph(self, *args): r'''From Giac's documentation: Help for truncate_graph: truncate_graph(Graph(G)) @@ -16288,9 +16288,9 @@ cdef class GiacMethods_base: See also: 1/ is_biconnected 2/ is_planar 3/ plane_dual Ex1:truncate_graph(graph("tetrahedron")) ''' - return GiacMethods['truncate_graph'](self,*args) + return GiacMethods['truncate_graph'](self, *args) - def tsimplify(self,*args): + def tsimplify(self, *args): r'''From Giac's documentation: Help for tsimplify: tsimplify(Expr) @@ -16298,9 +16298,9 @@ cdef class GiacMethods_base: See also: 1/ simplify Ex1:tsimplify(exp(2*x)+exp(x)) ''' - return GiacMethods['tsimplify'](self,*args) + return GiacMethods['tsimplify'](self, *args) - def tuer(self,*args): + def tuer(self, *args): r'''From Giac's documentation: Help for tuer: tuer(NULL) @@ -16308,9 +16308,9 @@ cdef class GiacMethods_base: See also: 1/ Ex1:tuer() ''' - return GiacMethods['tuer'](self,*args) + return GiacMethods['tuer'](self, *args) - def tukey_window(self,*args): + def tukey_window(self, *args): r'''From Giac's documentation: Help for tukey_window: tukey_window(Lst,[Real(a)],[Interval(n1..n2)]) @@ -16318,9 +16318,9 @@ cdef class GiacMethods_base: See also: 1/ blackman_harris_window 2/ blackman_window 3/ bohman_window 4/ cosine_window 5/ gaussian_window 6/ hamming_window 7/ hann_poisson_window 8/ hann_window 9/ parzen_window 10/ poisson_window 11/ riemann_window 12/ triangle_window 13/ bartlett_hann_window 14/ welch_window Ex1: scatterplot(tukey_window(randvector(1000,0..1),0.4)) ''' - return GiacMethods['tukey_window'](self,*args) + return GiacMethods['tukey_window'](self, *args) - def tutte_polynomial(self,*args): + def tutte_polynomial(self, *args): r'''From Giac's documentation: Help for tutte_polynomial: tutte_polynomial(Graph(G),[Var(x),Var(y)]) @@ -16329,9 +16329,9 @@ cdef class GiacMethods_base: Ex1:tutte_polynomial(graph("tetrahedron")) Ex2:tutte_polynomial(graph("tetrahedron"),1,1) ''' - return GiacMethods['tutte_polynomial'](self,*args) + return GiacMethods['tutte_polynomial'](self, *args) - def two_edge_connected_components(self,*args): + def two_edge_connected_components(self, *args): r'''From Giac's documentation: Help for two_edge_connected_components: two_edge_connected_components(Graph(G)) @@ -16339,9 +16339,9 @@ cdef class GiacMethods_base: See also: 1/ is_two_edge_connected 2/ connected_components Ex1:two_edge_connected_components(graph(trail(1,2,3,4,5,3,1),trail(5,6,7,8,6))) ''' - return GiacMethods['two_edge_connected_components'](self,*args) + return GiacMethods['two_edge_connected_components'](self, *args) - def ufactor(self,*args): + def ufactor(self, *args): r'''From Giac's documentation: Help for ufactor: ufactor(Unit,Unit) @@ -16349,9 +16349,9 @@ cdef class GiacMethods_base: See also: 1/ convert 2/ mksa 3/ usimplify Ex1:ufactor(100_C,1_A) ''' - return GiacMethods['ufactor'](self,*args) + return GiacMethods['ufactor'](self, *args) - def ugamma(self,*args): + def ugamma(self, *args): r'''From Giac's documentation: Help for ugamma: ugamma(Real(a),Real(x),[1]) @@ -16360,9 +16360,9 @@ cdef class GiacMethods_base: Ex1:ugamma(5.0,2.0) Ex2:ugamma(-5.1,2.1) ''' - return GiacMethods['ugamma'](self,*args) + return GiacMethods['ugamma'](self, *args) - def unapply(self,*args): + def unapply(self, *args): r'''From Giac's documentation: Help for unapply: unapply(Expr,Var) @@ -16371,9 +16371,9 @@ cdef class GiacMethods_base: Ex1:unapply(2*x^2,x) Ex2: f(x):=x*exp(x);g:=unapply(diff(f(x),x),x) ''' - return GiacMethods['unapply'](self,*args) + return GiacMethods['unapply'](self, *args) - def unarchive(self,*args): + def unarchive(self, *args): r'''From Giac's documentation: Help for unarchive: unarchive(Str(namefich),Seq(Var)) @@ -16382,9 +16382,9 @@ cdef class GiacMethods_base: Ex1:unarchive("toto") Ex2:unarchive("aa.txt") ''' - return GiacMethods['unarchive'](self,*args) + return GiacMethods['unarchive'](self, *args) - def underlying_graph(self,*args): + def underlying_graph(self, *args): r'''From Giac's documentation: Help for underlying_graph: underlying_graph(Graph(G)) @@ -16392,9 +16392,9 @@ cdef class GiacMethods_base: See also: 1/ is_directed 2/ is_weighted 3/ make_directed 4/ make_weighted Ex1:underlying_graph(digraph(trail(1,2,3,4,1))) ''' - return GiacMethods['underlying_graph'](self,*args) + return GiacMethods['underlying_graph'](self, *args) - def unfactored(self,*args): + def unfactored(self, *args): r'''From Giac's documentation: Help for unfactored: unfactored(Opt.) @@ -16406,9 +16406,9 @@ cdef class GiacMethods_base: Ex4: plotimplicit(x^2+y^2+z^2-1,[x,y,z],xstep=0.2,ystep=0.2,zstep=0.2,unfactored) Ex5: plotimplicit(x^2+y^2+z^2-1,x=0..1,y=0..1,z=0..1,xstep=0.2,ystep=0.2,zstep=0.2,unfactored) ''' - return GiacMethods['unfactored'](self,*args) + return GiacMethods['unfactored'](self, *args) - def uniform(self,*args): + def uniform(self, *args): r'''From Giac's documentation: Help for uniform: uniform(Real(a),Real(b),Real(x)) @@ -16419,9 +16419,9 @@ cdef class GiacMethods_base: Ex3: randvector(3,uniform,1.2,3.5) Ex4: ranm(4,3,uniform,1.2,3.5) ''' - return GiacMethods['uniform'](self,*args) + return GiacMethods['uniform'](self, *args) - def uniform_cdf(self,*args): + def uniform_cdf(self, *args): r'''From Giac's documentation: Help for uniform_cdf: uniform_cdf(Real(a),Real(b),Real(x0),[Real(y0)]) @@ -16430,9 +16430,9 @@ cdef class GiacMethods_base: Ex1:uniform_cdf(3.2,5.7,4.4) Ex2:uniform_cdf(3.2,5.7,4.4,5.4) ''' - return GiacMethods['uniform_cdf'](self,*args) + return GiacMethods['uniform_cdf'](self, *args) - def uniform_icdf(self,*args): + def uniform_icdf(self, *args): r'''From Giac's documentation: Help for uniform_icdf: uniform_icdf(Real(a),Real(b),Real(p)) @@ -16441,9 +16441,9 @@ cdef class GiacMethods_base: Ex1:uniform_icdf(4.2,10.3,0.95) Ex2:uniform_icdf(3.2,5.7,0.48) ''' - return GiacMethods['uniform_icdf'](self,*args) + return GiacMethods['uniform_icdf'](self, *args) - def uniformd(self,*args): + def uniformd(self, *args): r'''From Giac's documentation: Help for uniformd: uniformd(Real(a),Real(b),Real(x)) @@ -16454,9 +16454,9 @@ cdef class GiacMethods_base: Ex3: randvector(3,uniform,1.2,3.5) Ex4: ranm(4,3,uniform,1.2,3.5) ''' - return GiacMethods['uniformd'](self,*args) + return GiacMethods['uniformd'](self, *args) - def uniformd_cdf(self,*args): + def uniformd_cdf(self, *args): r'''From Giac's documentation: Help for uniformd_cdf: uniformd_cdf(Real(a),Real(b),Real(x0),[Real(y0)]) @@ -16465,9 +16465,9 @@ cdef class GiacMethods_base: Ex1:uniformd_cdf(3.2,5.7,4.4) Ex2:uniformd_cdf(3.2,5.7,4.4,5.4) ''' - return GiacMethods['uniformd_cdf'](self,*args) + return GiacMethods['uniformd_cdf'](self, *args) - def uniformd_icdf(self,*args): + def uniformd_icdf(self, *args): r'''From Giac's documentation: Help for uniformd_icdf: uniformd_icdf(Real(a),Real(b),Real(p)) @@ -16476,9 +16476,9 @@ cdef class GiacMethods_base: Ex1:uniformd_icdf(4.2,10.3,0.95) Ex2:uniformd_icdf(3.2,5.7,0.48) ''' - return GiacMethods['uniformd_icdf'](self,*args) + return GiacMethods['uniformd_icdf'](self, *args) - def unitV(self,*args): + def unitV(self, *args): r'''From Giac's documentation: Help for unitV: unitV(Lst||Cplx) @@ -16489,9 +16489,9 @@ cdef class GiacMethods_base: Ex3: fieldplot(-t*y,[t,y],normalize) Ex4: fieldplot(-t*y,[t,y],normalize,xstep=0.5,ystep=0.5) ''' - return GiacMethods['unitV'](self,*args) + return GiacMethods['unitV'](self, *args) - def unquote(self,*args): + def unquote(self, *args): r'''From Giac's documentation: Help for unquote: unquote(Expr) @@ -16499,9 +16499,9 @@ cdef class GiacMethods_base: See also: 1/ quote Ex1:unquote(a) ''' - return GiacMethods['unquote'](self,*args) + return GiacMethods['unquote'](self, *args) - def upper(self,*args): + def upper(self, *args): r'''From Giac's documentation: Help for upper: upper(Mtrx||Strng) @@ -16510,9 +16510,9 @@ cdef class GiacMethods_base: Ex1:upper([[1,2,3],[4,5,6],[7,8,9]]) Ex2:upper("hello") ''' - return GiacMethods['upper'](self,*args) + return GiacMethods['upper'](self, *args) - def user_operator(self,*args): + def user_operator(self, *args): r'''From Giac's documentation: Help for user_operator: user_operator(Str(R),Fnc(f),Opt(Binary||Unary||Delete)) @@ -16521,9 +16521,9 @@ cdef class GiacMethods_base: Ex1:user_operator("R",(x,y)->x*y+x+y,Binary) Ex2:user_operator("R",(x,y)->x*y+x+y,Delete) ''' - return GiacMethods['user_operator'](self,*args) + return GiacMethods['user_operator'](self, *args) - def usimplify(self,*args): + def usimplify(self, *args): r'''From Giac's documentation: Help for usimplify: usimplify(Unit) @@ -16531,9 +16531,9 @@ cdef class GiacMethods_base: See also: 1/ convert 2/ mksa 3/ ufactor Ex1:usimplify(100_(W*s)) ''' - return GiacMethods['usimplify'](self,*args) + return GiacMethods['usimplify'](self, *args) - def valuation(self,*args): + def valuation(self, *args): r'''From Giac's documentation: Help for valuation: valuation(Poly(P)) @@ -16544,9 +16544,9 @@ cdef class GiacMethods_base: Ex3:valuation(x^5+3*x^2) Ex4:valuation([5,0,0,3,0,0]) ''' - return GiacMethods['valuation'](self,*args) + return GiacMethods['valuation'](self, *args) - def vandermonde(self,*args): + def vandermonde(self, *args): r'''From Giac's documentation: Help for vandermonde: vandermonde(Vect(V)) @@ -16554,9 +16554,9 @@ cdef class GiacMethods_base: See also: 1/ det Ex1:vandermonde([1,2,a]) ''' - return GiacMethods['vandermonde'](self,*args) + return GiacMethods['vandermonde'](self, *args) - def variables_are_files(self,*args): + def variables_are_files(self, *args): r'''From Giac's documentation: Help for variables_are_files: variables_are_files(:=Intg(0 or 1)) @@ -16565,9 +16565,9 @@ cdef class GiacMethods_base: Ex1: variables_are_files:=1 Ex2: variables_are_files:=0 ''' - return GiacMethods['variables_are_files'](self,*args) + return GiacMethods['variables_are_files'](self, *args) - def variance(self,*args): + def variance(self, *args): r'''From Giac's documentation: Help for variance: variance(Lst||Mtrx,[Lst]) @@ -16577,9 +16577,9 @@ cdef class GiacMethods_base: Ex2:variance([1,2,3],[1,2,1]) Ex3:variance([[1,2,3],[5,6,7]]) ''' - return GiacMethods['variance'](self,*args) + return GiacMethods['variance'](self, *args) - def version(self,*args): + def version(self, *args): r'''From Giac's documentation: Help for version: version(NULL) @@ -16587,9 +16587,9 @@ cdef class GiacMethods_base: See also: 1/ Ex1:version() ''' - return GiacMethods['version'](self,*args) + return GiacMethods['version'](self, *args) - def vertex_connectivity(self,*args): + def vertex_connectivity(self, *args): r'''From Giac's documentation: Help for vertex_connectivity: vertex_connectivity(Graph(G)) @@ -16599,9 +16599,9 @@ cdef class GiacMethods_base: Ex2:vertex_connectivity(graph("clebsch")) Ex3:vertex_connectivity(complete_graph(5)) ''' - return GiacMethods['vertex_connectivity'](self,*args) + return GiacMethods['vertex_connectivity'](self, *args) - def vertex_degree(self,*args): + def vertex_degree(self, *args): r'''From Giac's documentation: Help for vertex_degree: vertex_degree(Graph(G),Vrtx(v)) @@ -16609,9 +16609,9 @@ cdef class GiacMethods_base: See also: 1/ degree_sequence 2/ is_regular 3/ maximum_degree 4/ minimum_degree 5/ vertex_in_degree 6/ vertex_out_degree Ex1:vertex_degree(digraph(trail(1,2,3,4,2)),2) ''' - return GiacMethods['vertex_degree'](self,*args) + return GiacMethods['vertex_degree'](self, *args) - def vertex_distance(self,*args): + def vertex_distance(self, *args): r'''From Giac's documentation: Help for vertex_distance: vertex_distance(Graph(G),Vrtx(s),Vrtx(t)||Lst(T)) @@ -16620,9 +16620,9 @@ cdef class GiacMethods_base: Ex1:vertex_distance(graph("petersen"),1,4) Ex2:vertex_distance(graph("petersen"),1,[2,4]) ''' - return GiacMethods['vertex_distance'](self,*args) + return GiacMethods['vertex_distance'](self, *args) - def vertex_in_degree(self,*args): + def vertex_in_degree(self, *args): r'''From Giac's documentation: Help for vertex_in_degree: vertex_in_degree(Graph(G),Vrtx(v)) @@ -16630,9 +16630,9 @@ cdef class GiacMethods_base: See also: 1/ degree_sequence 2/ is_regular 3/ maximum_degree 4/ minimum_degree 5/ vertex_degree 6/ vertex_out_degree Ex1:vertex_in_degree(digraph(trail(1,2,3,4,2)),2) ''' - return GiacMethods['vertex_in_degree'](self,*args) + return GiacMethods['vertex_in_degree'](self, *args) - def vertex_out_degree(self,*args): + def vertex_out_degree(self, *args): r'''From Giac's documentation: Help for vertex_out_degree: vertex_out_degree(Graph(G),Vrtx(v)) @@ -16640,9 +16640,9 @@ cdef class GiacMethods_base: See also: 1/ degree_sequence 2/ is_regular 3/ maximum_degree 4/ minimum_degree 5/ vertex_degree 6/ vertex_in_degree Ex1:vertex_out_degree(digraph(trail(1,2,3,4,2)),2) ''' - return GiacMethods['vertex_out_degree'](self,*args) + return GiacMethods['vertex_out_degree'](self, *args) - def vertices(self,*args): + def vertices(self, *args): r'''From Giac's documentation: Help for vertices: vertices(Polygon or Polyedr(P)) @@ -16652,9 +16652,9 @@ cdef class GiacMethods_base: Ex2:vertices(polyhedron([0,0,0],[0,5,0],[0,0,5],[1,2,6])) Ex3:vertices(isosceles_triangle(0,1,pi/4))[2] ''' - return GiacMethods['vertices'](self,*args) + return GiacMethods['vertices'](self, *args) - def vertices_abc(self,*args): + def vertices_abc(self, *args): r'''From Giac's documentation: Help for vertices_abc: vertices_abc(Polygon or Polyedr(P)) @@ -16664,9 +16664,9 @@ cdef class GiacMethods_base: Ex2:vertices_abc(polyhedron([0,0,0],[0,5,0],[0,0,5],[1,2,6])) Ex3:vertices_abc(isosceles_triangle(0,1,pi/4))[2] ''' - return GiacMethods['vertices_abc'](self,*args) + return GiacMethods['vertices_abc'](self, *args) - def vertices_abca(self,*args): + def vertices_abca(self, *args): r'''From Giac's documentation: Help for vertices_abca: vertices_abca(Polygon or Polyedr(P)) @@ -16676,9 +16676,9 @@ cdef class GiacMethods_base: Ex2:vertices_abca(polyhedron([0,0,0],[0,5,0],[0,0,5],[1,2,6])) Ex3:vertices_abca(isosceles_triangle(0,1,pi/4))[2] ''' - return GiacMethods['vertices_abca'](self,*args) + return GiacMethods['vertices_abca'](self, *args) - def vpotential(self,*args): + def vpotential(self, *args): r'''From Giac's documentation: Help for vpotential: vpotential(Vect(V),LstVar) @@ -16686,9 +16686,9 @@ cdef class GiacMethods_base: See also: 1/ curl 2/ potential Ex1:vpotential([2*x*y+3,x^2-4*z,-2*y*z],[x,y,z]) ''' - return GiacMethods['vpotential'](self,*args) + return GiacMethods['vpotential'](self, *args) - def web_graph(self,*args): + def web_graph(self, *args): r'''From Giac's documentation: Help for web_graph: web_graph(Intg(a),Intg(b)) @@ -16696,9 +16696,9 @@ cdef class GiacMethods_base: See also: 1/ prism_graph 2/ wheel_graph Ex1:web_graph(5,3) ''' - return GiacMethods['web_graph'](self,*args) + return GiacMethods['web_graph'](self, *args) - def weibull(self,*args): + def weibull(self, *args): r'''From Giac's documentation: Help for weibull: weibull(Real(k),Real(lambda),Real(theta),Real(x)) @@ -16708,9 +16708,9 @@ cdef class GiacMethods_base: Ex2:weibull(2.1,1.2,0.0,1.3) Ex3:weibull(2.1,1.2,0.5,1.8) ''' - return GiacMethods['weibull'](self,*args) + return GiacMethods['weibull'](self, *args) - def weibull_cdf(self,*args): + def weibull_cdf(self, *args): r'''From Giac's documentation: Help for weibull_cdf: weibull_cdf(Real(k),Real(lambda),Real(theta),Real(x0)) @@ -16722,9 +16722,9 @@ cdef class GiacMethods_base: Ex4:weibull_cdf(2.2,1.5,0.4,1.2) Ex5:weibull_cdf(2.2,1.5,0.4,1.2,1.9) ''' - return GiacMethods['weibull_cdf'](self,*args) + return GiacMethods['weibull_cdf'](self, *args) - def weibull_icdf(self,*args): + def weibull_icdf(self, *args): r'''From Giac's documentation: Help for weibull_icdf: weibull_icdf(Real(k),Real(lambda),Real(theta),Real(p)) @@ -16733,9 +16733,9 @@ cdef class GiacMethods_base: Ex1:weibull_icdf(4.2,1.3,0.0,0.95) Ex2:weibull_icdf(2.2,1.5,0.4,0.632) ''' - return GiacMethods['weibull_icdf'](self,*args) + return GiacMethods['weibull_icdf'](self, *args) - def weibulld(self,*args): + def weibulld(self, *args): r'''From Giac's documentation: Help for weibulld: weibulld(Real(k),Real(lambda),Real(theta),Real(x)) @@ -16745,9 +16745,9 @@ cdef class GiacMethods_base: Ex2:weibulld(2.1,1.2,0.0,1.3) Ex3:weibulld(2.1,1.2,0.5,1.8) ''' - return GiacMethods['weibulld'](self,*args) + return GiacMethods['weibulld'](self, *args) - def weibulld_cdf(self,*args): + def weibulld_cdf(self, *args): r'''From Giac's documentation: Help for weibulld_cdf: weibulld_cdf(Real(k),Real(lambda),Real(theta),Real(x0)) @@ -16759,9 +16759,9 @@ cdef class GiacMethods_base: Ex4:weibulld_cdf(2.2,1.5,0.4,1.2) Ex5:weibulld_cdf(2.2,1.5,0.4,1.2,1.9) ''' - return GiacMethods['weibulld_cdf'](self,*args) + return GiacMethods['weibulld_cdf'](self, *args) - def weibulld_icdf(self,*args): + def weibulld_icdf(self, *args): r'''From Giac's documentation: Help for weibulld_icdf: weibulld_icdf(Real(k),Real(lambda),Real(theta),Real(p)) @@ -16770,9 +16770,9 @@ cdef class GiacMethods_base: Ex1:weibulld_icdf(4.2,1.3,0.0,0.95) Ex2:weibulld_icdf(2.2,1.5,0.4,0.632) ''' - return GiacMethods['weibulld_icdf'](self,*args) + return GiacMethods['weibulld_icdf'](self, *args) - def weibullvariate(self,*args): + def weibullvariate(self, *args): r'''From Giac's documentation: Help for weibullvariate: weibullvariate(Real(a),Real(b)) @@ -16781,9 +16781,9 @@ cdef class GiacMethods_base: Ex1:weibullvariate(1,2) Ex2:weibullvariate(1.5,4) ''' - return GiacMethods['weibullvariate'](self,*args) + return GiacMethods['weibullvariate'](self, *args) - def weight_matrix(self,*args): + def weight_matrix(self, *args): r'''From Giac's documentation: Help for weight_matrix: weight_matrix(Graph(G)) @@ -16791,27 +16791,27 @@ cdef class GiacMethods_base: See also: 1/ set_edge_weight 2/ get_edge_weights 3/ is_weighted 4/ make_weighted 5/ assign_edge_weights Ex1:weight_matrix(graph(%{[[1,2],2],[[2,3],1]%}) ''' - return GiacMethods['weight_matrix'](self,*args) + return GiacMethods['weight_matrix'](self, *args) - def weighted(self,*args): + def weighted(self, *args): r'''From Giac's documentation: Help for weighted: weighted(Opt) Option for graph and digraph commands. See also: 1/ directed 2/ graph 3/ digraph ''' - return GiacMethods['weighted'](self,*args) + return GiacMethods['weighted'](self, *args) - def weights(self,*args): + def weights(self, *args): r'''From Giac's documentation: Help for weights: weights(Opt) Option for the edges command. See also: 1/ edges ''' - return GiacMethods['weights'](self,*args) + return GiacMethods['weights'](self, *args) - def welch_window(self,*args): + def welch_window(self, *args): r'''From Giac's documentation: Help for welch_window: welch_window(Lst,[Interval(n1..n2)]) @@ -16819,9 +16819,9 @@ cdef class GiacMethods_base: See also: 1/ blackman_harris_window 2/ blackman_window 3/ bohman_window 4/ cosine_window 5/ gaussian_window 6/ hamming_window 7/ hann_poisson_window 8/ hann_window 9/ parzen_window 10/ poisson_window 11/ riemann_window 12/ triangle_window 13/ tukey_window 14/ bartlett_hann_window Ex1: scatterplot(welch_window(randvector(1000,0..1))) ''' - return GiacMethods['welch_window'](self,*args) + return GiacMethods['welch_window'](self, *args) - def wheel_graph(self,*args): + def wheel_graph(self, *args): r'''From Giac's documentation: Help for wheel_graph: wheel_graph(Intg(n)) @@ -16829,9 +16829,9 @@ cdef class GiacMethods_base: See also: 1/ star_graph 2/ web_graph Ex1:wheel_graph(5) ''' - return GiacMethods['wheel_graph'](self,*args) + return GiacMethods['wheel_graph'](self, *args) - def widget_size(self,*args): + def widget_size(self, *args): r'''From Giac's documentation: Help for widget_size: widget_size(Intg(n)) @@ -16841,9 +16841,9 @@ cdef class GiacMethods_base: Ex2:widget_size(8) Ex3:widget_size(20,58,49,697,563,1,1,0) ''' - return GiacMethods['widget_size'](self,*args) + return GiacMethods['widget_size'](self, *args) - def wilcoxonp(self,*args): + def wilcoxonp(self, *args): r'''From Giac's documentation: Help for wilcoxonp: wilcoxonp(Intg,[Intg]) @@ -16852,9 +16852,9 @@ cdef class GiacMethods_base: Ex1:wilcoxonp(4) Ex2:wilcoxonp(7,5) ''' - return GiacMethods['wilcoxonp'](self,*args) + return GiacMethods['wilcoxonp'](self, *args) - def wilcoxons(self,*args): + def wilcoxons(self, *args): r'''From Giac's documentation: Help for wilcoxons: wilcoxons(List,List || Real) @@ -16863,9 +16863,9 @@ cdef class GiacMethods_base: Ex1:wilcoxons([1, 3, 4, 5, 7, 8, 8, 12, 15, 17] , [2, 6, 10, 11, 13, 14, 15, 18, 19, 20]) Ex2:wilcoxons([1, 3, 4, 5, 7, 8, 8, 12, 15, 17] , 10) ''' - return GiacMethods['wilcoxons'](self,*args) + return GiacMethods['wilcoxons'](self, *args) - def wilcoxont(self,*args): + def wilcoxont(self, *args): r'''From Giac's documentation: Help for wilcoxont: wilcoxont(List,List || Real,[Func],[Real]) @@ -16876,9 +16876,9 @@ cdef class GiacMethods_base: Ex3:wilcoxont([1, 3, 4, 5, 7, 8, 8, 12, 15, 17] , 10,'>') Ex4:wilcoxont([1, 3, 4, 5, 7, 8, 8, 12, 15, 17] , 10,'>',0.05) ''' - return GiacMethods['wilcoxont'](self,*args) + return GiacMethods['wilcoxont'](self, *args) - def writergb(self,*args): + def writergb(self, *args): r'''From Giac's documentation: Help for writergb: writergb(Str(s),Lst) @@ -16888,9 +16888,9 @@ cdef class GiacMethods_base: Ex2:writergb("image.png",[[255,0],[0,0]],[[0,255],[0,0]],[[0,0],[255,0]]) Ex3: a:=readrgb("rgb_image.png");writergb("brg_image.png",[a[0],a[4],a[1],a[3],a[2]]) ''' - return GiacMethods['writergb'](self,*args) + return GiacMethods['writergb'](self, *args) - def writewav(self,*args): + def writewav(self, *args): r'''From Giac's documentation: Help for writewav: writewav(Str(s),Lst(l)) @@ -16899,9 +16899,9 @@ cdef class GiacMethods_base: Ex1:writewav("la.wav",2^14*(sin(2*pi*440*soundsec(1)))) Ex2:writewav("beep.wav",[[1,16,44100,80000],[65000$10000,0$10000,65000$10000,0$10000]]) ''' - return GiacMethods['writewav'](self,*args) + return GiacMethods['writewav'](self, *args) - def xcas_mode(self,*args): + def xcas_mode(self, *args): r'''From Giac's documentation: Help for xcas_mode: xcas_mode(Intg(0) or 1 or 2 or 3) @@ -16910,9 +16910,9 @@ cdef class GiacMethods_base: Ex1:xcas_mode(1) Ex2:xcas_mode(0) ''' - return GiacMethods['xcas_mode'](self,*args) + return GiacMethods['xcas_mode'](self, *args) - def xml_print(self,*args): + def xml_print(self, *args): r'''From Giac's documentation: Help for xml_print: xml_print(Str) @@ -16920,18 +16920,18 @@ cdef class GiacMethods_base: See also: 1/ export_mathml Ex1:xml_print(export_mathml(a+2*b)) ''' - return GiacMethods['xml_print'](self,*args) + return GiacMethods['xml_print'](self, *args) - def xyztrange(self,*args): + def xyztrange(self, *args): r'''From Giac's documentation: Help for xyztrange: xyztrange(SeqReal) xyztrange puts or erases the axes on the graphic-screen (cf button Cfg). Ex1:xyztrange(-5.0,5.0,-5.0,2.0,-10.0,10.0,-1.0,6.0,-5.0,5.0,-1.2384,2.0,1,0.0,1.0) ''' - return GiacMethods['xyztrange'](self,*args) + return GiacMethods['xyztrange'](self, *args) - def zeros(self,*args): + def zeros(self, *args): r'''From Giac's documentation: Help for zeros: zeros(Expr,[Var]) @@ -16942,9 +16942,9 @@ cdef class GiacMethods_base: Ex3:zeros(ln(y)^2-2,y) Ex4:zeros([x^2-1,x^2-y^2],[x,y]) ''' - return GiacMethods['zeros'](self,*args) + return GiacMethods['zeros'](self, *args) - def ztrans(self,*args): + def ztrans(self, *args): r'''From Giac's documentation: Help for ztrans: ztrans(Expr,[Var],[ZtransVar]) @@ -16953,9 +16953,9 @@ cdef class GiacMethods_base: Ex1:ztrans(a^x) Ex2:ztrans(a^n,n,z) ''' - return GiacMethods['ztrans'](self,*args) + return GiacMethods['ztrans'](self, *args) - def type(self,*args): + def type(self, *args): r'''From Giac's documentation: Help for type: type(Expr) @@ -16964,9 +16964,9 @@ cdef class GiacMethods_base: Ex1:type("abc") Ex2:type([1,2,3]) ''' - return GiacMethods['type'](self,*args) + return GiacMethods['type'](self, *args) - def zip(self,*args): + def zip(self, *args): r'''From Giac's documentation: Help for zip: zip(Fnc2d(f),Lst(l1),Lst(l2),[Val(default)]) @@ -16977,5 +16977,5 @@ cdef class GiacMethods_base: Ex3:zip('+',[a,b,c,d], [1,2,3],5) Ex4:zip(sum,[a,b,c,d], [1,2,3,4]) ''' - return GiacMethods['zip'](self,*args) + return GiacMethods['zip'](self, *args) diff --git a/src/sage/libs/giac/giac.pyx b/src/sage/libs/giac/giac.pyx index 4094307f0fd..5b43dbe231d 100644 --- a/src/sage/libs/giac/giac.pyx +++ b/src/sage/libs/giac/giac.pyx @@ -642,7 +642,7 @@ cdef class GiacSetting(Pygen): def __get__(self): return (self.cas_setup()[6])._val - def __set__(self,value): + def __set__(self, value): l = Pygen('cas_setup()').eval() pl = [ i for i in l ] pl[6] = value @@ -655,7 +655,7 @@ cdef class GiacSetting(Pygen): def __get__(self): return (self.cas_setup()[9])._val == 1 - def __set__(self,value): + def __set__(self, value): l = Pygen('cas_setup()').eval() pl = [ i for i in l ] if value: @@ -683,7 +683,7 @@ cdef class GiacSetting(Pygen): def __get__(self): return (self.cas_setup()[2])._val == 1 - def __set__(self,value): + def __set__(self, value): l = Pygen('cas_setup()').eval() pl = [ i for i in l ] if value: @@ -712,7 +712,7 @@ cdef class GiacSetting(Pygen): def __get__(self): return (self.cas_setup()[7][3])._val - def __set__(self,value): + def __set__(self, value): l = Pygen('cas_setup()').eval() pl = [ i for i in l ] pl[7] = [l[7][0],l[7][1],l[7][2], value] @@ -736,7 +736,7 @@ cdef class GiacSetting(Pygen): def __get__(self): return (self.cas_setup()[5][1])._double - def __set__(self,value): + def __set__(self, value): l = Pygen('cas_setup()').eval() pl = [ i for i in l ] pl[5] = [l[5][0],value] @@ -759,7 +759,7 @@ cdef class GiacSetting(Pygen): def __get__(self): return (self.cas_setup()[5][0])._double - def __set__(self,value): + def __set__(self, value): l = Pygen('cas_setup()').eval() pl = [ i for i in l ] pl[5] = [value,l[5][1]] @@ -772,7 +772,7 @@ cdef class GiacSetting(Pygen): def __get__(self): return (self.cas_setup()[7][0])._val - def __set__(self,value): + def __set__(self, value): Pygen('threads:=%s'%(str(value))).eval() ######################################################## @@ -1221,8 +1221,8 @@ cdef class Pygen(GiacMethods_base): return self # To be able to use the eval function before the GiacMethods initialisation - def cas_setup(self,*args): - return Pygen('cas_setup')(self,*args) + def cas_setup(self, *args): + return Pygen('cas_setup')(self, *args) def savegen(self, str filename): """ @@ -1336,7 +1336,7 @@ cdef class Pygen(GiacMethods_base): sig_off() return result - def _integer_(self,Z=None): + def _integer_(self, Z=None): """ Convert giac integers or modular integers to sage Integers (via gmp). @@ -1797,7 +1797,7 @@ cdef vecteur _wrap_pylist(L) except +: ################################# # slice wrapper for a giac list ################################# -cdef vecteur _getgiacslice(Pygen L,slice sl) except +: +cdef vecteur _getgiacslice(Pygen L, slice sl) except +: cdef vecteur * V cdef int u @@ -2037,7 +2037,7 @@ class GiacInstance: def __init__(self): self.__dict__.update(GiacMethods) - def __call__(self,s): + def __call__(self, s): return _giac(s) def _sage_doc_(self): diff --git a/src/sage/libs/gsl/array.pyx b/src/sage/libs/gsl/array.pyx index 3916929cca4..2dc98555dbd 100644 --- a/src/sage/libs/gsl/array.pyx +++ b/src/sage/libs/gsl/array.pyx @@ -14,7 +14,7 @@ cdef class GSLDoubleArray: sage: a[:6:2] [0.0, 1.0, 1.0] """ - def __init__(self, size_t n, size_t stride = 1, data = None): + def __init__(self, size_t n, size_t stride=1, data=None): """ EXAMPLES:: diff --git a/src/sage/libs/gsl/errno.pxd b/src/sage/libs/gsl/errno.pxd index 02d599289fd..3d54c6ee0ef 100644 --- a/src/sage/libs/gsl/errno.pxd +++ b/src/sage/libs/gsl/errno.pxd @@ -5,9 +5,9 @@ from libc.stdio cimport FILE cdef extern from "gsl/gsl_errno.h": - ctypedef void gsl_error_handler_t (char * reason, char * file,int line, int gsl_errno) + ctypedef void gsl_error_handler_t (char * reason, char * file, int line, int gsl_errno) - ctypedef void gsl_stream_handler_t (char * label, char * file,int line, char * reason) + ctypedef void gsl_stream_handler_t (char * label, char * file, int line, char * reason) void gsl_error (char * reason,char * file, int line, int gsl_errno) diff --git a/src/sage/libs/lcalc/lcalc_Lfunction.pxd b/src/sage/libs/lcalc/lcalc_Lfunction.pxd index 715fa46bba0..b7d3126953c 100644 --- a/src/sage/libs/lcalc/lcalc_Lfunction.pxd +++ b/src/sage/libs/lcalc/lcalc_Lfunction.pxd @@ -105,12 +105,12 @@ ctypedef double Double cdef class Lfunction: cdef void *thisptr cdef void _init_fun(self, char *NAME, int what_type, dirichlet_coeff, long long Period, double q, c_Complex w, int A, double *g, c_Complex *l, int n_poles, c_Complex *p, c_Complex *r) noexcept - cdef c_Complex _value(self,c_Complex s,int derivative) noexcept - cdef c_Complex _hardy_z_function(self,c_Complex s) noexcept + cdef c_Complex _value(self, c_Complex s, int derivative) noexcept + cdef c_Complex _hardy_z_function(self, c_Complex s) noexcept cdef int _compute_rank(self) noexcept #strange bug, replacing Double with double gives me a compile error cdef Double _typedN(self, double T) noexcept - cdef void _find_zeros_v(self, double T1, double T2, double stepsize,doublevec *result) noexcept + cdef void _find_zeros_v(self, double T1, double T2, double stepsize, doublevec *result) noexcept cdef int _find_zeros(self, long count, long start, double max_refine, int rank, const char* message_stamp, doublevec* result) noexcept cdef str _repr diff --git a/src/sage/libs/lcalc/lcalc_Lfunction.pyx b/src/sage/libs/lcalc/lcalc_Lfunction.pyx index f1173543ab1..a8a71c2955a 100644 --- a/src/sage/libs/lcalc/lcalc_Lfunction.pyx +++ b/src/sage/libs/lcalc/lcalc_Lfunction.pyx @@ -402,19 +402,19 @@ cdef class Lfunction: cdef void _init_fun(self, char *NAME, int what_type, dirichlet_coeff, long long Period, double q, c_Complex w, int A, double *g, c_Complex *l, int n_poles, c_Complex *p, c_Complex *r) noexcept: raise NotImplementedError - cdef c_Complex _value(self,c_Complex s,int derivative) noexcept: + cdef c_Complex _value(self, c_Complex s, int derivative) noexcept: raise NotImplementedError - cdef c_Complex _hardy_z_function(self,c_Complex s) noexcept: + cdef c_Complex _hardy_z_function(self, c_Complex s) noexcept: raise NotImplementedError cdef int _compute_rank(self) noexcept: raise NotImplementedError - cdef double _typedN(self,double T) noexcept: + cdef double _typedN(self, double T) noexcept: raise NotImplementedError - cdef void _find_zeros_v(self,double T1, double T2, double stepsize, doublevec *result) noexcept: + cdef void _find_zeros_v(self, double T1, double T2, double stepsize, doublevec *result) noexcept: raise NotImplementedError cdef int _find_zeros(self, long count, long start, double max_refine, int rank, const char* message_stamp, doublevec *result) noexcept: @@ -498,10 +498,10 @@ cdef class Lfunction_I(Lfunction): self.thisptr=new_c_Lfunction_I(NAME, what_type, N, coeffs, Period, q, w, A, g, l, n_poles, p, r) del_ints(coeffs) - cdef inline c_Complex _value(self,c_Complex s,int derivative) noexcept: + cdef inline c_Complex _value(self, c_Complex s, int derivative) noexcept: return ((self.thisptr)).value(s, derivative, "pure") - cdef inline c_Complex _hardy_z_function(self,c_Complex s) noexcept: + cdef inline c_Complex _hardy_z_function(self, c_Complex s) noexcept: return ((self.thisptr)).value(s, 0, "rotated pure") cdef int _compute_rank(self) noexcept: @@ -635,10 +635,10 @@ cdef class Lfunction_D(Lfunction): self.thisptr=new_c_Lfunction_D(NAME, what_type, N, coeffs, Period, q, w, A, g, l, n_poles, p, r) del_doubles(coeffs) - cdef inline c_Complex _value(self,c_Complex s,int derivative) noexcept: + cdef inline c_Complex _value(self, c_Complex s, int derivative) noexcept: return ((self.thisptr)).value(s, derivative, "pure") - cdef inline c_Complex _hardy_z_function(self,c_Complex s) noexcept: + cdef inline c_Complex _hardy_z_function(self, c_Complex s) noexcept: return ((self.thisptr)).value(s, 0, "rotated pure") cdef inline int _compute_rank(self) noexcept: @@ -650,7 +650,7 @@ cdef class Lfunction_D(Lfunction): cdef double _typedN(self, double T) noexcept: return (self.thisptr).N(T) - cdef int _find_zeros(self, long count, long start,double max_refine, int rank, const char* message_stamp, doublevec *result) noexcept: + cdef int _find_zeros(self, long count, long start, double max_refine, int rank, const char* message_stamp, doublevec *result) noexcept: (self.thisptr).find_zeros(count, start, max_refine, rank, message_stamp, result) # debug tools @@ -777,10 +777,10 @@ cdef class Lfunction_C: del_Complexes(coeffs) - cdef inline c_Complex _value(self,c_Complex s,int derivative) noexcept: + cdef inline c_Complex _value(self, c_Complex s, int derivative) noexcept: return ((self.thisptr)).value(s, derivative, "pure") - cdef inline c_Complex _hardy_z_function(self,c_Complex s) noexcept: + cdef inline c_Complex _hardy_z_function(self, c_Complex s) noexcept: return ((self.thisptr)).value(s, 0,"rotated pure") cdef inline int _compute_rank(self) noexcept: @@ -858,10 +858,10 @@ cdef class Lfunction_Zeta(Lfunction): self.thisptr = new_c_Lfunction_Zeta() self._repr = "The Riemann zeta function" - cdef inline c_Complex _value(self,c_Complex s,int derivative) noexcept: + cdef inline c_Complex _value(self, c_Complex s, int derivative) noexcept: return ((self.thisptr)).value(s, derivative, "pure") - cdef inline c_Complex _hardy_z_function(self,c_Complex s) noexcept: + cdef inline c_Complex _hardy_z_function(self, c_Complex s) noexcept: return ((self.thisptr)).value(s, 0, "rotated pure") cdef inline int _compute_rank(self) noexcept: diff --git a/src/sage/libs/linkages/padics/unram_shared.pxi b/src/sage/libs/linkages/padics/unram_shared.pxi index e3edc87bc39..c13f060a227 100644 --- a/src/sage/libs/linkages/padics/unram_shared.pxi +++ b/src/sage/libs/linkages/padics/unram_shared.pxi @@ -83,7 +83,7 @@ def frobenius_unram(self, arithmetic=True): @cython.binding(True) -def norm_unram(self, base = None): +def norm_unram(self, base=None): r""" Return the absolute or relative norm of this element. @@ -170,7 +170,7 @@ def norm_unram(self, base = None): @cython.binding(True) -def trace_unram(self, base = None): +def trace_unram(self, base=None): r""" Return the absolute or relative trace of this element. diff --git a/src/sage/libs/mpmath/utils.pyx b/src/sage/libs/mpmath/utils.pyx index 0123d4190be..5f681852c68 100644 --- a/src/sage/libs/mpmath/utils.pyx +++ b/src/sage/libs/mpmath/utils.pyx @@ -75,7 +75,7 @@ cpdef isqrt(n): mpz_sqrt(y.value, m.value) return y -cpdef from_man_exp(man, exp, long prec = 0, str rnd = 'd'): +cpdef from_man_exp(man, exp, long prec=0, str rnd='d'): """ Create normalized mpf value tuple from mantissa and exponent. diff --git a/src/sage/libs/ntl/ntl_GF2X.pyx b/src/sage/libs/ntl/ntl_GF2X.pyx index 7f790b540e0..1a48250dc44 100644 --- a/src/sage/libs/ntl/ntl_GF2X.pyx +++ b/src/sage/libs/ntl/ntl_GF2X.pyx @@ -674,7 +674,7 @@ cdef class ntl_GF2X(): d.x = GF2X_diff(self.x) return d - def reverse(self, int hi = -2): + def reverse(self, int hi=-2): """ Return reverse of a[0]..a[hi] (hi >= -1) hi defaults to deg(a) diff --git a/src/sage/libs/ntl/ntl_ZZ_pE.pyx b/src/sage/libs/ntl/ntl_ZZ_pE.pyx index 2763c41cb54..4a39cf14051 100644 --- a/src/sage/libs/ntl/ntl_ZZ_pE.pyx +++ b/src/sage/libs/ntl/ntl_ZZ_pE.pyx @@ -328,7 +328,7 @@ cdef class ntl_ZZ_pE(): [1 1 1] """ self.c.restore_c() - cdef ntl_ZZ_pX r = ntl_ZZ_pX(v = None, modulus=self.c.pc) + cdef ntl_ZZ_pX r = ntl_ZZ_pX(v=None, modulus=self.c.pc) r.x = (self.c.f).x return r diff --git a/src/sage/libs/ntl/ntl_ZZ_pEContext.pyx b/src/sage/libs/ntl/ntl_ZZ_pEContext.pyx index 84f5f55f9ec..c9937943824 100644 --- a/src/sage/libs/ntl/ntl_ZZ_pEContext.pyx +++ b/src/sage/libs/ntl/ntl_ZZ_pEContext.pyx @@ -134,11 +134,11 @@ cdef class ntl_ZZ_pEContext_class(): self.pc.restore_c() self.x.restore() - #def ZZ_pX(self,v = None): + #def ZZ_pX(self, v=None): # from ntl_ZZ_pX import ntl_ZZ_pX # return ntl_ZZ_pX(v,modulus=self) - def ZZ_pE(self, v = None): + def ZZ_pE(self, v=None): """ Return a ZZ_pE object with modulus ``self`` out of the data v. @@ -151,7 +151,7 @@ cdef class ntl_ZZ_pEContext_class(): from sage.libs.ntl.ntl_ZZ_pE import ntl_ZZ_pE return ntl_ZZ_pE(v,modulus=self) - def ZZ_pEX(self, v = None): + def ZZ_pEX(self, v=None): """ Return a ZZ_pE object with modulus ``self`` out of the data v. diff --git a/src/sage/libs/ntl/ntl_ZZ_pEX.pyx b/src/sage/libs/ntl/ntl_ZZ_pEX.pyx index caeaa26e984..9aa36ce9fc2 100644 --- a/src/sage/libs/ntl/ntl_ZZ_pEX.pyx +++ b/src/sage/libs/ntl/ntl_ZZ_pEX.pyx @@ -1060,7 +1060,7 @@ cdef class ntl_ZZ_pEX(): [8 1] """ self.c.restore_c() - cdef ntl_ZZ_pE r = ntl_ZZ_pE(modulus = self.c) + cdef ntl_ZZ_pE r = ntl_ZZ_pE(modulus=self.c) sig_on() ZZ_pEX_TraceMod(r.x, self.x, modulus.x) sig_off() @@ -1115,7 +1115,7 @@ cdef class ntl_ZZ_pEX(): [] """ self.c.restore_c() - cdef ntl_ZZ_pE r = ntl_ZZ_pE(modulus = self.c) + cdef ntl_ZZ_pE r = ntl_ZZ_pE(modulus=self.c) sig_on() ZZ_pEX_resultant(r.x, self.x, other.x) sig_off() @@ -1138,7 +1138,7 @@ cdef class ntl_ZZ_pEX(): [9 2] """ self.c.restore_c() - cdef ntl_ZZ_pE r = ntl_ZZ_pE(modulus = self.c) + cdef ntl_ZZ_pE r = ntl_ZZ_pE(modulus=self.c) sig_on() ZZ_pEX_NormMod(r.x, self.x, modulus.x) sig_off() diff --git a/src/sage/libs/ntl/ntl_mat_GF2.pyx b/src/sage/libs/ntl/ntl_mat_GF2.pyx index ae33d4fbb49..479f4505b71 100644 --- a/src/sage/libs/ntl/ntl_mat_GF2.pyx +++ b/src/sage/libs/ntl/ntl_mat_GF2.pyx @@ -520,7 +520,7 @@ cdef class ntl_mat_GF2(): sig_off() return r - def IsIdent(self, n = -1): + def IsIdent(self, n=-1): """ Test if this matrix is the n x n identity matrix. diff --git a/src/sage/libs/ntl/ntl_mat_GF2E.pyx b/src/sage/libs/ntl/ntl_mat_GF2E.pyx index 795ad9674fa..eb044cbfc37 100644 --- a/src/sage/libs/ntl/ntl_mat_GF2E.pyx +++ b/src/sage/libs/ntl/ntl_mat_GF2E.pyx @@ -49,7 +49,7 @@ cdef class ntl_mat_GF2E(): r""" The \class{mat_GF2E} class implements arithmetic with matrices over `GF(2**x)`. """ - def __init__(self, modulus = None, nrows=0, ncols=0, v=None): + def __init__(self, modulus=None, nrows=0, ncols=0, v=None): """ Construct a matrix over ntl.GF2E. @@ -585,7 +585,7 @@ cdef class ntl_mat_GF2E(): sig_off() return r - def IsIdent(self, n = -1): + def IsIdent(self, n=-1): r""" Test if `A` is the `n \times n` identity matrix. diff --git a/src/sage/libs/ntl/ntlwrap_impl.h b/src/sage/libs/ntl/ntlwrap_impl.h index 083bab824cc..094cfb52280 100644 --- a/src/sage/libs/ntl/ntlwrap_impl.h +++ b/src/sage/libs/ntl/ntlwrap_impl.h @@ -487,13 +487,13 @@ static CYTHON_INLINE mat_ZZ* mat_ZZ_HNF(const mat_ZZ* A, const struct ZZ* D) static CYTHON_INLINE long mat_ZZ_LLL(struct ZZ **det, mat_ZZ *x, long a, long b, long verbose) { *det = new ZZ(); - return LLL(**det,*x,a,b,verbose); + return LLL(**det, *x, a, b, verbose); } static CYTHON_INLINE long mat_ZZ_LLL_U(struct ZZ **det, mat_ZZ *x, mat_ZZ *U, long a, long b, long verbose) { *det = new ZZ(); - return LLL(**det,*x,*U,a,b,verbose); + return LLL(**det, *x, *U, a, b, verbose); } diff --git a/src/sage/libs/singular/decl.pxd b/src/sage/libs/singular/decl.pxd index dddc452fd98..d8c6d9a1201 100644 --- a/src/sage/libs/singular/decl.pxd +++ b/src/sage/libs/singular/decl.pxd @@ -983,7 +983,7 @@ cdef extern from "singular/Singular/libsingular.h": void setFlag(leftv *A, int F) void resetFlag(leftv *A, int F) - ctypedef number* (*nMapFunc)(number *c,const n_Procs_s* src,const n_Procs_s* dst) + ctypedef number* (*nMapFunc)(number *c, const n_Procs_s* src, const n_Procs_s* dst) cdef extern from "singular/coeffs/coeffs.h": diff --git a/src/sage/libs/singular/function.pxd b/src/sage/libs/singular/function.pxd index facdcae674a..a83017e74ab 100644 --- a/src/sage/libs/singular/function.pxd +++ b/src/sage/libs/singular/function.pxd @@ -52,7 +52,7 @@ cdef class Converter(SageObject): cdef leftv * append_module(self, m) except NULL cdef to_sage_integer_matrix(self, intvec *mat) cdef object to_sage_module_element_sequence_destructive(self, ideal *i) - cdef to_sage_vector_destructive(self, poly *p, free_module = ?) + cdef to_sage_vector_destructive(self, poly *p, free_module=?) cdef to_sage_matrix(self, matrix* mat) cdef to_python(self, leftv* to_convert) diff --git a/src/sage/libs/singular/function.pyx b/src/sage/libs/singular/function.pyx index c6f65eb718a..da6a1d8c7a5 100644 --- a/src/sage/libs/singular/function.pyx +++ b/src/sage/libs/singular/function.pyx @@ -352,7 +352,7 @@ cdef leftv* new_leftv(void *data, res_type) noexcept: res.rtyp = res_type return res -cdef free_leftv(leftv *args, ring *r = NULL): +cdef free_leftv(leftv *args, ring *r=NULL): """ Kills this ``leftv`` and all ``leftv``s in the tail. @@ -692,7 +692,7 @@ cdef class Converter(SageObject): result[i,j] = p return result - cdef to_sage_vector_destructive(self, poly *p, free_module = None): + cdef to_sage_vector_destructive(self, poly *p, free_module=None): cdef int rank if free_module: rank = free_module.rank() @@ -826,7 +826,7 @@ cdef class Converter(SageObject): cdef poly *p ncols = mat.ncols() nrows = mat.nrows() - cdef matrix* _m=mpNew(nrows,ncols) + cdef matrix* _m=mpNew(nrows, ncols) for i in range(nrows): for j in range(ncols): #FIXME diff --git a/src/sage/libs/singular/polynomial.pyx b/src/sage/libs/singular/polynomial.pyx index 6f7f576cb02..db4b2ff35e2 100644 --- a/src/sage/libs/singular/polynomial.pyx +++ b/src/sage/libs/singular/polynomial.pyx @@ -200,7 +200,7 @@ cdef int singular_polynomial_call(poly **ret, poly *p, ring *r, list args, Leaked 0 bytes """ cdef long l = len(args) - cdef ideal *to_id = idInit(l,1) + cdef ideal *to_id = idInit(l, 1) cdef bint constant_args = 1 for i from 0 <= i < l: to_id.m[i]= p_Copy( get_element(args[i]), r) @@ -391,7 +391,7 @@ cdef int singular_polynomial_pow(poly **ret, poly *p, unsigned long exp, ring *r if r != currRing: rChangeCurrRing(r) - cdef int count = singular_polynomial_length_bounded(p,15) + cdef int count = singular_polynomial_length_bounded(p, 15) if count >= 15 or exp > 15: sig_on() ret[0] = pPower( p_Copy(p,r), exp) diff --git a/src/sage/libs/singular/singular.pxd b/src/sage/libs/singular/singular.pxd index ca31d02456c..9d764b51a6f 100644 --- a/src/sage/libs/singular/singular.pxd +++ b/src/sage/libs/singular/singular.pxd @@ -42,10 +42,10 @@ cpdef tuple si2sa_resolution_graded(Resolution res, tuple degrees) # Conversion from Sage to Singular types # ====================================== -cdef number *sa2si_QQ(Rational ,ring (*)) noexcept +cdef number *sa2si_QQ(Rational, ring (*)) noexcept cdef number *sa2si_ZZ(Integer d, ring *_ring) noexcept -cdef number *sa2si_GFqGivaro(int exp ,ring (*)) noexcept +cdef number *sa2si_GFqGivaro(int exp, ring (*)) noexcept cdef number *sa2si_GFqNTLGF2E(FFgf2eE elem, ring *_ring) noexcept cdef number *sa2si_GFq_generic(object vector, ring *_ring) noexcept cdef number *sa2si_ZZmod(IntegerMod_abstract d, ring *_ring) noexcept diff --git a/src/sage/manifolds/differentiable/affine_connection.py b/src/sage/manifolds/differentiable/affine_connection.py index d1e25cc3e31..73b6e5d42cd 100644 --- a/src/sage/manifolds/differentiable/affine_connection.py +++ b/src/sage/manifolds/differentiable/affine_connection.py @@ -1608,7 +1608,7 @@ def _derive_paral(self, tensor): # definition of the parallel function @parallel(p_iter='multiprocessing',ncpus=nproc) - def make_CovDerivative(ind_part,tc,gam,frame,n_con,rank,manif): + def make_CovDerivative(ind_part, tc, gam, frame, n_con, rank, manif): partial = [] for ind in ind_part: p = ind[-1] # derivation index diff --git a/src/sage/manifolds/differentiable/integrated_curve.py b/src/sage/manifolds/differentiable/integrated_curve.py index 135e6d53d32..17784f555e1 100644 --- a/src/sage/manifolds/differentiable/integrated_curve.py +++ b/src/sage/manifolds/differentiable/integrated_curve.py @@ -1293,7 +1293,7 @@ def system(t, y): # of the system to be provided if T.jacobian is None: - def jacobian(t,y): + def jacobian(t, y): jac = [] par = self._curve_parameter for i in range(dim): diff --git a/src/sage/manifolds/differentiable/levi_civita_connection.py b/src/sage/manifolds/differentiable/levi_civita_connection.py index 55c4aca9416..215756f00d3 100644 --- a/src/sage/manifolds/differentiable/levi_civita_connection.py +++ b/src/sage/manifolds/differentiable/levi_civita_connection.py @@ -507,7 +507,7 @@ def coef(self, frame=None): # definition of the parallel function @parallel(p_iter='multiprocessing',ncpus=nproc) - def make_Connect(local_list_ijk,chart,ginv,gg,manif): + def make_Connect(local_list_ijk, chart, ginv, gg, manif): partial = [] for i,j,k in local_list_ijk: rsum = 0 diff --git a/src/sage/manifolds/differentiable/metric.py b/src/sage/manifolds/differentiable/metric.py index e25033a8cb7..4a783db3478 100644 --- a/src/sage/manifolds/differentiable/metric.py +++ b/src/sage/manifolds/differentiable/metric.py @@ -2598,7 +2598,7 @@ def __init__(self, vector_field_module, name, signature=None, m sage: Int = M.open_subset('Int') sage: X.=Int.chart(r"t r:(0,2*m) th:(0,pi):\theta ph:(0,2*pi):\phi") - sage: XM = M.vector_field_module(); e= X.frame() + sage: XM = M.vector_field_module(); e = X.frame() sage: from sage.manifolds.differentiable.metric import \ ....: DegenerateMetric sage: g = DegenerateMetric(XM, 'g', signature=(2,1,1)); g diff --git a/src/sage/manifolds/differentiable/vectorfield_module.py b/src/sage/manifolds/differentiable/vectorfield_module.py index 43efcb19aa6..67cd1abd614 100644 --- a/src/sage/manifolds/differentiable/vectorfield_module.py +++ b/src/sage/manifolds/differentiable/vectorfield_module.py @@ -1385,7 +1385,7 @@ class VectorFieldFreeModule(FiniteRankFreeModule): Let us introduce an open subset of `J\subset I` and the vector field module corresponding to the restriction of `\Phi` to it:: - sage: J = I.open_subset('J', coord_def= {canon: t self._entries.nrows: raise TypeError("Expected highr <= self.nrows(), but got %d > %d instead."%(highr, self._entries.nrows)) - cdef Matrix_gf2e_dense A = self.new_matrix(nrows = nrows, ncols = ncols) + cdef Matrix_gf2e_dense A = self.new_matrix(nrows=nrows, ncols=ncols) if ncols == 0 or nrows == 0: return A A._entries = mzed_submatrix(A._entries, self._entries, row, col, highr, highc) diff --git a/src/sage/matrix/matrix_integer_dense.pyx b/src/sage/matrix/matrix_integer_dense.pyx index c0e0a1fff44..9ea2335b297 100644 --- a/src/sage/matrix/matrix_integer_dense.pyx +++ b/src/sage/matrix/matrix_integer_dense.pyx @@ -868,7 +868,7 @@ cdef class Matrix_integer_dense(Matrix_dense): [ 9 11 13] [ 9 11 13] """ - cdef Matrix_integer_dense M = self._new(self._nrows,self._ncols) + cdef Matrix_integer_dense M = self._new(self._nrows, self._ncols) sig_on() fmpz_mat_add(M._matrix,self._matrix,( right)._matrix) @@ -888,7 +888,7 @@ cdef class Matrix_integer_dense(Matrix_dense): [-2 0 2] [ 4 6 8] """ - cdef Matrix_integer_dense M = self._new(self._nrows,self._ncols) + cdef Matrix_integer_dense M = self._new(self._nrows, self._ncols) sig_on() fmpz_mat_sub(M._matrix,self._matrix,( right)._matrix) @@ -4164,7 +4164,7 @@ cdef class Matrix_integer_dense(Matrix_dense): raise ArithmeticError("non-invertible matrix") return A - def _solve_right_nonsingular_square(self, B, check_rank=True, algorithm = 'iml'): + def _solve_right_nonsingular_square(self, B, check_rank=True, algorithm='iml'): r""" If ``self`` is a matrix `A` of full rank, then this function returns a vector or matrix `X` such that `A X = B`. @@ -4606,7 +4606,7 @@ cdef class Matrix_integer_dense(Matrix_dense): M,d = self.transpose()._solve_flint(B.transpose(), right=True) return M.transpose(),d - def _rational_echelon_via_solve(self, solver = 'iml'): + def _rational_echelon_via_solve(self, solver='iml'): r""" Compute information that gives the reduced row echelon form (over QQ!) of a matrix with integer entries. @@ -5029,7 +5029,7 @@ cdef class Matrix_integer_dense(Matrix_dense): t = verbose('hermite mod %s' % D, caller_name='matrix_integer_dense') if self._nrows != self._ncols: raise ValueError("matrix is not square") - cdef Matrix_integer_dense res = self._new(self._nrows,self._ncols) + cdef Matrix_integer_dense res = self._new(self._nrows, self._ncols) self._hnf_modn(res, D) verbose('finished hnf mod', t, caller_name='matrix_integer_dense') return res diff --git a/src/sage/matrix/matrix_modn_dense_template.pxi b/src/sage/matrix/matrix_modn_dense_template.pxi index 36830da0549..177cebffb38 100644 --- a/src/sage/matrix/matrix_modn_dense_template.pxi +++ b/src/sage/matrix/matrix_modn_dense_template.pxi @@ -431,7 +431,7 @@ cpdef __matrix_from_rows_of_matrices(X): T = X[0] m = T._nrows * T._ncols - cdef Matrix_modn_dense_template A = T.new_matrix(nrows = n, ncols = m) + cdef Matrix_modn_dense_template A = T.new_matrix(nrows=n, ncols=m) for i from 0 <= i < n: T = X[i] @@ -2807,7 +2807,7 @@ cdef class Matrix_modn_dense_template(Matrix_dense): cdef Py_ssize_t nrows = self._nrows cdef Py_ssize_t ncols = self._ncols - cdef Matrix_modn_dense_template M = self.new_matrix(nrows = ncols, ncols = nrows) + cdef Matrix_modn_dense_template M = self.new_matrix(nrows=ncols, ncols=nrows) cdef Py_ssize_t i,j for i from 0 <= i < ncols: diff --git a/src/sage/matrix/matrix_polynomial_dense.pyx b/src/sage/matrix/matrix_polynomial_dense.pyx index 5b3c56ae573..99979a37ed8 100644 --- a/src/sage/matrix/matrix_polynomial_dense.pyx +++ b/src/sage/matrix/matrix_polynomial_dense.pyx @@ -291,7 +291,7 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): return all([self[i,j].is_constant() for j in range(self.ncols()) for i in range(self.nrows())]) - def coefficient_matrix(self,d,row_wise=True): + def coefficient_matrix(self, d, row_wise=True): r""" Return the constant matrix which is obtained from this matrix by taking the coefficient of its entries with degree specified by `d`. @@ -3106,7 +3106,7 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): If the option ``row_wise`` is set to ``False``, the same operation is performed, but with everything considered column-wise: column space of `B`, `i` th column of `R` and `A`, column-wise `s`-leading positions - and `s`-Popov form, and submatrices `R_{J,*}` and `P_{J,*}`. + and `s`-Popov form, and submatrices `R_{J, *}` and `P_{J, *}`. The operation above can be seen as a matrix generalization of division with remainder for univariate polynomials. If the option diff --git a/src/sage/matrix/matrix_rational_dense.pyx b/src/sage/matrix/matrix_rational_dense.pyx index 533f6b55c67..40c63470617 100644 --- a/src/sage/matrix/matrix_rational_dense.pyx +++ b/src/sage/matrix/matrix_rational_dense.pyx @@ -2776,7 +2776,7 @@ cdef class Matrix_rational_dense(Matrix_dense): We verify that 0 rows or columns works:: - sage: x = matrix(QQ,2,0); y= matrix(QQ,0,2); x*y + sage: x = matrix(QQ,2,0); y = matrix(QQ,0,2); x*y [0 0] [0 0] sage: matrix(ZZ, 0, 0) * matrix(QQ, 0, 5) diff --git a/src/sage/matrix/matrix_sparse.pyx b/src/sage/matrix/matrix_sparse.pyx index 95b8969e0aa..92a2d18d846 100644 --- a/src/sage/matrix/matrix_sparse.pyx +++ b/src/sage/matrix/matrix_sparse.pyx @@ -927,7 +927,7 @@ cdef class Matrix_sparse(matrix.Matrix): ncols = PyList_GET_SIZE(columns) nrows = PyList_GET_SIZE(rows) - cdef Matrix_sparse A = self.new_matrix(nrows = nrows, ncols = ncols) + cdef Matrix_sparse A = self.new_matrix(nrows=nrows, ncols=ncols) tmp = [el for el in columns if 0 <= el < self._ncols] columns = tmp diff --git a/src/sage/matrix/misc.pyx b/src/sage/matrix/misc.pyx index 17277336e3c..7fcb71f8240 100644 --- a/src/sage/matrix/misc.pyx +++ b/src/sage/matrix/misc.pyx @@ -281,10 +281,10 @@ def matrix_rational_echelon_form_multimodular(Matrix self, height_guess=None, pr if cmp_pivots(best_pivots, X[i].pivots()) <= 0: p = X[i].base_ring().order() if p not in lifts: - t0 = verbose("Lifting a good matrix", level=2, caller_name = "multimod echelon") + t0 = verbose("Lifting a good matrix", level=2, caller_name="multimod echelon") lift = X[i].lift() lifts[p] = (lift, p) - verbose("Finished lift", level=2, caller_name= "multimod echelon", t=t0) + verbose("Finished lift", level=2, caller_name="multimod echelon", t=t0) Y.append(lifts[p]) prod = prod * X[i].base_ring().order() verbose("finished comparing pivots", level=2, t=t, caller_name="multimod echelon") diff --git a/src/sage/matrix/special.py b/src/sage/matrix/special.py index b81703b6fe7..dbb0214994e 100644 --- a/src/sage/matrix/special.py +++ b/src/sage/matrix/special.py @@ -3050,7 +3050,7 @@ def random_unimodular_matrix(parent, upper_bound=None, max_tries=100): @matrix_method -def random_diagonalizable_matrix(parent,eigenvalues=None,dimensions=None): +def random_diagonalizable_matrix(parent, eigenvalues=None, dimensions=None): """ Create a random matrix that diagonalizes nicely. diff --git a/src/sage/matrix/strassen.pyx b/src/sage/matrix/strassen.pyx index 978773e3a27..7298dddabd3 100644 --- a/src/sage/matrix/strassen.pyx +++ b/src/sage/matrix/strassen.pyx @@ -20,7 +20,7 @@ from sage.matrix.matrix_window cimport MatrixWindow from cysignals.signals cimport sig_on, sig_off -def strassen_window_multiply(C, A,B, cutoff): +def strassen_window_multiply(C, A, B, cutoff): """ Multiply the submatrices specified by A and B, places result in C. Assumes that A and B have compatible dimensions to be diff --git a/src/sage/matroids/lean_matrix.pyx b/src/sage/matroids/lean_matrix.pyx index f7051f45c92..e0f86c6db83 100644 --- a/src/sage/matroids/lean_matrix.pyx +++ b/src/sage/matroids/lean_matrix.pyx @@ -593,8 +593,8 @@ cdef class LeanMatrix: cdef list lU_2 = sorted(list(U_2)) cdef list lV_2 = sorted(list(V_2)) - cdef dict rU = dict(zip(lU_2,range(len(U_2)))) - cdef dict rV = dict(zip(lV_2,range(len(V_2)))) + cdef dict rU = dict(zip(lU_2, range(len(U_2)))) + cdef dict rV = dict(zip(lV_2, range(len(V_2)))) # find a unique representation of every column in U_1xY_3 using columns in U_1xV_2 B = self.matrix_from_rows_and_columns(list(U_1), range(len(Y))) @@ -2550,7 +2550,7 @@ cdef class QuaternaryMatrix(LeanMatrix): Return a submatrix indexed by indicated rows and columns, as well as the column order of the resulting submatrix. """ - cdef QuaternaryMatrix A = QuaternaryMatrix(len(rows), len(columns), ring = self._gf4) + cdef QuaternaryMatrix A = QuaternaryMatrix(len(rows), len(columns), ring=self._gf4) cdef long r, c, lc, lg cdef mp_bitcnt_t *cols # deal with trivial case diff --git a/src/sage/matroids/linear_matroid.pyx b/src/sage/matroids/linear_matroid.pyx index 6848604f0c8..f8b3b34f67c 100644 --- a/src/sage/matroids/linear_matroid.pyx +++ b/src/sage/matroids/linear_matroid.pyx @@ -3855,7 +3855,7 @@ cdef class BinaryMatroid(LinearMatroid): if len(C[e] & C[f] & C[g]) > 0: M.append([0,col[e,f], col[e,g], col[f,e], col[f,g], col[g,e], col[g,f]]) r += 1 - cdef BinaryMatrix m = BinaryMatrix(r,c) + cdef BinaryMatrix m = BinaryMatrix(r, c) for r in range(len(M)): for c in M[r]: m.set(r,c) @@ -3881,7 +3881,7 @@ cdef class BinaryMatroid(LinearMatroid): # representability - cpdef binary_matroid(self, randomized_tests=1, verify = True): + cpdef binary_matroid(self, randomized_tests=1, verify=True): r""" Return a binary matroid representing ``self``. @@ -4743,7 +4743,7 @@ cdef class TernaryMatroid(LinearMatroid): # representability - cpdef ternary_matroid(self, randomized_tests=1, verify = True): + cpdef ternary_matroid(self, randomized_tests=1, verify=True): r""" Return a ternary matroid representing ``self``. @@ -6313,7 +6313,7 @@ cdef class RegularMatroid(LinearMatroid): """ return True - cpdef binary_matroid(self, randomized_tests=1, verify = True): + cpdef binary_matroid(self, randomized_tests=1, verify=True): r""" Return a binary matroid representing ``self``. @@ -6368,7 +6368,7 @@ cdef class RegularMatroid(LinearMatroid): """ return True - cpdef ternary_matroid(self, randomized_tests=1, verify = True): + cpdef ternary_matroid(self, randomized_tests=1, verify=True): r""" Return a ternary matroid representing ``self``. diff --git a/src/sage/matroids/matroid.pxd b/src/sage/matroids/matroid.pxd index 6218cb804f4..30e0e78a92d 100644 --- a/src/sage/matroids/matroid.pxd +++ b/src/sage/matroids/matroid.pxd @@ -234,9 +234,9 @@ cdef class Matroid(SageObject): cpdef broken_circuit_complex(self, ordering=*) # visualization - cpdef plot(self,B=*,lineorders=*,pos_method=*,pos_dict=*,save_pos=*) - cpdef show(self,B=*,lineorders=*,pos_method=*,pos_dict=*,save_pos=*,lims=*) - cpdef _fix_positions(self,pos_dict=*,lineorders=*) + cpdef plot(self, B=*, lineorders=*, pos_method=*, pos_dict=*, save_pos=*) + cpdef show(self, B=*, lineorders=*, pos_method=*, pos_dict=*, save_pos=*, lims=*) + cpdef _fix_positions(self, pos_dict=*, lineorders=*) # construction cpdef direct_sum(self, matroids) diff --git a/src/sage/matroids/matroid.pyx b/src/sage/matroids/matroid.pyx index 0384ff81a22..98ed3b11c53 100644 --- a/src/sage/matroids/matroid.pyx +++ b/src/sage/matroids/matroid.pyx @@ -6307,7 +6307,7 @@ cdef class Matroid(SageObject): from sage.matroids.linear_matroid import BinaryMatroid return BinaryMatroid(groundset=E, matrix=A, basis=list(basis), keep_initial_representation=False) - cpdef binary_matroid(self, randomized_tests=1, verify = True): + cpdef binary_matroid(self, randomized_tests=1, verify=True): r""" Return a binary matroid representing ``self``, if such a representation exists. @@ -6486,7 +6486,7 @@ cdef class Matroid(SageObject): from sage.matroids.linear_matroid import TernaryMatroid return TernaryMatroid(groundset=E, matrix=A, basis=basis, keep_initial_representation=False) - cpdef ternary_matroid(self, randomized_tests=1, verify = True): + cpdef ternary_matroid(self, randomized_tests=1, verify=True): r""" Return a ternary matroid representing ``self``, if such a representation exists. @@ -8132,7 +8132,7 @@ cdef class Matroid(SageObject): ret.rename("Chow ring of {} over {}".format(self, R)) return ret - cpdef plot(self, B=None, lineorders=None, pos_method=None,pos_dict=None,save_pos=False): + cpdef plot(self, B=None, lineorders=None, pos_method=None, pos_dict=None, save_pos=False): """ Return geometric representation as a sage graphics object. diff --git a/src/sage/misc/binary_tree.pyx b/src/sage/misc/binary_tree.pyx index 583e397a845..0756218e53c 100644 --- a/src/sage/misc/binary_tree.pyx +++ b/src/sage/misc/binary_tree.pyx @@ -491,7 +491,7 @@ class Test: def random(self): self.binary_tree() - def binary_tree(self, values = 100, cycles = 100000): + def binary_tree(self, values=100, cycles=100000): """ Perform a sequence of random operations, given random inputs to stress test the binary tree structure. diff --git a/src/sage/misc/c3.pyx b/src/sage/misc/c3.pyx index bd8057b361f..8dc7e9a9feb 100644 --- a/src/sage/misc/c3.pyx +++ b/src/sage/misc/c3.pyx @@ -177,7 +177,7 @@ cpdef list C3_algorithm(object start, str bases, str attribute, bint proper): out = [] else: out = [start] - cdef list args = getattr(start,bases) + cdef list args = getattr(start, bases) if not args: return out # Data structure / invariants: diff --git a/src/sage/misc/c3_controlled.pyx b/src/sage/misc/c3_controlled.pyx index 81f66f0c680..503130af7d3 100644 --- a/src/sage/misc/c3_controlled.pyx +++ b/src/sage/misc/c3_controlled.pyx @@ -953,7 +953,7 @@ cpdef tuple C3_sorted_merge(list lists, key=identity): last_list_non_empty = False #check_state() suggestion.update(holder.values()) - cdef list suggestion_list = sorted(suggestion, key = key, reverse=True) + cdef list suggestion_list = sorted(suggestion, key=key, reverse=True) #assert C3_merge(lists[:-1]+[suggestion_list]) == out return (out, suggestion_list) diff --git a/src/sage/misc/cachefunc.pyx b/src/sage/misc/cachefunc.pyx index f78b390e031..24fca81dd7f 100644 --- a/src/sage/misc/cachefunc.pyx +++ b/src/sage/misc/cachefunc.pyx @@ -69,7 +69,7 @@ be defined by simply using the decorator. However, an indirect approach is still needed for cpdef methods:: sage: # needs sage.misc.cython - sage: cython_code = ['cpdef test_meth(self,x):', + sage: cython_code = ['cpdef test_meth(self, x):', ....: ' "some doc for a wrapped cython method"', ....: ' return -x', ....: 'from sage.misc.cachefunc import cached_method', @@ -154,7 +154,7 @@ hardly by used. sage: cython_code = ["from sage.structure.element cimport Element, ElementWithCachedMethod", "from cpython.object cimport PyObject_RichCompare", ....: "cdef class MyBrokenElement(Element):", ....: " cdef public object x", - ....: " def __init__(self,P,x):", + ....: " def __init__(self, P, x):", ....: " self.x=x", ....: " Element.__init__(self,P)", ....: " def __neg__(self):", @@ -169,7 +169,7 @@ hardly by used. ....: " return -self", ....: "cdef class MyElement(ElementWithCachedMethod):", ....: " cdef public object x", - ....: " def __init__(self,P,x):", + ....: " def __init__(self, P, x):", ....: " self.x=x", ....: " ElementWithCachedMethod.__init__(self,P)", ....: " def __neg__(self):", @@ -267,7 +267,7 @@ Introspection works:: Some doc for direct method sage: print(sage_getsource(O.wrapped_method)) - cpdef test_meth(self,x): + cpdef test_meth(self, x): "some doc for a wrapped cython method" return -x sage: print(sage_getsource(O.direct_method)) @@ -312,7 +312,7 @@ latter is easy:: ....: "cdef class MyClass:", ....: " cdef public dict _cached_methods", ....: " @cached_method", - ....: " def f(self, a,b):", + ....: " def f(self, a, b):", ....: " return a*b"] sage: cython(os.linesep.join(cython_code)) sage: P = MyClass() @@ -333,7 +333,7 @@ enough in the following example:: ....: " cdef dict D", ....: " def __init__(self):", ....: " self.D = {}", - ....: " def __setattr__(self, n,v):", + ....: " def __setattr__(self, n, v):", ....: " self.D[n] = v", ....: " def __getattribute__(self, n):", ....: " try:", @@ -342,7 +342,7 @@ enough in the following example:: ....: " pass", ....: " return getattr(type(self),n).__get__(self)", ....: " @cached_method", - ....: " def f(self, a,b):", + ....: " def f(self, a, b):", ....: " return a+b"] sage: cython(os.linesep.join(cython_code)) sage: Q = MyOtherClass() @@ -1607,7 +1607,7 @@ class CachedMethodPickle(): """ return CachedMethodPickle,(self._instance,self._name,self._cache) - def __call__(self,*args,**kwds): + def __call__(self, *args, **kwds): """ The purpose of this call method is to kill ``self`` and to replace it by an actual :class:`CachedMethodCaller`. The last @@ -1636,9 +1636,9 @@ class CachedMethodPickle(): else: for k, v in self._cache: CM.cache[k] = v - return CM(*args,**kwds) + return CM(*args, **kwds) - def __getattr__(self,s): + def __getattr__(self, s): """ TESTS:: @@ -1692,7 +1692,7 @@ cdef class CachedMethodCaller(CachedFunction): sage: class A: ....: @cached_method - ....: def bar(self,x): + ....: def bar(self, x): ....: return x^2 sage: a = A() sage: a.bar @@ -1718,7 +1718,7 @@ cdef class CachedMethodCaller(CachedFunction): sage: class A: ....: @cached_method(do_pickle=True) - ....: def bar(self,x): + ....: def bar(self, x): ....: return x^2 sage: __main__.A = A @@ -1739,7 +1739,7 @@ cdef class CachedMethodCaller(CachedFunction): ....: def __init__(self, x): ....: self._x = x ....: @cached_method - ....: def f(self,*args): + ....: def f(self, *args): ....: return self._x^2 sage: a = Foo(2) sage: a.f.cache @@ -1812,7 +1812,7 @@ cdef class CachedMethodCaller(CachedFunction): ....: def __init__(self, x): ....: self._x = x ....: @cached_method - ....: def f(self,n=2): + ....: def f(self, n=2): ....: return self._x^n sage: a = Foo(2) sage: a.f() @@ -1865,7 +1865,7 @@ cdef class CachedMethodCaller(CachedFunction): sage: from sage.misc.superseded import deprecated_function_alias sage: class Foo: ....: @cached_method - ....: def f(self, x,y=1): + ....: def f(self, x, y=1): ....: return x+y ....: g = deprecated_function_alias(57, f) sage: a = Foo() @@ -2629,7 +2629,7 @@ cdef class CachedMethod(): ....: def __init__(self, x): ....: self._x = x ....: @cached_method - ....: def f(self,n): + ....: def f(self, n): ....: return self._x^n ....: @cached_method ....: def f0(self): @@ -2708,7 +2708,7 @@ cdef class CachedMethod(): ....: def __init__(self, x): ....: self._x = x ....: @cached_method - ....: def f(self,n=2): + ....: def f(self, n=2): ....: return self._x^n ....: g = deprecated_function_alias(57, f) sage: a = Foo(2) @@ -2742,7 +2742,7 @@ cdef class CachedMethod(): ....: def __init__(self, x): ....: self._x = x ....: @cached_method - ....: def f(self,n=2): + ....: def f(self, n=2): ....: return self._x^n sage: a = Foo(2) sage: a.f() @@ -2778,7 +2778,7 @@ cdef class CachedMethod(): ....: def f(self): ....: return 1 ....: @cached_method - ....: def g(self, x,n=3): + ....: def g(self, x, n=3): ....: return x^n sage: a = Foo() sage: type(a.f) @@ -3685,7 +3685,7 @@ class disk_cached_function: sage: foo(200) 1/200 """ - def __init__(self, dir, memory_cache = False, key=None): + def __init__(self, dir, memory_cache=False, key=None): """ EXAMPLES:: diff --git a/src/sage/misc/decorators.py b/src/sage/misc/decorators.py index e91acf5b5a9..f93f1227448 100644 --- a/src/sage/misc/decorators.py +++ b/src/sage/misc/decorators.py @@ -319,19 +319,19 @@ def decorator_defaults(func): sage: from sage.misc.decorators import decorator_defaults sage: @decorator_defaults - ....: def my_decorator(f,*args,**kwds): + ....: def my_decorator(f, *args, **kwds): ....: print(kwds) ....: print(args) ....: print(f.__name__) sage: @my_decorator - ....: def my_fun(a,b): + ....: def my_fun(a, b): ....: return a,b {} () my_fun sage: @my_decorator(3,4,c=1,d=2) - ....: def my_fun(a,b): + ....: def my_fun(a, b): ....: return a,b {'c': 1, 'd': 2} (3, 4) diff --git a/src/sage/misc/fpickle.pyx b/src/sage/misc/fpickle.pyx index fd192f1bf02..7a45ecc4f75 100644 --- a/src/sage/misc/fpickle.pyx +++ b/src/sage/misc/fpickle.pyx @@ -17,7 +17,7 @@ def code_ctor(*args): This indirectly tests this function. :: - sage: def foo(a,b,c=10): return a+b+c + sage: def foo(a, b, c=10): return a+b+c sage: sage.misc.fpickle.reduce_code(foo.__code__) (, ...) sage: unpickle_function(pickle_function(foo)) @@ -96,7 +96,7 @@ def unpickle_function(pickled): EXAMPLES:: - sage: def f(N,M): return N*M + sage: def f(N, M): return N*M ... sage: unpickle_function(pickle_function(f))(3,5) 15 diff --git a/src/sage/misc/function_mangling.pyx b/src/sage/misc/function_mangling.pyx index 79e508f19b8..afcbf86b823 100644 --- a/src/sage/misc/function_mangling.pyx +++ b/src/sage/misc/function_mangling.pyx @@ -47,7 +47,7 @@ cdef class ArgumentFixer: watching the caller. For example, :: - sage: def f(x = 10): + sage: def f(x=10): ....: return min(1,x) the following calls are equivalent, @@ -63,7 +63,7 @@ cdef class ArgumentFixer: but from the perspective of a wrapper, they are different:: sage: def wrap(g): - ....: def _g(*args,**kwargs): + ....: def _g(*args, **kwargs): ....: print("{} {}".format(args, kwargs)) ....: return g(*args, **kwargs) ....: return _g @@ -92,7 +92,7 @@ cdef class ArgumentFixer: ....: af = ArgumentFixer(g) ....: def _g(*args, **kwargs): ....: print(af.fix_to_pos()) - ....: return g(*args,**kwargs) + ....: return g(*args, **kwargs) ....: return _g sage: h2 = wrap2(f) sage: t = h2() @@ -105,13 +105,13 @@ cdef class ArgumentFixer: :: sage: class one: - ....: def __init__(self, x = 1): + ....: def __init__(self, x=1): ....: self.x = x sage: af = ArgumentFixer(one.__init__, classmethod=True) sage: af.fix_to_pos(1,2,3,a=31,b=2,n=3) ((1, 2, 3), (('a', 31), ('b', 2), ('n', 3))) """ - def __init__(self, f, classmethod = False): + def __init__(self, f, classmethod=False): try: arg_names, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, annotations = sage_getargspec(f) except AttributeError: @@ -159,7 +159,7 @@ cdef class ArgumentFixer: """ return "Argument Fixer of %s"%self.f - def fix_to_named(self, *args,**kwargs): + def fix_to_named(self, *args, **kwargs): """ Normalize the arguments with a preference for named arguments. @@ -185,7 +185,7 @@ cdef class ArgumentFixer: :: A,K = self.fix_to_pos(...) - self.f(*A,**dict(K))` + self.f(*A, **dict(K))` and :: @@ -247,7 +247,7 @@ cdef class ArgumentFixer: :: A,K = self.fix_to_pos(...) - self.f(*A,**dict(K)) + self.f(*A, **dict(K)) are equivalent to :: diff --git a/src/sage/misc/parser.pyx b/src/sage/misc/parser.pyx index 7a2c2cc99a4..522f5ebf55e 100644 --- a/src/sage/misc/parser.pyx +++ b/src/sage/misc/parser.pyx @@ -204,7 +204,7 @@ cdef class Tokenizer: token = self.next() return all - cpdef reset(self, int pos = 0): + cpdef reset(self, int pos=0): """ Reset the tokenizer to a given position. diff --git a/src/sage/misc/persist.pyx b/src/sage/misc/persist.pyx index 55540dc27b7..e4d5a4b3cde 100644 --- a/src/sage/misc/persist.pyx +++ b/src/sage/misc/persist.pyx @@ -456,14 +456,14 @@ def register_unpickle_override(module, name, callable, call_name=None): :: sage: class A(): - ....: def __init__(self,value): + ....: def __init__(self, value): ....: self.original_attribute = value ....: def __repr__(self): ....: return 'A(%s)' % self.original_attribute sage: class B(): - ....: def __init__(self,value): + ....: def __init__(self, value): ....: self.new_attribute = value - ....: def __setstate__(self,state): + ....: def __setstate__(self, state): ....: try: ....: self.new_attribute = state['new_attribute'] ....: except KeyError: # an old pickle diff --git a/src/sage/misc/sageinspect.py b/src/sage/misc/sageinspect.py index 1f2a39d7c78..c948099d09b 100644 --- a/src/sage/misc/sageinspect.py +++ b/src/sage/misc/sageinspect.py @@ -238,11 +238,11 @@ def _extract_embedded_position(docstring): The following has been fixed in :issue:`13916`:: - sage: cython('''cpdef test_funct(x,y): return''') # needs sage.misc.cython + sage: cython('''cpdef test_funct(x, y): return''') # needs sage.misc.cython sage: func_doc = inspect.getdoc(test_funct) # needs sage.misc.cython sage: with open(_extract_embedded_position(func_doc)[1]) as f: # needs sage.misc.cython ....: print(f.read()) - cpdef test_funct(x,y): return + cpdef test_funct(x, y): return Ensure that the embedded filename of the compiled function is correct. In particular it should be relative to ``spyx_tmp()`` in @@ -252,11 +252,11 @@ def _extract_embedded_position(docstring): sage: from sage.env import DOT_SAGE sage: from sage.misc.sage_ostools import restore_cwd sage: with restore_cwd(DOT_SAGE): # needs sage.misc.cython - ....: cython('''cpdef test_funct(x,y): return''') + ....: cython('''cpdef test_funct(x, y): return''') sage: func_doc = inspect.getdoc(test_funct) # needs sage.misc.cython sage: with open(_extract_embedded_position(func_doc)[1]) as f: # needs sage.misc.cython ....: print(f.read()) - cpdef test_funct(x,y): return + cpdef test_funct(x, y): return """ try: res = __embedded_position_re.search(docstring) @@ -1093,7 +1093,7 @@ def _sage_getargspec_cython(source): Some malformed input is detected:: - sage: sgc('def f(x,y') + sage: sgc('def f(x, y') Traceback (most recent call last): ... SyntaxError: Unexpected EOF while parsing argument list @@ -1484,7 +1484,7 @@ def sage_getargspec(obj): ....: 'cdef class MyClass:', ....: ' def _sage_src_(self):', ....: ' return "def foo(x, a=\\\')\\\"\\\', b={(2+1):\\\'bar\\\', not 1:3, 3<<4:5}): return\\n"', - ....: ' def __call__(self, m,n): return "something"'] + ....: ' def __call__(self, m, n): return "something"'] sage: cython('\n'.join(cython_code)) sage: O = MyClass() sage: print(sage.misc.sageinspect.sage_getsource(O)) @@ -1525,11 +1525,11 @@ def foo(x, a='\')"', b={not (2+1==3):'bar'}): return ....: ''' ....: class Foo: ....: @staticmethod - ....: def join(categories, bint as_list = False, tuple ignore_axioms=(), tuple axioms=()): pass + ....: def join(categories, bint as_list=False, tuple ignore_axioms=(), tuple axioms=()): pass ....: cdef class Bar: ....: @staticmethod - ....: def join(categories, bint as_list = False, tuple ignore_axioms=(), tuple axioms=()): pass - ....: cpdef meet(categories, bint as_list = False, tuple ignore_axioms=(), tuple axioms=()): pass + ....: def join(categories, bint as_list=False, tuple ignore_axioms=(), tuple axioms=()): pass + ....: cpdef meet(categories, bint as_list=False, tuple ignore_axioms=(), tuple axioms=()): pass ....: ''') sage: sage_getargspec(Foo.join) FullArgSpec(args=['categories', 'as_list', 'ignore_axioms', 'axioms'], varargs=None, varkw=None, @@ -2005,7 +2005,7 @@ def sage_getdoc(obj, obj_name='', embedded=False): sage: from sage.misc.sageinspect import sage_getdoc sage: sage_getdoc(identity_matrix)[87:124] # needs sage.modules 'Return the n x n identity matrix over' - sage: def f(a,b,c,d=1): return a+b+c+d + sage: def f(a, b, c, d=1): return a+b+c+d ... sage: import functools sage: f1 = functools.partial(f, 1,c=2) @@ -2244,9 +2244,9 @@ def sage_getsourcelines(obj): TESTS:: sage: # needs sage.misc.cython - sage: cython('''cpdef test_funct(x,y): return''') + sage: cython('''cpdef test_funct(x, y): return''') sage: sage_getsourcelines(test_funct) - (['cpdef test_funct(x,y): return\n'], 1) + (['cpdef test_funct(x, y): return\n'], 1) The following tests that an instance of ``functools.partial`` is correctly dealt with (see :issue:`9976`):: diff --git a/src/sage/modular/arithgroup/arithgroup_perm.py b/src/sage/modular/arithgroup/arithgroup_perm.py index 388cabfeed1..4238875048b 100644 --- a/src/sage/modular/arithgroup/arithgroup_perm.py +++ b/src/sage/modular/arithgroup/arithgroup_perm.py @@ -1019,7 +1019,7 @@ def _index_to_lr_cusp_width(self): return (l_cycle_length, r_cycle_length) - def _contains_sl2(self, a,b,c,d): + def _contains_sl2(self, a, b, c, d): r""" Test whether ``[a,b;c,d]`` is in the group or not. @@ -1145,7 +1145,7 @@ def is_normal(self): return False return True - def _conjugate(self,j0): + def _conjugate(self, j0): r""" Return the conjugate of ``self`` rooted at j0. @@ -1654,7 +1654,7 @@ def is_even(self): """ return False - def to_even_subgroup(self,relabel=True): + def to_even_subgroup(self, relabel=True): r""" Return the group with `-Id` added in it. @@ -1784,7 +1784,7 @@ def nregcusps(self): n += 1 return n//2 - def cusp_widths(self,exp=False): + def cusp_widths(self, exp=False): r""" Return the list of cusp widths. @@ -2391,7 +2391,7 @@ def coset_reps(self): """ return self.todd_coxeter()[0] - def cusp_widths(self,exp=False): + def cusp_widths(self, exp=False): r""" Return the list of cusp widths of the group. @@ -2462,7 +2462,7 @@ def to_even_subgroup(self, relabel=True): else: return self - def one_odd_subgroup(self,random=False): + def one_odd_subgroup(self, random=False): r""" Return an odd subgroup of index 2 in `\Gamma`, where `\Gamma` is this subgroup. If the optional argument ``random`` is False (the default), diff --git a/src/sage/modular/arithgroup/congroup_gamma.py b/src/sage/modular/arithgroup/congroup_gamma.py index 78d878aaf9d..2860ad5ad0a 100644 --- a/src/sage/modular/arithgroup/congroup_gamma.py +++ b/src/sage/modular/arithgroup/congroup_gamma.py @@ -140,7 +140,7 @@ def index(self): """ return prod([p**(3*e-2)*(p*p-1) for (p,e) in self.level().factor()]) - def _contains_sl2(self, a,b,c,d): + def _contains_sl2(self, a, b, c, d): r""" EXAMPLES:: @@ -326,7 +326,7 @@ def is_Gamma(x): return isinstance(x, Gamma_class) -def _lift_pair(U,V,N): +def _lift_pair(U, V, N): r""" Utility function. Given integers ``U, V, N``, with `N \ge 1` and `{\rm gcd}(U, V, N) = 1`, return a pair `(u, v)` congruent to `(U, V) \bmod N`, diff --git a/src/sage/modular/arithgroup/congroup_gamma0.py b/src/sage/modular/arithgroup/congroup_gamma0.py index ca0d050fe6f..611b67afe03 100644 --- a/src/sage/modular/arithgroup/congroup_gamma0.py +++ b/src/sage/modular/arithgroup/congroup_gamma0.py @@ -414,7 +414,7 @@ def gamma_h_subgroups(self): R = IntegerModRing(N) return [GammaH(N, H) for H in R.multiplicative_subgroups()] - def _contains_sl2(self, a,b,c,d): + def _contains_sl2(self, a, b, c, d): r""" Test whether x is an element of this group. diff --git a/src/sage/modular/arithgroup/congroup_gamma1.py b/src/sage/modular/arithgroup/congroup_gamma1.py index c450d98a783..b107686d7ad 100644 --- a/src/sage/modular/arithgroup/congroup_gamma1.py +++ b/src/sage/modular/arithgroup/congroup_gamma1.py @@ -238,7 +238,7 @@ def generators(self, algorithm='farey'): else: raise ValueError("Unknown algorithm '%s' (should be either 'farey' or 'todd-coxeter')" % algorithm) - def _contains_sl2(self, a,b,c,d): + def _contains_sl2(self, a, b, c, d): r""" Test whether x is an element of this group. diff --git a/src/sage/modular/arithgroup/congroup_generic.py b/src/sage/modular/arithgroup/congroup_generic.py index 41a09602a88..b94568522f6 100644 --- a/src/sage/modular/arithgroup/congroup_generic.py +++ b/src/sage/modular/arithgroup/congroup_generic.py @@ -332,7 +332,7 @@ def __reduce__(self): """ return CongruenceSubgroup_constructor, (self.image_mod_n(),) - def _contains_sl2(self, a,b,c,d): + def _contains_sl2(self, a, b, c, d): r""" Test whether ``[a,b;c,d]`` is an element of ``self``. @@ -455,7 +455,7 @@ def image_mod_n(self): """ raise NotImplementedError - def __init__(self,*args, **kwds): + def __init__(self, *args, **kwds): r""" Bypass the init function of the CongruenceSubgroupFromGroup class. diff --git a/src/sage/modular/arithgroup/congroup_sl2z.py b/src/sage/modular/arithgroup/congroup_sl2z.py index d95c9e18764..f7f6d47efed 100644 --- a/src/sage/modular/arithgroup/congroup_sl2z.py +++ b/src/sage/modular/arithgroup/congroup_sl2z.py @@ -118,7 +118,7 @@ def _element_constructor_(self, x, check=True): """ return ArithmeticSubgroupElement(self, x, check=check) - def _contains_sl2(self,a,b,c,d): + def _contains_sl2(self, a, b, c, d): r""" Test whether [a,b,c,d] is an element of self, where a,b,c,d are integers with `ad-bc=1`. In other words, always return True. diff --git a/src/sage/modular/btquotients/pautomorphicform.py b/src/sage/modular/btquotients/pautomorphicform.py index 53a7d2ac6f6..3d49d59bdfc 100644 --- a/src/sage/modular/btquotients/pautomorphicform.py +++ b/src/sage/modular/btquotients/pautomorphicform.py @@ -870,14 +870,14 @@ def is_simple(self): EXAMPLES:: - sage: X = BruhatTitsQuotient(3,29) - sage: H = X.harmonic_cocycles(4,prec =10) + sage: X = BruhatTitsQuotient(3, 29) + sage: H = X.harmonic_cocycles(4, prec=10) sage: H.rank() 14 sage: H.is_simple() False - sage: X = BruhatTitsQuotient(7,2) - sage: H = X.harmonic_cocycles(2,prec=10) + sage: X = BruhatTitsQuotient(7, 2) + sage: H = X.harmonic_cocycles(2, prec=10) sage: H.rank() 1 sage: H.is_simple() diff --git a/src/sage/modular/hecke/module.py b/src/sage/modular/hecke/module.py index e22ed609da6..bbc76fd1cbc 100644 --- a/src/sage/modular/hecke/module.py +++ b/src/sage/modular/hecke/module.py @@ -1695,7 +1695,7 @@ def system_of_eigenvalues(self, n, name='alpha'): Next we define a function that does the above:: - sage: def b(N,k=2): + sage: def b(N, k=2): ....: S = ModularSymbols(N,k,sign=-1).cuspidal_submodule().new_submodule() ....: for A in S.decomposition(): ....: print("{} {}".format(N, A.system_of_eigenvalues(5))) diff --git a/src/sage/modular/local_comp/local_comp.py b/src/sage/modular/local_comp/local_comp.py index 04d9123ab57..349c1e407e1 100644 --- a/src/sage/modular/local_comp/local_comp.py +++ b/src/sage/modular/local_comp/local_comp.py @@ -987,7 +987,7 @@ class ImprimitiveLocalComponent(LocalComponentBase): component and a character to twist by. """ - def __init__(self,newform, prime, twist_factor, min_twist, chi): + def __init__(self, newform, prime, twist_factor, min_twist, chi): r""" EXAMPLES:: diff --git a/src/sage/modular/modform/ambient_R.py b/src/sage/modular/modform/ambient_R.py index c07597e25dc..47b032176e6 100644 --- a/src/sage/modular/modform/ambient_R.py +++ b/src/sage/modular/modform/ambient_R.py @@ -39,7 +39,7 @@ def __init__(self, M, base_ring): ambient.ModularFormsAmbient.__init__(self, M.group(), M.weight(), base_ring, M.character(), M._eis_only) @cached_method(key=lambda self,sign: ZZ(sign)) # convert sign to an Integer before looking this up in the cache - def modular_symbols(self,sign=0): + def modular_symbols(self, sign=0): r""" Return the space of modular symbols attached to this space, with the given sign (default 0). diff --git a/src/sage/modular/modsym/manin_symbol.pyx b/src/sage/modular/modsym/manin_symbol.pyx index 7a98b5d1a40..726f78c55a6 100644 --- a/src/sage/modular/modsym/manin_symbol.pyx +++ b/src/sage/modular/modsym/manin_symbol.pyx @@ -287,7 +287,7 @@ cdef class ManinSymbol(Element): matrix[0]*self.u + matrix[2]*self.v, matrix[1]*self.u + matrix[3]*self.v)) - def apply(self, a,b,c,d): + def apply(self, a, b, c, d): """ Return the image of ``self`` under the matrix `[a,b;c,d]`. diff --git a/src/sage/modular/overconvergent/hecke_series.py b/src/sage/modular/overconvergent/hecke_series.py index 0b1502d2d9a..1bea5617707 100644 --- a/src/sage/modular/overconvergent/hecke_series.py +++ b/src/sage/modular/overconvergent/hecke_series.py @@ -153,7 +153,7 @@ def low_weight_bases(N, p, m, NN, weightbound): return generators -def random_low_weight_bases(N,p,m,NN,weightbound): +def random_low_weight_bases(N, p, m, NN, weightbound): r""" Return list of random integral bases of modular forms of level `N` and (even) weight at most weightbound with coefficients reduced modulo @@ -197,7 +197,7 @@ def random_low_weight_bases(N,p,m,NN,weightbound): return RandomLWB -def low_weight_generators(N,p,m,NN): +def low_weight_generators(N, p, m, NN): r""" Return a list of lists of modular forms, and an even natural number. @@ -248,7 +248,7 @@ def low_weight_generators(N,p,m,NN): return generators, weightbound -def random_solution(B,K): +def random_solution(B, K): r""" Return a random solution in nonnegative integers to the equation `a_1 + 2 a_2 + 3 a_3 + ... + B a_B = K`, using a greedy algorithm. diff --git a/src/sage/modular/pollack_stevens/modsym.py b/src/sage/modular/pollack_stevens/modsym.py index 8df8655e5e9..ddb1f861f1b 100644 --- a/src/sage/modular/pollack_stevens/modsym.py +++ b/src/sage/modular/pollack_stevens/modsym.py @@ -1574,7 +1574,7 @@ def specialize(self, new_base_ring=None): return self.__class__(self._map.specialize(new_base_ring), self.parent()._specialize_parent_space(new_base_ring), construct=True) - def padic_lseries(self,*args, **kwds): + def padic_lseries(self, *args, **kwds): """ Return the `p`-adic `L`-series of this modular symbol. diff --git a/src/sage/modules/free_module_element.pyx b/src/sage/modules/free_module_element.pyx index 3f397404988..095e078c83c 100644 --- a/src/sage/modules/free_module_element.pyx +++ b/src/sage/modules/free_module_element.pyx @@ -4141,7 +4141,7 @@ cdef class FreeModuleElement(Vector): # abstract base class (1/2, 1/3, -cos(1) + 1) """ from sage.misc.functional import integral - return self.apply_map(lambda x: integral(x,*args, **kwds)) + return self.apply_map(lambda x: integral(x, *args, **kwds)) integrate = integral @@ -4179,11 +4179,11 @@ cdef class FreeModuleElement(Vector): # abstract base class # return self.apply_map(lambda x: x.nintegral(*args, **kwds) for x in self) if self.is_sparse(): - v = [(i,z.nintegral(*args,**kwds)) for i,z in self.dict(copy=False).items()] + v = [(i,z.nintegral(*args, **kwds)) for i,z in self.dict(copy=False).items()] answers = dict([(i,a[0]) for i,a in v]) v=dict(v) else: - v = [z.nintegral(*args,**kwds) for z in self.list()] + v = [z.nintegral(*args, **kwds) for z in self.list()] answers = [a[0] for a in v] return (vector(answers,sparse=self.is_sparse()), v) @@ -4850,7 +4850,7 @@ cdef class FreeModuleElement_generic_sparse(FreeModuleElement): We can initialize with dicts, lists, tuples and derived types:: sage: from sage.modules.free_module_element import FreeModuleElement_generic_sparse - sage: def S(R,n): + sage: def S(R, n): ....: return FreeModule(R, n, sparse=True) sage: # needs sage.symbolic diff --git a/src/sage/modules/vector_integer_dense.pyx b/src/sage/modules/vector_integer_dense.pyx index 3605f4cf865..fc1bef4dda6 100644 --- a/src/sage/modules/vector_integer_dense.pyx +++ b/src/sage/modules/vector_integer_dense.pyx @@ -190,7 +190,7 @@ cdef class Vector_integer_dense(free_module_element.FreeModuleElement): """ mpz_set(self._entries[i], (value).value) - def list(self,copy=True): + def list(self, copy=True): """ The list of entries of the vector. diff --git a/src/sage/modules/vector_numpy_dense.pyx b/src/sage/modules/vector_numpy_dense.pyx index b6e6d37473f..f04163d2e82 100644 --- a/src/sage/modules/vector_numpy_dense.pyx +++ b/src/sage/modules/vector_numpy_dense.pyx @@ -128,7 +128,7 @@ cdef class Vector_numpy_dense(FreeModuleElement): from copy import copy return self._new(copy(self._vector_numpy)) - def __init__(self, parent, entries, coerce = True, copy = True): + def __init__(self, parent, entries, coerce=True, copy=True): """ Fill the vector with entries. diff --git a/src/sage/modules/with_basis/invariant.py b/src/sage/modules/with_basis/invariant.py index 5c4202419a5..b97539d5a27 100644 --- a/src/sage/modules/with_basis/invariant.py +++ b/src/sage/modules/with_basis/invariant.py @@ -170,7 +170,7 @@ class FiniteDimensionalInvariantModule(SubmoduleWithBasis): sage: C = IntegerVectors(4, length=3, min_part=0) # representing degree-4 monomials sage: M = CombinatorialFreeModule(QQ, C) # isomorphic to deg-4 homog. polynomials sage: G = SymmetricGroup(3) - sage: def perm_action(g,x): return M.monomial(C(g(list(x)))) + sage: def perm_action(g, x): return M.monomial(C(g(list(x)))) sage: perm_action(G((1,2,3)), C([4,3,2])) B[[3, 2, 4]] sage: R = Representation(G, M, perm_action) @@ -227,7 +227,7 @@ def __init__(self, M, S, action=operator.mul, side='left', *args, **kwargs): sage: G = GroupExp()(QQ) # a group that is not finitely generated sage: M = CombinatorialFreeModule(QQ, [1,2,3]) - sage: def on_basis(g,m): return M.monomial(m) # trivial rep'n + sage: def on_basis(g, m): return M.monomial(m) # trivial rep'n sage: from sage.modules.with_basis.representation import Representation sage: R = Representation(G, M, on_basis) sage: R.invariant_module() @@ -372,7 +372,7 @@ def semigroup(self): sage: G = SymmetricGroup(3) sage: M = CombinatorialFreeModule(QQ, [1,2,3], prefix='M') - sage: def action(g,x): return M.monomial(g(x)) + sage: def action(g, x): return M.monomial(g(x)) sage: I = M.invariant_module(G, action_on_basis=action) sage: I.semigroup() Symmetric group of order 3! as a permutation group @@ -422,7 +422,7 @@ def _mul_(self, other): sage: G = CyclicPermutationGroup(3); G.rename('G') sage: M = algebras.Exterior(QQ, 'x', 3) - sage: def on_basis(g,m): return M.prod([M.monomial(FrozenBitset([g(j+1)-1])) for j in m]) # cyclically permute generators + sage: def on_basis(g, m): return M.prod([M.monomial(FrozenBitset([g(j+1)-1])) for j in m]) # cyclically permute generators sage: R = Representation(G, M, on_basis, category=Algebras(QQ).WithBasis().FiniteDimensional(), side='right') sage: I = R.invariant_module(); I.rename('I') sage: B = I.basis() @@ -504,7 +504,7 @@ def _acted_upon_(self, scalar, self_on_left=False): sage: E = algebras.Exterior(QQ, 'x', 3) - sage: def on_basis(g,m): return E.prod([E.monomial(FrozenBitset([g(j+1)-1])) for j in m]) # cyclically permute generators + sage: def on_basis(g, m): return E.prod([E.monomial(FrozenBitset([g(j+1)-1])) for j in m]) # cyclically permute generators sage: R = Representation(G, E, on_basis, category=Algebras(QQ).WithBasis().FiniteDimensional()) sage: I = R.invariant_module() sage: B = I.basis() @@ -552,7 +552,7 @@ def _acted_upon_(self, scalar, self_on_left=False): sage: [b._acted_upon_(G((1,3,2)), self_on_left=True) for b in I.basis()] [B[0]] - sage: def on_basis(g,m): return E.prod([E.monomial(FrozenBitset([g(j+1)-1])) for j in m]) # cyclically permute generators + sage: def on_basis(g, m): return E.prod([E.monomial(FrozenBitset([g(j+1)-1])) for j in m]) # cyclically permute generators sage: R = Representation(G, E, on_basis, category=Algebras(QQ).WithBasis().FiniteDimensional(), side='right') sage: I = R.invariant_module() sage: B = I.basis() @@ -711,7 +711,7 @@ class FiniteDimensionalTwistedInvariantModule(SubmoduleWithBasis): sage: G = SymmetricGroup(3); G.rename('S3') sage: E = algebras.Exterior(QQ, 'x', 3); E.rename('E') - sage: def action(g,m): return E.prod([E.monomial(FrozenBitset([g(j+1)-1])) for j in m]) + sage: def action(g, m): return E.prod([E.monomial(FrozenBitset([g(j+1)-1])) for j in m]) sage: from sage.modules.with_basis.representation import Representation sage: EA = Representation(G, E, action, category=Algebras(QQ).WithBasis().FiniteDimensional()) sage: T = EA.twisted_invariant_module([2,0,-1]) @@ -758,7 +758,7 @@ def __classcall_private__(cls, M, G, chi, sage: M = CombinatorialFreeModule(QQ, [1,2,3]) sage: G = SymmetricGroup(3) - sage: def action(g,x): return M.term(g(x)) + sage: def action(g, x): return M.term(g(x)) sage: T = M.twisted_invariant_module(G, [2,0,-1], action_on_basis=action) Check that it works for tuples:: @@ -844,7 +844,7 @@ def __init__(self, M, G, chi, action=operator.mul, side='left', **kwargs): Conjugacy class of cycle type [3] in Symmetric group of order 3! as a permutation group] sage: from sage.groups.class_function import ClassFunction sage: chi = ClassFunction(G, [2,0,-1]) # the standard representation character values - sage: def action(g,x): return M.term(g(x)) + sage: def action(g, x): return M.term(g(x)) sage: import __main__ sage: __main__.action = action sage: T = M.twisted_invariant_module(G, chi, action_on_basis=action) @@ -946,7 +946,7 @@ def project(self, x): sage: M = CombinatorialFreeModule(QQ, [1,2,3]); M.rename('M') sage: B = M.basis() sage: G = SymmetricGroup(3); G.rename('S3') - sage: def action(g,x): return M.term(g(x)) + sage: def action(g, x): return M.term(g(x)) sage: T = M.twisted_invariant_module(G, [2,0,-1], action_on_basis=action) sage: m = B[1] + B[2] + B[3] sage: parent(m) @@ -975,7 +975,7 @@ def project_ambient(self, x): sage: M = CombinatorialFreeModule(QQ, [1,2,3]); M.rename('M') sage: B = M.basis() sage: G = SymmetricGroup(3); G.rename('S3') - sage: def action(g,x): return M.term(g(x)) + sage: def action(g, x): return M.term(g(x)) sage: T = M.twisted_invariant_module(G, [2,0,-1], action_on_basis=action) To compare with ``self.project``, we can inspect the parents. @@ -1017,7 +1017,7 @@ def projection_matrix(self): EXAMPLES:: sage: M = CombinatorialFreeModule(QQ, [1,2,3]) - sage: def action(g,x): return(M.term(g(x))) + sage: def action(g, x): return(M.term(g(x))) sage: G = SymmetricGroup(3) If the matrix `A` has columns form a basis for diff --git a/src/sage/modules/with_basis/morphism.py b/src/sage/modules/with_basis/morphism.py index 68ad2521493..2359672a055 100644 --- a/src/sage/modules/with_basis/morphism.py +++ b/src/sage/modules/with_basis/morphism.py @@ -515,7 +515,7 @@ class TriangularModuleMorphism(ModuleMorphism): A lower triangular (but not unitriangular) morphism:: sage: X = CombinatorialFreeModule(QQ, [1, 2, 3]); X.rename('X'); x = X.basis() - sage: def lt(i): return sum(j*x[j] for j in range(i,4)) + sage: def lt(i): return sum(j*x[j] for j in range(i, 4)) sage: phi = X.module_morphism(lt, triangular='lower', codomain=X) sage: phi(x[2]) 2*B[2] + 3*B[3] @@ -635,7 +635,7 @@ def __init__(self, triangular='upper', unitriangular=False, TESTS:: sage: X = CombinatorialFreeModule(QQ, [1, 2, 3]); X.rename('X'); x = X.basis() - sage: def lt(i): return sum(j*x[j] for j in range(i,4)) + sage: def lt(i): return sum(j*x[j] for j in range(i, 4)) sage: import __main__; __main__.lt = lt # Fake lt being defined in a python module sage: phi = X.module_morphism(lt, triangular='lower', codomain=X) sage: phi.__class__ @@ -1180,7 +1180,7 @@ def __init__(self, domain, on_basis, codomain=None, category=None, **keywords): sage: X = CombinatorialFreeModule(QQ, ZZ) sage: from sage.modules.with_basis.morphism import TriangularModuleMorphismByLinearity - sage: def on_basis(i): return X.sum_of_monomials(range(i-2,i+1)) + sage: def on_basis(i): return X.sum_of_monomials(range(i-2, i+1)) sage: import __main__; __main__.on_basis = on_basis # Fake on_basis being defined in a python module sage: phi = TriangularModuleMorphismByLinearity( ....: X, on_basis=on_basis, codomain=X) @@ -1198,7 +1198,7 @@ def _richcmp_(self, other, op): sage: X = CombinatorialFreeModule(QQ, ZZ) sage: from sage.modules.with_basis.morphism import TriangularModuleMorphismByLinearity - sage: def on_basis(i): return X.sum_of_monomials(range(i-2,i+1)) + sage: def on_basis(i): return X.sum_of_monomials(range(i-2, i+1)) sage: phi = TriangularModuleMorphismByLinearity( ....: X, on_basis=on_basis, codomain=X) sage: phi == phi diff --git a/src/sage/monoids/automatic_semigroup.py b/src/sage/monoids/automatic_semigroup.py index c4926239f8d..fac295b2341 100644 --- a/src/sage/monoids/automatic_semigroup.py +++ b/src/sage/monoids/automatic_semigroup.py @@ -169,7 +169,7 @@ class AutomaticSemigroup(UniqueRepresentation, Parent): sage: M2 = matrix([[0,0,0],[1,1,0],[0,0,1]]) sage: M1.set_immutable() sage: M2.set_immutable() - sage: def prod_m(x,y): + sage: def prod_m(x, y): ....: z=x*y ....: z.set_immutable() ....: return z @@ -483,7 +483,7 @@ def ambient(self): sage: M2 = matrix([[0,0,0],[1,1,0],[0,0,1]]) sage: M1.set_immutable() sage: M2.set_immutable() - sage: def prod_m(x,y): + sage: def prod_m(x, y): ....: z=x*y ....: z.set_immutable() ....: return z diff --git a/src/sage/numerical/backends/cvxopt_backend.pyx b/src/sage/numerical/backends/cvxopt_backend.pyx index 14c60dc3167..085340726fb 100644 --- a/src/sage/numerical/backends/cvxopt_backend.pyx +++ b/src/sage/numerical/backends/cvxopt_backend.pyx @@ -55,7 +55,7 @@ cdef class CVXOPTBackend(GenericBackend): cdef dict answer cdef dict param - def __cinit__(self, maximization = True): + def __cinit__(self, maximization=True): """ Cython constructor. @@ -276,7 +276,7 @@ cdef class CVXOPTBackend(GenericBackend): else: return self.objective_function[variable] - cpdef set_objective(self, list coeff, d = 0.0): + cpdef set_objective(self, list coeff, d=0.0): """ Set the objective function. @@ -915,7 +915,7 @@ cdef class CVXOPTBackend(GenericBackend): return self.col_name_var[index] return "x_" + repr(index) - cpdef variable_upper_bound(self, int index, value = False): + cpdef variable_upper_bound(self, int index, value=False): """ Return or define the upper bound on a variable. @@ -944,7 +944,7 @@ cdef class CVXOPTBackend(GenericBackend): else: return self.col_upper_bound[index] - cpdef variable_lower_bound(self, int index, value = False): + cpdef variable_lower_bound(self, int index, value=False): """ Return or define the lower bound on a variable. @@ -973,7 +973,7 @@ cdef class CVXOPTBackend(GenericBackend): else: return self.col_lower_bound[index] - cpdef solver_parameter(self, name, value = None): + cpdef solver_parameter(self, name, value=None): """ Return or define a solver parameter. diff --git a/src/sage/numerical/backends/glpk_backend.pyx b/src/sage/numerical/backends/glpk_backend.pyx index dddde9a07b6..5e1f0dcdf82 100644 --- a/src/sage/numerical/backends/glpk_backend.pyx +++ b/src/sage/numerical/backends/glpk_backend.pyx @@ -37,7 +37,7 @@ cdef class GLPKBackend(GenericBackend): MIP Backend that uses the GLPK solver. """ - def __cinit__(self, maximization = True): + def __cinit__(self, maximization=True): """ Constructor. @@ -537,7 +537,7 @@ cdef class GLPKBackend(GenericBackend): Removing fancy constraints does not make Sage crash:: - sage: MixedIntegerLinearProgram(solver= "GLPK").remove_constraints([0, -2]) + sage: MixedIntegerLinearProgram(solver="GLPK").remove_constraints([0, -2]) Traceback (most recent call last): ... ValueError: The constraint's index i must satisfy 0 <= i < number_of_constraints diff --git a/src/sage/numerical/backends/glpk_exact_backend.pyx b/src/sage/numerical/backends/glpk_exact_backend.pyx index a9289264a42..96f18df6fe8 100644 --- a/src/sage/numerical/backends/glpk_exact_backend.pyx +++ b/src/sage/numerical/backends/glpk_exact_backend.pyx @@ -28,7 +28,7 @@ cdef class GLPKExactBackend(GLPKBackend): There is no support for integer variables. """ - def __cinit__(self, maximization = True): + def __cinit__(self, maximization=True): """ Constructor. diff --git a/src/sage/numerical/backends/glpk_graph_backend.pxd b/src/sage/numerical/backends/glpk_graph_backend.pxd index 2e4b29a25a9..f72ad9ba077 100644 --- a/src/sage/numerical/backends/glpk_graph_backend.pxd +++ b/src/sage/numerical/backends/glpk_graph_backend.pxd @@ -51,5 +51,5 @@ cdef class GLPKGraphBackend(): cdef int s cdef int t cpdef int write_maxflow(self, fname) except -1 - cpdef double maxflow_ffalg(self, u = ?, v = ?) except -1 + cpdef double maxflow_ffalg(self, u=?, v=?) except -1 cpdef double cpp(self) noexcept diff --git a/src/sage/numerical/backends/glpk_graph_backend.pyx b/src/sage/numerical/backends/glpk_graph_backend.pyx index 2a89dfe0bd1..3618ec0ca9d 100644 --- a/src/sage/numerical/backends/glpk_graph_backend.pyx +++ b/src/sage/numerical/backends/glpk_graph_backend.pyx @@ -183,7 +183,7 @@ cdef class GLPKGraphBackend(): 3.0 """ - def __cinit__(self, data = None, format = "plain"): + def __cinit__(self, data=None, format="plain"): """ Constructor. diff --git a/src/sage/numerical/backends/interactivelp_backend.pyx b/src/sage/numerical/backends/interactivelp_backend.pyx index ea1a53aedce..3519303a817 100644 --- a/src/sage/numerical/backends/interactivelp_backend.pyx +++ b/src/sage/numerical/backends/interactivelp_backend.pyx @@ -41,7 +41,7 @@ cdef class InteractiveLPBackend: sage: p = get_solver(solver = "InteractiveLP") """ - def __cinit__(self, maximization = True, base_ring = None): + def __cinit__(self, maximization=True, base_ring=None): """ Cython constructor. diff --git a/src/sage/numerical/backends/ppl_backend.pyx b/src/sage/numerical/backends/ppl_backend.pyx index 24b0c8e80ac..72074210054 100644 --- a/src/sage/numerical/backends/ppl_backend.pyx +++ b/src/sage/numerical/backends/ppl_backend.pyx @@ -49,7 +49,7 @@ cdef class PPLBackend(GenericBackend): # Common denominator for objective function in self.mip (not for the constant term) cdef Integer obj_denominator - def __cinit__(self, maximization = True, base_ring = None): + def __cinit__(self, maximization=True, base_ring=None): """ Constructor. diff --git a/src/sage/numerical/mip.pyx b/src/sage/numerical/mip.pyx index 2395868b43d..78ac846d3df 100644 --- a/src/sage/numerical/mip.pyx +++ b/src/sage/numerical/mip.pyx @@ -670,7 +670,7 @@ cdef class MixedIntegerLinearProgram(SageObject): """ return self._backend.base_ring() - def set_problem_name(self,name): + def set_problem_name(self, name): r""" Set the name of the ``MixedIntegerLinearProgram``. @@ -914,7 +914,7 @@ cdef class MixedIntegerLinearProgram(SageObject): """ return self._backend.ncols() - def constraints(self, indices = None): + def constraints(self, indices=None): r""" Return a list of constraints, as 3-tuples. @@ -970,7 +970,7 @@ cdef class MixedIntegerLinearProgram(SageObject): solver used, we define a short function reordering it before it is printed. The output would look the same without this function applied:: - sage: def reorder_constraint(lb,indcoef,ub): + sage: def reorder_constraint(lb, indcoef, ub): ....: ind, coef = indcoef ....: d = dict(zip(ind, coef)) ....: ind.sort() @@ -1310,7 +1310,7 @@ cdef class MixedIntegerLinearProgram(SageObject): lb if lb is not None else "-oo", ub if ub is not None else "+oo")) - def write_mps(self,filename,modern=True): + def write_mps(self, filename, modern=True): r""" Write the linear program as a MPS file. @@ -1343,7 +1343,7 @@ cdef class MixedIntegerLinearProgram(SageObject): """ self._backend.write_mps(filename, modern) - def write_lp(self,filename): + def write_lp(self, filename): r""" Write the linear program as a LP file. @@ -1782,7 +1782,7 @@ cdef class MixedIntegerLinearProgram(SageObject): else: return val - def set_objective(self,obj): + def set_objective(self, obj): r""" Set the objective of the ``MixedIntegerLinearProgram``. @@ -2492,7 +2492,7 @@ cdef class MixedIntegerLinearProgram(SageObject): """ return self._backend.is_variable_integer(self._variables[e]) - def set_real(self,ee): + def set_real(self, ee): r""" Set a variable or a ``MIPVariable`` as real. @@ -2778,7 +2778,7 @@ cdef class MixedIntegerLinearProgram(SageObject): except TypeError: return self._backend.variable_upper_bound(self._variables[v]) - def solver_parameter(self, name, value = None): + def solver_parameter(self, name, value=None): """ Return or define a solver parameter. @@ -3026,7 +3026,7 @@ cdef class MixedIntegerLinearProgram(SageObject): """ return self._backend.get_relative_objective_gap() - def interactive_lp_problem(self,form='standard'): + def interactive_lp_problem(self, form='standard'): r""" Return an InteractiveLPProblem and, if available, a basis. diff --git a/src/sage/numerical/optimize.py b/src/sage/numerical/optimize.py index 7b3d0456147..95e363346e9 100644 --- a/src/sage/numerical/optimize.py +++ b/src/sage/numerical/optimize.py @@ -442,7 +442,7 @@ def minimize(func, x0, gradient=None, hessian=None, algorithm='default', return vector(RDF, min) -def minimize_constrained(func,cons,x0,gradient=None,algorithm='default', **args): +def minimize_constrained(func, cons, x0, gradient=None, algorithm='default', **args): r""" Minimize a function with constraints. diff --git a/src/sage/numerical/sdp.pyx b/src/sage/numerical/sdp.pyx index 7c08ed08e10..6693b943806 100644 --- a/src/sage/numerical/sdp.pyx +++ b/src/sage/numerical/sdp.pyx @@ -459,7 +459,7 @@ cdef class SemidefiniteProgram(SageObject): """ return self._backend.base_ring() - def set_problem_name(self,name): + def set_problem_name(self, name): r""" Set the name of the ``SemidefiniteProgram``. @@ -1049,7 +1049,7 @@ cdef class SemidefiniteProgram(SageObject): """ return self._backend.slack(i, sparse=sparse) - def solver_parameter(self, name, value = None): + def solver_parameter(self, name, value=None): """ Return or define a solver parameter. diff --git a/src/sage/parallel/decorate.py b/src/sage/parallel/decorate.py index a01d680bdcc..90ee3a5cc42 100644 --- a/src/sage/parallel/decorate.py +++ b/src/sage/parallel/decorate.py @@ -110,7 +110,7 @@ def __call__(self, f): sage: P = sage.parallel.decorate.Parallel() - sage: def g(n,m): return n+m + sage: def g(n, m): return n+m sage: h = P(g) # indirect doctest sage: list(h([(2,3)])) [(((2, 3), {}), 5)] @@ -358,7 +358,7 @@ def parallel(p_iter='fork', ncpus=None, **kwds): when calling the parallel function:: sage: @parallel - ....: def f(a,b): return a*b + ....: def f(a, b): return a*b sage: for X, Y in sorted(list(f([(2,3),(3,5),(5,7)]))): print((X, Y)) (((2, 3), {}), 6) (((3, 5), {}), 15) @@ -456,7 +456,7 @@ def __call__(self, f): EXAMPLES:: sage: F = sage.parallel.decorate.Fork(timeout=3) - sage: def g(n,m): return n+m + sage: def g(n, m): return n+m sage: h = F(g) # indirect doctest sage: h(2,3) 5 diff --git a/src/sage/parallel/reference.py b/src/sage/parallel/reference.py index 6a855874330..e5587022576 100644 --- a/src/sage/parallel/reference.py +++ b/src/sage/parallel/reference.py @@ -26,7 +26,7 @@ def parallel_iter(f, inputs): EXAMPLES:: - sage: def f(N,M=10): return N*M + sage: def f(N, M=10): return N*M sage: inputs = [((2,3),{}), (tuple(), {'M':5,'N':3}), ((2,),{})] sage: set_random_seed(0) sage: for a, val in sage.parallel.reference.parallel_iter(f, inputs): diff --git a/src/sage/plot/animate.py b/src/sage/plot/animate.py index 16672405c8e..c37a17531d8 100644 --- a/src/sage/plot/animate.py +++ b/src/sage/plot/animate.py @@ -432,7 +432,7 @@ def make_image(self, frame, filename, **kwds): sage: class MyAnimation(Animation): ....: def make_image(self, frame, filename, **kwds): ....: P = parametric_plot(frame[0], frame[1], **frame[2]) - ....: P.save_image(filename,**kwds) + ....: P.save_image(filename, **kwds) sage: t = SR.var("t") sage: x = lambda t: cos(t) diff --git a/src/sage/plot/contour_plot.py b/src/sage/plot/contour_plot.py index 26874790ec5..a59397e8b23 100644 --- a/src/sage/plot/contour_plot.py +++ b/src/sage/plot/contour_plot.py @@ -415,7 +415,7 @@ def contour_plot(f, xrange, yrange, **options): .. PLOT:: x,y = var('x,y') - def f(x,y): return x**2 + y**2 + def f(x, y): return x**2 + y**2 g = contour_plot(f, (-2,2), (-2,2)) sphinx_plot(g) @@ -427,7 +427,7 @@ def f(x,y): return x**2 + y**2 .. PLOT:: x,y = var('x,y') - def f(x,y): return x**2 + y**2 + def f(x, y): return x**2 + y**2 g = contour_plot(f, (-2, 2), (-2, 2), contours=2, cmap=[(1,0,0), (0,1,0), (0,0,1)]) sphinx_plot(g) @@ -440,7 +440,7 @@ def f(x,y): return x**2 + y**2 .. PLOT:: x,y = var('x,y') - def f(x,y): return x**2 + y**2 + def f(x, y): return x**2 + y**2 g = contour_plot(f, (-2,2), (-2,2), contours=(0.1,1.0,1.2,1.4), cmap='hsv') sphinx_plot(g) @@ -452,7 +452,7 @@ def f(x,y): return x**2 + y**2 .. PLOT:: x,y = var('x,y') - def f(x,y): return x**2 + y**2 + def f(x, y): return x**2 + y**2 g = contour_plot(f, (-2,2), (-2,2), contours=(1.0,), fill=False) sphinx_plot(g) @@ -475,7 +475,7 @@ def f(x,y): return x**2 + y**2 .. PLOT:: x,y = var('x,y') - def f(x,y): return x**2 + y**2 + def f(x, y): return x**2 + y**2 g = contour_plot(f, (-2,2), (-2,2), fill=False, linewidths=10) sphinx_plot(g) @@ -488,7 +488,7 @@ def f(x,y): return x**2 + y**2 .. PLOT:: x,y = var('x,y') - def f(x,y): return x**2 + y**2 + def f(x, y): return x**2 + y**2 g = contour_plot(f, (-2,2), (-2,2), fill=False, linestyles='dashdot') sphinx_plot(g) @@ -667,7 +667,7 @@ def f(x,y): return x**2 + y**2 .. PLOT:: x,y = var('x,y') - def f(x,y): return x**2 + y**2 + def f(x, y): return x**2 + y**2 g = contour_plot(f, (-2,2), (-2,2), labels=True, label_colors='red') sphinx_plot(g) @@ -680,7 +680,7 @@ def f(x,y): return x**2 + y**2 .. PLOT:: x,y = var('x,y') - def f(x,y): return x**2 + y**2 + def f(x, y): return x**2 + y**2 g = contour_plot(f, (x,-3,3), (y,-3,3), colorbar=True) sphinx_plot(g) @@ -692,7 +692,7 @@ def f(x,y): return x**2 + y**2 .. PLOT:: x,y = var('x,y') - def f(x,y): return x**2 + y**2 + def f(x, y): return x**2 + y**2 g = contour_plot(f, (x,-3,3), (y,-3,3), colorbar=True, colorbar_orientation='horizontal') sphinx_plot(g) @@ -704,7 +704,7 @@ def f(x,y): return x**2 + y**2 .. PLOT:: x,y = var('x,y') - def f(x,y): return x**2 + y**2 + def f(x, y): return x**2 + y**2 g = contour_plot(f, (x,-3,3), (y,-3,3), contours=[-2,-1,4], colorbar=True) sphinx_plot(g) @@ -718,7 +718,7 @@ def f(x,y): return x**2 + y**2 .. PLOT:: x,y = var('x,y') - def f(x,y): return x**2 + y**2 + def f(x, y): return x**2 + y**2 g = contour_plot(f, (x,-3,3), (y,-3,3), contours=[-2,-1,4], colorbar=True, colorbar_spacing='uniform') sphinx_plot(g) @@ -732,7 +732,7 @@ def f(x,y): return x**2 + y**2 .. PLOT:: x,y = var('x,y') - def f(x,y): return x**2 + y**2 + def f(x, y): return x**2 + y**2 g = contour_plot(f, (x,-3,3), (y,-3,3), contours=[0,2,3,6], colorbar=True, colorbar_format='%.3f') sphinx_plot(g) @@ -747,7 +747,7 @@ def f(x,y): return x**2 + y**2 .. PLOT:: x,y = var('x,y') - def f(x,y): return x**2 + y**2 + def f(x, y): return x**2 + y**2 g = contour_plot(f, (x,-3,3), (y,-3,3), labels=True, label_colors='red', contours=[0,2,3,6], colorbar=True) @@ -762,7 +762,7 @@ def f(x,y): return x**2 + y**2 .. PLOT:: x,y = var('x,y') - def f(x,y): return x**2 + y**2 + def f(x, y): return x**2 + y**2 g = contour_plot(f, (x,-3,3), (y,-3,3), cmap='winter', contours=20, fill=False, colorbar=True) sphinx_plot(g) @@ -793,7 +793,7 @@ def f(x,y): return x**2 + y**2 .. PLOT:: x,y = var('x,y') - def f(x,y): return cos(x) + sin(y) + def f(x, y): return cos(x) + sin(y) g = contour_plot(f, (0,pi), (0,pi), axes=True) sphinx_plot(g) @@ -819,7 +819,7 @@ def f(x,y): return cos(x) + sin(y) .. PLOT:: x,y = var('x,y') - def f(x,y): return cos(x) + sin(y) + def f(x, y): return cos(x) + sin(y) g = contour_plot(f, (-pi,pi), (-pi,pi), fill=False, axes=True) sphinx_plot(g) @@ -1132,7 +1132,7 @@ def implicit_plot(f, xrange, yrange, **options): .. PLOT:: - def f(x,y): return x**2 + y**2 - 2 + def f(x, y): return x**2 + y**2 - 2 g = implicit_plot(f, (-3,3), (-3,3), fill=True, plot_points=500) sphinx_plot(g) @@ -1143,7 +1143,7 @@ def f(x,y): return x**2 + y**2 - 2 .. PLOT:: - def f(x,y): return x**2 + y**2 - 2 + def f(x, y): return x**2 + y**2 - 2 g = implicit_plot(f, (-3,3), (-3,3), linewidth=6) sphinx_plot(g) @@ -1155,7 +1155,7 @@ def f(x,y): return x**2 + y**2 - 2 .. PLOT:: x, y =var("x y") - def f(x,y): return x**2 + y**2 - 2 + def f(x, y): return x**2 + y**2 - 2 g = implicit_plot(f, (-3,3), (-3,3), linestyle='dashdot') sphinx_plot(g) @@ -1168,7 +1168,7 @@ def f(x,y): return x**2 + y**2 - 2 .. PLOT:: - def f(x,y): return x**2 + y**2 - 2 + def f(x, y): return x**2 + y**2 - 2 g = implicit_plot(f, (-3,3), (-3,3), color='red', fill=True, fillcolor='green', plot_points=500) sphinx_plot(g) @@ -1237,7 +1237,7 @@ def f(x,y): return x**2 + y**2 - 2 ....: z = 0 ....: for i in range(n): ....: z = z*z + c - ....: def f(x,y): + ....: def f(x, y): ....: val = z(CDF(x, y)) ....: return val.norm() - 4 ....: return f @@ -1254,7 +1254,7 @@ def mandel(n): z = 0 for i in range(n): z = z*z + c - def f(x,y): + def f(x, y): val = z(CDF(x, y)) return val.norm() - 4 return f @@ -1273,7 +1273,7 @@ def mandel(n): z = 0 for i in range(n): z = z*z + c - def f(x,y): + def f(x, y): val = z(CDF(x, y)) return val.norm() - 4 return f @@ -1296,7 +1296,7 @@ def mandel(n): z = 0 for i in range(n): z = z*z + c - def f(x,y): + def f(x, y): val = z(CDF(x, y)) return val.norm() - 4 return f diff --git a/src/sage/plot/density_plot.py b/src/sage/plot/density_plot.py index 84d08518a0b..dbbeb767775 100644 --- a/src/sage/plot/density_plot.py +++ b/src/sage/plot/density_plot.py @@ -212,7 +212,7 @@ def density_plot(f, xrange, yrange, **options): .. PLOT:: x,y = var('x,y') - def f(x,y): return x**2 * cos(x*y) + def f(x, y): return x**2 * cos(x*y) g = density_plot(f, (x,-10,5), (y,-5,5), interpolation='sinc', plot_points=100) sphinx_plot(g) @@ -296,7 +296,7 @@ def f(x,y): return x**2 * cos(x*y) Check that :issue:`17684` is fixed, i.e., symbolic values can be plotted:: - sage: def f(x,y): + sage: def f(x, y): ....: return SR(x) sage: density_plot(f, (0,1), (0,1)) Graphics object consisting of 1 graphics primitive diff --git a/src/sage/plot/matrix_plot.py b/src/sage/plot/matrix_plot.py index 900ac9989e0..aa8309b5bc0 100644 --- a/src/sage/plot/matrix_plot.py +++ b/src/sage/plot/matrix_plot.py @@ -234,7 +234,7 @@ def _render_on_subplot(self, subplot): if options.get('colorbar', False): colorbar_options = options['colorbar_options'] from matplotlib import colorbar - cax,kwds = colorbar.make_axes_gridspec(subplot,**colorbar_options) + cax,kwds = colorbar.make_axes_gridspec(subplot, **colorbar_options) colorbar.Colorbar(cax, image, **kwds) if flip_y: diff --git a/src/sage/plot/plot.py b/src/sage/plot/plot.py index d1e21abe20a..c8f5a0fca96 100644 --- a/src/sage/plot/plot.py +++ b/src/sage/plot/plot.py @@ -641,7 +641,7 @@ def f(x): return (x-3)*(x-5)*(x-7)+40 # Currently not used - see comment above about # figure.canvas.mpl_connect('draw_event', pad_for_tick_labels) # TODO - figure out how to use this, add documentation -# def adjust_figure_to_contain_bbox(fig, bbox,pad=1.1): +# def adjust_figure_to_contain_bbox(fig, bbox, pad=1.1): # """ # For each amount we are over (in axes coordinates), we adjust by over*pad # to give ourselves a bit of padding. @@ -2194,7 +2194,7 @@ def _plot(funcs, xrange, parametric=False, # Check to see if funcs is a list of functions that will be all plotted together. if isinstance(funcs, (list, tuple)) and not parametric: - def golden_rainbow(i,lightness=0.4): + def golden_rainbow(i, lightness=0.4): # note: sage's "blue" has hue-saturation-lightness values (2/3, 1, 1/2). g = 0.61803398875 return Color((0.66666666666666 + i*g) % 1, 1, lightness, space='hsl') diff --git a/src/sage/plot/plot3d/index_face_set.pyx b/src/sage/plot/plot3d/index_face_set.pyx index 04cd6866f8d..9fb52e59923 100644 --- a/src/sage/plot/plot3d/index_face_set.pyx +++ b/src/sage/plot/plot3d/index_face_set.pyx @@ -1012,7 +1012,7 @@ cdef class IndexFaceSet(PrimitiveObject): sage: var('x,y,z') # needs sage.symbolic (x, y, z) sage: P = implicit_plot3d(z-x*y,(-2,2),(-2,2),(-2,2)) # needs sage.symbolic - sage: def condi(x,y,z): + sage: def condi(x, y, z): ....: return bool(x*x+y*y+z*z <= Integer(1)) sage: R = P.add_condition(condi, 20); R # needs sage.symbolic Graphics3d Object @@ -1021,13 +1021,13 @@ cdef class IndexFaceSet(PrimitiveObject): x,y,z = var('x,y,z') P = implicit_plot3d(z-x*y,(-2,2),(-2,2),(-2,2)) - def condi(x,y,z): + def condi(x, y, z): return bool(x*x+y*y+z*z <= Integer(1)) sphinx_plot(P.add_condition(condi,40)) An example with colors:: - sage: def condi(x,y,z): + sage: def condi(x, y, z): ....: return bool(x*x+y*y <= 1.1) sage: cm = colormaps.hsv sage: cf = lambda x,y,z: float(x+y) % 1 @@ -1039,7 +1039,7 @@ cdef class IndexFaceSet(PrimitiveObject): .. PLOT:: x,y,z = var('x,y,z') - def condi(x,y,z): + def condi(x, y, z): return bool(x*x+y*y <= 1.1) cm = colormaps.hsv cf = lambda x,y,z: float(x+y) % 1 @@ -1050,7 +1050,7 @@ cdef class IndexFaceSet(PrimitiveObject): sage: P = implicit_plot3d(x**4+y**4+z**2-4, (x,-2,2), (y,-2,2), (z,-2,2), # needs sage.symbolic ....: alpha=0.3) - sage: def cut(a,b,c): + sage: def cut(a, b, c): ....: return a*a+c*c > 2 sage: Q = P.add_condition(cut,40); Q # needs sage.symbolic Graphics3d Object @@ -1059,7 +1059,7 @@ cdef class IndexFaceSet(PrimitiveObject): x,y,z = var('x,y,z') P = implicit_plot3d(x**4+y**4+z**2-4,(x,-2,2),(y,-2,2),(z,-2,2),alpha=0.3) - def cut(a,b,c): + def cut(a, b, c): return a*a+c*c > 2 sphinx_plot(P.add_condition(cut,40)) @@ -1067,7 +1067,7 @@ cdef class IndexFaceSet(PrimitiveObject): sage: P = plot3d(-sin(2*x*x+2*y*y)*exp(-x*x-y*y), (x,-2,2), (y,-2,2), # needs sage.symbolic ....: color='gold') - sage: def cut(x,y,z): + sage: def cut(x, y, z): ....: return x*x+y*y < 1 sage: Q = P.add_condition(cut);Q # needs sage.symbolic Graphics3d Object @@ -1076,7 +1076,7 @@ cdef class IndexFaceSet(PrimitiveObject): x,y,z = var('x,y,z') P = plot3d(-sin(2*x*x+2*y*y)*exp(-x*x-y*y),(x,-2,2),(y,-2,2),color='gold') - def cut(x,y,z): + def cut(x, y, z): return x*x+y*y < 1 sphinx_plot(P.add_condition(cut)) @@ -1087,7 +1087,7 @@ cdef class IndexFaceSet(PrimitiveObject): sage: # needs sage.symbolic sage: x,y,z = var('x,y,z') sage: P = plot3d(cos(x*y),(x,-2,2),(y,-2,2),color='red',opacity=0.1) - sage: def condi(x,y,z): + sage: def condi(x, y, z): ....: return not(x*x+y*y <= 1) sage: Q = P.add_condition(condi, 40) sage: L = Q.json_repr(Q.default_render_params()) @@ -1097,7 +1097,7 @@ cdef class IndexFaceSet(PrimitiveObject): A test that this works with polygons:: sage: p = polygon3d([[2,0,0], [0,2,0], [0,0,3]]) - sage: def f(x,y,z): + sage: def f(x, y, z): ....: return bool(x*x+y*y+z*z<=5) sage: cut = p.add_condition(f,60,1.0e-12); cut.face_list() # needs sage.symbolic [[(0.556128491210302, 0.0, 2.165807263184547), diff --git a/src/sage/plot/plot3d/parametric_plot3d.py b/src/sage/plot/plot3d/parametric_plot3d.py index fa8a69a805e..6a3da2b830f 100644 --- a/src/sage/plot/plot3d/parametric_plot3d.py +++ b/src/sage/plot/plot3d/parametric_plot3d.py @@ -166,7 +166,7 @@ def parametric_plot3d(f, urange, vrange=None, plot_points='automatic', values in the interval [0,1]. :: sage: u,v = var('u,v') - sage: def cf(u,v): return sin(u+v/2)**2 + sage: def cf(u, v): return sin(u+v/2)**2 sage: P = parametric_plot3d((cos(u), sin(u)+cos(v), sin(v)), ....: (u,0,2*pi), (v,-pi,pi), color=(cf,colormaps.PiYG), plot_points=[60,60]) sage: P.show(viewer='tachyon') @@ -174,7 +174,7 @@ def parametric_plot3d(f, urange, vrange=None, plot_points='automatic', .. PLOT:: u,v = var('u,v') - def cf(u,v): return sin(u+v/2)**2 + def cf(u, v): return sin(u+v/2)**2 P = parametric_plot3d((cos(u), sin(u)+cos(v), sin(v)), (u,0,2*pi), (v,-pi,pi), color=(cf,colormaps.PiYG), plot_points=[60,60]) sphinx_plot(P) @@ -182,7 +182,7 @@ def cf(u,v): return sin(u+v/2)**2 Another example, a colored Möbius band:: sage: cm = colormaps.ocean - sage: def c(x,y): return sin(x*y)**2 + sage: def c(x, y): return sin(x*y)**2 sage: from sage.plot.plot3d.parametric_surface import MoebiusStrip sage: MoebiusStrip(5, 1, plot_points=200, color=(c,cm)) Graphics3d Object @@ -190,7 +190,7 @@ def cf(u,v): return sin(u+v/2)**2 .. PLOT:: cm = colormaps.ocean - def c(x,y): return sin(x*y)**2 + def c(x, y): return sin(x*y)**2 from sage.plot.plot3d.parametric_surface import MoebiusStrip sphinx_plot(MoebiusStrip(5, 1, plot_points=200, color=(c,cm))) @@ -198,8 +198,8 @@ def c(x,y): return sin(x*y)**2 sage: from sage.plot.plot3d.parametric_surface import ParametricSurface sage: cm = colormaps.autumn - sage: def c(x,y): return sin(x*y)**2 - sage: def g(x,y): return x, y+sin(y), x**2 + y**2 + sage: def c(x, y): return sin(x*y)**2 + sage: def g(x, y): return x, y+sin(y), x**2 + y**2 sage: ParametricSurface(g, (srange(-10,10,0.1), srange(-5,5.0,0.1)), color=(c,cm)) Graphics3d Object @@ -207,8 +207,8 @@ def c(x,y): return sin(x*y)**2 from sage.plot.plot3d.parametric_surface import ParametricSurface cm = colormaps.autumn - def c(x,y): return sin(x*y)**2 - def g(x,y): return x, y+sin(y), x**2 + y**2 + def c(x, y): return sin(x*y)**2 + def g(x, y): return x, y+sin(y), x**2 + y**2 sphinx_plot(ParametricSurface(g, (srange(-10,10,0.1), srange(-5,5.0,0.1)), color=(c,cm))) We call the space curve function but with polynomials instead of diff --git a/src/sage/plot/plot3d/parametric_surface.pyx b/src/sage/plot/plot3d/parametric_surface.pyx index dab78e762a5..efff00af83b 100644 --- a/src/sage/plot/plot3d/parametric_surface.pyx +++ b/src/sage/plot/plot3d/parametric_surface.pyx @@ -18,14 +18,14 @@ AUTHORS: EXAMPLES:: sage: from sage.plot.plot3d.parametric_surface import ParametricSurface, MoebiusStrip - sage: def f(x,y): return x+y, sin(x)*sin(y), x*y + sage: def f(x, y): return x+y, sin(x)*sin(y), x*y sage: P = ParametricSurface(f, (srange(0,10,0.1), srange(-5,5.0,0.1))) sage: show(P) .. PLOT:: from sage.plot.plot3d.parametric_surface import ParametricSurface - def f(x,y): return x+y, sin(x)*sin(y), x*y + def f(x, y): return x+y, sin(x)*sin(y), x*y sphinx_plot(ParametricSurface(f, (srange(0,10,0.1), srange(-5,5.0,0.1)))) :: @@ -50,13 +50,13 @@ By default, the surface is colored with one single color. :: .. PLOT:: from sage.plot.plot3d.parametric_surface import ParametricSurface - def f(x,y): return x+y, sin(x)*sin(y), x*y + def f(x, y): return x+y, sin(x)*sin(y), x*y sphinx_plot(ParametricSurface(f, (srange(0,10,0.1), srange(-5,5.0,0.1)), color='red')) One can instead provide a coloring function and a colormap:: - sage: def f(x,y): return x+y, x-y, x*y - sage: def c(x,y): return sin((x+y)/2)**2 + sage: def f(x, y): return x+y, x-y, x*y + sage: def c(x, y): return sin((x+y)/2)**2 sage: cm = colormaps.RdYlGn sage: P = ParametricSurface(f, (srange(-5,5,0.1), srange(-5,5.0,0.1)), color=(c,cm)) sage: P.show(viewer='tachyon') @@ -64,8 +64,8 @@ One can instead provide a coloring function and a colormap:: .. PLOT:: from sage.plot.plot3d.parametric_surface import ParametricSurface - def f(x,y): return x+y, x-y, x*y - def c(x,y): return sin((x+y)/2)**2 + def f(x, y): return x+y, x-y, x*y + def c(x, y): return sin((x+y)/2)**2 cm = colormaps.RdYlGn sphinx_plot(ParametricSurface(f, (srange(-5,5,0.1), srange(-5,5.0,0.1)), color=(c,cm))) @@ -75,7 +75,7 @@ This value is passed to the chosen colormap. Another colored example:: sage: colm = colormaps.autumn - sage: def g(x,y): return x, y, x**2 + y**2 + sage: def g(x, y): return x, y, x**2 + y**2 sage: P = ParametricSurface(g, (srange(-10,10,0.1), srange(-5,5.0,0.1)), color=(c,colm)) sage: P.show(viewer='tachyon') @@ -83,8 +83,8 @@ Another colored example:: from sage.plot.plot3d.parametric_surface import ParametricSurface colm = colormaps.autumn - def g(x,y): return x, y, x**2 + y**2 - def c(x,y): return sin((x+y)/2)**2 + def g(x, y): return x, y, x**2 + y**2 + def c(x, y): return sin((x+y)/2)**2 sphinx_plot(ParametricSurface(g, (srange(-10,10,0.1), srange(-5,5.0,0.1)), color=(c,colm))) .. NOTE:: @@ -161,7 +161,7 @@ cdef class ParametricSurface(IndexFaceSet): EXAMPLES:: sage: from sage.plot.plot3d.parametric_surface import ParametricSurface - sage: def f(x,y): return cos(x)*sin(y), sin(x)*sin(y), cos(y)+log(tan(y/2))+0.2*x + sage: def f(x, y): return cos(x)*sin(y), sin(x)*sin(y), cos(y)+log(tan(y/2))+0.2*x sage: S = ParametricSurface(f, (srange(0,12.4,0.1), srange(0.1,2,0.1))) sage: show(S) @@ -171,14 +171,14 @@ cdef class ParametricSurface(IndexFaceSet): .. PLOT:: from sage.plot.plot3d.parametric_surface import ParametricSurface - def f(x,y): return cos(x)*sin(y), sin(x)*sin(y), cos(y)+log(tan(y/2))+0.2*x + def f(x, y): return cos(x)*sin(y), sin(x)*sin(y), cos(y)+log(tan(y/2))+0.2*x sphinx_plot(ParametricSurface(f, (srange(0,12.4,0.1), srange(0.1,2,0.1)))) The Hessenberg surface: :: - sage: def f(u,v): + sage: def f(u, v): ....: a = 1 ....: from math import cos, sin, sinh, cosh ....: x = cos(a)*(cos(u)*sinh(v)-cos(3*u)*sinh(3*v)/3) + sin(a)*( @@ -194,7 +194,7 @@ cdef class ParametricSurface(IndexFaceSet): .. PLOT:: - def f(u,v): + def f(u, v): a = 1 from math import cos, sin, sinh, cosh x = cos(a)*(cos(u)*sinh(v)-cos(3*u)*sinh(3*v)/3) + sin(a)*(sin(u)*cosh(v)-sin(3*u)*cosh(3*v)/3) @@ -207,8 +207,8 @@ cdef class ParametricSurface(IndexFaceSet): A colored example using the ``color`` keyword:: - sage: def g(x,y): return x, y, - x**2 + y**2 - sage: def c(x,y): return sin((x-y/2)*y/4)**2 + sage: def g(x, y): return x, y, - x**2 + y**2 + sage: def c(x, y): return sin((x-y/2)*y/4)**2 sage: cm = colormaps.gist_rainbow sage: P = ParametricSurface(g, (srange(-10,10,0.1), ....: srange(-5,5.0,0.1)),color=(c,cm)) @@ -217,8 +217,8 @@ cdef class ParametricSurface(IndexFaceSet): .. PLOT:: from sage.plot.plot3d.parametric_surface import ParametricSurface - def g(x,y): return x, y, - x**2 + y**2 - def c(x,y): return sin((x-y/2)*y/4)**2 + def g(x, y): return x, y, - x**2 + y**2 + def c(x, y): return sin((x-y/2)*y/4)**2 cm = colormaps.gist_rainbow sphinx_plot(ParametricSurface(g, (srange(-10,10,0.1), srange(-5,5.0,0.1)),color=(c,cm))) """ @@ -231,7 +231,7 @@ cdef class ParametricSurface(IndexFaceSet): EXAMPLES:: sage: from sage.plot.plot3d.parametric_surface import ParametricSurface - sage: def f(x,y): return x+y, sin(x)*sin(y), x*y + sage: def f(x, y): return x+y, sin(x)*sin(y), x*y sage: S = ParametricSurface(f, (srange(0,12.4,0.1), srange(0.1,2,0.1))) """ if isinstance(f, list): @@ -489,7 +489,7 @@ cdef class ParametricSurface(IndexFaceSet): TESTS:: sage: from sage.plot.plot3d.parametric_surface import ParametricSurface, MoebiusStrip - sage: def f(x,y): return x+y, sin(x)*sin(y), x*y # indirect doctests + sage: def f(x, y): return x+y, sin(x)*sin(y), x*y # indirect doctests sage: P = ParametricSurface(f, (srange(0,10,0.1), srange(-5,5.0,0.1))) # indirect doctests sage: P.show() # indirect doctests sage: S = MoebiusStrip(1, .2) # indirect doctests @@ -638,7 +638,7 @@ cdef class ParametricSurface(IndexFaceSet): TESTS:: sage: from sage.plot.plot3d.parametric_surface import ParametricSurface - sage: def f(x,y): return x+y,x-y,x*y + sage: def f(x, y): return x+y,x-y,x*y sage: P = ParametricSurface(f) sage: P.get_grid(.1) Traceback (most recent call last): @@ -763,7 +763,7 @@ cdef class ParametricSurface(IndexFaceSet): TESTS:: sage: from sage.plot.plot3d.parametric_surface import ParametricSurface - sage: def f(x,y): return x+y,x-y,x*y + sage: def f(x, y): return x+y,x-y,x*y sage: P = ParametricSurface(f,(srange(0,1,0.1),srange(0,1,0.1))) sage: P.eval(0,0) Traceback (most recent call last): diff --git a/src/sage/plot/plot3d/plot3d.py b/src/sage/plot/plot3d/plot3d.py index 3b583082a9a..d6bc165610e 100644 --- a/src/sage/plot/plot3d/plot3d.py +++ b/src/sage/plot/plot3d/plot3d.py @@ -19,7 +19,7 @@ :: - sage: def f(x,y): + sage: def f(x, y): ....: return math.sin(y^2 + x^2)/math.sqrt(x^2 + y^2 + 0.0001) sage: P = plot3d(f, (-3, 3),(-3, 3), adaptive=True, ....: color=rainbow(60, 'rgbtuple'), max_bend=.1, max_depth=15) @@ -27,13 +27,13 @@ .. PLOT:: - def f(x,y): return math.sin(y**2 + x**2)/math.sqrt(x**2 + y**2 + 0.0001) + def f(x, y): return math.sin(y**2 + x**2)/math.sqrt(x**2 + y**2 + 0.0001) P = plot3d(f, (-3, 3), (-3, 3), adaptive=True, color=rainbow(60, 'rgbtuple'), max_bend=.1, max_depth=15) sphinx_plot(P) :: - sage: def f(x,y): + sage: def f(x, y): ....: return math.exp(x/5)*math.sin(y) ....: sage: P = plot3d(f, (-5, 5), (-5, 5), adaptive=True, color=['red', 'yellow']) @@ -43,7 +43,7 @@ def f(x,y): return math.sin(y**2 + x**2)/math.sqrt(x**2 + y**2 + 0.0001) .. PLOT:: - def f(x,y): return math.exp(x/5)*math.sin(y) + def f(x, y): return math.exp(x/5)*math.sin(y) P = plot3d(f, (-5, 5), (-5, 5), adaptive=True, color=['red', 'yellow']) from sage.plot.plot3d.plot3d import axes S = P + axes(6, color='black') @@ -82,7 +82,7 @@ def c(x, y): return float((x + y + x*y)/15) % 1 sage: S += sphere((.45, .1, .15), size=.1, color='white') sage: S += sphere((.51, .1,.17), size=.05, color='black') sage: S += sphere((.5, 0, -.2), size=.1, color='yellow') - sage: def f(x,y): return math.exp(x/5)*math.cos(y) + sage: def f(x, y): return math.exp(x/5)*math.cos(y) sage: P = plot3d(f, (-5, 5), (-5, 5), adaptive=True, ....: color=['red','yellow'], max_depth=10) sage: cape_man = P.scale(.2) + S.translate(1, 0, 0) @@ -96,7 +96,7 @@ def c(x, y): return float((x + y + x*y)/15) % 1 S += sphere((.45, -.1, .15), size=.1, color='white') + sphere((.51,-.1,.17), size=.05, color='black') S += sphere((.45, .1, .15), size=.1, color='white') + sphere((.51, .1,.17), size=.05, color='black') S += sphere((.5, 0, -.2), size=.1, color='yellow') - def f(x,y): return math.exp(x/5)*math.cos(y) + def f(x, y): return math.exp(x/5)*math.cos(y) P = plot3d(f, (-5, 5), (-5, 5), adaptive=True, color=['red','yellow'], max_depth=10) cape_man = P.scale(.2) + S.translate(1, 0, 0) cape_man.aspect_ratio([1, 1, 1]) @@ -272,7 +272,7 @@ def to_cartesian(self, func, params=None): FullArgSpec(args=['a', 'b'], varargs=None, varkw=None, defaults=None, kwonlyargs=[], kwonlydefaults=None, annotations={}) - sage: def g(a,b): return 2*a+b + sage: def g(a, b): return 2*a+b sage: t1,t2,t3=T.to_cartesian(g) sage: sage_getargspec(t1) FullArgSpec(args=['a', 'b'], varargs=None, varkw=None, defaults=None, @@ -387,12 +387,12 @@ def _find_arguments_for_callable(func): sage: from sage.plot.plot3d.plot3d import _find_arguments_for_callable sage: _find_arguments_for_callable(lambda x,y: x+y) ['x', 'y'] - sage: def f(a,b,c): return a+b+c + sage: def f(a, b, c): return a+b+c sage: _find_arguments_for_callable(f) ['a', 'b', 'c'] sage: _find_arguments_for_callable(lambda x,y,z=2: x+y+z) ['x', 'y'] - sage: def f(a,b,c,d=2,e=1): return a+b+c+d+e + sage: def f(a, b, c, d=2, e=1): return a+b+c+d+e sage: _find_arguments_for_callable(f) ['a', 'b', 'c'] sage: g(w,r,t)=w+r+t diff --git a/src/sage/plot/plot3d/revolution_plot3d.py b/src/sage/plot/plot3d/revolution_plot3d.py index 6c16263d971..721573516a5 100644 --- a/src/sage/plot/plot3d/revolution_plot3d.py +++ b/src/sage/plot/plot3d/revolution_plot3d.py @@ -27,7 +27,7 @@ @rename_keyword(alpha='opacity') -def revolution_plot3d(curve,trange,phirange=None,parallel_axis='z',axis=(0,0),print_vector=False,show_curve=False,**kwds): +def revolution_plot3d(curve, trange, phirange=None, parallel_axis='z', axis=(0, 0), print_vector=False, show_curve=False, **kwds): r""" Return a plot of a revolved curve. @@ -196,7 +196,7 @@ def revolution_plot3d(curve,trange,phirange=None,parallel_axis='z',axis=(0,0),pr function must take values in the interval `[0,1]`. :: sage: u, phi = var('u,phi') - sage: def cf(u,phi): return sin(phi+u) ^ 2 + sage: def cf(u, phi): return sin(phi+u) ^ 2 sage: curve = (1+u^2/4, 0, u) sage: revolution_plot3d(curve, (u,-2,2), (0,2*pi), parallel_axis='z', ....: color=(cf, colormaps.PiYG)).show(aspect_ratio=(1,1,1)) diff --git a/src/sage/plot/plot3d/tachyon.py b/src/sage/plot/plot3d/tachyon.py index 83315e33368..adb1d80b7be 100644 --- a/src/sage/plot/plot3d/tachyon.py +++ b/src/sage/plot/plot3d/tachyon.py @@ -559,7 +559,7 @@ def show(self, **kwds): sage: h = Tachyon(xres=512, yres=512, camera_position=(4,-4,3), ....: viewdir=(-4,4,-3), raydepth=4) sage: h.light((4.4,-4.4,4.4), 0.2, (1,1,1)) - sage: def f(x,y): return float(sin(x*y)) + sage: def f(x, y): return float(sin(x*y)) sage: h.texture('t0', ambient=0.1, diffuse=0.9, specular=0.1, ....: opacity=1.0, color=(1.0,0,0)) sage: h.plot(f, (-4,4), (-4,4), "t0", max_depth=5, initial_depth=3, # needs sage.symbolic @@ -577,7 +577,7 @@ def show(self, **kwds): sage: s = Tachyon(xres=512, yres=512, camera_position=(4,-4,3), ....: viewdir=(-4,4,-3), raydepth=4) sage: s.light((4.4,-4.4,4.4), 0.2, (1,1,1)) - sage: def f(x,y): return float(sin(x*y)) + sage: def f(x, y): return float(sin(x*y)) sage: s.texture('t0', ambient=0.1, diffuse=0.9, specular=0.1, ....: opacity=1.0, color=(1.0,0,0)) sage: s.plot(f, (-4,4), (-4,4), "t0", max_depth=5, initial_depth=3, # needs sage.symbolic @@ -600,7 +600,7 @@ def show(self, **kwds): sage: d = Tachyon(xres=512, yres=512, camera_position=(4,-4,3), ....: viewdir=(-4,4,-3), raydepth=4) sage: d.light((4.4,-4.4,4.4), 0.2, (1,1,1)) - sage: def f(x,y): return float(sin(x*y)) + sage: def f(x, y): return float(sin(x*y)) sage: d.texture('t0', ambient=0.1, diffuse=0.9, specular=0.1, ....: opacity=1.0, color=(1.0,0,0)) sage: d.plot(f,(-4,4),(-4,4),"t0",max_depth=5,initial_depth=3, # needs sage.symbolic @@ -1004,7 +1004,7 @@ def plot(self, f, xmin_xmax, ymin_ymax, texture, grad_f=None, sage: t = Tachyon(xres=512, yres=512, camera_position=(4,-4,3), ....: viewdir=(-4,4,-3), raydepth=4) sage: t.light((4.4,-4.4,4.4), 0.2, (1,1,1)) - sage: def f(x,y): return float(sin(x*y)) + sage: def f(x, y): return float(sin(x*y)) sage: t.texture('t0', ambient=0.1, diffuse=0.9, specular=0.1, ....: opacity=1.0, color=(1.0,0,0)) sage: t.plot(f, (-4,4), (-4,4), "t0", max_depth=5, initial_depth=3, # needs sage.symbolic @@ -1020,8 +1020,8 @@ def plot(self, f, xmin_xmax, ymin_ymax, texture, grad_f=None, sage: t = Tachyon(xres=512, yres=512, camera_position=(4,-4,3), ....: viewdir=(-4,4,-3), raydepth=4) sage: t.light((4.4,-4.4,4.4), 0.2, (1,1,1)) - sage: def f(x,y): return float(sin(x*y)) - sage: def g(x,y): return (float(y*cos(x*y)), float(x*cos(x*y)), 1) + sage: def f(x, y): return float(sin(x*y)) + sage: def g(x, y): return (float(y*cos(x*y)), float(x*cos(x*y)), 1) sage: t.texture('t0', ambient=0.1, diffuse=0.9, specular=0.1, ....: opacity=1.0, color=(1.0,0,0)) sage: t.plot(f, (-4,4), (-4,4), "t0", max_depth=5, initial_depth=3, # needs sage.symbolic diff --git a/src/sage/plot/plot3d/tri_plot.py b/src/sage/plot/plot3d/tri_plot.py index 4453d8c574c..a2e843778eb 100644 --- a/src/sage/plot/plot3d/tri_plot.py +++ b/src/sage/plot/plot3d/tri_plot.py @@ -30,7 +30,7 @@ class Triangle: """ A graphical triangle class. """ - def __init__(self,a,b,c,color=0): + def __init__(self, a, b, c, color=0): """ a, b, c : triples (x,y,z) representing corners on a triangle in 3-space. @@ -101,7 +101,7 @@ class SmoothTriangle(Triangle): """ A class for smoothed triangles. """ - def __init__(self,a,b,c,da,db,dc,color=0): + def __init__(self, a, b, c, da, db, dc, color=0): """ a, b, c : triples (x,y,z) representing corners on a triangle in 3-space da, db, dc : triples (dx,dy,dz) representing the normal vector at each point a,b,c @@ -265,10 +265,10 @@ def __init__(self, triangle_factory, f, min_x__max_x, min_y__max_y, g=None, raise ValueError('plot rectangle is really a line; make sure min_x != max_x and min_y != max_y') self._num_colors = num_colors if g is None: - def fcn(x,y): + def fcn(x, y): return [self._f(x,y)] else: - def fcn(x,y): + def fcn(x, y): return [self._f(x,y), self._g(x,y)] self._fcn = fcn @@ -541,7 +541,7 @@ def extrema(self, list): self._max = max(list+[self._max]) -def crossunit(u,v): +def crossunit(u, v): """ This function computes triangle normal unit vectors by taking the cross-products of the midpoint-to-corner vectors. It always goes diff --git a/src/sage/quadratic_forms/quadratic_form__ternary_Tornaria.py b/src/sage/quadratic_forms/quadratic_form__ternary_Tornaria.py index 0e447f982dd..3922767e870 100644 --- a/src/sage/quadratic_forms/quadratic_form__ternary_Tornaria.py +++ b/src/sage/quadratic_forms/quadratic_form__ternary_Tornaria.py @@ -25,7 +25,7 @@ # TO DO -- Add second argument -# def __call__(self,v,w=None): +# def __call__(self, v, w=None): # if w is None: # return half(v * self._matrix_() * v) # else: diff --git a/src/sage/rings/bernmm.pyx b/src/sage/rings/bernmm.pyx index 492181f1f22..f3af4355bd0 100644 --- a/src/sage/rings/bernmm.pyx +++ b/src/sage/rings/bernmm.pyx @@ -39,7 +39,7 @@ cdef extern from "bernmm/bern_modp.h": from sage.rings.rational cimport Rational -def bernmm_bern_rat(long k, int num_threads = 1): +def bernmm_bern_rat(long k, int num_threads=1): r""" Compute `k`-th Bernoulli number using a multimodular algorithm. (Wrapper for bernmm library.) diff --git a/src/sage/rings/complex_double.pyx b/src/sage/rings/complex_double.pyx index d6e5a7d05b1..98477e0dd72 100644 --- a/src/sage/rings/complex_double.pyx +++ b/src/sage/rings/complex_double.pyx @@ -2601,7 +2601,7 @@ cdef class ComplexToCDF(Morphism): cdef ComplexDoubleField_class _CDF _CDF = ComplexDoubleField_class() CDF = _CDF # external interface -cdef ComplexDoubleElement I = ComplexDoubleElement(0,1) +cdef ComplexDoubleElement I = ComplexDoubleElement(0, 1) def ComplexDoubleField(): diff --git a/src/sage/rings/complex_interval.pyx b/src/sage/rings/complex_interval.pyx index c9273384788..f9649751a14 100644 --- a/src/sage/rings/complex_interval.pyx +++ b/src/sage/rings/complex_interval.pyx @@ -321,7 +321,7 @@ cdef class ComplexIntervalFieldElement(FieldElement): g = polygon2d([(x0, y0), (x1, y0), (x1, y1), (x0, y1), (x0, y0)], thickness=pointsize/4, **kwds) # Nearly empty polygons don't show up. - g += self.center().plot(pointsize= pointsize, **kwds) + g += self.center().plot(pointsize=pointsize, **kwds) return g def _latex_(self): diff --git a/src/sage/rings/finite_rings/element_base.pyx b/src/sage/rings/finite_rings/element_base.pyx index aa0a66b4748..a9c54232163 100755 --- a/src/sage/rings/finite_rings/element_base.pyx +++ b/src/sage/rings/finite_rings/element_base.pyx @@ -202,7 +202,7 @@ cdef class FinitePolyExtElement(FiniteRingElement): f = Cx([base_map(c) for c in f]) return codomain(f(im_gens[0])) - def minpoly(self,var='x',algorithm='pari'): + def minpoly(self, var='x', algorithm='pari'): """ Return the minimal polynomial of this element (over the corresponding prime subfield). @@ -822,7 +822,7 @@ cdef class FinitePolyExtElement(FiniteRingElement): """ return self.square_root(extend=extend, all=all) - def nth_root(self, n, extend = False, all = False, algorithm=None, cunningham=False): + def nth_root(self, n, extend=False, all=False, algorithm=None, cunningham=False): r""" Return an `n`-th root of ``self``. @@ -941,7 +941,7 @@ cdef class FinitePolyExtElement(FiniteRingElement): n = Integer(n) return self._nth_root_common(n, all, algorithm, cunningham) - def pth_power(self, int k = 1): + def pth_power(self, int k=1): """ Return the `(p^k)`-th power of self, where `p` is the characteristic of the field. @@ -975,7 +975,7 @@ cdef class FinitePolyExtElement(FiniteRingElement): frobenius = pth_power - def pth_root(self, int k = 1): + def pth_root(self, int k=1): """ Return the `(p^k)`-th root of self, where `p` is the characteristic of the field. diff --git a/src/sage/rings/finite_rings/finite_field_base.pyx b/src/sage/rings/finite_rings/finite_field_base.pyx index 085ce14ce87..b5234146c03 100644 --- a/src/sage/rings/finite_rings/finite_field_base.pyx +++ b/src/sage/rings/finite_rings/finite_field_base.pyx @@ -846,7 +846,7 @@ cdef class FiniteField(Field): """ return 1 - def is_field(self, proof = True): + def is_field(self, proof=True): """ Return whether or not the finite field is a field, i.e., always returns ``True``. diff --git a/src/sage/rings/finite_rings/integer_mod.pyx b/src/sage/rings/finite_rings/integer_mod.pyx index 0b220e81a1e..cf2d43ca59a 100644 --- a/src/sage/rings/finite_rings/integer_mod.pyx +++ b/src/sage/rings/finite_rings/integer_mod.pyx @@ -1350,7 +1350,7 @@ cdef class IntegerMod_abstract(FiniteRingElement): square_root = sqrt - def nth_root(self, n, extend = False, all = False, algorithm = None, cunningham = False): + def nth_root(self, n, extend=False, all=False, algorithm=None, cunningham=False): r""" Return an `n`-th root of ``self``. diff --git a/src/sage/rings/finite_rings/residue_field.pyx b/src/sage/rings/finite_rings/residue_field.pyx index 3146f7fd764..be83c5165f6 100644 --- a/src/sage/rings/finite_rings/residue_field.pyx +++ b/src/sage/rings/finite_rings/residue_field.pyx @@ -307,7 +307,7 @@ class ResidueFieldFactory(UniqueFactory): sage: K.residue_field(K.ideal(3)) # needs sage.rings.number_field Residue field of Fractional ideal (3) """ - def create_key_and_extra_args(self, p, names = None, check=True, impl=None, **kwds): + def create_key_and_extra_args(self, p, names=None, check=True, impl=None, **kwds): """ Return a tuple containing the key (uniquely defining data) and any extra arguments. diff --git a/src/sage/rings/fraction_field_element.pyx b/src/sage/rings/fraction_field_element.pyx index 3d14ab66134..bd8718da968 100644 --- a/src/sage/rings/fraction_field_element.pyx +++ b/src/sage/rings/fraction_field_element.pyx @@ -263,7 +263,7 @@ cdef class FractionFieldElement(FieldElement): """ return self._denominator - def is_square(self,root=False): + def is_square(self, root=False): """ Return whether or not ``self`` is a perfect square. diff --git a/src/sage/rings/function_field/constructor.py b/src/sage/rings/function_field/constructor.py index a316c384bd1..72b2976bc43 100644 --- a/src/sage/rings/function_field/constructor.py +++ b/src/sage/rings/function_field/constructor.py @@ -88,7 +88,7 @@ def create_key(self, F, names): names = (names,) return (F, names) - def create_object(self, version, key,**extra_args): + def create_object(self, version, key, **extra_args): """ Create the object from the key and extra arguments. This is only called if the object was not found in the cache. @@ -142,7 +142,7 @@ class FunctionFieldExtensionFactory(UniqueFactory): sage: L is M # needs sage.rings.function_field True """ - def create_key(self,polynomial,names): + def create_key(self, polynomial, names): """ Given the arguments and keywords, create a key that uniquely determines this object. @@ -174,7 +174,7 @@ def create_key(self,polynomial,names): names = (names,) return (polynomial,names,polynomial.base_ring()) - def create_object(self,version,key,**extra_args): + def create_object(self, version, key, **extra_args): """ Create the object from the key and extra arguments. This is only called if the object was not found in the cache. diff --git a/src/sage/rings/function_field/divisor.py b/src/sage/rings/function_field/divisor.py index 13247abe3b0..b62fa02c93b 100644 --- a/src/sage/rings/function_field/divisor.py +++ b/src/sage/rings/function_field/divisor.py @@ -920,7 +920,7 @@ def pivot(v): if e != 0: return (i,e.numerator().degree() - e.denominator().degree()) - def greater(v,w): # v and w are not equal + def greater(v, w): # v and w are not equal return v[0] < w[0] or v[0] == w[0] and v[1] > w[1] # collate rows by their pivot position diff --git a/src/sage/rings/function_field/order_polymod.py b/src/sage/rings/function_field/order_polymod.py index 16ff2d8f2ae..ed2223fcdab 100644 --- a/src/sage/rings/function_field/order_polymod.py +++ b/src/sage/rings/function_field/order_polymod.py @@ -1372,7 +1372,7 @@ def mul(Ib, Jb): h = matrix(m).echelon_form() return cut_last_zero_rows(h) - def add(Ib,Jb): + def add(Ib, Jb): m = block_matrix([[Ib], [Jb]]) h = m.echelon_form() return cut_last_zero_rows(h) diff --git a/src/sage/rings/integer.pxd b/src/sage/rings/integer.pxd index 1165895729e..c113d562835 100644 --- a/src/sage/rings/integer.pxd +++ b/src/sage/rings/integer.pxd @@ -23,8 +23,8 @@ cdef class Integer(EuclideanDomainElement): cdef _or(Integer self, Integer other) cdef _xor(Integer self, Integer other) - cpdef size_t _exact_log_log2_iter(self,Integer m) noexcept - cpdef size_t _exact_log_mpfi_log(self,m) noexcept + cpdef size_t _exact_log_log2_iter(self, Integer m) noexcept + cpdef size_t _exact_log_mpfi_log(self, m) noexcept cpdef RingElement _valuation(Integer self, Integer p) cdef object _val_unit(Integer self, Integer p) cdef Integer _divide_knowing_divisible_by(Integer self, Integer right) diff --git a/src/sage/rings/integer.pyx b/src/sage/rings/integer.pyx index 9616e7946bc..206c4c458d8 100644 --- a/src/sage/rings/integer.pyx +++ b/src/sage/rings/integer.pyx @@ -215,7 +215,7 @@ cdef set_from_Integer(Integer self, Integer other): mpz_set(self.value, other.value) -cdef _digits_naive(mpz_t v,l,int offset,Integer base,digits): +cdef _digits_naive(mpz_t v, l, int offset, Integer base, digits): """ This method fills in digit entries in the list, l, using the most basic digit algorithm -- repeat division by base. @@ -262,7 +262,7 @@ cdef _digits_naive(mpz_t v,l,int offset,Integer base,digits): mpz_clear(mpz_value) -cdef _digits_internal(mpz_t v,l,int offset,int power_index,power_list,digits): +cdef _digits_internal(mpz_t v, l, int offset, int power_index, power_list, digits): """ INPUT: @@ -1131,7 +1131,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): sage: "{0:#x}; {0:#b}; {0:+05d}".format(ZZ(17)) '0x11; 0b10001; +0017' """ - return int(self).__format__(*args,**kwargs) + return int(self).__format__(*args, **kwargs) def ordinal_str(self): """ @@ -2439,7 +2439,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): raise ValueError("%s is not a %s power" % (self, integer_ring.ZZ(n).ordinal_str())) - cpdef size_t _exact_log_log2_iter(self,Integer m) noexcept: + cpdef size_t _exact_log_log2_iter(self, Integer m) noexcept: r""" This is only for internal use only. You should expect it to crash and burn for negative or other malformed input. In particular, if @@ -2517,7 +2517,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): sig_off() return l_min - cpdef size_t _exact_log_mpfi_log(self,m) noexcept: + cpdef size_t _exact_log_mpfi_log(self, m) noexcept: """ This is only for internal use only. You should expect it to crash and burn for negative or other malformed input. @@ -5993,7 +5993,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): if mpz_cmp_ui(self.value, 2) < 0: return smallInteger(2) - cdef mp_bitcnt_t bit_index = mpz_sizeinbase(self.value,2) + cdef mp_bitcnt_t bit_index = mpz_sizeinbase(self.value, 2) cdef Integer n = PY_NEW(Integer) mpz_add_ui(n.value, self.value, 1 if mpz_even_p(self.value) else 2) @@ -6066,7 +6066,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): cdef Integer n = PY_NEW(Integer) mpz_sub_ui(n.value, self.value, 1) - cdef mp_bitcnt_t bit_index = mpz_sizeinbase(n.value,2)-1 + cdef mp_bitcnt_t bit_index = mpz_sizeinbase(n.value, 2)-1 if mpz_even_p(n.value): mpz_sub_ui(n.value, n.value, 1) diff --git a/src/sage/rings/integer_ring.pyx b/src/sage/rings/integer_ring.pyx index 2b2ec33294c..346a67481e1 100644 --- a/src/sage/rings/integer_ring.pyx +++ b/src/sage/rings/integer_ring.pyx @@ -876,7 +876,7 @@ cdef class IntegerRing_class(CommutativeRing): return True return super()._repr_option(key) - def is_field(self, proof = True): + def is_field(self, proof=True): """ Return ``False`` since the integers are not a field. @@ -1158,7 +1158,7 @@ cdef class IntegerRing_class(CommutativeRing): """ return True - def completion(self, p, prec, extras = {}): + def completion(self, p, prec, extras={}): r""" Return the metric completion of the integers at the prime `p`. diff --git a/src/sage/rings/invariants/invariant_theory.py b/src/sage/rings/invariants/invariant_theory.py index fb953f98813..836dc8dd249 100644 --- a/src/sage/rings/invariants/invariant_theory.py +++ b/src/sage/rings/invariants/invariant_theory.py @@ -3498,7 +3498,7 @@ def syzygy(self, Delta, Theta, Theta_prime, Delta_prime, S, S_prime, F, J): sage: R. = QQ[] sage: monomials = [x^2, x*y, y^2, x*z, y*z, z^2] - sage: def q_rnd(): return sum(randint(-1000,1000)*m for m in monomials) + sage: def q_rnd(): return sum(randint(-1000, 1000)*m for m in monomials) sage: biquadratic = invariant_theory.ternary_biquadratic(q_rnd(), q_rnd(), [x,y,z]) sage: Delta = biquadratic.Delta_invariant() sage: Theta = biquadratic.Theta_invariant() @@ -3880,7 +3880,7 @@ def syzygy(self, Delta, Theta, Phi, Theta_prime, Delta_prime, U, V, T, T_prime, sage: R. = QQ[] sage: monomials = [x^2, x*y, y^2, x*z, y*z, z^2, x*w, y*w, z*w, w^2] - sage: def q_rnd(): return sum(randint(-1000,1000)*m for m in monomials) + sage: def q_rnd(): return sum(randint(-1000, 1000)*m for m in monomials) sage: biquadratic = invariant_theory.quaternary_biquadratic(q_rnd(), q_rnd()) sage: Delta = biquadratic.Delta_invariant() sage: Theta = biquadratic.Theta_invariant() diff --git a/src/sage/rings/multi_power_series_ring.py b/src/sage/rings/multi_power_series_ring.py index 35c4d4beb32..3a30b89b9e9 100644 --- a/src/sage/rings/multi_power_series_ring.py +++ b/src/sage/rings/multi_power_series_ring.py @@ -1047,7 +1047,7 @@ def prec_ideal(self): """ return self._poly_ring().ideal(self._poly_ring().gens()) - def bigoh(self,prec): + def bigoh(self, prec): """ Return big oh with precision ``prec``. The function ``O`` does the same thing. @@ -1062,7 +1062,7 @@ def bigoh(self,prec): """ return self.zero().O(prec) - def O(self,prec): + def O(self, prec): """ Return big oh with precision ``prec``. This function is an alias for ``bigoh``. @@ -1077,7 +1077,7 @@ def O(self,prec): """ return self.bigoh(prec) - def _send_to_bg(self,f): + def _send_to_bg(self, f): """ Send an element of the foreground polynomial ring to the background power series ring. @@ -1100,7 +1100,7 @@ def _send_to_bg(self,f): raise TypeError("Cannot coerce input to polynomial ring.") return self._bg_ps_ring(f.homogeneous_components()) - def _send_to_fg(self,f): + def _send_to_fg(self, f): """ Send an element of the background univariate power series ring to the foreground multivariate polynomial ring. diff --git a/src/sage/rings/multi_power_series_ring_element.py b/src/sage/rings/multi_power_series_ring_element.py index 8e1789d5672..9c27ba678bb 100644 --- a/src/sage/rings/multi_power_series_ring_element.py +++ b/src/sage/rings/multi_power_series_ring_element.py @@ -671,7 +671,7 @@ def _im_gens_(self, codomain, im_gens, base_map=None): else: return codomain(self._subs_formal(*im_gens, base_map=base_map)) - def __getitem__(self,n): + def __getitem__(self, n): """ Return summand of total degree ``n``. @@ -2130,7 +2130,7 @@ class MO: sage: w^2 1 + 2*a + O(a, b, c)^2 """ - def __init__(self,x): + def __init__(self, x): """ Initialize ``self``. diff --git a/src/sage/rings/number_field/selmer_group.py b/src/sage/rings/number_field/selmer_group.py index 5204cfc80b6..283db17c84e 100644 --- a/src/sage/rings/number_field/selmer_group.py +++ b/src/sage/rings/number_field/selmer_group.py @@ -133,7 +133,7 @@ def _coords_in_C_p(I, C, p): raise ValueError("The {} power of {} is not principal".format(p.ordinal_str(),I)) -def _coords_in_C_mod_p(I,C,p): +def _coords_in_C_mod_p(I, C, p): r""" Return coordinates of the ideal ``I`` with respect to a basis of the `p`-cotorsion of the ideal class group ``C``. diff --git a/src/sage/rings/padics/CA_template.pxi b/src/sage/rings/padics/CA_template.pxi index 0e6a10b67d9..9a274d6d81e 100644 --- a/src/sage/rings/padics/CA_template.pxi +++ b/src/sage/rings/padics/CA_template.pxi @@ -684,7 +684,7 @@ cdef class CAElement(pAdicTemplateElement): """ return ciszero(self.value, self.prime_pow) - def is_zero(self, absprec = None): + def is_zero(self, absprec=None): r""" Determine whether this element is zero modulo `\pi^{\mbox{absprec}}`. diff --git a/src/sage/rings/padics/CR_template.pxi b/src/sage/rings/padics/CR_template.pxi index 853a3c3df79..f6f3bc8a632 100644 --- a/src/sage/rings/padics/CR_template.pxi +++ b/src/sage/rings/padics/CR_template.pxi @@ -992,7 +992,7 @@ cdef class CRElement(pAdicTemplateElement): """ return self.relprec == 0 and not exactzero(self.ordp) - def is_zero(self, absprec = None): + def is_zero(self, absprec=None): r""" Determine whether this element is zero modulo `\pi^{\mbox{absprec}}`. diff --git a/src/sage/rings/padics/FM_template.pxi b/src/sage/rings/padics/FM_template.pxi index c05930fb0af..07a091a9313 100644 --- a/src/sage/rings/padics/FM_template.pxi +++ b/src/sage/rings/padics/FM_template.pxi @@ -533,7 +533,7 @@ cdef class FMElement(pAdicTemplateElement): """ return ciszero(self.value, self.prime_pow) - def is_zero(self, absprec = None): + def is_zero(self, absprec=None): r""" Return whether ``self`` is zero modulo `\pi^{\mbox{absprec}}`. diff --git a/src/sage/rings/padics/FP_template.pxi b/src/sage/rings/padics/FP_template.pxi index 654c3d6b6a3..69454eeb842 100644 --- a/src/sage/rings/padics/FP_template.pxi +++ b/src/sage/rings/padics/FP_template.pxi @@ -862,7 +862,7 @@ cdef class FPElement(pAdicTemplateElement): """ return very_pos_val(self.ordp) - def is_zero(self, absprec = None): + def is_zero(self, absprec=None): r""" Return whether ``self`` is zero modulo `\pi^{\mbox{absprec}}`. diff --git a/src/sage/rings/padics/local_generic_element.pyx b/src/sage/rings/padics/local_generic_element.pyx index 84143902e86..e3f1db454ff 100644 --- a/src/sage/rings/padics/local_generic_element.pyx +++ b/src/sage/rings/padics/local_generic_element.pyx @@ -194,7 +194,7 @@ cdef class LocalGenericElement(CommutativeRingElement): """ raise TypeError("this local element is not iterable") - def slice(self, i, j, k = 1, lift_mode='simple'): + def slice(self, i, j, k=1, lift_mode='simple'): r""" Return the sum of the `pi^{i + l \cdot k}` terms of the series expansion of this element, where pi is the uniformizer, @@ -815,7 +815,7 @@ cdef class LocalGenericElement(CommutativeRingElement): """ return self.square_root(extend, all) - #def square_root(self, extend = True, all = False): + #def square_root(self, extend=True, all=False): # raise NotImplementedError #def unit_part(self): diff --git a/src/sage/rings/padics/morphism.pyx b/src/sage/rings/padics/morphism.pyx index d4684f9649d..6f0d501bc86 100644 --- a/src/sage/rings/padics/morphism.pyx +++ b/src/sage/rings/padics/morphism.pyx @@ -28,7 +28,7 @@ cdef class FrobeniusEndomorphism_padics(RingHomomorphism): """ A class implementing Frobenius endomorphisms on `p`-adic fields. """ - def __init__ (self,domain,n=1): + def __init__ (self, domain, n=1): """ INPUT: @@ -218,7 +218,7 @@ cdef class FrobeniusEndomorphism_padics(RingHomomorphism): """ return self._power - def __pow__(self,n,modulus): + def __pow__(self, n, modulus): """ Return the `n`-th iterate of this endomorphism. diff --git a/src/sage/rings/padics/padic_ZZ_pX_CA_element.pyx b/src/sage/rings/padics/padic_ZZ_pX_CA_element.pyx index 7efcfc5a047..0e826c40db8 100644 --- a/src/sage/rings/padics/padic_ZZ_pX_CA_element.pyx +++ b/src/sage/rings/padics/padic_ZZ_pX_CA_element.pyx @@ -196,7 +196,7 @@ from sage.rings.infinity import infinity cdef long maxordp = (1L << (sizeof(long) * 8 - 2)) -1 cdef class pAdicZZpXCAElement(pAdicZZpXElement): - def __init__(self, parent, x, absprec = infinity, relprec = infinity, empty = False): + def __init__(self, parent, x, absprec=infinity, relprec=infinity, empty=False): """ Create an element of a capped absolute precision, unramified or Eisenstein extension of Zp or Qp. @@ -1769,7 +1769,7 @@ cdef class pAdicZZpXCAElement(pAdicZZpXElement): """ return ZZ_pX_ConstTerm(self.value) - def is_equal_to(self, right, absprec = None): + def is_equal_to(self, right, absprec=None): """ Return whether ``self`` is equal to ``right`` modulo ``self.uniformizer()^absprec``. @@ -1995,7 +1995,7 @@ cdef class pAdicZZpXCAElement(pAdicZZpXElement): ZZ_pX_MulMod_pre(cur.x, cur.x, x, m[0]) return matrix(R, n, n, L) -# def matrix(self, base = None): +# def matrix(self, base=None): # """ # If base is None, return the matrix of right multiplication by # the element on the power basis `1, x, x^2, \ldots, x^{d-1}` @@ -2034,7 +2034,7 @@ cdef class pAdicZZpXCAElement(pAdicZZpXElement): # """ # raise NotImplementedError - def teichmuller_expansion(self, n = None): + def teichmuller_expansion(self, n=None): r""" Return a list [`a_0`, `a_1`,..., `a_n`] such that: @@ -2164,7 +2164,7 @@ cdef class pAdicZZpXCAElement(pAdicZZpXElement): else: self.prime_pow.teichmuller_set_c(&self.value, &self.value, self.absprec) -# def padded_list(self, n, lift_mode = 'simple'): +# def padded_list(self, n, lift_mode='simple'): # """ # Returns a list of coefficients of pi starting with `pi^0` up to # `pi^n` exclusive (padded with zeros if needed) diff --git a/src/sage/rings/padics/padic_ZZ_pX_CR_element.pyx b/src/sage/rings/padics/padic_ZZ_pX_CR_element.pyx index 82d04980363..5db54020fb2 100644 --- a/src/sage/rings/padics/padic_ZZ_pX_CR_element.pyx +++ b/src/sage/rings/padics/padic_ZZ_pX_CR_element.pyx @@ -223,7 +223,7 @@ cdef inline int check_ordp(long a) except -1: cdef class pAdicZZpXCRElement(pAdicZZpXElement): - def __init__(self, parent, x, absprec = infinity, relprec = infinity, empty = False): + def __init__(self, parent, x, absprec=infinity, relprec=infinity, empty=False): r""" Create an element of a capped relative precision, unramified or Eisenstein extension of `\ZZ_p` or `\QQ_p`. @@ -2327,7 +2327,7 @@ cdef class pAdicZZpXCRElement(pAdicZZpXElement): ZZ_to_mpz(ans.value, &tmp_z) return ans - def is_zero(self, absprec = None): + def is_zero(self, absprec=None): r""" Return whether the valuation of this element is at least ``absprec``. If ``absprec`` is ``None``, checks if this element @@ -2585,7 +2585,7 @@ cdef class pAdicZZpXCRElement(pAdicZZpXElement): """ return ZZ_pX_ConstTerm((self).unit) - def is_equal_to(self, right, absprec = None): + def is_equal_to(self, right, absprec=None): """ Return whether this element is equal to ``right`` modulo ``self.uniformizer()^absprec``. @@ -2703,7 +2703,7 @@ cdef class pAdicZZpXCRElement(pAdicZZpXElement): ZZ_pX_conv_modulus(ans.unit, self.unit, self.prime_pow.get_context_capdiv(rprec).x) return ans - def expansion(self, n = None, lift_mode = 'simple'): + def expansion(self, n=None, lift_mode='simple'): """ Return a list giving a series representation of ``self``. @@ -2877,7 +2877,7 @@ cdef class pAdicZZpXCRElement(pAdicZZpXElement): ZZ_pX_MulMod_pre(cur.x, cur.x, x, m[0]) return matrix(R, n, n, L) -# def matrix(self, base = None): +# def matrix(self, base=None): # """ # If base is None, return the matrix of right multiplication by # the element on the power basis `1, x, x^2, \ldots, x^{d-1}` @@ -2915,7 +2915,7 @@ cdef class pAdicZZpXCRElement(pAdicZZpXElement): # """ # raise NotImplementedError - def teichmuller_expansion(self, n = None): + def teichmuller_expansion(self, n=None): r""" Return a list [`a_0`, `a_1`,..., `a_n`] such that: @@ -3060,7 +3060,7 @@ cdef class pAdicZZpXCRElement(pAdicZZpXElement): else: self.prime_pow.teichmuller_set_c(&self.unit, &self.unit, self.relprec) -# def padded_list(self, n, lift_mode = 'simple'): +# def padded_list(self, n, lift_mode='simple'): # """ # Return a list of coefficients of pi starting with `pi^0` up to # `pi^n` exclusive (padded with zeros if needed) @@ -3130,7 +3130,7 @@ cdef class pAdicZZpXCRElement(pAdicZZpXElement): mpz_set_ui(ans.value, self.relprec) return ans -# def residue(self, n = 1): +# def residue(self, n=1): # """ # Reduces this element modulo pi^n. # """ diff --git a/src/sage/rings/padics/padic_ZZ_pX_FM_element.pyx b/src/sage/rings/padics/padic_ZZ_pX_FM_element.pyx index a3dcd42b3d6..de3df469423 100644 --- a/src/sage/rings/padics/padic_ZZ_pX_FM_element.pyx +++ b/src/sage/rings/padics/padic_ZZ_pX_FM_element.pyx @@ -879,7 +879,7 @@ cdef class pAdicZZpXFMElement(pAdicZZpXElement): ans.value = self.value # does this actually copy correctly return ans - def is_zero(self, absprec = None): + def is_zero(self, absprec=None): """ Return whether the valuation of ``self`` is at least ``absprec``; if ``absprec`` is ``None``, return whether @@ -1038,7 +1038,7 @@ cdef class pAdicZZpXFMElement(pAdicZZpXElement): ZZ_pX_MulMod_pre(cur.x, cur.x, x, m[0]) return matrix(R, n, n, L) -# def matrix(self, base = None): +# def matrix(self, base=None): # """ # If base is None, return the matrix of right multiplication by # the element on the power basis `1, x, x^2, \ldots, x^{d-1}` @@ -1380,7 +1380,7 @@ cdef class pAdicZZpXFMElement(pAdicZZpXElement): return zero return [zero] * ordp + ulist - def teichmuller_expansion(self, n = None): + def teichmuller_expansion(self, n=None): r""" Return a list `[a_0, a_1, \ldots, a_n]` such that. @@ -1532,7 +1532,7 @@ cdef class pAdicZZpXFMElement(pAdicZZpXElement): # """ # raise NotImplementedError -# def padded_list(self, n, lift_mode = 'simple'): +# def padded_list(self, n, lift_mode='simple'): # """ # Returns a list of coefficients of pi starting with `pi^0` up to # `pi^n` exclusive (padded with zeros if needed) diff --git a/src/sage/rings/padics/padic_ZZ_pX_element.pyx b/src/sage/rings/padics/padic_ZZ_pX_element.pyx index b2d6267503e..9e907b25899 100644 --- a/src/sage/rings/padics/padic_ZZ_pX_element.pyx +++ b/src/sage/rings/padics/padic_ZZ_pX_element.pyx @@ -291,7 +291,7 @@ cdef class pAdicZZpXElement(pAdicExtElement): cdef ZZ_pX_c shifter = (self._ntl_rep()).x #cdef ntl_ZZ_pContext_class cup = self.prime_pow.get_context(self.prime_pow.prec_cap + (self.prime_pow).low_length) - #cdef ntl_ZZ_pX printer = ntl_ZZ_pX([],cup) + #cdef ntl_ZZ_pX printer = ntl_ZZ_pX([], cup) #printer.x = ((self.prime_pow).low_shifter[0]).val() #print(printer) @@ -429,7 +429,7 @@ cdef class pAdicZZpXElement(pAdicExtElement): norm_of_uniformizer = (-1)**self.parent().degree() * self.parent().defining_polynomial()[0] return self.parent().ground_ring()(self.unit_part().matrix_mod_pn().det()) * norm_of_uniformizer**self.valuation() - def trace(self, base = None): + def trace(self, base=None): r""" Return the absolute or relative trace of this element. diff --git a/src/sage/rings/padics/padic_extension_generic.py b/src/sage/rings/padics/padic_extension_generic.py index e3e97906be2..d3ca159a5fc 100644 --- a/src/sage/rings/padics/padic_extension_generic.py +++ b/src/sage/rings/padics/padic_extension_generic.py @@ -475,7 +475,7 @@ def polynomial_ring(self): """ return self._given_poly.parent() - #def teichmuller(self, x, prec = None): + #def teichmuller(self, x, prec=None): # if prec is None: # prec = self.precision_cap() # x = self(x, prec) @@ -652,7 +652,7 @@ def free_module(self, base=None, basis=None, map=True): #def principal_unit_group(self): # raise NotImplementedError - #def zeta(self, n = None): + #def zeta(self, n=None): # raise NotImplementedError #def zeta_order(self): diff --git a/src/sage/rings/padics/padic_generic.py b/src/sage/rings/padics/padic_generic.py index 3f041a5e146..39d1fb43006 100644 --- a/src/sage/rings/padics/padic_generic.py +++ b/src/sage/rings/padics/padic_generic.py @@ -198,7 +198,7 @@ def __richcmp__(self, other, op): # def ngens(self): # return 1 - # def gen(self, n = 0): + # def gen(self, n=0): # if n != 0: # raise IndexError, "only one generator" # return self(self.prime()) diff --git a/src/sage/rings/padics/padic_generic_element.pyx b/src/sage/rings/padics/padic_generic_element.pyx index ec3b1848416..073a3d98f5f 100644 --- a/src/sage/rings/padics/padic_generic_element.pyx +++ b/src/sage/rings/padics/padic_generic_element.pyx @@ -1877,7 +1877,7 @@ cdef class pAdicGenericElement(LocalGenericElement): #def log_artin_hasse(self): # raise NotImplementedError - def multiplicative_order(self, prec = None): + def multiplicative_order(self, prec=None): r""" Return the multiplicative order of ``self``, where ``self`` is considered to be one if it is one modulo `p^{\mbox{prec}}`. @@ -1975,7 +1975,7 @@ cdef class pAdicGenericElement(LocalGenericElement): return order return infinity - def valuation(self, p = None): + def valuation(self, p=None): r""" Return the valuation of this element. @@ -2099,7 +2099,7 @@ cdef class pAdicGenericElement(LocalGenericElement): """ raise NotImplementedError - def ordp(self, p = None): + def ordp(self, p=None): r""" Return the valuation of ``self``, normalized so that the valuation of `p` is 1. @@ -4056,7 +4056,7 @@ cdef class pAdicGenericElement(LocalGenericElement): """ raise NotImplementedError - def _polylog_res_1(self, n, p_branch = 0): + def _polylog_res_1(self, n, p_branch=0): r""" Return `Li_n(`self`)`, the `n`-th `p`-adic polylogarithm of ``self``, assuming that ``self`` is congruent to `1 \pmod p`. diff --git a/src/sage/rings/padics/padic_printing.pyx b/src/sage/rings/padics/padic_printing.pyx index c0988388066..634e6d64115 100644 --- a/src/sage/rings/padics/padic_printing.pyx +++ b/src/sage/rings/padics/padic_printing.pyx @@ -76,7 +76,7 @@ class pAdicPrinterDefaults(SageObject): """ This class stores global defaults for `p`-adic printing. """ - def __init__(self, mode = 'series', pos = True, max_ram_terms = -1, max_unram_terms = -1, max_terse_terms = -1, sep = "|", alphabet = None): + def __init__(self, mode='series', pos=True, max_ram_terms=-1, max_unram_terms=-1, max_terse_terms=-1, sep="|", alphabet=None): r""" Instances of this class store global defaults used in determining printing options during the creation of `p`-adic @@ -150,7 +150,7 @@ class pAdicPrinterDefaults(SageObject): else: raise ValueError("invalid printing mode") - def allow_negatives(self, neg = None): + def allow_negatives(self, neg=None): r""" Controls whether or not to display a balanced representation. @@ -172,7 +172,7 @@ class pAdicPrinterDefaults(SageObject): else: self._pos = not neg - def max_series_terms(self, max = None): + def max_series_terms(self, max=None): r""" Controls the maximum number of terms shown when printing in ``'series'``, ``'digits'`` or ``'bars'`` mode. @@ -197,7 +197,7 @@ class pAdicPrinterDefaults(SageObject): else: self._max_ram_terms = int(max) - def max_unram_terms(self, max = None): + def max_unram_terms(self, max=None): r""" For rings with non-prime residue fields, controls how many terms appear in the coefficient of each ``pi^n`` when printing in @@ -222,7 +222,7 @@ class pAdicPrinterDefaults(SageObject): else: self._max_unram_terms = int(max) - def max_poly_terms(self, max = None): + def max_poly_terms(self, max=None): r""" Controls the number of terms appearing when printing polynomial representations in ``'terse'`` or ``'val-unit'`` modes. @@ -248,7 +248,7 @@ class pAdicPrinterDefaults(SageObject): else: self._max_terse_terms = int(max) - def sep(self, sep = None): + def sep(self, sep=None): r""" Controls the separator used in ``'bars'`` mode. @@ -271,7 +271,7 @@ class pAdicPrinterDefaults(SageObject): else: self._sep = str(sep) - def alphabet(self, alphabet = None): + def alphabet(self, alphabet=None): r""" Controls the alphabet used to translate `p`-adic digits into strings (so that no separator need be used in ``'digits'`` mode). @@ -832,7 +832,7 @@ cdef class pAdicPrinter_class(SageObject): else: return trim_zeros(list(value.unit_part().expansion(lift_mode='smallest'))) - def repr_gen(self, elt, do_latex, pos = None, mode = None, ram_name = None): + def repr_gen(self, elt, do_latex, pos=None, mode=None, ram_name=None): """ The entry point for printing an element. diff --git a/src/sage/rings/padics/padic_template_element.pxi b/src/sage/rings/padics/padic_template_element.pxi index c842d9934cd..381887d6a5b 100644 --- a/src/sage/rings/padics/padic_template_element.pxi +++ b/src/sage/rings/padics/padic_template_element.pxi @@ -383,7 +383,7 @@ cdef class pAdicTemplateElement(pAdicGenericElement): """ raise NotImplementedError - def expansion(self, n = None, lift_mode = 'simple', start_val = None): + def expansion(self, n=None, lift_mode='simple', start_val=None): r""" Return the coefficients in a `\pi`-adic expansion. If this is a field element, start at @@ -560,7 +560,7 @@ cdef class pAdicTemplateElement(pAdicGenericElement): else: return expansion[n] - def teichmuller_expansion(self, n = None): + def teichmuller_expansion(self, n=None): r""" Return an iterator over coefficients `a_0, a_1, \dots, a_n` such that diff --git a/src/sage/rings/padics/pow_computer.pyx b/src/sage/rings/padics/pow_computer.pyx index 9719dfa1efe..cbd0118b455 100644 --- a/src/sage/rings/padics/pow_computer.pyx +++ b/src/sage/rings/padics/pow_computer.pyx @@ -638,7 +638,7 @@ cdef PowComputer_base PowComputer_c(Integer m, Integer cache_limit, Integer prec # To speed up the creation of PowComputers with the same m, we might eventually want to copy over data from an existing PowComputer. -def PowComputer(m, cache_limit, prec_cap, in_field = False, prec_type=None): +def PowComputer(m, cache_limit, prec_cap, in_field=False, prec_type=None): r""" Return a ``PowComputer`` that caches the values `1, m, m^2, \ldots, m^{C}`, where `C` is ``cache_limit``. diff --git a/src/sage/rings/padics/pow_computer_ext.pyx b/src/sage/rings/padics/pow_computer_ext.pyx index 389bd0bb20d..13d60f11f28 100644 --- a/src/sage/rings/padics/pow_computer_ext.pyx +++ b/src/sage/rings/padics/pow_computer_ext.pyx @@ -201,7 +201,7 @@ cdef int ZZ_pX_Eis_init(PowComputer_ZZ_pX prime_pow, ntl_ZZ_pX shift_seed) excep #ZZ_div(a, ZZ_p_rep(ZZ_pX_ConstTerm(modup)), prime_pow.small_powers[1]) #ZZ_InvMod(a, a, prime_pow.pow_ZZ_tmp(prime_pow.prec_cap + low_length)[0]) #ZZ_negate(a, a) - ##cdef ntl_ZZ_pX printer = ntl_ZZ_pX([],prime_pow.get_context(prime_pow.prec_cap)) + ##cdef ntl_ZZ_pX printer = ntl_ZZ_pX([], prime_pow.get_context(prime_pow.prec_cap)) ##printer.x = modup # Note that we're losing one digit of precision here. # This is correct because right shifting does not preserve precision. @@ -728,7 +728,7 @@ cdef class PowComputer_ext(PowComputer_class): return self.ram_prec_cap cdef class PowComputer_ZZ_pX(PowComputer_ext): - def __cinit__(self, Integer prime, long cache_limit, long prec_cap, long ram_prec_cap, bint in_field, poly, shift_seed = None): + def __cinit__(self, Integer prime, long cache_limit, long prec_cap, long ram_prec_cap, bint in_field, poly, shift_seed=None): """ Initialization. @@ -1221,7 +1221,7 @@ cdef class PowComputer_ZZ_pX_FM(PowComputer_ZZ_pX): and unramified extensions of `\ZZ_p`. """ - def __cinit__(self, Integer prime, long cache_limit, long prec_cap, long ram_prec_cap, bint in_field, poly, shift_seed = None): + def __cinit__(self, Integer prime, long cache_limit, long prec_cap, long ram_prec_cap, bint in_field, poly, shift_seed=None): """ Caches a context and modulus for ``prime^prec_cap``. @@ -1316,7 +1316,7 @@ cdef class PowComputer_ZZ_pX_FM_Eis(PowComputer_ZZ_pX_FM): This class computes and stores ``low_shifter`` and ``high_shifter``, which aid in right shifting elements. """ - def __cinit__(self, Integer prime, long cache_limit, long prec_cap, long ram_prec_cap, bint in_field, poly, shift_seed = None): + def __cinit__(self, Integer prime, long cache_limit, long prec_cap, long ram_prec_cap, bint in_field, poly, shift_seed=None): """ Call ``Eis_init``, which initializes ``high_shifter`` and ``low_shifter``. @@ -1545,7 +1545,7 @@ cdef class PowComputer_ZZ_pX_small(PowComputer_ZZ_pX): extensions of the base `p`-adic fields. """ - def __cinit__(self, Integer prime, long cache_limit, long prec_cap, long ram_prec_cap, bint in_field, poly, shift_seed = None): + def __cinit__(self, Integer prime, long cache_limit, long prec_cap, long ram_prec_cap, bint in_field, poly, shift_seed=None): """ Caches contexts and moduli densely between 1 and cache_limit. @@ -1745,7 +1745,7 @@ cdef class PowComputer_ZZ_pX_small_Eis(PowComputer_ZZ_pX_small): This class computes and stores ``low_shifter`` and ``high_shifter``, which aid in right shifting elements. These are only stored at maximal precision: in order to get lower precision versions just reduce mod p^n. """ - def __cinit__(self, Integer prime, long cache_limit, long prec_cap, long ram_prec_cap, bint in_field, poly, shift_seed = None): + def __cinit__(self, Integer prime, long cache_limit, long prec_cap, long ram_prec_cap, bint in_field, poly, shift_seed=None): """ Initialization. @@ -1907,7 +1907,7 @@ cdef class PowComputer_ZZ_pX_big(PowComputer_ZZ_pX): a dictionary of contexts and moduli of """ - def __cinit__(self, Integer prime, long cache_limit, long prec_cap, long ram_prec_cap, bint in_field, poly, shift_seed = None): + def __cinit__(self, Integer prime, long cache_limit, long prec_cap, long ram_prec_cap, bint in_field, poly, shift_seed=None): """ Caches contexts and moduli densely between 1 and cache_limit. Caches a context and modulus for prec_cap. Also creates the dictionaries. @@ -2178,7 +2178,7 @@ cdef class PowComputer_ZZ_pX_big_Eis(PowComputer_ZZ_pX_big): These are only stored at maximal precision: in order to get lower precision versions just reduce mod p^n. """ - def __cinit__(self, Integer prime, long cache_limit, long prec_cap, long ram_prec_cap, bint in_field, poly, shift_seed = None): + def __cinit__(self, Integer prime, long cache_limit, long prec_cap, long ram_prec_cap, bint in_field, poly, shift_seed=None): """ Initialization. @@ -2335,7 +2335,7 @@ cdef class PowComputer_ZZ_pX_big_Eis(PowComputer_ZZ_pX_big): return ZZ_pX_eis_shift_p(self, x, a, n, finalprec) -def PowComputer_ext_maker(prime, cache_limit, prec_cap, ram_prec_cap, in_field, poly, prec_type = "small", ext_type = "u", shift_seed = None): +def PowComputer_ext_maker(prime, cache_limit, prec_cap, ram_prec_cap, in_field, poly, prec_type="small", ext_type="u", shift_seed=None): r""" Return a ``PowComputer`` that caches the values `1, p, p^2, \ldots, p^C`, where `C` is ``cache_limit``. diff --git a/src/sage/rings/padics/pow_computer_flint.pyx b/src/sage/rings/padics/pow_computer_flint.pyx index cac2d70d758..6f316b05e2a 100644 --- a/src/sage/rings/padics/pow_computer_flint.pyx +++ b/src/sage/rings/padics/pow_computer_flint.pyx @@ -33,7 +33,7 @@ cdef class PowComputer_flint(PowComputer_class): sage: PowComputer_flint(5, 20, 20, 20, False) FLINT PowComputer for 5 """ - def __cinit__(self, Integer prime, long cache_limit, long prec_cap, long ram_prec_cap, bint in_field, poly=None, shift_seed = None): + def __cinit__(self, Integer prime, long cache_limit, long prec_cap, long ram_prec_cap, bint in_field, poly=None, shift_seed=None): """ Memory initialization. diff --git a/src/sage/rings/polynomial/multi_polynomial.pyx b/src/sage/rings/polynomial/multi_polynomial.pyx index ca25adc23f0..a906ffce164 100644 --- a/src/sage/rings/polynomial/multi_polynomial.pyx +++ b/src/sage/rings/polynomial/multi_polynomial.pyx @@ -1391,7 +1391,7 @@ cdef class MPolynomial(CommutativePolynomial): v = [self] + [self.map_coefficients(k.hom([k.gen()**(p**i)])) for i in range(1,e)] return prod(v).change_ring(k.prime_subfield()) - def sylvester_matrix(self, right, variable = None): + def sylvester_matrix(self, right, variable=None): r""" Given two nonzero polynomials ``self`` and ``right``, return the Sylvester matrix of the polynomials with respect to a given variable. @@ -1545,7 +1545,7 @@ cdef class MPolynomial(CommutativePolynomial): return M - def discriminant(self,variable): + def discriminant(self, variable): r""" Return the discriminant of ``self`` with respect to the given variable. diff --git a/src/sage/rings/polynomial/multi_polynomial_element.py b/src/sage/rings/polynomial/multi_polynomial_element.py index 6c4ec02c1b1..ca1f1c538a4 100644 --- a/src/sage/rings/polynomial/multi_polynomial_element.py +++ b/src/sage/rings/polynomial/multi_polynomial_element.py @@ -1657,7 +1657,7 @@ def variables(self): """ return tuple([self.parent().gen(index) for index in self.degrees().nonzero_positions()]) - def variable(self,i): + def variable(self, i): """ Return the `i`-th variable occurring in this polynomial. @@ -2200,7 +2200,7 @@ def factor(self, proof=None): return F @handle_AA_and_QQbar - def lift(self,I): + def lift(self, I): """ Given an ideal `I = (f_1,...,f_r)` and some `g` (= ``self``) in `I`, find `s_1,...,s_r` such that `g = s_1 f_1 + ... + s_r f_r`. diff --git a/src/sage/rings/polynomial/multi_polynomial_ideal.py b/src/sage/rings/polynomial/multi_polynomial_ideal.py index 222da435df2..26b194722e0 100644 --- a/src/sage/rings/polynomial/multi_polynomial_ideal.py +++ b/src/sage/rings/polynomial/multi_polynomial_ideal.py @@ -3724,7 +3724,7 @@ def _groebner_strategy(self): from sage.libs.singular.groebner_strategy import NCGroebnerStrategy return NCGroebnerStrategy(self.std()) - def reduce(self,p): + def reduce(self, p): """ Reduce an element modulo a Groebner basis for this ideal. @@ -3759,7 +3759,7 @@ def reduce(self,p): """ return self._groebner_strategy().normal_form(p) - def _contains_(self,p): + def _contains_(self, p): """ EXAMPLES: @@ -4739,7 +4739,7 @@ def groebner_basis(self, algorithm='', deg_bound=None, mult_bound=None, prot=Fal gb = self._groebner_basis_ginv(*args, **kwds) elif ":" in algorithm: ginv,alg = algorithm.split(":") - gb = self._groebner_basis_ginv(algorithm=alg,*args, **kwds) + gb = self._groebner_basis_ginv(algorithm=alg, *args, **kwds) else: raise NameError("Algorithm '%s' unknown." % algorithm) elif algorithm == 'giac:gbasis': diff --git a/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx b/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx index d05760d84cd..cb692c6e4cc 100644 --- a/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx +++ b/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx @@ -1702,7 +1702,7 @@ cdef class MPolynomialRing_libsingular(MPolynomialRing_base): sage: P.monomial_lcm(x,P(1)) x """ - cdef poly *m = p_ISet(1,self._ring) + cdef poly *m = p_ISet(1, self._ring) if self is not f._parent: f = self.coerce(f) @@ -2884,7 +2884,7 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): cdef poly *_degrees = 0 cdef poly *p = self._poly cdef ring *r = self._parent_ring - cdef poly *newp = p_ISet(0,r) + cdef poly *newp = p_ISet(0, r) cdef poly *newptemp cdef int i cdef int flag @@ -3146,7 +3146,7 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): return -2 return result - def __getitem__(self,x): + def __getitem__(self, x): """ Same as ``self.monomial_coefficient`` but for exponent vectors. @@ -4576,7 +4576,7 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): """ global errorreported - cdef ideal *fI = idInit(1,1) + cdef ideal *fI = idInit(1, 1) cdef ideal *_I cdef MPolynomialRing_libsingular parent = self._parent cdef int i = 0 @@ -4888,7 +4888,7 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): if n_GetChar(_ring.cf) > 1<<29: raise NotImplementedError("GCD of multivariate polynomials over prime fields with characteristic > 2^29 is not implemented.") - cdef int count = singular_polynomial_length_bounded(self._poly,20) \ + cdef int count = singular_polynomial_length_bounded(self._poly, 20) \ + singular_polynomial_length_bounded(_right._poly,20) if count >= 20: sig_on() @@ -4964,7 +4964,7 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): if n_GetChar(_ring.cf) > 1<<29: raise NotImplementedError("LCM of multivariate polynomials over prime fields with characteristic > 2^29 is not implemented.") - cdef int count = singular_polynomial_length_bounded(self._poly,20) \ + cdef int count = singular_polynomial_length_bounded(self._poly, 20) \ + singular_polynomial_length_bounded(_g._poly,20) if count >= 20: sig_on() @@ -5044,7 +5044,7 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): if n_GetChar(r.cf) > 1<<29: raise NotImplementedError("Division of multivariate polynomials over prime fields with characteristic > 2^29 is not implemented.") - cdef int count = singular_polynomial_length_bounded(self._poly,15) + cdef int count = singular_polynomial_length_bounded(self._poly, 15) if count >= 15: # note that _right._poly must be of shorter length than self._poly for us to care about this call sig_on() if r!=currRing: rChangeCurrRing(r) # singclap_pdivide diff --git a/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx b/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx index 19c2ddac7b1..ac5e445908d 100644 --- a/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx +++ b/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx @@ -392,21 +392,21 @@ cdef class MPolynomialRing_base(CommutativeRing): EXAMPLES:: - sage: def F(a,b,c): + sage: def F(a, b, c): ....: return a^3*b + b + c^2 + 25 ....: sage: R. = PolynomialRing(QQ) sage: R.interpolation(4, F) # needs sage.modules x^3*y + z^2 + y + 25 - sage: def F(a,b,c): + sage: def F(a, b, c): ....: return a^3*b + b + c^2 + 25 ....: sage: R. = PolynomialRing(QQ) sage: R.interpolation([3,1,2], F) # needs sage.modules x^3*y + z^2 + y + 25 - sage: def F(a,b,c): + sage: def F(a, b, c): ....: return a^3*b + b + c^2 + 25 ....: sage: R. = PolynomialRing(QQ) @@ -444,7 +444,7 @@ cdef class MPolynomialRing_base(CommutativeRing): as well. So if you give wrong bounds, you will get a wrong answer without any warning. :: - sage: def F(a,b,c): + sage: def F(a, b, c): ....: return a^3*b + b + c^2 + 25 ....: sage: R. = PolynomialRing(QQ) diff --git a/src/sage/rings/polynomial/multi_polynomial_sequence.py b/src/sage/rings/polynomial/multi_polynomial_sequence.py index 37381c084ac..61b4f6afb1a 100644 --- a/src/sage/rings/polynomial/multi_polynomial_sequence.py +++ b/src/sage/rings/polynomial/multi_polynomial_sequence.py @@ -856,7 +856,7 @@ def subs(self, *args, **kwargs): sage: F = F.subs(s); F # needs sage.rings.polynomial.pbori Polynomial Sequence with 40 Polynomials in 16 Variables """ - return PolynomialSequence(self._ring, [tuple([f.subs(*args,**kwargs) for f in r]) for r in self._parts]) + return PolynomialSequence(self._ring, [tuple([f.subs(*args, **kwargs) for f in r]) for r in self._parts]) def _singular_(self): """ diff --git a/src/sage/rings/polynomial/plural.pyx b/src/sage/rings/polynomial/plural.pyx index 35de7feefe5..0751068f27a 100644 --- a/src/sage/rings/polynomial/plural.pyx +++ b/src/sage/rings/polynomial/plural.pyx @@ -335,7 +335,7 @@ cdef class NCPolynomialRing_plural(Ring): from sage.libs.singular.function import singular_function ncalgebra = singular_function('nc_algebra') - cdef RingWrap rw = ncalgebra(self._c, self._d, ring = P) + cdef RingWrap rw = ncalgebra(self._c, self._d, ring=P) # rw._output() self._ring = singular_ring_reference(rw._ring) @@ -1184,7 +1184,7 @@ cdef class NCPolynomialRing_plural(Ring): sage: P.monomial_lcm(x,P(1)) x """ - cdef poly *m = p_ISet(1,self._ring) + cdef poly *m = p_ISet(1, self._ring) if self is not f._parent: f = self.coerce(f) @@ -2091,7 +2091,7 @@ cdef class NCPolynomial_plural(RingElement): cdef poly *_degrees = 0 cdef poly *p = self._poly cdef ring *r = (self._parent)._ring - cdef poly *newp = p_ISet(0,r) + cdef poly *newp = p_ISet(0, r) cdef poly *newptemp cdef int i cdef int flag @@ -2353,7 +2353,7 @@ cdef class NCPolynomial_plural(RingElement): return -2 return result - def __getitem__(self,x): + def __getitem__(self, x): """ Same as :meth:`monomial_coefficient` but for exponent vectors. @@ -3117,7 +3117,7 @@ def SCA(base_ring, names, alt_vars, order='degrevlex'): return H.quotient(I) -def ExteriorAlgebra(base_ring, names,order='degrevlex'): +def ExteriorAlgebra(base_ring, names, order='degrevlex'): """ Return the exterior algebra on some generators. diff --git a/src/sage/rings/polynomial/polynomial_element.pyx b/src/sage/rings/polynomial/polynomial_element.pyx index 53bb07c2fc4..a3fa5343788 100644 --- a/src/sage/rings/polynomial/polynomial_element.pyx +++ b/src/sage/rings/polynomial/polynomial_element.pyx @@ -208,7 +208,7 @@ cdef class Polynomial(CommutativePolynomial): .. automethod:: _mul_trunc_ """ - def __init__(self, parent, is_gen = False, construct=False): + def __init__(self, parent, is_gen=False, construct=False): """ The following examples illustrate creation of elements of polynomial rings, and some basic arithmetic. @@ -3528,7 +3528,7 @@ cdef class Polynomial(CommutativePolynomial): @cython.boundscheck(False) @cython.wraparound(False) @cython.overflowcheck(False) - def _mul_karatsuba(self, right, K_threshold = None): + def _mul_karatsuba(self, right, K_threshold=None): r""" Compute the product of two polynomials using the Karatsuba divide and conquer multiplication algorithm. This is only used over a @@ -4323,7 +4323,7 @@ cdef class Polynomial(CommutativePolynomial): """ return [self.diff()] - def integral(self,var=None): + def integral(self, var=None): """ Return the integral of this polynomial. @@ -5314,7 +5314,7 @@ cdef class Polynomial(CommutativePolynomial): raise NotImplementedError("splitting_field() is only implemented over number fields and finite fields") - def pseudo_quo_rem(self,other): + def pseudo_quo_rem(self, other): r""" Compute the pseudo-division of two polynomials. @@ -5831,7 +5831,7 @@ cdef class Polynomial(CommutativePolynomial): return R.fraction_field()[self._parent.variable_name()].quotient(self, names) - def sylvester_matrix(self, right, variable = None): + def sylvester_matrix(self, right, variable=None): """ Return the Sylvester matrix of ``self`` and ``right``. @@ -11819,7 +11819,7 @@ cdef list do_karatsuba_different_size(list left, list right, Py_ssize_t K_thresh @cython.boundscheck(False) @cython.wraparound(False) @cython.overflowcheck(False) -cdef list do_karatsuba(list left, list right, Py_ssize_t K_threshold,Py_ssize_t start_l, Py_ssize_t start_r,Py_ssize_t num_elts): +cdef list do_karatsuba(list left, list right, Py_ssize_t K_threshold, Py_ssize_t start_l, Py_ssize_t start_r, Py_ssize_t num_elts): """ Core routine for Karatsuba multiplication. This function works for two polynomials of the same degree. diff --git a/src/sage/rings/polynomial/polynomial_rational_flint.pyx b/src/sage/rings/polynomial/polynomial_rational_flint.pyx index ceaa9d7b2d5..c11592cf2d6 100644 --- a/src/sage/rings/polynomial/polynomial_rational_flint.pyx +++ b/src/sage/rings/polynomial/polynomial_rational_flint.pyx @@ -1495,7 +1495,7 @@ cdef class Polynomial_rational_flint(Polynomial): fmpz_get_mpz(den.value, fmpq_poly_denref(self._poly)) return den - def _derivative(self, var = None): + def _derivative(self, var=None): """ Return the derivative of this polynomial with respect to ``var``. diff --git a/src/sage/rings/polynomial/real_roots.pyx b/src/sage/rings/polynomial/real_roots.pyx index a91a95a1d55..bf294c3c398 100644 --- a/src/sage/rings/polynomial/real_roots.pyx +++ b/src/sage/rings/polynomial/real_roots.pyx @@ -1248,7 +1248,7 @@ def de_casteljau_intvec(Vector_integer_dense c, int c_bitsize, Rational x, int u # An ULP is a "unit in the last place"; it is the (varying) unit for # how much adjacent floating-point numbers differ from each other. # A half-ULP is half this amount; it is the maximum rounding error -# in the basic operations (+,-,*,/) in a correctly-operating IEEE +# in the basic operations (+, -, *, /) in a correctly-operating IEEE # floating-point unit. # (Note that by default, the x86 does not use IEEE double precision; # instead, it uses extra precision, which can (counterintuitively) diff --git a/src/sage/rings/polynomial/skew_polynomial_finite_field.pyx b/src/sage/rings/polynomial/skew_polynomial_finite_field.pyx index 0c8c660c18c..8193108d25a 100644 --- a/src/sage/rings/polynomial/skew_polynomial_finite_field.pyx +++ b/src/sage/rings/polynomial/skew_polynomial_finite_field.pyx @@ -842,7 +842,7 @@ cdef class SkewPolynomial_finite_field_dense(SkewPolynomial_finite_order_dense): cdef list indices = sample(range(1, m+1), m) cdef unit = self.leading_coefficient() - cdef SkewPolynomial_finite_field_dense left = self._new_c(self._coeffs[:],skew_ring) + cdef SkewPolynomial_finite_field_dense left = self._new_c(self._coeffs[:], skew_ring) left = left.right_monic() cdef SkewPolynomial_finite_field_dense right = skew_ring.one() cdef SkewPolynomial_finite_field_dense L, R diff --git a/src/sage/rings/polynomial/skew_polynomial_finite_order.pyx b/src/sage/rings/polynomial/skew_polynomial_finite_order.pyx index f90484cba62..e92cca63198 100644 --- a/src/sage/rings/polynomial/skew_polynomial_finite_order.pyx +++ b/src/sage/rings/polynomial/skew_polynomial_finite_order.pyx @@ -94,7 +94,7 @@ cdef class SkewPolynomial_finite_order_dense(SkewPolynomial_generic_dense): else: col = 0 exp = r - cdef SkewPolynomial_finite_order_dense powx = self._new_c([zero,one], parent) + cdef SkewPolynomial_finite_order_dense powx = self._new_c([zero, one], parent) cdef SkewPolynomial_finite_order_dense v if (exp % 2 == 1): v = self._new_c([zero,one], parent) diff --git a/src/sage/rings/polynomial/term_order.py b/src/sage/rings/polynomial/term_order.py index 1bed10ba867..b9eb319a12a 100644 --- a/src/sage/rings/polynomial/term_order.py +++ b/src/sage/rings/polynomial/term_order.py @@ -1210,7 +1210,7 @@ def sortkey_block(self, f): n += len(block) return key - def greater_tuple_matrix(self,f,g): + def greater_tuple_matrix(self, f, g): """ Return the greater exponent tuple with respect to the matrix term order. @@ -1239,7 +1239,7 @@ def greater_tuple_matrix(self,f,g): return g return g - def greater_tuple_lex(self,f,g): + def greater_tuple_lex(self, f, g): """ Return the greater exponent tuple with respect to the lexicographical term order. @@ -1261,7 +1261,7 @@ def greater_tuple_lex(self,f,g): """ return f > g and f or g - def greater_tuple_invlex(self,f,g): + def greater_tuple_invlex(self, f, g): """ Return the greater exponent tuple with respect to the inversed lexicographical term order. @@ -1285,7 +1285,7 @@ def greater_tuple_invlex(self,f,g): """ return f.reversed() > g.reversed() and f or g - def greater_tuple_deglex(self,f,g): + def greater_tuple_deglex(self, f, g): """ Return the greater exponent tuple with respect to the total degree lexicographical term order. @@ -1311,7 +1311,7 @@ def greater_tuple_deglex(self,f,g): sg = sum(g.nonzero_values(sort=False)) return ( sf > sg or ( sf == sg and f > g )) and f or g - def greater_tuple_degrevlex(self,f,g): + def greater_tuple_degrevlex(self, f, g): """ Return the greater exponent tuple with respect to the total degree reversed lexicographical term order. @@ -1337,7 +1337,7 @@ def greater_tuple_degrevlex(self,f,g): sg = sum(g.nonzero_values(sort=False)) return ( sf > sg or ( sf == sg and f.reversed() < g.reversed() )) and f or g - def greater_tuple_negdegrevlex(self,f,g): + def greater_tuple_negdegrevlex(self, f, g): """ Return the greater exponent tuple with respect to the negative degree reverse lexicographical term order. @@ -1366,7 +1366,7 @@ def greater_tuple_negdegrevlex(self,f,g): sg = sum(g.nonzero_values(sort=False)) return ( sf < sg or ( sf == sg and f.reversed() < g.reversed() )) and f or g - def greater_tuple_negdeglex(self,f,g): + def greater_tuple_negdeglex(self, f, g): """ Return the greater exponent tuple with respect to the negative degree lexicographical term order. @@ -1395,7 +1395,7 @@ def greater_tuple_negdeglex(self,f,g): sg = sum(g.nonzero_values(sort=False)) return ( sf < sg or ( sf == sg and f > g )) and f or g - def greater_tuple_degneglex(self,f,g): + def greater_tuple_degneglex(self, f, g): """ Return the greater exponent tuple with respect to the degree negative lexicographical term order. @@ -1421,7 +1421,7 @@ def greater_tuple_degneglex(self,f,g): sg = sum(g.nonzero_values(sort=False)) return ( sf > sg or ( sf == sg and f < g )) and f or g - def greater_tuple_neglex(self,f,g): + def greater_tuple_neglex(self, f, g): """ Return the greater exponent tuple with respect to the negative lexicographical term order. @@ -1446,7 +1446,7 @@ def greater_tuple_neglex(self,f,g): """ return (f < g) and f or g - def greater_tuple_wdeglex(self,f,g): + def greater_tuple_wdeglex(self, f, g): """ Return the greater exponent tuple with respect to the weighted degree lexicographical term order. @@ -1473,7 +1473,7 @@ def greater_tuple_wdeglex(self,f,g): sg = sum(l*r for (l,r) in zip(g,self._weights)) return (sf > sg or ( sf == sg and f > g )) and f or g - def greater_tuple_wdegrevlex(self,f,g): + def greater_tuple_wdegrevlex(self, f, g): """ Return the greater exponent tuple with respect to the weighted degree reverse lexicographical term order. @@ -1500,7 +1500,7 @@ def greater_tuple_wdegrevlex(self,f,g): sg = sum(l*r for (l,r) in zip(g,self._weights)) return (sf > sg or ( sf == sg and f.reversed() < g.reversed())) and f or g - def greater_tuple_negwdeglex(self,f,g): + def greater_tuple_negwdeglex(self, f, g): """ Return the greater exponent tuple with respect to the negative weighted degree lexicographical term order. @@ -1530,7 +1530,7 @@ def greater_tuple_negwdeglex(self,f,g): sg = sum(l*r for (l,r) in zip(g,self._weights)) return (sf < sg or ( sf == sg and f > g )) and f or g - def greater_tuple_negwdegrevlex(self,f,g): + def greater_tuple_negwdegrevlex(self, f, g): """ Return the greater exponent tuple with respect to the negative weighted degree reverse lexicographical term order. @@ -1560,7 +1560,7 @@ def greater_tuple_negwdegrevlex(self,f,g): sg = sum(l*r for (l,r) in zip(g,self._weights)) return (sf < sg or ( sf == sg and f.reversed() < g.reversed() )) and f or g - def greater_tuple_block(self, f,g): + def greater_tuple_block(self, f, g): """ Return the greater exponent tuple with respect to the block order as specified when constructing this element. diff --git a/src/sage/rings/power_series_poly.pyx b/src/sage/rings/power_series_poly.pyx index 309d72c8f6a..39b05cce069 100644 --- a/src/sage/rings/power_series_poly.pyx +++ b/src/sage/rings/power_series_poly.pyx @@ -874,7 +874,7 @@ cdef class PowerSeries_poly(PowerSeries): return PowerSeries_poly(self._parent, self.__f._derivative(), self.prec()-1, check=False) - def integral(self,var=None): + def integral(self, var=None): """ Return the integral of this power series. diff --git a/src/sage/rings/power_series_ring_element.pyx b/src/sage/rings/power_series_ring_element.pyx index b1ca6ea4ab1..1d24794eb37 100644 --- a/src/sage/rings/power_series_ring_element.pyx +++ b/src/sage/rings/power_series_ring_element.pyx @@ -839,7 +839,7 @@ cdef class PowerSeries(AlgebraElement): v = [a[i] for i in range(min(prec, len(a)))] return self._parent(v, prec) - def __getitem__(self,n): + def __getitem__(self, n): r""" Return the coefficient of `t^n` in this power series, where `t` is the indeterminate of the power series ring. @@ -2317,7 +2317,7 @@ cdef class PowerSeries(AlgebraElement): coeffs = self[:prec] return self._parent(coeffs, prec) - def solve_linear_de(self, prec = infinity, b = None, f0 = None): + def solve_linear_de(self, prec=infinity, b=None, f0=None): r""" Obtain a power series solution to an inhomogeneous linear differential equation of the form: diff --git a/src/sage/rings/quotient_ring.py b/src/sage/rings/quotient_ring.py index 4cf3979265f..6721fea2421 100644 --- a/src/sage/rings/quotient_ring.py +++ b/src/sage/rings/quotient_ring.py @@ -35,7 +35,7 @@ ....: self._power = n ....: self._power = n ....: Ideal_nc.__init__(self, R, [R.prod(m) for m in product(R.gens(), repeat=n)]) - ....: def reduce(self,x): + ....: def reduce(self, x): ....: R = self.ring() ....: return add([c*R(m) for m,c in x if len(m) = FreeAlgebra(QQ, 3) # needs sage.combinat sage.modules @@ -793,7 +793,7 @@ def lift(self, x=None): return self.lifting_map() return self.lifting_map()(x) - def retract(self,x): + def retract(self, x): """ The image of an element of the cover ring under the quotient map. diff --git a/src/sage/rings/ring.pyx b/src/sage/rings/ring.pyx index 17d0150357d..6733db3aa9c 100644 --- a/src/sage/rings/ring.pyx +++ b/src/sage/rings/ring.pyx @@ -1416,7 +1416,7 @@ cdef class Field(CommutativeRing): """ return self - def is_field(self, proof = True): + def is_field(self, proof=True): """ Return ``True`` since this is a field. diff --git a/src/sage/rings/ring_extension_element.pyx b/src/sage/rings/ring_extension_element.pyx index 67b6aa90879..92447a722e1 100644 --- a/src/sage/rings/ring_extension_element.pyx +++ b/src/sage/rings/ring_extension_element.pyx @@ -383,7 +383,7 @@ cdef class RingExtensionElement(CommutativeAlgebraElement): """ return left._backend._richcmp_(backend_element(right), op) - cpdef _add_(self,other): + cpdef _add_(self, other): r""" Return the sum of this element and ``other``. @@ -423,7 +423,7 @@ cdef class RingExtensionElement(CommutativeAlgebraElement): ans._backend = -self._backend return ans - cpdef _sub_(self,other): + cpdef _sub_(self, other): r""" Return the difference of this element and ``other``. @@ -443,7 +443,7 @@ cdef class RingExtensionElement(CommutativeAlgebraElement): ans._backend = self._backend - (other)._backend return ans - cpdef _mul_(self,other): + cpdef _mul_(self, other): r""" Return the product of this element and ``other``. @@ -463,7 +463,7 @@ cdef class RingExtensionElement(CommutativeAlgebraElement): ans._backend = self._backend * (other)._backend return ans - cpdef _div_(self,other): + cpdef _div_(self, other): r""" Return the quotient of this element by ``other``, considered as an element of the fraction field. diff --git a/src/sage/schemes/elliptic_curves/cm.py b/src/sage/schemes/elliptic_curves/cm.py index 6760719e789..e02a117ee3c 100755 --- a/src/sage/schemes/elliptic_curves/cm.py +++ b/src/sage/schemes/elliptic_curves/cm.py @@ -288,7 +288,7 @@ def is_HCP(f, check_monic_irreducible=True): return D if f == hilbert_class_polynomial(D) else zero -def OrderClassNumber(D0,h0,f): +def OrderClassNumber(D0, h0, f): r""" Return the class number h(f**2 * D0), given h(D0)=h0. diff --git a/src/sage/schemes/elliptic_curves/constructor.py b/src/sage/schemes/elliptic_curves/constructor.py index 831ee47e280..5a97d2eda9b 100755 --- a/src/sage/schemes/elliptic_curves/constructor.py +++ b/src/sage/schemes/elliptic_curves/constructor.py @@ -1271,7 +1271,7 @@ def EllipticCurve_from_cubic(F, P=None, morphism=True): C, E, fwd_defining_poly, fwd_post, inv_defining_poly, inv_post) -def tangent_at_smooth_point(C,P): +def tangent_at_smooth_point(C, P): r"""Return the tangent at the smooth point `P` of projective curve `C`. INPUT: diff --git a/src/sage/schemes/elliptic_curves/ell_number_field.py b/src/sage/schemes/elliptic_curves/ell_number_field.py index eea2e5cc243..8af221880b6 100755 --- a/src/sage/schemes/elliptic_curves/ell_number_field.py +++ b/src/sage/schemes/elliptic_curves/ell_number_field.py @@ -541,7 +541,7 @@ def is_local_integral_model(self, *P): return all(self.is_local_integral_model(x) for x in P) return all(x.valuation(P) >= 0 for x in self.ainvs()) - def local_integral_model(self,*P): + def local_integral_model(self, *P): r""" Return a model of ``self`` which is integral at the prime ideal `P`. @@ -1898,7 +1898,7 @@ def global_minimal_model(self, proof=None, semi_global=False): raise ValueError("%s has no global minimal model! For a semi-global minimal model use semi_global=True" % self) - def reduction(self,place): + def reduction(self, place): r""" Return the reduction of the elliptic curve at a place of good reduction. diff --git a/src/sage/schemes/elliptic_curves/ell_point.py b/src/sage/schemes/elliptic_curves/ell_point.py index d9b7189552e..5131abbec00 100755 --- a/src/sage/schemes/elliptic_curves/ell_point.py +++ b/src/sage/schemes/elliptic_curves/ell_point.py @@ -4169,7 +4169,7 @@ def discrete_log(self, Q): ' methods in Sage uniform. Please update your code.') return Q.log(self) - def padic_elliptic_logarithm(self,Q, p): + def padic_elliptic_logarithm(self, Q, p): r""" Return the discrete logarithm of `Q` to base `P` = ``self``, that is, an integer `x` such that `xP = Q` only for anomalous curves. diff --git a/src/sage/schemes/elliptic_curves/ell_rational_field.py b/src/sage/schemes/elliptic_curves/ell_rational_field.py index d00187d49a2..41e5ea3a9eb 100755 --- a/src/sage/schemes/elliptic_curves/ell_rational_field.py +++ b/src/sage/schemes/elliptic_curves/ell_rational_field.py @@ -4116,7 +4116,7 @@ def cremona_label(self, space=False): label = cremona_label - def reduction(self,p): + def reduction(self, p): r""" Return the reduction of the elliptic curve at a prime of good reduction. @@ -5945,7 +5945,7 @@ def antilogarithm(self, z, max_denominator=None): except TypeError: raise ValueError("approximated point not on the curve") - def integral_x_coords_in_interval(self,xmin,xmax): + def integral_x_coords_in_interval(self, xmin, xmax): r""" Return the set of integers `x` with `xmin\le x\le xmax` which are `x`-coordinates of rational points on this curve. @@ -6136,7 +6136,7 @@ def integral_points(self, mw_base='auto', both_signs=False, verbose=False): # INTERNAL FUNCTIONS ################################################ ############################## begin ################################ - def point_preprocessing(free,tor): + def point_preprocessing(free, tor): r""" Transform the mw_basis ``free`` into a `\ZZ`-basis for `E(\QQ)\cap E^0(`\RR)`. If there is a torsion point on the diff --git a/src/sage/schemes/elliptic_curves/ell_wp.py b/src/sage/schemes/elliptic_curves/ell_wp.py index 5c8e7930830..622f8fed5f3 100755 --- a/src/sage/schemes/elliptic_curves/ell_wp.py +++ b/src/sage/schemes/elliptic_curves/ell_wp.py @@ -167,7 +167,7 @@ def weierstrass_p(E, prec=20, algorithm=None): return wp(z*u) * u**2 -def compute_wp_pari(E,prec): +def compute_wp_pari(E, prec): r""" Compute the Weierstrass `\wp`-function with the ``ellwp`` function from PARI. diff --git a/src/sage/schemes/elliptic_curves/gal_reps.py b/src/sage/schemes/elliptic_curves/gal_reps.py index b9360acdf56..8f0e0ed9a60 100755 --- a/src/sage/schemes/elliptic_curves/gal_reps.py +++ b/src/sage/schemes/elliptic_curves/gal_reps.py @@ -203,7 +203,7 @@ def __repr__(self): """ return "Compatible family of Galois representations associated to the " + repr(self._E) - def __eq__(self,other): + def __eq__(self, other): r""" Compare two Galois representations. We define tho compatible families of representations @@ -1081,7 +1081,7 @@ def image_type(self, p): self.__image_type[p] = "The image could not be determined. Sorry." return self.__image_type[p] - def image_classes(self,p,bound=10000): + def image_classes(self, p, bound=10000): r""" This function returns, given the representation `\rho` a list of `p` values that add up to 1, representing the @@ -1228,7 +1228,7 @@ def image_classes(self,p,bound=10000): # ell-adic reps - def is_unramified(self,p,ell): + def is_unramified(self, p, ell): r""" Return true if the Galois representation to `GL_2(\ZZ_p)` is unramified at `\ell`, i.e. if the inertia group at a place above `\ell` in `\text{Gal}(\bar\QQ/\QQ)` has trivial image in @@ -1262,7 +1262,7 @@ def is_unramified(self,p,ell): raise ValueError('ell (=%s) must be prime' % ell) return (ell != p) and self._E.has_good_reduction(ell) - def is_unipotent(self,p,ell): + def is_unipotent(self, p, ell): r""" Return true if the Galois representation to `GL_2(\ZZ_p)` is unipotent at `\ell\neq p`, i.e. if the inertia group at a place above `\ell` in `\text{Gal}(\bar\QQ/\QQ)` maps into a Borel subgroup. @@ -1301,7 +1301,7 @@ def is_unipotent(self,p,ell): raise ValueError("unipotent is not defined for l = p, use semistable instead.") return not self._E.has_additive_reduction(ell) - def is_quasi_unipotent(self,p,ell): + def is_quasi_unipotent(self, p, ell): r""" Return true if the Galois representation to `GL_2(\ZZ_p)` is quasi-unipotent at `\ell\neq p`, i.e. if there is a finite extension `K/\QQ` such that the inertia group at a place above `\ell` in `\text{Gal}(\bar\QQ/K)` maps into a Borel subgroup. @@ -1330,7 +1330,7 @@ def is_quasi_unipotent(self,p,ell): # p-adic reps - def is_ordinary(self,p): + def is_ordinary(self, p): r""" Return true if the `p`-adic Galois representation to `GL_2(\ZZ_p)` is ordinary, i.e. if the image of the decomposition group in `\text{Gal}(\bar\QQ/\QQ)` above he prime `p` maps into @@ -1360,7 +1360,7 @@ def is_ordinary(self,p): raise NotImplementedError('is_ordinary is only implemented for semi-stable representations') return self._E.has_multiplicative_reduction(p) or (self._E.has_good_reduction(p) and self._E.ap(p) % p != 0) - def is_crystalline(self,p): + def is_crystalline(self, p): r""" Return true is the `p`-adic Galois representation to `GL_2(\ZZ_p)` is crystalline. @@ -1384,7 +1384,7 @@ def is_crystalline(self,p): raise ValueError('p (=%s) must be prime' % p) return self._E.has_good_reduction(p) - def is_potentially_crystalline(self,p): + def is_potentially_crystalline(self, p): r""" Return true is the `p`-adic Galois representation to `GL_2(\ZZ_p)` is potentially crystalline, i.e. if there is a finite extension `K/\QQ_p` such that the `p`-adic representation becomes crystalline. @@ -1409,7 +1409,7 @@ def is_potentially_crystalline(self,p): raise ValueError('p (=%s) must be prime' % p) return self._E.j_invariant().valuation(p) >= 0 - def is_semistable(self,p): + def is_semistable(self, p): r""" Return true if the `p`-adic Galois representation to `GL_2(\ZZ_p)` is semistable. @@ -1435,7 +1435,7 @@ def is_semistable(self,p): raise ValueError('p (=%s) must be prime' % p) return not self._E.has_additive_reduction(p) - def is_potentially_semistable(self,p): + def is_potentially_semistable(self, p): r""" Return true if the `p`-adic Galois representation to `GL_2(\ZZ_p)` is potentially semistable. diff --git a/src/sage/schemes/elliptic_curves/gal_reps_number_field.py b/src/sage/schemes/elliptic_curves/gal_reps_number_field.py index a4eb66a6df7..7824893b05f 100755 --- a/src/sage/schemes/elliptic_curves/gal_reps_number_field.py +++ b/src/sage/schemes/elliptic_curves/gal_reps_number_field.py @@ -132,7 +132,7 @@ def __repr__(self): else: return "Compatible family of Galois representations associated to the " + repr(self.E) - def __eq__(self,other): + def __eq__(self, other): r""" Compare two Galois representations. @@ -1191,7 +1191,7 @@ def Billerey_P_l(E, l): return P -def Billerey_B_l(E,l,B=0): +def Billerey_B_l(E, l, B=0): r""" Return Billerey's `B_l`, adapted from the definition in [Bil2011]_, after (9). diff --git a/src/sage/schemes/elliptic_curves/heegner.py b/src/sage/schemes/elliptic_curves/heegner.py index 1bff085023c..f0a7087d7ea 100755 --- a/src/sage/schemes/elliptic_curves/heegner.py +++ b/src/sage/schemes/elliptic_curves/heegner.py @@ -1177,7 +1177,7 @@ def __getitem__(self, i): """ EXAMPLES:: - sage: E = EllipticCurve('389a'); F= E.heegner_point(-7,5).ring_class_field() + sage: E = EllipticCurve('389a'); F = E.heegner_point(-7,5).ring_class_field() sage: G = F.galois_group(F.quadratic_field()) sage: G[0] Class field automorphism defined by x^2 + x*y + 44*y^2 @@ -1666,7 +1666,7 @@ def ideal(self): EXAMPLES:: - sage: E = EllipticCurve('389a'); F= E.heegner_point(-20,3).ring_class_field() + sage: E = EllipticCurve('389a'); F = E.heegner_point(-20,3).ring_class_field() sage: G = F.galois_group(F.quadratic_field()) sage: G[1].ideal() Fractional ideal (2, 1/2*sqrt_minus_20 + 1) @@ -4283,7 +4283,7 @@ def plot(self, prec=53, *args, **kwds): if not P: # point at infinity return Graphics() - return point((P[0].real(), P[1].real()),*args, **kwds) + return point((P[0].real(), P[1].real()), *args, **kwds) else: raise NotImplementedError diff --git a/src/sage/schemes/elliptic_curves/kraus.py b/src/sage/schemes/elliptic_curves/kraus.py index 49dff06b493..5e749a0448d 100755 --- a/src/sage/schemes/elliptic_curves/kraus.py +++ b/src/sage/schemes/elliptic_curves/kraus.py @@ -798,7 +798,7 @@ def check_Kraus_global(c4, c6, assume_nonsingular=False, debug=False): sage: E = EllipticCurve([a, 0, 1, 2*a^2 + 5*a + 3, -a^2 - 3*a - 2]) sage: assert E.conductor().norm() == 8 sage: G = K.galois_group(names='b') - sage: def conj_curve(E,sigma): return EllipticCurve([sigma(a) for a in E.ainvs()]) + sage: def conj_curve(E, sigma): return EllipticCurve([sigma(a) for a in E.ainvs()]) sage: EL = conj_curve(E,G[0]) sage: L = EL.base_field() sage: assert L.class_number() == 2 diff --git a/src/sage/schemes/elliptic_curves/padic_lseries.py b/src/sage/schemes/elliptic_curves/padic_lseries.py index 1fcc30764b2..6cb54115933 100755 --- a/src/sage/schemes/elliptic_curves/padic_lseries.py +++ b/src/sage/schemes/elliptic_curves/padic_lseries.py @@ -1640,7 +1640,7 @@ def bernardi_sigma_function(self, prec=20): return sigma_of_z - def Dp_valued_height(self,prec=20): + def Dp_valued_height(self, prec=20): r""" Return the canonical `p`-adic height with values in the Dieudonné module `D_p(E)`. @@ -1674,7 +1674,7 @@ def Dp_valued_height(self,prec=20): n = _multiple_to_make_good_reduction(E) n = LCM(n, E.Np(p)) # allowed here because E has good reduction at p - def height(P,check=True): + def height(P, check=True): if P.is_finite_order(): return Qp(p,prec)(0) if check: @@ -1755,7 +1755,7 @@ def regv(vec): return M.determinant() - def Dp_pairing(vec1,vec2): + def Dp_pairing(vec1, vec2): return (vec1[0]*vec2[1]-vec1[1]*vec2[0]) omega_vec = vector([K(1),K(0)]) diff --git a/src/sage/schemes/generic/divisor.py b/src/sage/schemes/generic/divisor.py index 441efbf36e7..0099a74b86c 100755 --- a/src/sage/schemes/generic/divisor.py +++ b/src/sage/schemes/generic/divisor.py @@ -53,7 +53,7 @@ lazy_import('sage.schemes.generic.morphism', 'SchemeMorphism') -def CurvePointToIdeal(C,P): +def CurvePointToIdeal(C, P): r""" Return the vanishing ideal of a point on a curve. diff --git a/src/sage/schemes/generic/morphism.py b/src/sage/schemes/generic/morphism.py index 56bfb8da197..51906d804eb 100755 --- a/src/sage/schemes/generic/morphism.py +++ b/src/sage/schemes/generic/morphism.py @@ -246,7 +246,7 @@ def __call__(self, x, *args, **kwds): converter = D._internal_coerce_map_from(P) if converter is None: try: - return self.pushforward(x,*args,**kwds) + return self.pushforward(x, *args, **kwds) except (AttributeError, TypeError, NotImplementedError): pass # raise TypeError, "%s must be coercible into %s"%(x, self.domain()) # Here, we would like to do diff --git a/src/sage/schemes/hyperelliptic_curves/jacobian_morphism.py b/src/sage/schemes/hyperelliptic_curves/jacobian_morphism.py index c0cbccd84ea..8194f25f45c 100755 --- a/src/sage/schemes/hyperelliptic_curves/jacobian_morphism.py +++ b/src/sage/schemes/hyperelliptic_curves/jacobian_morphism.py @@ -211,7 +211,7 @@ def cantor_reduction(a, b, f, h, genus): return (a, b) -def cantor_composition_simple(D1,D2,f,genus): +def cantor_composition_simple(D1, D2, f, genus): r""" Given `D_1` and `D_2` two reduced Mumford divisors on the Jacobian of the curve `y^2 = f(x)`, @@ -270,7 +270,7 @@ def cantor_composition_simple(D1,D2,f,genus): return (a, b) -def cantor_composition(D1,D2,f,h,genus): +def cantor_composition(D1, D2, f, h, genus): r""" EXAMPLES:: @@ -808,7 +808,7 @@ def __neg__(self): D = (polys[0],-polys[1]-(h+polys[0]) % (polys[0])) return JacobianMorphism_divisor_class_field(X, D, check=False) - def _add_(self,other): + def _add_(self, other): r""" Return a Mumford representative of the divisor ``self + other``. diff --git a/src/sage/schemes/projective/projective_point.py b/src/sage/schemes/projective/projective_point.py index 7f941ec6726..c5d6b02c05a 100755 --- a/src/sage/schemes/projective/projective_point.py +++ b/src/sage/schemes/projective/projective_point.py @@ -625,7 +625,7 @@ def normalize_coordinates(self): self.scale_by(-ZZ.one()) self._normalized = True - def dehomogenize(self,n): + def dehomogenize(self, n): r""" Dehomogenizes at the `n`-th coordinate. diff --git a/src/sage/schemes/toric/divisor.py b/src/sage/schemes/toric/divisor.py index 1da707e0cb6..fe043e5dbb0 100755 --- a/src/sage/schemes/toric/divisor.py +++ b/src/sage/schemes/toric/divisor.py @@ -954,7 +954,7 @@ def is_ample(self): sage: fan = Fan(cones=[(0,1), (1,2), (2,3), (3,0)], ....: rays=[(-1,2), (0,1), (1,0), (0,-1)]) sage: F2 = ToricVariety(fan,'u1, u2, u3, u4') - sage: def D(a,b): return a*F2.divisor(2) + b*F2.divisor(3) + sage: def D(a, b): return a*F2.divisor(2) + b*F2.divisor(3) sage: [ (a,b) for a,b in product(range(-3,3), repeat=2) ....: if D(a,b).is_ample() ] [(1, 1), (1, 2), (2, 1), (2, 2)] @@ -1031,7 +1031,7 @@ def is_nef(self): sage: fan = Fan(cones=[(0,1), (1,2), (2,3), (3,0)], ....: rays=[(-1,2), (0,1), (1,0), (0,-1)]) sage: F2 = ToricVariety(fan,'u1, u2, u3, u4') - sage: def D(a,b): return a*F2.divisor(2) + b*F2.divisor(3) + sage: def D(a, b): return a*F2.divisor(2) + b*F2.divisor(3) sage: [ (a,b) for a,b in product(range(-3,3), repeat=2) ....: if D(a,b).is_ample() ] [(1, 1), (1, 2), (2, 1), (2, 2)] diff --git a/src/sage/sets/set_from_iterator.py b/src/sage/sets/set_from_iterator.py index 6f68f1245b8..19d11c7ad85 100644 --- a/src/sage/sets/set_from_iterator.py +++ b/src/sage/sets/set_from_iterator.py @@ -39,7 +39,7 @@ sage: from sage.sets.set_from_iterator import set_from_method sage: class A: ....: @set_from_method - ....: def f(self,n): + ....: def f(self, n): ....: return xsrange(n) sage: a = A() sage: a.f(3) @@ -776,7 +776,7 @@ def __call__(self, *args, **kwds): sage: from sage.sets.set_from_iterator import set_from_method sage: class A: ....: @set_from_method(name = lambda self,n: str(self)*n) - ....: def f(self,n): + ....: def f(self, n): ....: return xsrange(n) ....: def __repr__(self): ....: return "A" diff --git a/src/sage/stats/time_series.pyx b/src/sage/stats/time_series.pyx index e4845126012..8386aabe691 100644 --- a/src/sage/stats/time_series.pyx +++ b/src/sage/stats/time_series.pyx @@ -557,7 +557,7 @@ cdef class TimeSeries: memcpy(v._values + i*T._length, T._values, sizeof(double)*T._length) return v - def autoregressive_fit(self,M): + def autoregressive_fit(self, M): r""" This method fits the time series to an autoregressive process of order ``M``. That is, we assume the process is given by @@ -782,7 +782,7 @@ cdef class TimeSeries: t._values[i] = self._values[i] if self._values[i] >= 0 else -self._values[i] return t - def diffs(self, Py_ssize_t k = 1): + def diffs(self, Py_ssize_t k=1): r""" Return the new time series got by taking the differences of successive terms in the time series. So if ``self`` is the time diff --git a/src/sage/structure/category_object.pyx b/src/sage/structure/category_object.pyx index a72d3fcd887..e0c217a0e3b 100644 --- a/src/sage/structure/category_object.pyx +++ b/src/sage/structure/category_object.pyx @@ -78,7 +78,7 @@ cdef class CategoryObject(SageObject): """ An object in some category. """ - def __init__(self, category = None, base = None): + def __init__(self, category=None, base=None): """ Initialize an object in a category. @@ -722,7 +722,7 @@ cdef class CategoryObject(SageObject): return d - def __setstate__(self,d): + def __setstate__(self, d): try: version = d['_pickle_version'] except KeyError: diff --git a/src/sage/structure/element.pyx b/src/sage/structure/element.pyx index 18a58f46103..14cae09d6f0 100644 --- a/src/sage/structure/element.pyx +++ b/src/sage/structure/element.pyx @@ -4699,7 +4699,7 @@ def coerce_binop(method): sage: from sage.structure.element import coerce_binop sage: class MyRational(Rational): - ....: def __init__(self,value): + ....: def __init__(self, value): ....: self.v = value ....: @coerce_binop ....: def test_add(self, other, keyword='z'): diff --git a/src/sage/structure/parent_base.pyx b/src/sage/structure/parent_base.pyx index 7cef8f692c5..a9c5e80a1a9 100644 --- a/src/sage/structure/parent_base.pyx +++ b/src/sage/structure/parent_base.pyx @@ -28,7 +28,7 @@ cdef class ParentWithBase(Parent_old): Parent_old.__init__(self, *args, **kwds) self._base = base - cdef _coerce_c_impl(self,x): + cdef _coerce_c_impl(self, x): check_old_coerce(self) from sage.misc.superseded import deprecation deprecation(33497, "_coerce_c_impl is deprecated, use coerce instead") diff --git a/src/sage/structure/unique_representation.py b/src/sage/structure/unique_representation.py index c7bb3783658..d5208beb1ea 100644 --- a/src/sage/structure/unique_representation.py +++ b/src/sage/structure/unique_representation.py @@ -763,7 +763,7 @@ class CachedRepresentation(WithPicklingByInitArgs): implementation does not work:: sage: class MyClass3(CachedRepresentation): - ....: def __init__(self, value = 3): + ....: def __init__(self, value=3): ....: self.value = value sage: MyClass3(3) is MyClass3() False @@ -772,7 +772,7 @@ class CachedRepresentation(WithPicklingByInitArgs): sage: class MyClass3(UniqueRepresentation): ....: @staticmethod - ....: def __classcall__(cls, value = 3): + ....: def __classcall__(cls, value=3): ....: return super().__classcall__(cls, value) ....: ....: def __init__(self, value): @@ -1130,7 +1130,7 @@ def _clear_cache_(cls): sage: class B(A): ....: @staticmethod ....: def __classcall__(cls, *args, **kwds): - ....: return super().__classcall__(cls,*args,**kwds) + ....: return super().__classcall__(cls, *args, **kwds) sage: class C(B): pass sage: a = A(1) sage: b = B(2) @@ -1163,7 +1163,7 @@ def _clear_cache_(cls): ....: @staticmethod ....: def __classcall_private__(cls, *args, **kwds): ....: print("Private B") - ....: return super().__classcall__(cls,*args,**kwds) + ....: return super().__classcall__(cls, *args, **kwds) sage: class C(B): pass sage: a = A(1) sage: b = B(2) diff --git a/src/sage/symbolic/benchmark.py b/src/sage/symbolic/benchmark.py index 89a62a422c6..b8b98948c04 100644 --- a/src/sage/symbolic/benchmark.py +++ b/src/sage/symbolic/benchmark.py @@ -19,7 +19,7 @@ Problem R2:: - sage: def hermite(n,y): + sage: def hermite(n, y): ....: if n == 1: return 2*y ....: if n == 0: return 1 ....: return expand(2*y*hermite(n-1,y) - 2*(n-1)*hermite(n-2,y)) @@ -37,7 +37,7 @@ Problem R5:: - sage: def blowup(L,n): + sage: def blowup(L, n): ....: for i in [0..n]: ....: L.append( (L[i] + L[i+1]) * L[i+2] ) sage: L = list(var('x,y,z')) diff --git a/src/sage/symbolic/expression.pyx b/src/sage/symbolic/expression.pyx index f221fd64de0..52da8232dc6 100644 --- a/src/sage/symbolic/expression.pyx +++ b/src/sage/symbolic/expression.pyx @@ -10010,7 +10010,7 @@ cdef class Expression(Expression_abc): sig_off() return new_Expression_from_GEx(self._parent, r) - def numerator(self, bint normalize = True): + def numerator(self, bint normalize=True): """ Return the numerator of this symbolic expression. @@ -11018,7 +11018,7 @@ cdef class Expression(Expression_abc): trig_simplify = simplify_trig - def simplify_rational(self,algorithm='full', map=False): + def simplify_rational(self, algorithm='full', map=False): r""" Simplify rational expressions. @@ -11604,7 +11604,7 @@ cdef class Expression(Expression_abc): log_simplify = simplify_log - def expand_log(self,algorithm='products'): + def expand_log(self, algorithm='products'): r""" Simplify symbolic expression, which can contain logs. diff --git a/src/sage/symbolic/function.pyx b/src/sage/symbolic/function.pyx index 362d01ea297..86860237d5b 100644 --- a/src/sage/symbolic/function.pyx +++ b/src/sage/symbolic/function.pyx @@ -1294,7 +1294,7 @@ cdef class SymbolicFunction(Function): sage: t(x, y) foo(x, y) - sage: def ev(self, x,y): return 2*x + sage: def ev(self, x, y): return 2*x sage: foo = function("foo", nargs=2, eval_func=ev) # needs sage.symbolic sage: foo.__getstate__() # needs sage.symbolic (2, 'foo', 2, None, {}, True, diff --git a/src/sage/symbolic/function_factory.py b/src/sage/symbolic/function_factory.py index 057d1e07811..1918e166443 100644 --- a/src/sage/symbolic/function_factory.py +++ b/src/sage/symbolic/function_factory.py @@ -270,7 +270,7 @@ def function(s, **kwds) -> SymbolicFunction | list[SymbolicFunction]: sage: foo(x).conjugate() 2*x - sage: def deriv(self, *args,**kwds): + sage: def deriv(self, *args, **kwds): ....: print("{} {}".format(args, kwds)) ....: return args[kwds['diff_param']]^2 sage: foo = function("foo", nargs=2, derivative_func=deriv) diff --git a/src/sage/symbolic/ring.pyx b/src/sage/symbolic/ring.pyx index 32afe8d3a62..65fccee5324 100644 --- a/src/sage/symbolic/ring.pyx +++ b/src/sage/symbolic/ring.pyx @@ -675,7 +675,7 @@ cdef class SymbolicRing(sage.rings.abc.SymbolicRing): Simple definition of a functional derivative:: - sage: def functional_derivative(expr,f,x): + sage: def functional_derivative(expr, f, x): ....: with SR.temp_var() as a: ....: return expr.subs({f(x):a}).diff(a).subs({a:f(x)}) sage: f = function('f') @@ -686,7 +686,7 @@ cdef class SymbolicRing(sage.rings.abc.SymbolicRing): Contrast this to a similar implementation using SR.var(), which gives a wrong result in our example:: - sage: def functional_derivative(expr,f,x): + sage: def functional_derivative(expr, f, x): ....: a = SR.var('a') ....: return expr.subs({f(x):a}).diff(a).subs({a:f(x)}) sage: f = function('f') diff --git a/src/sage/tensor/modules/tensor_with_indices.py b/src/sage/tensor/modules/tensor_with_indices.py index e65277935a7..be7c88a859c 100644 --- a/src/sage/tensor/modules/tensor_with_indices.py +++ b/src/sage/tensor/modules/tensor_with_indices.py @@ -937,7 +937,7 @@ def permute_indices(self, permutation): swap_params = list(combinations(range(self._tensor.tensor_rank()+1), 3)) # The associated permutation is as follows - def swap(param,N): + def swap(param, N): i,j,k = param L = list(range(1,N+1)) L = L[:i] + L[j:k] + L[i:j] + L[k:] diff --git a/src/sage/tests/book_schilling_zabrocki_kschur_primer.py b/src/sage/tests/book_schilling_zabrocki_kschur_primer.py index 69f1e2a1dca..2358c98039d 100644 --- a/src/sage/tests/book_schilling_zabrocki_kschur_primer.py +++ b/src/sage/tests/book_schilling_zabrocki_kschur_primer.py @@ -384,9 +384,9 @@ Sage example in ./kschurnotes/notes-mike-anne.tex, line 2487:: sage: Sym = SymmetricFunctions(QQ) - sage: ks = Sym.kschur(3,t=1) + sage: ks = Sym.kschur(3, t=1) sage: h = Sym.homogeneous() - sage: for mu in Partitions(7, max_part =3): + sage: for mu in Partitions(7, max_part=3): ....: print(h(ks(mu))) h[3, 3, 1] h[3, 2, 2] - h[3, 3, 1] diff --git a/src/sage/tests/book_stein_ent.py b/src/sage/tests/book_stein_ent.py index a4b7632705f..970b377e962 100644 --- a/src/sage/tests/book_stein_ent.py +++ b/src/sage/tests/book_stein_ent.py @@ -206,9 +206,9 @@ ....: if gcd(e,phi_n) == 1: break ....: d = lift(Mod(e,phi_n)^(-1)) ....: return e, d, n -sage: def encrypt(m,e,n): +sage: def encrypt(m, e, n): ....: return lift(Mod(m,n)^e) -sage: def decrypt(c,d,n): +sage: def decrypt(c, d, n): ....: return lift(Mod(c,n)^d) sage: e,d,n = rsa(20) sage: c = encrypt(123, e, n) @@ -348,7 +348,7 @@ 1 sage: 1/zeta -zeta^3 - zeta^2 - zeta - 1 -sage: def gauss_sum(a,p): +sage: def gauss_sum(a, p): ....: K. = CyclotomicField(p) ....: return sum(legendre_symbol(n,p) * zeta^(a*n) for n in range(1,p)) sage: g2 = gauss_sum(2,5); g2 @@ -527,7 +527,7 @@ ....: y3^2 - (x3^3 + a*x3 + b)] ... sage: Q = R.quotient(rels) -sage: def op(P1,P2): +sage: def op(P1, P2): ....: x1,y1 = P1; x2,y2 = P2 ....: lam = (y1 - y2)/(x1 - x2); nu = y1 - lam*x1 ....: x3 = lam^2 - x1 - x2; y3 = -lam*x3 - nu diff --git a/src/sage/tests/books/computational-mathematics-with-sagemath/combinat_doctest.py b/src/sage/tests/books/computational-mathematics-with-sagemath/combinat_doctest.py index 08a76fd6dfb..aaa1ef87842 100644 --- a/src/sage/tests/books/computational-mathematics-with-sagemath/combinat_doctest.py +++ b/src/sage/tests/books/computational-mathematics-with-sagemath/combinat_doctest.py @@ -704,7 +704,7 @@ Sage example in ./combinat.tex, line 2130:: - sage: def words(alphabet,l): + sage: def words(alphabet, l): ....: if l == 0: yield [] ....: else: ....: for word in words(alphabet, l-1): diff --git a/src/sage/tests/books/computational-mathematics-with-sagemath/float_doctest.py b/src/sage/tests/books/computational-mathematics-with-sagemath/float_doctest.py index 7b6587ecaf6..e283c56c74b 100644 --- a/src/sage/tests/books/computational-mathematics-with-sagemath/float_doctest.py +++ b/src/sage/tests/books/computational-mathematics-with-sagemath/float_doctest.py @@ -188,7 +188,7 @@ Sage example in ./float.tex, line 1072:: - sage: def iter(y,delta,a,n): + sage: def iter(y, delta, a, n): ....: for i in range(0,n): ....: y += delta ....: delta *= a @@ -196,7 +196,7 @@ Sage example in ./float.tex, line 1087:: - sage: def exact(y,delta,a,n): + sage: def exact(y, delta, a, n): ....: return y+delta*(1-a^n)/(1-a) Sage example in ./float.tex, line 1106:: @@ -209,7 +209,7 @@ Sage example in ./float.tex, line 1128:: - sage: def sumcomp(y,delta,e,n,a): + sage: def sumcomp(y, delta, e, n, a): ....: for i in range(0,n): ....: b = y ....: e += delta @@ -357,7 +357,7 @@ Sage example in ./float.tex, line 1975:: - sage: def bisect(funct,x,tol,zeros): + sage: def bisect(funct, x, tol, zeros): ....: if 0 in funct(x): ....: if x.diameter()>tol: ....: x1,x2 = x.bisection() @@ -388,7 +388,7 @@ Sage example in ./float.tex, line 2022:: - sage: def NearlySingularMatrix(R,n): + sage: def NearlySingularMatrix(R, n): ....: M=matrix(R,n,n) ....: for i in range(0,n): ....: for j in range(0,n): @@ -408,7 +408,7 @@ Sage example in ./float.tex, line 2064:: - sage: def tryDet(R,n): + sage: def tryDet(R, n): ....: p = 53 ....: z = True ....: while z: diff --git a/src/sage/tests/books/computational-mathematics-with-sagemath/graphique_doctest.py b/src/sage/tests/books/computational-mathematics-with-sagemath/graphique_doctest.py index 0e79bd37093..8de427630d4 100644 --- a/src/sage/tests/books/computational-mathematics-with-sagemath/graphique_doctest.py +++ b/src/sage/tests/books/computational-mathematics-with-sagemath/graphique_doctest.py @@ -153,7 +153,7 @@ sage: n = 11; L = srange(6, 18, 12 / n); R = srange(3, 9, 6 / n) sage: CI = list(zip(L, R)) # list of initial conditions - sage: def g(x,y): + sage: def g(x, y): ....: v = vector(dX_dt([x, y])) # for a nicer graph, we ....: return v/v.norm() # normalise the vector field sage: x, y = var('x, y') diff --git a/src/sage/tests/books/computational-mathematics-with-sagemath/integration_doctest.py b/src/sage/tests/books/computational-mathematics-with-sagemath/integration_doctest.py index bf0bb747282..5bcd8aa9de6 100644 --- a/src/sage/tests/books/computational-mathematics-with-sagemath/integration_doctest.py +++ b/src/sage/tests/books/computational-mathematics-with-sagemath/integration_doctest.py @@ -226,12 +226,12 @@ Sage example in ./integration.tex, line 1244:: - sage: def f_1(t,y,params): return [y[1],params[0]*(1-y[0]^2)*y[1]-y[0]] + sage: def f_1(t, y, params): return [y[1],params[0]*(1-y[0]^2)*y[1]-y[0]] sage: T.function = f_1 Sage example in ./integration.tex, line 1266:: - sage: def j_1(t,y,params): + sage: def j_1(t, y, params): ....: return [[0, 1], ....: [-2*params[0]*y[0]*y[1]-1, params[0]*(1-y[0]^2)], ....: [0,0]] diff --git a/src/sage/tests/books/computational-mathematics-with-sagemath/linsolve_doctest.py b/src/sage/tests/books/computational-mathematics-with-sagemath/linsolve_doctest.py index e5f90964e0c..00bcd8136a9 100644 --- a/src/sage/tests/books/computational-mathematics-with-sagemath/linsolve_doctest.py +++ b/src/sage/tests/books/computational-mathematics-with-sagemath/linsolve_doctest.py @@ -280,7 +280,7 @@ Sage example in ./linsolve.tex, line 2124:: - sage: def eval(P,x): + sage: def eval(P, x): ....: if len(P) == 0: ....: return 0 ....: else: @@ -288,12 +288,12 @@ Sage example in ./linsolve.tex, line 2133:: - sage: def pscal(P,Q,lx): + sage: def pscal(P, Q, lx): ....: return float(sum(eval(P,s)*eval(Q,s) for s in lx)) Sage example in ./linsolve.tex, line 2139:: - sage: def padd(P,a,Q): + sage: def padd(P, a, Q): ....: for i in range(0,len(Q)): ....: P[i] += a*Q[i] @@ -309,7 +309,7 @@ Sage example in ./linsolve.tex, line 2160:: - sage: def orthopoly(n,x): + sage: def orthopoly(n, x): ....: if n > len(x): ....: raise BadParamsforOrthop(n, len(x)) ....: orth = [[1./sqrt(float(len(x)))]] @@ -384,7 +384,7 @@ sage: from numpy.linalg import * sage: from numpy import array sage: from numpy.random import rand - sage: def power(A,x,N): # power iteration + sage: def power(A, x, N): # power iteration ....: for i in range(N): ....: y = A*x ....: z = y/norm(y) diff --git a/src/sage/tests/books/computational-mathematics-with-sagemath/numbertheory_doctest.py b/src/sage/tests/books/computational-mathematics-with-sagemath/numbertheory_doctest.py index c167763ae2c..486065812a9 100644 --- a/src/sage/tests/books/computational-mathematics-with-sagemath/numbertheory_doctest.py +++ b/src/sage/tests/books/computational-mathematics-with-sagemath/numbertheory_doctest.py @@ -98,7 +98,7 @@ Sage example in ./numbertheory.tex, line 593:: - sage: def harmonic_mod(n,m): + sage: def harmonic_mod(n, m): ....: return add([1/x % m for x in range(1,n+1)]) sage: def harmonic2(n): ....: q = lcm(range(1,n+1)) diff --git a/src/sage/tests/books/computational-mathematics-with-sagemath/recequadiff_doctest.py b/src/sage/tests/books/computational-mathematics-with-sagemath/recequadiff_doctest.py index 8ac271ac7ca..97d2adb5c7a 100644 --- a/src/sage/tests/books/computational-mathematics-with-sagemath/recequadiff_doctest.py +++ b/src/sage/tests/books/computational-mathematics-with-sagemath/recequadiff_doctest.py @@ -340,7 +340,7 @@ Sage example in ./recequadiff.tex, line 1582:: - sage: def cloud(u,n): + sage: def cloud(u, n): ....: L = [[0,u(0)]]; ....: for k in [1..n]: ....: L += [[k,u(k)]] @@ -352,7 +352,7 @@ Sage example in ./recequadiff.tex, line 1619:: - sage: def snail(f,x,u0,n,xmin,xmax): + sage: def snail(f, x, u0, n, xmin, xmax): ....: u = u0 ....: P = plot(x, x, xmin, xmax, color='gray') ....: for i in range(n): diff --git a/src/sage/tests/books/computational-mathematics-with-sagemath/sol/float_doctest.py b/src/sage/tests/books/computational-mathematics-with-sagemath/sol/float_doctest.py index ebec4373196..e762e6d2ca0 100644 --- a/src/sage/tests/books/computational-mathematics-with-sagemath/sol/float_doctest.py +++ b/src/sage/tests/books/computational-mathematics-with-sagemath/sol/float_doctest.py @@ -75,7 +75,7 @@ Sage example in ./sol/float.tex, line 179:: - sage: def recur(x1,x0): + sage: def recur(x1, x0): ....: return 111 - 1130/x1 + 3000/(x0*x1) Sage example in ./sol/float.tex, line 190:: diff --git a/src/sage/tests/books/computational-mathematics-with-sagemath/sol/graphique_doctest.py b/src/sage/tests/books/computational-mathematics-with-sagemath/sol/graphique_doctest.py index 4871ae52f98..a999cc1fdf8 100644 --- a/src/sage/tests/books/computational-mathematics-with-sagemath/sol/graphique_doctest.py +++ b/src/sage/tests/books/computational-mathematics-with-sagemath/sol/graphique_doctest.py @@ -61,7 +61,7 @@ Sage example in ./sol/graphique.tex, line 154:: sage: n = 10; L = srange(6, 18, 12 / n); R = srange(3, 9, 6 / n) - sage: def g(x,y): v = vector(f(x, y)); return v / v.norm() + sage: def g(x, y): v = vector(f(x, y)); return v / v.norm() sage: q = plot_vector_field(g(x, y), (x, 0, 60), (y, 0, 36)) sage: for j in range(n): ....: P = desolve_system_rk4(f(x,y), [x,y], @@ -76,7 +76,7 @@ sage: def dX_dt(X, t=0): return [X[1], 0.5*X[1] - X[0] - X[1]^3] sage: t = srange(0, 40, 0.01); x0 = srange(-2, 2, 0.1); y0 = 2.5 sage: CI = [[i, y0] for i in x0] + [[i, -y0] for i in x0] - sage: def g(x,y): v = vector(dX_dt([x, y])); return v / v.norm() + sage: def g(x, y): v = vector(dX_dt([x, y])); return v / v.norm() sage: x, y = var('x, y'); n = len(CI) sage: q = plot_vector_field(g(x, y), (x, -3, 3), (y, -y0, y0)) sage: for j in range(n): # long time diff --git a/src/sage/tests/books/computational-mathematics-with-sagemath/sol/graphtheory_doctest.py b/src/sage/tests/books/computational-mathematics-with-sagemath/sol/graphtheory_doctest.py index f32f65028af..d6e3834c495 100644 --- a/src/sage/tests/books/computational-mathematics-with-sagemath/sol/graphtheory_doctest.py +++ b/src/sage/tests/books/computational-mathematics-with-sagemath/sol/graphtheory_doctest.py @@ -9,7 +9,7 @@ Sage example in ./sol/graphtheory.tex, line 5:: - sage: def circulant(n,d): + sage: def circulant(n, d): ....: g = Graph(n) ....: for u in range(n): ....: for c in range(d): @@ -18,7 +18,7 @@ Sage example in ./sol/graphtheory.tex, line 19:: - sage: def kneser(n,k): + sage: def kneser(n, k): ....: g = Graph() ....: g.add_vertices(Subsets(n,k)) ....: for u in g: @@ -29,7 +29,7 @@ Sage example in ./sol/graphtheory.tex, line 33:: - sage: def kneser(n,k): + sage: def kneser(n, k): ....: g = Graph() ....: sommets = Set(range(n)) ....: g.add_vertices(Subsets(sommets,k)) diff --git a/src/sage/tests/books/computational-mathematics-with-sagemath/sol/nonlinear_doctest.py b/src/sage/tests/books/computational-mathematics-with-sagemath/sol/nonlinear_doctest.py index a296d48d995..50bd9fd2d2f 100644 --- a/src/sage/tests/books/computational-mathematics-with-sagemath/sol/nonlinear_doctest.py +++ b/src/sage/tests/books/computational-mathematics-with-sagemath/sol/nonlinear_doctest.py @@ -38,7 +38,7 @@ sage: from types import GeneratorType, FunctionType sage: def checklength(u, v, w, prec): ....: return abs(v - u) < 2 * prec - sage: def iterate(series,check=checklength,prec=10^-5,maxit=100): + sage: def iterate(series, check=checklength, prec=10^-5, maxit=100): ....: assert isinstance(series, GeneratorType) ....: assert isinstance(check, FunctionType) ....: niter = 2 diff --git a/src/sage/tests/books/computational-mathematics-with-sagemath/sol/numbertheory_doctest.py b/src/sage/tests/books/computational-mathematics-with-sagemath/sol/numbertheory_doctest.py index 3899766500d..8d4536d89a6 100644 --- a/src/sage/tests/books/computational-mathematics-with-sagemath/sol/numbertheory_doctest.py +++ b/src/sage/tests/books/computational-mathematics-with-sagemath/sol/numbertheory_doctest.py @@ -26,7 +26,7 @@ Sage example in ./sol/numbertheory.tex, line 52:: - sage: def enum_carmichael_pq(n,a,m,p,q,verbose): + sage: def enum_carmichael_pq(n, a, m, p, q, verbose): ....: if (a-q) % gcd(m,q*(q-1)) != 0: return 0 ....: s = 0 ....: a = crt (a, q, m, q*(q-1)); m = lcm(m,q*(q-1)) From e29692d24c45d01c5335754d0a4771465c7f3bd1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gonzalo=20Tornar=C3=ADa?= Date: Sat, 2 Nov 2024 16:34:44 -0300 Subject: [PATCH 402/537] Don't (mis)use `prec_words_to_bits()` We need to remove this function from cypari2, because pari 2.17 has changed precision from words to bits which would cause confusion. Besides, the current usage is incorrect, since `log_pari.precision()` will give the precision in *decimal digits* not in words. --- src/sage/schemes/elliptic_curves/ell_point.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/sage/schemes/elliptic_curves/ell_point.py b/src/sage/schemes/elliptic_curves/ell_point.py index d9b7189552e..8345cd08231 100755 --- a/src/sage/schemes/elliptic_curves/ell_point.py +++ b/src/sage/schemes/elliptic_curves/ell_point.py @@ -142,7 +142,6 @@ try: from sage.libs.pari.all import pari, PariError - from cypari2.pari_instance import prec_words_to_bits except ImportError: PariError = () @@ -3712,7 +3711,7 @@ def elliptic_logarithm(self, embedding=None, precision=100, E_pari = E_work.pari_curve() log_pari = E_pari.ellpointtoz(pt_pari, precision=working_prec) - while prec_words_to_bits(log_pari.precision()) < precision: + while log_pari.bitprecision() < precision: # result is not precise enough, re-compute with double # precision. if the base field is not QQ, this # requires modifying the precision of the embedding, From ea86281dedc1b2213a55b3439fcd8dca459986a2 Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Sun, 3 Nov 2024 12:12:01 +0800 Subject: [PATCH 403/537] Meson: minor revision --- .gitignore | 1 + meson.build | 2 +- src/meson.build | 1 - src/sage/meson.build | 4 ++-- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.gitignore b/.gitignore index 7d8c2f0adc4..c229618b365 100644 --- a/.gitignore +++ b/.gitignore @@ -309,6 +309,7 @@ build-install build/cp* # Meson temporary files +subprojects/wrapdb.json src/sage/interfaces/__init__.py src/sage/crypto/block_cipher/__init__.py src/sage/crypto/public_key/__init__.py diff --git a/meson.build b/meson.build index 8bf73d23d55..ac5594852ff 100644 --- a/meson.build +++ b/meson.build @@ -35,7 +35,7 @@ endif # Workaround for missing init files (Cython doesn't handle namespace packages well) create_files_command = [ - 'python3', + py, '-c', ''' import os diff --git a/src/meson.build b/src/meson.build index 12d82fa91c3..b4d82d96805 100644 --- a/src/meson.build +++ b/src/meson.build @@ -80,7 +80,6 @@ blas_order += ['cblas', 'openblas', 'OpenBLAS', 'flexiblas', 'blis', 'blas'] blas = dependency(blas_order) gsl = dependency( 'gsl', - fallback: ['gsl', 'gsl_dep'], version: '>=2.5', required: true, ) diff --git a/src/sage/meson.build b/src/sage/meson.build index 687ac549c10..e63757e17f4 100644 --- a/src/sage/meson.build +++ b/src/sage/meson.build @@ -6,7 +6,7 @@ conf_data = configuration_data() conf_data.set('PACKAGE_VERSION', '1.2.3') conf_data.set('SAGE_ROOT', meson.current_source_dir() / '..' / '..') # We use Python's prefix here to make it work with conda -prefix = py.get_variable('prefix', '') +prefix = fs.as_posix(py.get_variable('prefix', '')) conf_data.set('prefix', prefix) datadir = fs.expanduser(get_option('datadir')) if not fs.is_absolute(datadir) @@ -56,7 +56,7 @@ ecm_bin = find_program(['ecm', 'gmp-ecm'], required: true) conf_data.set('SAGE_ECMBIN', ecm_bin.full_path()) config_file = configure_file( - input: '../../pkgs/sage-conf_conda/_sage_conf/_conf.py.in', + input: '../../pkgs/sage-conf/_sage_conf/_conf.py.in', output: 'config.py', install_dir: py.get_install_dir() / 'sage', install: true, From 900fbc50057a916c71c9f7622bcbb840e758f8b7 Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Mon, 28 Oct 2024 21:44:24 +0800 Subject: [PATCH 404/537] Replace division by zero with +-inf --- src/sage/rings/integer.pyx | 4 ++-- src/sage/rings/rational.pyx | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/sage/rings/integer.pyx b/src/sage/rings/integer.pyx index 9616e7946bc..291cbb786d7 100644 --- a/src/sage/rings/integer.pyx +++ b/src/sage/rings/integer.pyx @@ -7755,9 +7755,9 @@ cdef double mpz_get_d_nearest(mpz_t x) except? -648555075988944.5: # Check for overflow if sx > 1024: if resultsign < 0: - return -1.0/0.0 + return float('-inf') else: - return 1.0/0.0 + return float('inf') # General case diff --git a/src/sage/rings/rational.pyx b/src/sage/rings/rational.pyx index 272650abeef..bc29e952b1a 100644 --- a/src/sage/rings/rational.pyx +++ b/src/sage/rings/rational.pyx @@ -3993,9 +3993,9 @@ cdef double mpq_get_d_nearest(mpq_t x) except? -648555075988944.5: return 0.0 elif shift >= 971: # |d| > 2^1024 if resultsign < 0: - return -1.0/0.0 + return float('-inf') else: - return 1.0/0.0 + return float('inf') sig_on() From d0e35b2a6ec1e0f6e1f5ce9de1f36a3860f574f9 Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Mon, 28 Oct 2024 21:47:17 +0800 Subject: [PATCH 405/537] Replace deprecated/removed mem_fun_ref ../src/sage/symbolic/ginac/archive.cpp(584): error C2039: 'mem_fun_ref': is not a member of 'std' C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.41.34120\include\sstream(19): note: see declaration of 'std' ../src/sage/symbolic/ginac/archive.cpp(584): error C3861: 'mem_fun_ref': identifier not found ../src/sage/symbolic/ginac/archive.cpp(584): error C2672: 'for_each': no matching overloaded function found --- src/sage/symbolic/ginac/archive.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/symbolic/ginac/archive.cpp b/src/sage/symbolic/ginac/archive.cpp index bd078895da0..0362d397ec1 100644 --- a/src/sage/symbolic/ginac/archive.cpp +++ b/src/sage/symbolic/ginac/archive.cpp @@ -581,7 +581,7 @@ void archive::clear() /** Delete cached unarchived expressions in all archive_nodes (mainly for debugging). */ void archive::forget() { - for_each(nodes.begin(), nodes.end(), std::mem_fun_ref(&archive_node::forget)); + std::for_each(nodes.begin(), nodes.end(), [](archive_node &node) { node.forget(); }); } /** Delete cached unarchived expressions from node (for debugging). */ From cfeac23469d5ebb6079e37955e4a4fa0c4c82aca Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Mon, 28 Oct 2024 22:35:07 +0800 Subject: [PATCH 406/537] Replace `os.uname` by more universal `platform.system` `os.uname` is not available on Windows --- src/sage/doctest/external.py | 4 ++-- src/sage/doctest/forker.py | 3 ++- src/sage/env.py | 2 +- src/sage/interfaces/singular.py | 3 ++- src/sage/misc/viewer.py | 3 ++- src/sage_docbuild/utils.py | 3 ++- src/sage_setup/setenv.py | 6 +++--- 7 files changed, 14 insertions(+), 10 deletions(-) diff --git a/src/sage/doctest/external.py b/src/sage/doctest/external.py index 56727bd79f6..bf0309d3131 100644 --- a/src/sage/doctest/external.py +++ b/src/sage/doctest/external.py @@ -32,12 +32,12 @@ #***************************************************************************** import multiprocessing -import os +import platform # With OS X, Python 3.8 defaults to use 'spawn' instead of 'fork' in # multiprocessing, and Sage doctesting doesn't work with 'spawn'. See # trac #27754. -if os.uname().sysname == 'Darwin': +if platform.system() == 'Darwin': multiprocessing.set_start_method('fork', force=True) Array = multiprocessing.Array diff --git a/src/sage/doctest/forker.py b/src/sage/doctest/forker.py index b69c842836c..bf6d49906de 100644 --- a/src/sage/doctest/forker.py +++ b/src/sage/doctest/forker.py @@ -48,6 +48,7 @@ import os +import platform import sys import time import signal @@ -80,7 +81,7 @@ # With OS X, Python 3.8 defaults to use 'spawn' instead of 'fork' in # multiprocessing, and Sage doctesting doesn't work with 'spawn'. See # trac #27754. -if os.uname().sysname == 'Darwin': +if platform.system() == 'Darwin': multiprocessing.set_start_method('fork', force=True) diff --git a/src/sage/env.py b/src/sage/env.py index c6fb123cc72..38926645069 100644 --- a/src/sage/env.py +++ b/src/sage/env.py @@ -36,6 +36,7 @@ from typing import Optional import sage +import platform import os import socket import sys @@ -165,7 +166,6 @@ def var(key: str, *fallbacks: Optional[str], force: bool = False) -> Optional[st # system info -UNAME = var("UNAME", os.uname()[0]) HOSTNAME = var("HOSTNAME", socket.gethostname()) LOCAL_IDENTIFIER = var("LOCAL_IDENTIFIER", "{}.{}".format(HOSTNAME, os.getpid())) diff --git a/src/sage/interfaces/singular.py b/src/sage/interfaces/singular.py index ed883b07105..3202b314075 100644 --- a/src/sage/interfaces/singular.py +++ b/src/sage/interfaces/singular.py @@ -335,6 +335,7 @@ # **************************************************************************** import os +import platform import re import sys import pexpect @@ -407,7 +408,7 @@ def __init__(self, maxread=None, script_subdirectory=None, restart_on_ctrlc=True, verbose_start=False, logfile=logfile, - eval_using_file_cutoff=100 if os.uname()[0] == "SunOS" else 1000) + eval_using_file_cutoff=100 if platform.system() == "SunOS" else 1000) self.__libs = [] self._prompt_wait = prompt self.__to_clear = [] # list of variable names that need to be cleared. diff --git a/src/sage/misc/viewer.py b/src/sage/misc/viewer.py index badc70a963a..3be9d14609d 100644 --- a/src/sage/misc/viewer.py +++ b/src/sage/misc/viewer.py @@ -26,6 +26,7 @@ --------------------- """ +import platform from sage.structure.sage_object import SageObject @@ -66,7 +67,7 @@ def default_viewer(viewer=None): PDF_VIEWER = BROWSER PNG_VIEWER = BROWSER - elif os.uname()[0] == 'Darwin': + elif platform.system() == 'Darwin': # Simple on OS X, since there is an open command that opens # anything, using the user's preferences. BROWSER = 'open -W' diff --git a/src/sage_docbuild/utils.py b/src/sage_docbuild/utils.py index 50b54b2aa6b..f34c65b10e1 100644 --- a/src/sage_docbuild/utils.py +++ b/src/sage_docbuild/utils.py @@ -4,6 +4,7 @@ import errno import os +import platform import traceback from typing import Optional @@ -193,7 +194,7 @@ def build_many(target, args, processes=None): # With OS X, Python 3.8 defaults to use 'spawn' instead of 'fork' # in multiprocessing, and Sage docbuilding doesn't work with # 'spawn'. See trac #27754. - if os.uname().sysname == "Darwin": + if platform.system() == "Darwin": set_start_method("fork", force=True) from queue import Empty diff --git a/src/sage_setup/setenv.py b/src/sage_setup/setenv.py index b868360d612..48a38afad74 100644 --- a/src/sage_setup/setenv.py +++ b/src/sage_setup/setenv.py @@ -1,7 +1,7 @@ # Set some environment variables in the running process import os -import sage.env +import platform from pathlib import Path def _environ_prepend(var, value, separator=':'): @@ -12,7 +12,7 @@ def _environ_prepend(var, value, separator=':'): os.environ[var] = value def setenv(): - from sage.env import UNAME, SAGE_LOCAL, SAGE_VENV, SAGE_ARCHFLAGS, SAGE_PKG_CONFIG_PATH + from sage.env import SAGE_LOCAL, SAGE_VENV, SAGE_ARCHFLAGS, SAGE_PKG_CONFIG_PATH ## ## from sage-env: @@ -32,7 +32,7 @@ def setenv(): _environ_prepend('CPATH', f'{SAGE_LOCAL}/include') _environ_prepend('LDFLAGS', f'-L{SAGE_LOCAL}/lib -Wl,-rpath,{SAGE_LOCAL}/lib', separator=' ') - if UNAME == 'Linux': + if platform.system() == 'Linux': _environ_prepend('LDFLAGS', f'-Wl,-rpath-link,{SAGE_LOCAL}/lib', separator=' ') if Path(SAGE_VENV).resolve() != Path(SAGE_LOCAL).resolve(): From ee7d19680e185cff2ec560e6fa9f42fe7c7f81e3 Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Mon, 28 Oct 2024 21:50:30 +0800 Subject: [PATCH 407/537] Remove `register` macro in Ginac C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.41.34120\include\xkeycheck.h(341): warning C4005: 'register': macro redefinition ../src/sage/symbolic/ginac/constant.cpp(23): note: see previous definition of 'register' C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.41.34120\include\xkeycheck.h(343): fatal error C1189: #error: The C++ Standard Library forbids macroizing the keyword "register". Enable warning C4005 to find the forbidden define. --- src/sage/symbolic/ginac/constant.cpp | 1 - src/sage/symbolic/ginac/ex.cpp | 1 - src/sage/symbolic/ginac/fderivative.cpp | 1 - src/sage/symbolic/ginac/function.cpp | 1 - src/sage/symbolic/ginac/inifcns_hyperg.cpp | 1 - src/sage/symbolic/ginac/numeric.cpp | 1 - 6 files changed, 6 deletions(-) diff --git a/src/sage/symbolic/ginac/constant.cpp b/src/sage/symbolic/ginac/constant.cpp index 64e225f0213..f768e021c4e 100644 --- a/src/sage/symbolic/ginac/constant.cpp +++ b/src/sage/symbolic/ginac/constant.cpp @@ -20,7 +20,6 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#define register #include #include "py_funcs.h" #include "constant.h" diff --git a/src/sage/symbolic/ginac/ex.cpp b/src/sage/symbolic/ginac/ex.cpp index a4783ab0c8b..d4f077153dc 100644 --- a/src/sage/symbolic/ginac/ex.cpp +++ b/src/sage/symbolic/ginac/ex.cpp @@ -20,7 +20,6 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#define register #include #include "ex.h" #include "ex_utils.h" diff --git a/src/sage/symbolic/ginac/fderivative.cpp b/src/sage/symbolic/ginac/fderivative.cpp index a47db8823f3..8621ba598a8 100644 --- a/src/sage/symbolic/ginac/fderivative.cpp +++ b/src/sage/symbolic/ginac/fderivative.cpp @@ -20,7 +20,6 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#define register #include #include "py_funcs.h" #include "fderivative.h" diff --git a/src/sage/symbolic/ginac/function.cpp b/src/sage/symbolic/ginac/function.cpp index 67d608c6240..62824b46946 100644 --- a/src/sage/symbolic/ginac/function.cpp +++ b/src/sage/symbolic/ginac/function.cpp @@ -20,7 +20,6 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#define register #define PY_SSIZE_T_CLEAN #include #include "py_funcs.h" diff --git a/src/sage/symbolic/ginac/inifcns_hyperg.cpp b/src/sage/symbolic/ginac/inifcns_hyperg.cpp index 1ad2ff785b1..a1c037fc96d 100644 --- a/src/sage/symbolic/ginac/inifcns_hyperg.cpp +++ b/src/sage/symbolic/ginac/inifcns_hyperg.cpp @@ -23,7 +23,6 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#define register #include #include "py_funcs.h" #include "inifcns.h" diff --git a/src/sage/symbolic/ginac/numeric.cpp b/src/sage/symbolic/ginac/numeric.cpp index a9bbfba9e15..e973390ffa2 100644 --- a/src/sage/symbolic/ginac/numeric.cpp +++ b/src/sage/symbolic/ginac/numeric.cpp @@ -49,7 +49,6 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#define register #define PY_SSIZE_T_CLEAN #include #include "flint/fmpz.h" From 7f2d945bf2827bd55739987138eb338e8127b17d Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Mon, 28 Oct 2024 21:45:14 +0800 Subject: [PATCH 408/537] Fix Ginac cast error ../src/sage/symbolic/ginac/upoly-ginac.cpp(219): error C2440: '': cannot convert from 'size_t' to 'GiNaC::numeric' ../src/sage/symbolic/ginac/upoly-ginac.cpp(219): note: 'GiNaC::numeric::numeric': ambiguous call to overloaded function --- src/sage/symbolic/ginac/upoly-ginac.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/sage/symbolic/ginac/upoly-ginac.cpp b/src/sage/symbolic/ginac/upoly-ginac.cpp index b51ec3be8f8..3c45c686e82 100644 --- a/src/sage/symbolic/ginac/upoly-ginac.cpp +++ b/src/sage/symbolic/ginac/upoly-ginac.cpp @@ -216,12 +216,12 @@ std::pair quo_rem(const ex &a, const ex &b, const ex &x, bool check_args) } for (size_t i=0; i(i))); if (avec.size() > bdeg) avec.resize(bdeg); for (size_t i=0; i(i))); return std::make_pair(add(qvec), add(avec)); } @@ -565,7 +565,7 @@ ex parfrac(const ex & a, const ex & x) return a; size_t expo = ex_to(ee).to_int(); for (size_t j=1; j<=expo; ++j) { - ex eee = power(e.op(0), numeric(j)); + ex eee = power(e.op(0), numeric(static_cast(j))); factor.push_back(eee); cofac.push_back((facmul/eee).expand()); } @@ -582,7 +582,7 @@ ex parfrac(const ex & a, const ex & x) return a; size_t expo = ex_to(facmul.op(1)).to_int(); for (size_t j=1; j<=expo; ++j) { - ex ee = power(facmul.op(0), numeric(j)); + ex ee = power(facmul.op(0), numeric(static_cast(j))); factor.push_back(ee); cofac.push_back((facmul/ee).expand()); } From e7327ecdfe364c54d314f73e2a52812ebac3f2ca Mon Sep 17 00:00:00 2001 From: Volker Braun Date: Sun, 3 Nov 2024 12:05:24 +0100 Subject: [PATCH 409/537] Allow optional elliptic curve data from database_cremona_ellcurve If the optional db in istalled, then extra data is passed to the elliptic curve constructor. Recently unexpected keyword arguments were changed to an exception, without taking the optional package into account. Caused by https://github.com/sagemath/sage/pull/38361 --- src/sage/schemes/elliptic_curves/ell_rational_field.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/sage/schemes/elliptic_curves/ell_rational_field.py b/src/sage/schemes/elliptic_curves/ell_rational_field.py index d00187d49a2..d124d017e6b 100755 --- a/src/sage/schemes/elliptic_curves/ell_rational_field.py +++ b/src/sage/schemes/elliptic_curves/ell_rational_field.py @@ -203,6 +203,9 @@ def __init__(self, ainvs, **kwds): self.__regulator = (kwds.pop('regulator'), True) if 'torsion_order' in kwds: self._set_torsion_order(kwds.pop('torsion_order')) + if 'db_extra' in kwds: + # optional data provided by database_cremona_ellcurve + self.db_extra = kwds.pop('db_extra') if kwds: raise TypeError(f"unexpected keyword arguments: {kwds}") From 3042cfd81dd5f13be6236a44ba294b427db6e33c Mon Sep 17 00:00:00 2001 From: dcoudert Date: Sun, 3 Nov 2024 17:56:12 +0100 Subject: [PATCH 410/537] fix issue 38900: preserve backend with unpikling --- src/sage/graphs/base/graph_backends.pyx | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/src/sage/graphs/base/graph_backends.pyx b/src/sage/graphs/base/graph_backends.pyx index 4363a812995..bb07f948d4f 100644 --- a/src/sage/graphs/base/graph_backends.pyx +++ b/src/sage/graphs/base/graph_backends.pyx @@ -668,6 +668,8 @@ cdef class GenericGraphBackend(SageObject): produces a copy of ``self``. The function returned is always :func:`unpickle_graph_backend`. + EXAMPLES: + Pickling of the static graph backend makes pickling of immutable graphs and digraphs work:: @@ -703,20 +705,30 @@ cdef class GenericGraphBackend(SageObject): sage: gi = g.copy(immutable=True) sage: loads(dumps(gi)) == gi True + + TESTS: + + Check that :issue:`38900` is fixed: + + sage: from itertools import product + sage: for sparse, immutable in product([True, False], [True, False]): + ....: G = Graph([[0, 1, 2], [(0, 1)]], sparse=sparse, immutable=immutable) + ....: H = loads(dumps(G)) + ....: if type(G._backend) != type(H._backend): + ....: print(sparse, immutable, type(G._backend), type(H._backend)) """ from sage.graphs.base.static_sparse_backend import StaticSparseBackend from sage.graphs.base.sparse_graph import SparseGraphBackend from sage.graphs.base.dense_graph import DenseGraphBackend - # implementation, data_structure, multiedges, directed, loops + # data_structure, multiedges, directed, loops if isinstance(self, CGraphBackend): - implementation = "c_graph" if isinstance(self, SparseGraphBackend): data_structure = "sparse" elif isinstance(self, DenseGraphBackend): data_structure = "dense" elif isinstance(self, StaticSparseBackend): - implementation = "static_sparse" + data_structure = "static_sparse" else: raise Exception multiedges = ( self)._multiple_edges @@ -735,7 +747,8 @@ cdef class GenericGraphBackend(SageObject): return (unpickle_graph_backend, (directed, vertices, edges, {'loops': loops, - 'multiedges': multiedges})) + 'multiedges': multiedges, + 'data_structure': data_structure})) def unpickle_graph_backend(directed, vertices, edges, kwds): @@ -779,6 +792,5 @@ def unpickle_graph_backend(directed, vertices, edges, kwds): else: from sage.graphs.graph import Graph as constructor - G = constructor(data=edges, **kwds) - G.add_vertices(vertices) + G = constructor(data=[vertices, edges], format='vertices_and_edges', **kwds) return G._backend From 00535fe30057fe7e4c33ddeb76dab224307089e3 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Mon, 4 Nov 2024 10:49:39 +0530 Subject: [PATCH 411/537] Resolved PEP8 changes --- src/sage/matroids/chow_ring.py | 8 +++++--- src/sage/matroids/chow_ring_ideal.py | 12 ++++++------ src/sage/matroids/matroid.pyx | 9 +++++---- 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/src/sage/matroids/chow_ring.py b/src/sage/matroids/chow_ring.py index 57c20813edd..1b7c651fc08 100644 --- a/src/sage/matroids/chow_ring.py +++ b/src/sage/matroids/chow_ring.py @@ -109,12 +109,14 @@ def _repr_(self): sage: ch Chow ring of Fano: Binary matroid of rank 3 on 7 elements, type (3, 0) """ + output = "Chow ring of {}".format(self._matroid) if self._augmented is True: + output = "Augmented " + output if self._presentation == 'fy': - return "Augmented Chow ring of {} in Feitchner-Yuzvinsky presentation".format(self._matroid) + output += "Feitchner-Yuzvinsky presentation" elif self._presentation == 'atom-free': - return "Augmented Chow ring of {} in atom-free presentation".format(self._matroid) - return "Chow ring of {}".format(self._matroid) + output += "atom-free presentation" + return output + " over " + repr(self.base_ring()) def _latex_(self): r""" diff --git a/src/sage/matroids/chow_ring_ideal.py b/src/sage/matroids/chow_ring_ideal.py index 760d35341d4..7199b0478f5 100644 --- a/src/sage/matroids/chow_ring_ideal.py +++ b/src/sage/matroids/chow_ring_ideal.py @@ -165,12 +165,12 @@ def _gens_constructor(self, poly_ring): term *= self._flats_generator[el] I.append(term) #Stanley-Reisner Ideal atoms = self._matroid.lattice_of_flats().atoms() - atoms_gen = {a:poly_ring.zero() for a in atoms} + atoms_gen = {a: poly_ring.zero() for a in atoms} for F in flats: for a in atoms: if a.issubset(F): atoms_gen[a] += self._flats_generator[F] - J = list(atoms_gen.values()) #Linear Generators + J = list(atoms_gen.values()) # Linear generators return I + J def _repr_(self): @@ -457,7 +457,7 @@ def _gens_constructor(self, poly_ring): Q.append(self._flats_generator[x] * self._flats_generator[F]) else: term += self._flats_generator[F] - L.append(self._flats_generator[x] + term) #Linear Generators + L.append(self._flats_generator[x] + term) # Linear generators L.append(term1) return Q + L @@ -672,14 +672,14 @@ def _gens_constructor(self, poly_ring): for F, G in antichains: Q.append(self._flats_generator[F] * self._flats_generator[G]) for F in self._flats: - for x in E: # generators for every set of flats containing element + for x in E: # generators for every set of flats containing element term = poly_ring.zero() for H in flats_containing[x]: term += self._flats_generator[H] if term**2 not in Q: Q.append(term**2) - if F not in flats_containing[x]: #generators for every set of flats not containing element + if F not in flats_containing[x]: # generators for every set of flats not containing element Q.append(self._flats_generator[F]*term) return Q @@ -789,7 +789,7 @@ def normal_basis(self, algorithm='', *args, **kwargs): ranges[0] = range(1, max_powers[0] + 1) first_rank = ranks[subset[k-1]] + 1 for combination in product(*(r for r in ranges)): - #Generating combinations for all powers from 1 to max_powers + # Generating combinations for all powers from 1 to max_powers if sum(combination) <= first_rank: expression = R.one() for val, c in zip(subset, combination): diff --git a/src/sage/matroids/matroid.pyx b/src/sage/matroids/matroid.pyx index 56135b71821..8f680bdd0c0 100644 --- a/src/sage/matroids/matroid.pyx +++ b/src/sage/matroids/matroid.pyx @@ -8041,10 +8041,11 @@ cdef class Matroid(SageObject): - ``M`` -- matroid - ``R`` -- commutative ring - - ``augmented`` -- boolean; when ``True``, this is the augmented - Chow ring and if ``False``, this is the non-augmented Chow ring - - ``presentation`` -- string (default: ``None``); one of the following - (ignored if ``augmented=False``) + - ``augmented`` -- boolean (default: ``False``); when ``True``, this + is the augmented Chow ring and if ``False``, this is the + non-augmented Chow ring + - ``presentation`` -- string; if ``augmented=True``, then this + must be one of the following (ignored if ``augmented=False``): * ``"fy"`` - the Feitchner-Yuzvinsky presentation * ``"atom-free"`` - the atom-free presentation From de683a8118384b3e30f85fb09018d70cb414afda Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Mon, 4 Nov 2024 11:00:15 +0530 Subject: [PATCH 412/537] added multiplication table --- src/sage/matroids/matroid.pyx | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/sage/matroids/matroid.pyx b/src/sage/matroids/matroid.pyx index 8f680bdd0c0..e81d035848b 100644 --- a/src/sage/matroids/matroid.pyx +++ b/src/sage/matroids/matroid.pyx @@ -8064,8 +8064,18 @@ cdef class Matroid(SageObject): We construct a more interesting example using the Fano matroid:: sage: M = matroids.catalog.Fano() - sage: A = M.chow_ring(QQ, augmented=False); A + sage: A = M.chow_ring(QQ); A Chow ring of Fano: Binary matroid of rank 3 on 7 elements, type (3, 0) + sage: G = A.gens()[6:] + sage: matrix([[x * y for x in G] for y in G]) + [2*Adef^2 0 0 -Adef^2 0 -Adef^2 -Adef^2 0] + [ 0 Adef^2 0 0 0 0 0 0] + [ 0 0 Adef^2 0 0 0 0 0] + [ -Adef^2 0 0 Adef^2 0 0 0 0] + [ 0 0 0 0 Adef^2 0 0 0] + [ -Adef^2 0 0 0 0 Adef^2 0 0] + [ -Adef^2 0 0 0 0 0 Adef^2 0] + [ 0 0 0 0 0 0 0 Adef^2] The augmented Chow ring can also be constructed with the Feitchner-Yuzvinsky and atom-free presentation:: From 0f85f745c6639b53d15fa3fae126c070ced749f8 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Mon, 4 Nov 2024 11:04:09 +0530 Subject: [PATCH 413/537] Added computations --- src/sage/matroids/matroid.pyx | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/sage/matroids/matroid.pyx b/src/sage/matroids/matroid.pyx index e81d035848b..c6b763ba44c 100644 --- a/src/sage/matroids/matroid.pyx +++ b/src/sage/matroids/matroid.pyx @@ -8066,7 +8066,13 @@ cdef class Matroid(SageObject): sage: M = matroids.catalog.Fano() sage: A = M.chow_ring(QQ); A Chow ring of Fano: Binary matroid of rank 3 on 7 elements, type (3, 0) - sage: G = A.gens()[6:] + sage: G = A.gens()[6:]; G + (Ag, Aabf, Aace, Aadg, Abcd, Abeg, Acfg, Adef) + sage: Ag, Aabf, Aace, Aadg, Abcd, Abeg, Acfg, Adef = G + sage: Ag*Ag + 2*Adef^2 + sage: Ag*Abeg + -Adef^2 sage: matrix([[x * y for x in G] for y in G]) [2*Adef^2 0 0 -Adef^2 0 -Adef^2 -Adef^2 0] [ 0 Adef^2 0 0 0 0 0 0] From 6ca02bb3082f1b38484f856fa825c2149c977952 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Mon, 4 Nov 2024 11:40:16 +0530 Subject: [PATCH 414/537] Edited repr() doctests --- src/sage/matroids/chow_ring.py | 8 +++++--- src/sage/matroids/matroid.pyx | 9 ++++++--- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/sage/matroids/chow_ring.py b/src/sage/matroids/chow_ring.py index 1b7c651fc08..86fcc36dd8c 100644 --- a/src/sage/matroids/chow_ring.py +++ b/src/sage/matroids/chow_ring.py @@ -70,10 +70,11 @@ class ChowRing(QuotientRing_generic): EXAMPLES:: - sage: M1 = matroids.catalog.P8pp() #more examples + sage: M1 = matroids.catalog.P8pp() sage: ch = M1.chow_ring(QQ, False) sage: ch Chow ring of P8'': Matroid of rank 4 on 8 elements with 8 nonspanning circuits + over Rational Field """ def __init__(self, R, M, augmented, presentation=None): r""" @@ -108,14 +109,15 @@ def _repr_(self): sage: ch = M1.chow_ring(QQ, False) sage: ch Chow ring of Fano: Binary matroid of rank 3 on 7 elements, type (3, 0) + over Rational Field """ output = "Chow ring of {}".format(self._matroid) if self._augmented is True: output = "Augmented " + output if self._presentation == 'fy': - output += "Feitchner-Yuzvinsky presentation" + output += " in Feitchner-Yuzvinsky presentation" elif self._presentation == 'atom-free': - output += "atom-free presentation" + output += " in atom-free presentation" return output + " over " + repr(self.base_ring()) def _latex_(self): diff --git a/src/sage/matroids/matroid.pyx b/src/sage/matroids/matroid.pyx index 7e4402b9111..c0c98a26150 100644 --- a/src/sage/matroids/matroid.pyx +++ b/src/sage/matroids/matroid.pyx @@ -8060,7 +8060,8 @@ cdef class Matroid(SageObject): sage: M = matroids.Wheel(2) sage: A = M.chow_ring(R=ZZ, augmented=False); A - Chow ring of Wheel(2): Regular matroid of rank 2 on 4 elements with 5 bases + Chow ring of Wheel(2): Regular matroid of rank 2 on 4 elements with + 5 bases over Integer Ring sage: A.defining_ideal()._gens_constructor(A.defining_ideal().ring()) [A0*A1, A0*A23, A1*A23, A0 + A0123, A1 + A0123, A23 + A0123] sage: A23 = A.gen(0) @@ -8072,6 +8073,7 @@ cdef class Matroid(SageObject): sage: M = matroids.catalog.Fano() sage: A = M.chow_ring(QQ); A Chow ring of Fano: Binary matroid of rank 3 on 7 elements, type (3, 0) + over Rational Field sage: G = A.gens()[6:]; G (Ag, Aabf, Aace, Aadg, Abcd, Abeg, Acfg, Adef) sage: Ag, Aabf, Aace, Aadg, Abcd, Abeg, Acfg, Adef = G @@ -8095,11 +8097,12 @@ cdef class Matroid(SageObject): sage: M = matroids.Wheel(3) sage: ch = M.chow_ring(QQ, augmented=True, presentation='fy'); ch Augmented Chow ring of Wheel(3): Regular matroid of rank 3 on - 6 elements with 16 bases in Feitchner-Yuzvinsky presentation + 6 elements with 16 bases in Feitchner-Yuzvinsky presentation over + Rational Field sage: M = matroids.Uniform(3, 6) sage: ch = M.chow_ring(QQ, augmented=True, presentation='atom-free'); ch Augmented Chow ring of U(3, 6): Matroid of rank 3 on 6 elements with circuit-closures - {3: {{0, 1, 2, 3, 4, 5}}} in atom-free presentation + {3: {{0, 1, 2, 3, 4, 5}}} in atom-free presentation over Rational Field """ from sage.matroids.chow_ring import ChowRing return ChowRing(M=self, R=R, augmented=augmented, presentation=presentation) From a239339851d5b670857609cded79487fd5956fad Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Mon, 4 Nov 2024 11:52:45 +0530 Subject: [PATCH 415/537] Fixed linting error --- 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 86fcc36dd8c..dbcdcdf4fde 100644 --- a/src/sage/matroids/chow_ring.py +++ b/src/sage/matroids/chow_ring.py @@ -117,7 +117,7 @@ def _repr_(self): if self._presentation == 'fy': output += " in Feitchner-Yuzvinsky presentation" elif self._presentation == 'atom-free': - output += " in atom-free presentation" + output += " in atom-free presentation" return output + " over " + repr(self.base_ring()) def _latex_(self): From ab3354285a00e6102d45e0cb0405952b1b812da1 Mon Sep 17 00:00:00 2001 From: Kwankyu Lee Date: Fri, 6 Sep 2024 10:32:03 +0900 Subject: [PATCH 416/537] Use artifact-doc-develop for PR event --- .ci/create-changes-html.sh | 6 ++ .github/workflows/doc-build.yml | 78 +++++++++++++------ src/sage/crypto/sbox.pyx | 2 +- src/sage/matrix/matrix2.pyx | 2 +- .../rings/polynomial/polynomial_element.pyx | 4 +- src/sage/rings/ring_extension.pyx | 2 +- src/sage/rings/ring_extension_element.pyx | 2 +- 7 files changed, 66 insertions(+), 30 deletions(-) diff --git a/.ci/create-changes-html.sh b/.ci/create-changes-html.sh index 0e80d0d2814..0cc86f34b13 100755 --- a/.ci/create-changes-html.sh +++ b/.ci/create-changes-html.sh @@ -16,6 +16,12 @@ echo '' >> CHANGES.html echo '' >> CHANGES.html cat >> CHANGES.html << EOF + ; d' \ -e 's;#L[0-9]*";";' \ + -e 's;tab-set--[0-9]*-;tab-set-;' \ && true) # Create git repo from old doc (cd doc && \ @@ -223,6 +224,7 @@ jobs: -e '/;,\;; d' \ -e 's;#L[0-9]*";";' \ + -e 's;tab-set--[0-9]*-;tab-set-;' \ && git commit -a -m 'wipe-out') # Since HEAD is at commit 'wipe-out', HEAD~1 is commit 'new' (new doc), HEAD~2 is commit 'old' (old doc) (cd doc && git diff $(git rev-parse HEAD~2) -- "*.html") > diff.txt From b9567a69abdc3364d1a84a5eebfeb398e2e0ec93 Mon Sep 17 00:00:00 2001 From: Kwankyu Lee Date: Tue, 10 Sep 2024 14:36:33 +0900 Subject: [PATCH 418/537] Squeeze more disk space --- .github/workflows/doc-build.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/doc-build.yml b/.github/workflows/doc-build.yml index f0895778a17..7b4ea38e044 100644 --- a/.github/workflows/doc-build.yml +++ b/.github/workflows/doc-build.yml @@ -267,6 +267,8 @@ jobs: id: buildlivedoc if: startsWith(github.ref, 'refs/tags/') run: | + # Avoid running out of disk space + rm -rf upstream export MAKE="make -j5 --output-sync=recurse" SAGE_NUM_THREADS=5 export PATH="build/bin:$PATH" eval $(sage-print-system-package-command auto update) From 980078eab5ac3c7bce39a9259bcdeb4a580e9804 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Mon, 4 Nov 2024 08:47:44 +0100 Subject: [PATCH 419/537] fixing ruff E714 --- src/sage/algebras/shuffle_algebra.py | 2 +- src/sage/crypto/block_cipher/miniaes.py | 4 ++-- src/sage/dynamics/arithmetic_dynamics/berkovich_ds.py | 2 +- src/sage/graphs/graph.py | 2 +- src/sage/groups/abelian_gps/abelian_aut.py | 2 +- src/sage/groups/abelian_gps/abelian_group_gap.py | 2 +- src/sage/groups/affine_gps/group_element.py | 4 ++-- src/sage/interfaces/psage.py | 2 +- src/sage/logic/boolformula.py | 2 +- src/sage/misc/rest_index_of_methods.py | 2 +- src/sage/modules/fp_graded/morphism.py | 2 +- src/sage/rings/finite_rings/galois_group.py | 2 +- src/sage/rings/invariants/invariant_theory.py | 2 +- src/sage/rings/localization.py | 4 ++-- src/sage/rings/number_field/number_field.py | 2 +- src/sage/rings/polynomial/multi_polynomial_element.py | 2 +- src/sage/rings/polynomial/multi_polynomial_ideal.py | 2 +- src/sage/rings/polynomial/polynomial_quotient_ring.py | 2 +- src/sage/rings/valuation/gauss_valuation.py | 2 +- 19 files changed, 22 insertions(+), 22 deletions(-) diff --git a/src/sage/algebras/shuffle_algebra.py b/src/sage/algebras/shuffle_algebra.py index adee056035c..aea170d2295 100644 --- a/src/sage/algebras/shuffle_algebra.py +++ b/src/sage/algebras/shuffle_algebra.py @@ -439,7 +439,7 @@ def _element_constructor_(self, x): if isinstance(P, ShuffleAlgebra): if P is self: return x - if not (P is self.base_ring()): + if P is not self.base_ring(): return self.element_class(self, x.monomial_coefficients()) if isinstance(P, DualPBWBasis): return self(P.expansion(x)) diff --git a/src/sage/crypto/block_cipher/miniaes.py b/src/sage/crypto/block_cipher/miniaes.py index 0a421c17e5e..cf591029d80 100644 --- a/src/sage/crypto/block_cipher/miniaes.py +++ b/src/sage/crypto/block_cipher/miniaes.py @@ -1642,7 +1642,7 @@ def GF_to_binary(self, G): return B(S) # G is a matrix over GF(16) elif isinstance(G, Matrix_dense): - if not (G.base_ring() is K): + if G.base_ring() is not K: raise TypeError("input G must be an element of GF(16), a list of elements of GF(16), or a matrix over GF(16)") S = "".join(str(self._GF_to_bin[G[i][j]]) for i in range(G.nrows()) for j in range(G.ncols())) @@ -1772,7 +1772,7 @@ def GF_to_integer(self, G): return [self._GF_to_int[g] for g in G] # G is a matrix over GF(16) elif isinstance(G, Matrix_dense): - if not (G.base_ring() is K): + if G.base_ring() is not K: raise TypeError("input G must be an element of GF(16), a list of elements of GF(16), or a matrix over GF(16)") return [self._GF_to_int[G[i][j]] for i in range(G.nrows()) for j in range(G.ncols())] # the type of G doesn't match the supported types diff --git a/src/sage/dynamics/arithmetic_dynamics/berkovich_ds.py b/src/sage/dynamics/arithmetic_dynamics/berkovich_ds.py index f84ab7e94ed..9734b3767ac 100644 --- a/src/sage/dynamics/arithmetic_dynamics/berkovich_ds.py +++ b/src/sage/dynamics/arithmetic_dynamics/berkovich_ds.py @@ -703,7 +703,7 @@ def conjugate(self, M, adjugate=False, new_ideal=None): new_system = self._system.conjugate(M, adjugate=adjugate) system_domain = new_system.domain() if new_ideal is None: - if not system_domain.base_ring() is QQ: + if system_domain.base_ring() is not QQ: new_ideal = system_domain.base_ring().prime_above(self.domain().ideal()) else: new_ideal = self.domain().ideal() diff --git a/src/sage/graphs/graph.py b/src/sage/graphs/graph.py index 4eced79fe9b..c2e2393eaef 100644 --- a/src/sage/graphs/graph.py +++ b/src/sage/graphs/graph.py @@ -2695,7 +2695,7 @@ def is_perfect(self, certificate=False): return True if not certificate else None answer = self.is_odd_hole_free(certificate=certificate) - if not (answer is True): + if answer is not True: return answer return self_complement.is_odd_hole_free(certificate=certificate) diff --git a/src/sage/groups/abelian_gps/abelian_aut.py b/src/sage/groups/abelian_gps/abelian_aut.py index 89551916589..c58eebc4b4f 100644 --- a/src/sage/groups/abelian_gps/abelian_aut.py +++ b/src/sage/groups/abelian_gps/abelian_aut.py @@ -404,7 +404,7 @@ def is_subgroup_of(self, G): """ if not isinstance(G, AbelianGroupAutomorphismGroup_gap): raise ValueError("input must be an instance of AbelianGroup_gap") - if not self.ambient() is G.ambient(): + if self.ambient() is not G.ambient(): return False return G.gap().IsSubsemigroup(self).sage() diff --git a/src/sage/groups/abelian_gps/abelian_group_gap.py b/src/sage/groups/abelian_gps/abelian_group_gap.py index 0c0d6a5f49b..eb41bbd8320 100644 --- a/src/sage/groups/abelian_gps/abelian_group_gap.py +++ b/src/sage/groups/abelian_gps/abelian_group_gap.py @@ -533,7 +533,7 @@ def is_subgroup_of(self, G): """ if not isinstance(G, AbelianGroup_gap): raise ValueError("input must be an instance of AbelianGroup_gap") - if not self.ambient() is G.ambient(): + if self.ambient() is not G.ambient(): return False return G.gap().IsSubsemigroup(self).sage() diff --git a/src/sage/groups/affine_gps/group_element.py b/src/sage/groups/affine_gps/group_element.py index fff5881868f..b1e3cd1e0cb 100644 --- a/src/sage/groups/affine_gps/group_element.py +++ b/src/sage/groups/affine_gps/group_element.py @@ -132,9 +132,9 @@ def __init__(self, parent, A, b=0, convert=True, check=True): # Note: the coercion framework expects that we raise TypeError for invalid input if not isinstance(A, Matrix): raise TypeError('A must be a matrix') - if not (A.parent() is parent.matrix_space()): + if A.parent() is not parent.matrix_space(): raise TypeError('A must be an element of ' + str(parent.matrix_space())) - if not (b.parent() is parent.vector_space()): + if b.parent() is not parent.vector_space(): raise TypeError('b must be an element of ' + str(parent.vector_space())) parent._element_constructor_check(A, b) super().__init__(parent) diff --git a/src/sage/interfaces/psage.py b/src/sage/interfaces/psage.py index 96d4233bbeb..9fba3d1d015 100644 --- a/src/sage/interfaces/psage.py +++ b/src/sage/interfaces/psage.py @@ -122,7 +122,7 @@ def __del__(self): except OSError: pass - if not (self._expect is None): + if self._expect is not None: cmd = 'kill -9 %s' % self._expect.pid os.system(cmd) diff --git a/src/sage/logic/boolformula.py b/src/sage/logic/boolformula.py index d22c0443461..b496bb91158 100644 --- a/src/sage/logic/boolformula.py +++ b/src/sage/logic/boolformula.py @@ -1106,7 +1106,7 @@ def convert_opt(self, tree): :func:`~sage.logic.logicparser.apply_func()` in :mod:`~sage.logic.logicparser`. """ - if not isinstance(tree[1], tuple) and not (tree[1] is None): + if not isinstance(tree[1], tuple) and tree[1] is not None: lval = ('prop', tree[1]) else: lval = tree[1] diff --git a/src/sage/misc/rest_index_of_methods.py b/src/sage/misc/rest_index_of_methods.py index 0d1d46f63b7..e7d4ca448ff 100644 --- a/src/sage/misc/rest_index_of_methods.py +++ b/src/sage/misc/rest_index_of_methods.py @@ -275,7 +275,7 @@ def local_filter(f, name): else: return not any(hasattr(s, name) for s in superclasses) else: - return inspect.isclass(root) or not (f is gen_rest_table_index) + return inspect.isclass(root) or f is not gen_rest_table_index def can_import(f): # poke it to provoke a lazy import to resolve diff --git a/src/sage/modules/fp_graded/morphism.py b/src/sage/modules/fp_graded/morphism.py index 890178110a6..5f3c9e461c6 100755 --- a/src/sage/modules/fp_graded/morphism.py +++ b/src/sage/modules/fp_graded/morphism.py @@ -1138,7 +1138,7 @@ def lift(self, f, verbose=False): M = f.domain() # It is an error to call this function with incompatible arguments. - if not f.codomain() is N: + if f.codomain() is not N: raise ValueError('the codomains of this homomorphism and the homomorphism ' 'we are lifting over are different') diff --git a/src/sage/rings/finite_rings/galois_group.py b/src/sage/rings/finite_rings/galois_group.py index 1cdd70fcbb2..880aea93c76 100644 --- a/src/sage/rings/finite_rings/galois_group.py +++ b/src/sage/rings/finite_rings/galois_group.py @@ -142,7 +142,7 @@ def _element_constructor_(self, x, check=True): else: raise RuntimeError("Automorphism was not a power of Frobenius") elif isinstance(x, FrobeniusEndomorphism_finite_field): - if check and not x.domain() is k: + if check and x.domain() is not k: raise ValueError("Not an automorphism of the correct finite field") n = x.power() elif isinstance(x, list) and len(x) == 1 and x[0] in ZZ: diff --git a/src/sage/rings/invariants/invariant_theory.py b/src/sage/rings/invariants/invariant_theory.py index fb953f98813..c2e80fbe633 100644 --- a/src/sage/rings/invariants/invariant_theory.py +++ b/src/sage/rings/invariants/invariant_theory.py @@ -286,7 +286,7 @@ def diff(j): dg = g.form().derivative(x,h-j).derivative(y,j) return (-1)**j * binomial(h,j) * df * dg tv = scalar * sum([diff(j) for j in range(h+1)]) - if not tv.parent() is R: + if tv.parent() is not R: S = tv.parent() x = S(x) y = S(y) diff --git a/src/sage/rings/localization.py b/src/sage/rings/localization.py index be1fc217a8d..ab6916d36c8 100644 --- a/src/sage/rings/localization.py +++ b/src/sage/rings/localization.py @@ -685,9 +685,9 @@ def __init__(self, base_ring, extra_units, names=None, normalize=True, category= sage: L = R.localization(x**2 + 1) # needs sage.libs.pari sage: TestSuite(L).run() """ - if type(extra_units) is tuple: + if isinstance(extra_units, tuple): extra_units = list(extra_units) - if not type(extra_units) is list: + elif not isinstance(extra_units, list): extra_units = [extra_units] from sage.rings.polynomial.laurent_polynomial_ring_base import LaurentPolynomialRing_generic diff --git a/src/sage/rings/number_field/number_field.py b/src/sage/rings/number_field/number_field.py index 315e31cf42f..7128d40032e 100644 --- a/src/sage/rings/number_field/number_field.py +++ b/src/sage/rings/number_field/number_field.py @@ -10415,7 +10415,7 @@ def hilbert_symbol_negative_at_S(self, S, b, check=True): from sage.groups.additive_abelian.additive_abelian_group import AdditiveAbelianGroup # input checks - if not type(S) is list: + if not isinstance(S, list): raise TypeError("first argument must be a list") if b not in self: raise TypeError("second argument must be an element of this field") diff --git a/src/sage/rings/polynomial/multi_polynomial_element.py b/src/sage/rings/polynomial/multi_polynomial_element.py index 6c4ec02c1b1..6ffe1353fc9 100644 --- a/src/sage/rings/polynomial/multi_polynomial_element.py +++ b/src/sage/rings/polynomial/multi_polynomial_element.py @@ -688,7 +688,7 @@ def degree(self, x=None, std_grading=False): return Integer(self.element().degree(None)) return self.weighted_degree(self.parent().term_order().weights()) if isinstance(x, MPolynomial): - if not x.parent() is self.parent(): + if x.parent() is not self.parent(): try: x = self.parent().coerce(x) except TypeError: diff --git a/src/sage/rings/polynomial/multi_polynomial_ideal.py b/src/sage/rings/polynomial/multi_polynomial_ideal.py index 8e358652be3..4352d9efbac 100644 --- a/src/sage/rings/polynomial/multi_polynomial_ideal.py +++ b/src/sage/rings/polynomial/multi_polynomial_ideal.py @@ -638,7 +638,7 @@ def _singular_(self, singular=None): try: self.ring()._singular_(singular).set_ring() I = self.__singular - if not (I.parent() is singular): + if I.parent() is not singular: raise ValueError I._check_valid() return I diff --git a/src/sage/rings/polynomial/polynomial_quotient_ring.py b/src/sage/rings/polynomial/polynomial_quotient_ring.py index 027a8997067..9851c477abf 100644 --- a/src/sage/rings/polynomial/polynomial_quotient_ring.py +++ b/src/sage/rings/polynomial/polynomial_quotient_ring.py @@ -216,7 +216,7 @@ def create_key(self, ring, polynomial, names=None): raise TypeError("ring must be a polynomial ring") if not isinstance(polynomial, polynomial_element.Polynomial): raise TypeError("must be a polynomial") - if not polynomial.parent() is ring: + if polynomial.parent() is not ring: raise TypeError("polynomial must be in ring") c = polynomial.leading_coefficient() diff --git a/src/sage/rings/valuation/gauss_valuation.py b/src/sage/rings/valuation/gauss_valuation.py index ca67b25274e..0e867e0a2f5 100644 --- a/src/sage/rings/valuation/gauss_valuation.py +++ b/src/sage/rings/valuation/gauss_valuation.py @@ -97,7 +97,7 @@ def create_key(self, domain, v=None): if v is None: v = domain.base_ring().valuation() - if not v.domain() is domain.base_ring(): + if v.domain() is not domain.base_ring(): raise ValueError("the domain of v must be the base ring of domain but %r is not defined over %r but over %r" % (v, domain.base_ring(), v.domain())) if not v.is_discrete_valuation(): raise ValueError("v must be a discrete valuation but %r is not" % (v,)) From 350bba3847823222bf2191b748ecebd99d087206 Mon Sep 17 00:00:00 2001 From: janmenjayap Date: Mon, 4 Nov 2024 13:23:04 +0530 Subject: [PATCH 420/537] added has_perfect_matching() --- src/sage/graphs/matching_covered_graph.py | 85 +++++++++++++++++++++++ 1 file changed, 85 insertions(+) diff --git a/src/sage/graphs/matching_covered_graph.py b/src/sage/graphs/matching_covered_graph.py index 08444b90cf9..550e6c06bdb 100644 --- a/src/sage/graphs/matching_covered_graph.py +++ b/src/sage/graphs/matching_covered_graph.py @@ -1795,6 +1795,91 @@ def get_matching(self): """ return self._matching + @doc_index('Overwritten methods') + def has_perfect_matching(G, algorithm='Edmonds', solver=None, verbose=0, + *, integrality_tolerance=1e-3): + r""" + Return whether the graph has a perfect matching. + + .. NOTE:: + + This method overwrites the + :meth:`~sage.graphs.graph.Graph.has_perfect_matching` method in + order to return ``True`` (provided the input arguments are valid) + as matching covered graphs always admit a perfect matching. + + INPUT: + + - ``algorithm`` -- string (default: ``'Edmonds'``) + + - ``'Edmonds'`` uses Edmonds' algorithm as implemented in NetworkX to + find a matching of maximal cardinality, then check whether this + cardinality is half the number of vertices of the graph. + + - ``'LP_matching'`` uses a Linear Program to find a matching of + maximal cardinality, then check whether this cardinality is half the + number of vertices of the graph. + + - ``'LP'`` uses a Linear Program formulation of the perfect matching + problem: put a binary variable ``b[e]`` on each edge `e`, and for + each vertex `v`, require that the sum of the values of the edges + incident to `v` is 1. + + - ``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 (only useful when + ``algorithm == "LP_matching"`` or ``algorithm == "LP"``) + + - ``integrality_tolerance`` -- float; parameter for use with MILP + solvers over an inexact base ring; see + :meth:`MixedIntegerLinearProgram.get_values`. + + OUTPUT: + + - If the input arguments are valid, a boolean (``True``) is returned as + a maximum matching of a matching covered graph is always a perfect + matching, otherwise a :exc:`~ValueError` is raised. + + EXAMPLES: + + Note that regardless of the algorithm (as long as the input arguments + are in valid format), the method always returns the boolean ``True``:: + + sage: P = graphs.PetersenGraph() + sage: P.has_perfect_matching() # Calls Graph.has_perfect_matching() + True + sage: G = MatchingCoveredGraph(P) + sage: G.has_perfect_matching() # Calls MatchingCoveredGraph.has_perfect_matching() + True + sage: W = graphs.WheelGraph(6) + sage: H = MatchingCoveredGraph(W) + sage: H.has_perfect_matching(algorithm='LP_matching') + True + + Providing with an algorithm, that is not one of ``'Edmonds'``, + ``'LP_matching'`` or ``'LP'``:: + + sage: S = graphs.StaircaseGraph(4) + sage: J = MatchingCoveredGraph(S) + sage: J.has_perfect_matching(algorithm='algorithm') + Traceback (most recent call last): + ... + ValueError: algorithm must be set to 'Edmonds', + 'LP_matching' or 'LP' + """ + if algorithm in ['Edmonds', 'LP_matching', 'LP']: + return True + + raise ValueError('algorithm must be set to \'Edmonds\', ' + '\'LP_matching\' or \'LP\'') + @doc_index('Miscellaneous methods') def update_matching(self, matching): r""" From 71e09d0e7e72cbaf1800308058be22d1edfb0cd4 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Mon, 4 Nov 2024 14:09:03 +0530 Subject: [PATCH 421/537] Edited doctest --- src/sage/matroids/matroid.pyx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/sage/matroids/matroid.pyx b/src/sage/matroids/matroid.pyx index c0c98a26150..493d9176045 100644 --- a/src/sage/matroids/matroid.pyx +++ b/src/sage/matroids/matroid.pyx @@ -8074,6 +8074,10 @@ cdef class Matroid(SageObject): sage: A = M.chow_ring(QQ); A Chow ring of Fano: Binary matroid of rank 3 on 7 elements, type (3, 0) over Rational Field + + Next, we get the non-trivial generators and do some computations:: + + sage: # needs sage.libs.singular sage.rings.finite_rings sage: G = A.gens()[6:]; G (Ag, Aabf, Aace, Aadg, Abcd, Abeg, Acfg, Adef) sage: Ag, Aabf, Aace, Aadg, Abcd, Abeg, Acfg, Adef = G From 79f410bc9a3ff2f9b609740c7a3b32b0f6a698ea Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Mon, 4 Nov 2024 14:09:31 +0530 Subject: [PATCH 422/537] Edited doctests --- src/sage/matroids/matroid.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/matroids/matroid.pyx b/src/sage/matroids/matroid.pyx index 493d9176045..12c4c6a527a 100644 --- a/src/sage/matroids/matroid.pyx +++ b/src/sage/matroids/matroid.pyx @@ -8075,7 +8075,7 @@ cdef class Matroid(SageObject): Chow ring of Fano: Binary matroid of rank 3 on 7 elements, type (3, 0) over Rational Field - Next, we get the non-trivial generators and do some computations:: + Next we get the non-trivial generators and do some computations:: sage: # needs sage.libs.singular sage.rings.finite_rings sage: G = A.gens()[6:]; G From 722d0ce6ec87dcb722eea1bbc80c828a433cf218 Mon Sep 17 00:00:00 2001 From: janmenjayap Date: Mon, 4 Nov 2024 15:36:58 +0530 Subject: [PATCH 423/537] corrected the indentation --- src/sage/graphs/matching_covered_graph.py | 26 +++++++++++------------ 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/sage/graphs/matching_covered_graph.py b/src/sage/graphs/matching_covered_graph.py index 550e6c06bdb..2870d8da28f 100644 --- a/src/sage/graphs/matching_covered_graph.py +++ b/src/sage/graphs/matching_covered_graph.py @@ -1812,34 +1812,34 @@ def has_perfect_matching(G, algorithm='Edmonds', solver=None, verbose=0, - ``algorithm`` -- string (default: ``'Edmonds'``) - - ``'Edmonds'`` uses Edmonds' algorithm as implemented in NetworkX to + - ``'Edmonds'`` uses Edmonds' algorithm as implemented in NetworkX to find a matching of maximal cardinality, then check whether this cardinality is half the number of vertices of the graph. - - ``'LP_matching'`` uses a Linear Program to find a matching of + - ``'LP_matching'`` uses a Linear Program to find a matching of maximal cardinality, then check whether this cardinality is half the number of vertices of the graph. - - ``'LP'`` uses a Linear Program formulation of the perfect matching + - ``'LP'`` uses a Linear Program formulation of the perfect matching problem: put a binary variable ``b[e]`` on each edge `e`, and for each vertex `v`, require that the sum of the values of the edges incident to `v` is 1. - ``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 - `. + 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 (only useful when - ``algorithm == "LP_matching"`` or ``algorithm == "LP"``) + set to 0 by default, which means quiet (only useful when + ``algorithm == "LP_matching"`` or ``algorithm == "LP"``) - ``integrality_tolerance`` -- float; parameter for use with MILP - solvers over an inexact base ring; see - :meth:`MixedIntegerLinearProgram.get_values`. + solvers over an inexact base ring; see + :meth:`MixedIntegerLinearProgram.get_values`. OUTPUT: From 61c9140dad41e5fc7111269a4ce9f70845d02c21 Mon Sep 17 00:00:00 2001 From: janmenjayap Date: Mon, 4 Nov 2024 15:45:15 +0530 Subject: [PATCH 424/537] added index of methods --- src/sage/graphs/matching_covered_graph.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/sage/graphs/matching_covered_graph.py b/src/sage/graphs/matching_covered_graph.py index 2870d8da28f..9117b1eaf59 100644 --- a/src/sage/graphs/matching_covered_graph.py +++ b/src/sage/graphs/matching_covered_graph.py @@ -93,7 +93,7 @@ # https://www.gnu.org/licenses/ # **************************************************************************** from .graph import Graph -from sage.misc.rest_index_of_methods import doc_index +from sage.misc.rest_index_of_methods import doc_index, gen_thematic_rest_table_index class MatchingCoveredGraph(Graph): r""" @@ -1964,4 +1964,6 @@ def update_matching(self, matching): self._matching = M.edges() except Exception as exception: - raise exception \ No newline at end of file + raise exception + +__doc__ = __doc__.replace("{INDEX_OF_METHODS}", gen_thematic_rest_table_index(MatchingCoveredGraph)) \ No newline at end of file From 05dd74a5d3daa7fc263f9c4f01119c9c32a6579f Mon Sep 17 00:00:00 2001 From: janmenjayap Date: Mon, 4 Nov 2024 16:37:57 +0530 Subject: [PATCH 425/537] added one more blankline after the class definition --- src/sage/graphs/matching_covered_graph.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/sage/graphs/matching_covered_graph.py b/src/sage/graphs/matching_covered_graph.py index 9117b1eaf59..c0978092ec3 100644 --- a/src/sage/graphs/matching_covered_graph.py +++ b/src/sage/graphs/matching_covered_graph.py @@ -1966,4 +1966,5 @@ def update_matching(self, matching): except Exception as exception: raise exception + __doc__ = __doc__.replace("{INDEX_OF_METHODS}", gen_thematic_rest_table_index(MatchingCoveredGraph)) \ No newline at end of file From 2233158a5d23b48c44b7ff224b86bcabb9a116a0 Mon Sep 17 00:00:00 2001 From: janmenjayap Date: Mon, 4 Nov 2024 18:39:29 +0530 Subject: [PATCH 426/537] updated the documentation --- src/sage/graphs/matching_covered_graph.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/sage/graphs/matching_covered_graph.py b/src/sage/graphs/matching_covered_graph.py index c0978092ec3..e0c52b180d5 100644 --- a/src/sage/graphs/matching_covered_graph.py +++ b/src/sage/graphs/matching_covered_graph.py @@ -631,7 +631,6 @@ def __repr__(self): return s.capitalize() return "".join(["Matching covered ", s]) - @doc_index('Overwritten methods') def _subgraph_by_adding(self, vertices=None, edges=None, edge_property=None, immutable=None): r""" Return the matching covered subgraph containing the given vertices and edges. From 9c9f804c7d0829d0a78c5eb23945b88c5c74103d Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Mon, 4 Nov 2024 21:32:10 +0530 Subject: [PATCH 427/537] Incorporated changes --- src/sage/matroids/chow_ring_ideal.py | 24 +++++++++++++----------- src/sage/matroids/matroid.pyx | 4 ++-- 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/src/sage/matroids/chow_ring_ideal.py b/src/sage/matroids/chow_ring_ideal.py index 7199b0478f5..0f0eea77f17 100644 --- a/src/sage/matroids/chow_ring_ideal.py +++ b/src/sage/matroids/chow_ring_ideal.py @@ -97,11 +97,11 @@ class ChowRingIdeal_nonaug(ChowRingIdeal): 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 + circuit-closures {3: {{0, 1, 2, 3, 4, 5}}} - non augmented sage: ch = matroids.catalog.Fano().chow_ring(QQ, False) sage: ch.defining_ideal() Chow ring ideal of Fano: Binary matroid of rank 3 on 7 elements, - type (3, 0) - non augmented + type (3, 0) - non augmented """ def __init__(self, M, R): r""" @@ -198,7 +198,7 @@ def _latex_(self): I_{M} + J_{M} of matroid \text{\texttt{Matroid{ }of{ }rank{ }2{ }on{ }4{ }elements{ }with{ }3{ }bases}} """ from sage.misc.latex import latex - return 'I_{M} + J_{M} of matroid ' + latex(self._matroid) + return '(I_{{{M}}} + J_{{{M}}}'.format(M=latex(self._matroid)) def groebner_basis(self, algorithm='', *args, **kwargs): r""" @@ -222,7 +222,7 @@ def groebner_basis(self, algorithm='', *args, **kwargs): [A0*A1, A0*A2, A1*A2, A0, A1, A2, A0*A3, A1*A3, A2*A3, A3] sage: ch.defining_ideal().groebner_basis().is_groebner() True - sage: ch.defining_ideal().hilbert_series() == ch.defining_ideal().hilbert_series(algorithm='singular') + sage: ch.defining_ideal().hilbert_series() == ch.defining_ideal().gens().ideal().hilbert_series() True """ if algorithm == '': @@ -237,12 +237,12 @@ def groebner_basis(self, algorithm='', *args, **kwargs): flats_gen = self._flats_generator lattice_flats = Poset((flats, reln)) antichains = lattice_flats.antichains().elements_of_depth_iterator(2) - for subset in antichains: #Taking antichains of size 2 + for subset in antichains: # Taking antichains of size 2 term = R.one() for x in subset: term *= flats_gen[x] gb.append(term) - for F in flats: #Reduced groebner basis by computing the sum first and then the product + for F in flats: # Reduced groebner basis by computing the sum first and then the product term = R.zero() for G in lattice_flats.order_filter([F]): term += flats_gen[G] @@ -296,6 +296,7 @@ def normal_basis(self, algorithm='', *args, **kwargs): monomial_basis.append(expression) return PolynomialSequence(R, [monomial_basis]) + class AugmentedChowRingIdeal_fy(ChowRingIdeal): r""" The augmented Chow ring ideal of matroid `M` over ring `R` in @@ -440,9 +441,9 @@ def _gens_constructor(self, poly_ring): B + B0 + B1 + B2 + B3 + B4 + B5 + B013 + B025 + B04 + B124 + B15 + B23 + B345 + B012345] """ E = list(self._matroid.groundset()) - Q = list() - L = list() - reln = lambda x,y: x <= y + Q = [] + L = [] + reln = lambda x, y: x <= y lattice_flats = Poset((self._flats, reln)) antichains = lattice_flats.antichains().elements_of_depth_iterator(2) for F, G in antichains: @@ -497,7 +498,7 @@ def groebner_basis(self, algorithm='', *args, **kwargs): Polynomial Sequence with 178 Polynomials in 25 Variables sage: ch.defining_ideal().groebner_basis(algorithm='').is_groebner() True - sage: ch.defining_ideal().hilbert_series() == ch.defining_ideal().hilbert_series(algorithm='singular') + sage: ch.defining_ideal().hilbert_series() == ch.defining_ideal().gens().ideal().hilbert_series() True """ if algorithm == '': @@ -578,6 +579,7 @@ def normal_basis(self, algorithm='', *args, **kwargs): monomial_basis.append(expression) return PolynomialSequence(R, [monomial_basis]) + class AugmentedChowRingIdeal_atom_free(ChowRingIdeal): r""" The augmented Chow ring ideal for a matroid `M` over ring `R` in the @@ -720,7 +722,7 @@ def groebner_basis(self, algorithm='', *args, **kwargs): Polynomial Sequence with 253 Polynomials in 22 Variables sage: ch.defining_ideal().groebner_basis(algorithm='').is_groebner() True - sage: ch.defining_ideal().hilbert_series() == ch.defining_ideal().hilbert_series(algorithm='singular') + sage: ch.defining_ideal().hilbert_series() == ch.defining_ideal().gens().ideal().hilbert_series() True """ if algorithm == '': diff --git a/src/sage/matroids/matroid.pyx b/src/sage/matroids/matroid.pyx index 12c4c6a527a..0427af753de 100644 --- a/src/sage/matroids/matroid.pyx +++ b/src/sage/matroids/matroid.pyx @@ -8053,8 +8053,8 @@ cdef class Matroid(SageObject): - ``presentation`` -- string; if ``augmented=True``, then this must be one of the following (ignored if ``augmented=False``): - * ``"fy"`` - the Feitchner-Yuzvinsky presentation - * ``"atom-free"`` - the atom-free presentation + * ``"fy"`` - the Feitchner-Yuzvinsky presentation + * ``"atom-free"`` - the atom-free presentation EXAMPLES:: From dd58ae36861e2a4f964ea78d4d1e94a5ded584f2 Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Mon, 4 Nov 2024 17:11:58 +0100 Subject: [PATCH 428/537] Apply suggestions from code review Co-authored-by: Travis Scrimshaw --- src/sage/rings/species.py | 38 ++++++++++++++++++-------------------- 1 file changed, 18 insertions(+), 20 deletions(-) diff --git a/src/sage/rings/species.py b/src/sage/rings/species.py index 7bc55e6ccb5..174b0944d60 100644 --- a/src/sage/rings/species.py +++ b/src/sage/rings/species.py @@ -59,9 +59,9 @@ def __classcall__(cls, parent, C, dompart): arity, representing the assignment of each element of the domain of ``dis`` to a sort - ..WARNING:: + .. WARNING:: - we do not check whether ``C`` is indeed directly + We do not check whether ``C`` is indeed directly indecomposable. TESTS:: @@ -156,7 +156,7 @@ class of subgroups conjugate to ``C``, together with the dompart = [[ZZ(e ** mp) for e in b] for b in dompart] mc = tuple([len(b) for b in dompart]) - key = mc, dis + key = (mc, dis) if key in parent._cache: lookup = parent._cache[key] if parent._arity == 1 and lookup: @@ -593,7 +593,7 @@ def __contains__(self, x): sage: (0, {0: []}) in AtomicSpecies("X, Y") False """ - if parent(x) == self: + if parent(x) is self: return True if isinstance(x, PermutationGroup_generic): if self._arity == 1: @@ -926,9 +926,8 @@ def _element_constructor_(self, G, pi=None, check=True): ... ValueError: 0 must be a permutation group or a pair specifying a group action on the given domain pi=None - """ - if parent(G) == self: + if parent(G) is self: # pi cannot be None because of framework raise ValueError("cannot reassign sorts to a molecular species") @@ -968,7 +967,7 @@ def _element_constructor_(self, G, pi=None, check=True): domain=list(chain(*dompart))) H = _stabilizer_subgroups(S, X, a) if len(H) > 1: - raise ValueError("Action is not transitive") + raise ValueError("action is not transitive") return self(H[0], pi, check=check) def grading_set(self): @@ -1408,7 +1407,7 @@ def __call__(self, *args): # TODO: the case that G in F(G) has a constant part and F # is a polynomial species is not yet covered - see # section 4.3 of [ALL2002]_ - Mlist = [None for _ in range(sum(self.grade()))] + Mlist = [None] * sum(self.grade()) G, dompart = self.permutation_group() for i, v in enumerate(dompart): for k in v: @@ -1628,10 +1627,10 @@ def _compose_with_singletons(self, names, args): INPUT: - - ``names``, the (flat) list of names of the result - - ``args``, the sequence of `k` compositions, each of - which sums to the corresponding degree of ``self``, - where `k` is the arity of ``self``. + - ``names``, the (flat) list of names of the result + - ``args``, the sequence of `k` compositions, each of + which sums to the corresponding degree of ``self``, + where `k` is the arity of ``self`` OUTPUT: @@ -1717,10 +1716,10 @@ def _compose_with_weighted_singletons(self, names, multiplicities, degrees): in sort `i`, and the total length of the compositions is the number of names - ..TODO:: + .. TODO:: - once this is thoroughly tested, there should be an - optional keyword parameter to skip the checks + Once this is thoroughly tested, there should be an + optional keyword parameter to skip the checks. EXAMPLES: @@ -2029,7 +2028,6 @@ def _element_constructor_(self, G, pi=None, check=True): - ``check`` -- boolean (default: ``True``); skip input checking if ``False`` - EXAMPLES:: sage: from sage.rings.species import PolynomialSpecies @@ -2240,9 +2238,9 @@ def _powersum(self, s, n): coefficient of `t^n/n` in `\log E(tX)`, where `E` is the species of sets. - ..TODO:: + .. TODO:: - this is really a univariate species, so it would be better + This is really a univariate species, so it would be better to have a fast way to change all the variables of a univariate species into a new sort. @@ -2273,9 +2271,9 @@ def _exponential(self, multiplicities, degrees): r""" Return `E(\sum_i m_i X_i)` in the specified degrees. - ..TODO:: + .. TODO:: - rethink the signature + Rethink the signature. EXAMPLES:: From 8a15c61639c2c1753754eef01ec35669f0038d51 Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Mon, 4 Nov 2024 17:14:32 +0100 Subject: [PATCH 429/537] remove unnecessary else spotted by tscrim --- src/sage/rings/species.py | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/src/sage/rings/species.py b/src/sage/rings/species.py index 174b0944d60..09eb6abf82c 100644 --- a/src/sage/rings/species.py +++ b/src/sage/rings/species.py @@ -162,17 +162,16 @@ class of subgroups conjugate to ``C``, together with the if parent._arity == 1 and lookup: assert len(lookup) == 1 return lookup[0] - else: - domain = list(chain(*map(sorted, dompart))) - dis_gap = dis.gap() - dis_gens = dis_gap.GeneratorsOfGroup() - for elm in lookup: - # check whether the assignment to sorts given by - # dompart and by elm._dompart are the same - elm_domain = list(chain(*map(sorted, elm._dompart))) - mp = libgap.MappingPermListList(elm_domain, domain) - if all(g ** mp in dis_gap for g in dis_gens): - return elm + domain = list(chain(*map(sorted, dompart))) + dis_gap = dis.gap() + dis_gens = dis_gap.GeneratorsOfGroup() + for elm in lookup: + # check whether the assignment to sorts given by + # dompart and by elm._dompart are the same + elm_domain = list(chain(*map(sorted, elm._dompart))) + mp = libgap.MappingPermListList(elm_domain, domain) + if all(g ** mp in dis_gap for g in dis_gens): + return elm else: lookup = parent._cache[key] = [] From a305a741b2430064df422913cbead5a45eeab6d2 Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Mon, 4 Nov 2024 17:16:35 +0100 Subject: [PATCH 430/537] implement _an_element_ instead of caching an_element as spotted by tscrim --- src/sage/rings/species.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/sage/rings/species.py b/src/sage/rings/species.py index 09eb6abf82c..5f652d56977 100644 --- a/src/sage/rings/species.py +++ b/src/sage/rings/species.py @@ -663,8 +663,7 @@ def graded_component(self, mc): return Set([self(G, pi, check=False) for G in S.conjugacy_classes_subgroups() if len(G.disjoint_direct_product_decomposition()) <= 1]) - @cached_method - def an_element(self): + def _an_element_(self): """ Return an element of ``self``. @@ -2188,8 +2187,7 @@ def one_basis(self): """ return self._indices.one() - @cached_method - def an_element(self): + def _an_element_(self): """ Return an element of ``self``. From cb5ef7b1e03a5e19ce7f0c79ecc8fcf680064ce2 Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Mon, 4 Nov 2024 17:16:59 +0100 Subject: [PATCH 431/537] adapt doctest --- src/sage/rings/species.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/rings/species.py b/src/sage/rings/species.py index 5f652d56977..30744af0feb 100644 --- a/src/sage/rings/species.py +++ b/src/sage/rings/species.py @@ -887,7 +887,7 @@ def _element_constructor_(self, G, pi=None, check=True): sage: M((X, a), {0: [1,2], 1: [3,4]}) Traceback (most recent call last): ... - ValueError: Action is not transitive + ValueError: action is not transitive sage: G = PermutationGroup([[(1,3),(5,7)]], domain=[1,3,5,7]) sage: M(G, ([1,3], [5,7])) From e62310cef8b00a2de9c11fcb61fbbedcd8adb66d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Mon, 4 Nov 2024 17:44:40 +0100 Subject: [PATCH 432/537] remove the last use of PrincipalIdealDomain --- src/sage/rings/polynomial/polynomial_ring.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/sage/rings/polynomial/polynomial_ring.py b/src/sage/rings/polynomial/polynomial_ring.py index 2bda9f6f9c3..bc63f4c242b 100644 --- a/src/sage/rings/polynomial/polynomial_ring.py +++ b/src/sage/rings/polynomial/polynomial_ring.py @@ -149,7 +149,7 @@ from sage.categories.principal_ideal_domains import PrincipalIdealDomains from sage.categories.rings import Rings -from sage.rings.ring import (Ring, IntegralDomain, PrincipalIdealDomain) +from sage.rings.ring import (Ring, IntegralDomain) from sage.structure.element import RingElement import sage.rings.rational_field as rational_field from sage.rings.rational_field import QQ @@ -2154,8 +2154,7 @@ def construction(self): implementation=implementation), self.base_ring() -class PolynomialRing_field(PolynomialRing_integral_domain, - PrincipalIdealDomain): +class PolynomialRing_field(PolynomialRing_integral_domain): def __init__(self, base_ring, name='x', sparse=False, implementation=None, element_class=None, category=None): """ @@ -2217,9 +2216,14 @@ def _element_class(): from sage.rings.polynomial.polynomial_element_generic import Polynomial_generic_dense_field return Polynomial_generic_dense_field + if category is None: + cat = PrincipalIdealDomains() + else: + cat &= PrincipalIdealDomains() + PolynomialRing_integral_domain.__init__(self, base_ring, name=name, sparse=sparse, implementation=implementation, - element_class=_element_class(), category=category) + element_class=_element_class(), category=cat) def _ideal_class_(self, n=0): """ From cd7b5a983d08ce5d26804d0baae957c9a808086b Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Mon, 4 Nov 2024 17:47:07 +0100 Subject: [PATCH 433/537] do not use assert for input checking, spotted by tscrim --- src/sage/rings/species.py | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/src/sage/rings/species.py b/src/sage/rings/species.py index 30744af0feb..c72cf09507a 100644 --- a/src/sage/rings/species.py +++ b/src/sage/rings/species.py @@ -655,8 +655,16 @@ def graded_component(self, mc): 1 sage: A.graded_component([2, 3]) # random {{((2,3)(4,5), (1,2,3)): ({4, 5}, {1, 2, 3})}} + + TESTS:: + + sage: A.graded_component([0]) + Traceback (most recent call last): + ... + ValueError: invalid degree """ - assert len(mc) == self._arity + if len(mc) != self._arity: + raise ValueError("invalid degree") S = SymmetricGroup(sum(mc)).young_subgroup(mc) domain = S.domain() pi = {i: domain[sum(mc[:i]): sum(mc[:i+1])] for i in range(len(mc))} @@ -1011,8 +1019,16 @@ def graded_component(self, mc): {((1,2,3), (1,3)(4,5)): ({1, 2, 3}, {4, 5})}, X*{((1,2)(3,4),): ({1, 2}, {3, 4})}, X*E_2(X)*Y^2, E_3(X)*E_2(Y), C_3(X)*Y^2, C_3(X)*E_2(Y)} + + TESTS:: + + sage: M.graded_component([0]) + Traceback (most recent call last): + ... + ValueError: invalid degree """ - assert len(mc) == self._arity + if len(mc) != self._arity: + raise ValueError("invalid degree") S = SymmetricGroup(sum(mc)).young_subgroup(mc) domain = S.domain() pi = {i: domain[sum(mc[:i]): sum(mc[:i+1])] for i in range(len(mc))} From 0bc0224cee0875df93f1f35a0e21d47fa3d77d3c Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Mon, 4 Nov 2024 17:50:50 +0100 Subject: [PATCH 434/537] remove superfluous __init__ as spotted by tscrim --- src/sage/rings/species.py | 31 ++++++++++++------------------- 1 file changed, 12 insertions(+), 19 deletions(-) diff --git a/src/sage/rings/species.py b/src/sage/rings/species.py index c72cf09507a..765fb035bba 100644 --- a/src/sage/rings/species.py +++ b/src/sage/rings/species.py @@ -1035,29 +1035,22 @@ def graded_component(self, mc): return Set([self(G, pi, check=False) for G in S.conjugacy_classes_subgroups()]) class Element(IndexedFreeAbelianMonoidElement): - def __init__(self, parent, x): - r""" - Initialize a molecular species. - - INPUT: - - - ``x`` -- a dictionary mapping atomic species to exponents - - EXAMPLES:: + r""" + A molecular species. - sage: from sage.rings.species import MolecularSpecies - sage: M = MolecularSpecies("X") - sage: M(CyclicPermutationGroup(3)) # indirect doctest - C_3 + EXAMPLES:: - TESTS:: + sage: from sage.rings.species import MolecularSpecies + sage: M = MolecularSpecies("X") + sage: M(CyclicPermutationGroup(3)) + C_3 - sage: X = M(CyclicPermutationGroup(3)) - sage: C3 = M(CyclicPermutationGroup(3)) - sage: TestSuite(X*C3).run() - """ - super().__init__(parent, x) + TESTS:: + sage: X = M(CyclicPermutationGroup(3)) + sage: C3 = M(CyclicPermutationGroup(3)) + sage: TestSuite(X*C3).run() + """ @cached_method def grade(self): r""" From 580a5c2a87ea422c011befa6fb9e9d42772a9965 Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Mon, 4 Nov 2024 18:00:53 +0100 Subject: [PATCH 435/537] sort cover relations as str --- src/sage/rings/species.py | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/sage/rings/species.py b/src/sage/rings/species.py index 765fb035bba..4da28f01d08 100644 --- a/src/sage/rings/species.py +++ b/src/sage/rings/species.py @@ -263,13 +263,13 @@ def __lt__(self, other): sage: P = Poset([A.subset(4), lambda b, c: b <= c]) sage: len(P.cover_relations()) 7 - sage: P.cover_relations() # random - [[E_4, Eo_4], + sage: sorted(P.cover_relations(), key=str) + [[C_4, {((1,2)(3,4),)}], + [E_4, Eo_4], [E_4, P_4], [Eo_4, Pb_4], [P_4, C_4], [P_4, Pb_4], - [C_4, {((1,2)(3,4),)}], [Pb_4, {((1,2)(3,4),)}]] TESTS:: @@ -1100,24 +1100,24 @@ def _richcmp_(self, other, op): sage: P = Poset([M.subset(4), lambda b, c: b <= c]) sage: len(P.cover_relations()) 17 - sage: P.cover_relations() # random - [[E_4, P_4], + sage: sorted(P.cover_relations(), key=str) + [[C_4, {((1,2)(3,4),)}], + [E_2^2, X^2*E_2], + [E_2^2, {((1,2)(3,4),)}], [E_4, Eo_4], + [E_4, P_4], [E_4, X*E_3], + [Eo_4, Pb_4], + [Eo_4, X*C_3], [P_4, C_4], [P_4, E_2^2], [P_4, Pb_4], - [C_4, {((1,2)(3,4),)}], - [E_2^2, {((1,2)(3,4),)}], - [E_2^2, X^2*E_2], - [Eo_4, Pb_4], - [Eo_4, X*C_3], [Pb_4, {((1,2)(3,4),)}], - [{((1,2)(3,4),)}, X^4], - [X*E_3, X^2*E_2], + [X*C_3, X^4], [X*E_3, X*C_3], + [X*E_3, X^2*E_2], [X^2*E_2, X^4], - [X*C_3, X^4]] + [{((1,2)(3,4),)}, X^4]] TESTS:: From 0ca9a5bb28903dcbc2f150b5f15b6499be419b39 Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Mon, 4 Nov 2024 18:20:38 +0100 Subject: [PATCH 436/537] more replacements of parent == self to parent is self --- src/sage/rings/species.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/rings/species.py b/src/sage/rings/species.py index 4da28f01d08..cb48673d21c 100644 --- a/src/sage/rings/species.py +++ b/src/sage/rings/species.py @@ -470,7 +470,7 @@ def _element_constructor_(self, G, pi=None, check=True): ValueError: 0 must be a permutation group """ if check: - if parent(G) == self: + if parent(G) is self: # pi cannot be None because of framework raise ValueError("cannot reassign sorts to an atomic species") if not isinstance(G, PermutationGroup_generic): @@ -2099,7 +2099,7 @@ def _element_constructor_(self, G, pi=None, check=True): sage: P((X, lambda g, x: act(x[0], x[1], g)), pi) 2*Y*E_2(X) """ - if parent(G) == self: + if parent(G) is self: # pi cannot be None because of framework raise ValueError("cannot reassign sorts to a polynomial species") if isinstance(G, PermutationGroup_generic): From e798f08d869af76a45084d6e467974b7727da40d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Mon, 4 Nov 2024 19:31:48 +0100 Subject: [PATCH 437/537] fix mistake --- src/sage/rings/polynomial/polynomial_ring.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/rings/polynomial/polynomial_ring.py b/src/sage/rings/polynomial/polynomial_ring.py index bc63f4c242b..0ab8074ec1e 100644 --- a/src/sage/rings/polynomial/polynomial_ring.py +++ b/src/sage/rings/polynomial/polynomial_ring.py @@ -2219,7 +2219,7 @@ def _element_class(): if category is None: cat = PrincipalIdealDomains() else: - cat &= PrincipalIdealDomains() + cat = category & PrincipalIdealDomains() PolynomialRing_integral_domain.__init__(self, base_ring, name=name, sparse=sparse, implementation=implementation, From 736dfb3c790e47ecac134f3dc8fd94f6626d0b4f Mon Sep 17 00:00:00 2001 From: Marc Culler Date: Mon, 4 Nov 2024 15:00:22 -0600 Subject: [PATCH 438/537] Add a patch to the ecm spkg so it uses .sx rather than .s as the extension for assembler files. --- build/pkgs/ecm/patches/assembler.patch | 67 ++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 build/pkgs/ecm/patches/assembler.patch diff --git a/build/pkgs/ecm/patches/assembler.patch b/build/pkgs/ecm/patches/assembler.patch new file mode 100644 index 00000000000..2e3d6c94b6d --- /dev/null +++ b/build/pkgs/ecm/patches/assembler.patch @@ -0,0 +1,67 @@ +*** a/x86_64/Makefile.in Mon Nov 4 14:08:05 2024 +--- b/x86_64/Makefile.in Mon Nov 4 14:15:46 2024 +*************** +*** 355,361 **** + all: all-am + + .SUFFIXES: +! .SUFFIXES: .asm .lo .o .obj .s + $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ +--- 355,361 ---- + all: all-am + + .SUFFIXES: +! .SUFFIXES: .asm .lo .o .obj .sx + $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ +*************** +*** 406,418 **** + distclean-compile: + -rm -f *.tab.c + +! .s.o: + $(AM_V_CCAS)$(CCASCOMPILE) -c -o $@ $< + +! .s.obj: + $(AM_V_CCAS)$(CCASCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +! .s.lo: + $(AM_V_CCAS)$(LTCCASCOMPILE) -c -o $@ $< + + mostlyclean-libtool: +--- 406,418 ---- + distclean-compile: + -rm -f *.tab.c + +! .sx.o: + $(AM_V_CCAS)$(CCASCOMPILE) -c -o $@ $< + +! .sx.obj: + $(AM_V_CCAS)$(CCASCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +! .sx.lo: + $(AM_V_CCAS)$(LTCCASCOMPILE) -c -o $@ $< + + mostlyclean-libtool: +*************** +*** 706,713 **** + mulredc1_20.asm: mulredc1.m4 + $(M4) -DLENGTH=20 $< > $@ + +! .asm.s: +! $(M4) -I../ -DOPERATION_$* `test -f $< || echo '$(srcdir)/'`$< >$*.s + # Nothing here needs the C preprocessor, and including this rule causes + # "make" to build .S, then .s files which fails on case-insensitive + # filesystems +--- 706,713 ---- + mulredc1_20.asm: mulredc1.m4 + $(M4) -DLENGTH=20 $< > $@ + +! .asm.sx: +! $(M4) -I../ -DOPERATION_$* `test -f $< || echo '$(srcdir)/'`$< >$*.sx + # Nothing here needs the C preprocessor, and including this rule causes + # "make" to build .S, then .s files which fails on case-insensitive + # filesystems From 27e653654626527422bc1f0d872266b8c2ebf35a Mon Sep 17 00:00:00 2001 From: janmenjayap Date: Tue, 5 Nov 2024 06:05:48 +0530 Subject: [PATCH 439/537] updated the description of has_perfect_matching() --- src/sage/graphs/matching_covered_graph.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/graphs/matching_covered_graph.py b/src/sage/graphs/matching_covered_graph.py index e0c52b180d5..6cb7e57c31d 100644 --- a/src/sage/graphs/matching_covered_graph.py +++ b/src/sage/graphs/matching_covered_graph.py @@ -1798,7 +1798,7 @@ def get_matching(self): def has_perfect_matching(G, algorithm='Edmonds', solver=None, verbose=0, *, integrality_tolerance=1e-3): r""" - Return whether the graph has a perfect matching. + Check whether the graph has a perfect matching. .. NOTE:: From 1484670ec52d53cec76f8974e9c7d84f52e0129a Mon Sep 17 00:00:00 2001 From: janmenjayap Date: Tue, 5 Nov 2024 07:21:27 +0530 Subject: [PATCH 440/537] updated the todo list --- src/sage/graphs/matching_covered_graph.py | 140 ++++++++++++++++------ 1 file changed, 105 insertions(+), 35 deletions(-) diff --git a/src/sage/graphs/matching_covered_graph.py b/src/sage/graphs/matching_covered_graph.py index 6cb7e57c31d..b24144f523b 100644 --- a/src/sage/graphs/matching_covered_graph.py +++ b/src/sage/graphs/matching_covered_graph.py @@ -28,55 +28,125 @@ The following methods are to be incorporated in :class:`~MatchingCoveredGraph`: + .. csv-table:: + :class: contentstable + :widths: 30, 70 + :delim: | + + ``__hash__()`` | Compute a hash for ``self``, if ``self`` is immutable. + ``_subgraph_by_deleting()`` | Return the matching covered subgraph containing the provided vertices and edges. + Overwritten Methods: - - ``delete_edge()`` | Delete the edge from ``u`` to ``v``. - - ``delete_edges()`` | Delete edges from an iterable container. + .. csv-table:: + :class: contentstable + :widths: 30, 70 + :delim: | + + ``add_clique()`` | Add a clique to the graph with the provided vertices. + ``add_cycle()`` | Add a cycle to the graph with the provided vertices. + ``add_path()`` | Add a path to the graph with the provided vertices. + ``cartesian_product()`` | Return the Cartesian product of ``self`` and ``other``. + ``clear()`` | Empties the graph of vertices and edges and removes name, associated objects, and position information. + ``complement()`` | Return the complement of the graph. + ``contract_edge()`` | Contract an edge from ``u`` to ``v``. + ``contract_edges()`` | Contract edges from an iterable container. + ``degree_constrained_subgraph()`` | Return a degree-constrained matching covered subgraph. + ``delete_edge()`` | Delete the edge from ``u`` to ``v``. + ``delete_edges()`` | Delete edges from an iterable container. + ``delete_multiedge()`` | Delete all edges from ``u`` to ``v``. + ``disjoint_union()`` | Return the disjoint union of ``self`` and ``other``. + ``disjunctive_product()`` | Return the disjunctive product of ``self`` and ``other``. + ``has_loops()`` | Return whether there are loops in the matching covered graph. + ``is_biconnected()`` | Check if the matching covered graph is biconnected. + ``is_block_graph()`` | Check whether the matching covered graph is a block graph. + ``is_cograph()`` | Check whether the matching covered graph is cograph. + ``is_forest()`` | Check if the matching covered graph is a forest, i.e. a disjoint union of trees. + ``is_matching_covered()`` | Check if the graph is matching covered. + ``is_path()`` | Check whether the graph is a path. + ``is_subgraph()`` | Check whether the matching covered graph is a subgraph of ``other``. + ``is_tree()`` | Check whether the matching covered graph is a tree. + ``join()`` | Return the join of ``self`` and ``other``. + ``lexicographic_product()`` | Return the lexicographic product of ``self`` and ``other``. + ``load_afile()`` | Load the matching covered graph specified in the given file into the current object. + ``loop_edges()`` | Return a list of all loops in the matching covered graph. + ``loop_vertices()`` | Return a list of vertices with loops. + ``merge_vertices()`` | Merge vertices. + ``number_of_loops()`` | Return the number of edges that are loops. + ``random_subgraph()`` | Return a random matching covered subgraph containing each vertex with probability ``p``. + ``remove_loops()`` | Remove loops on vertices in ``vertices``. + ``save_afile()`` | Save the graph to file in alist format. + ``strong_product()`` | Return the strong product of ``self`` and ``other``. + ``subdivide_edge()`` | Subdivide an edge `k` times. + ``subdivide_edges()`` | Subdivide `k` times edges from an iterable container. + ``subgraph()`` | Return the matching covered subgraph containing the given vertices and edges. + ``subgraph_search()`` | Return a copy of (matching covered) ``G`` in ``self``. + ``subgraph_search_count()`` | Return the number of labelled occurrences of (matching covered) ``G`` in ``self``. + ``subgraph_search_iterator()`` | Return an iterator over the labelled copies of (matching covered) ``G`` in ``self``. + ``tensor_product()`` | Return the tensor product of ``self`` and ``other``. + ``to_undirected()`` | Return an undirected Graph instance of the matching covered graph. + ``transitive_closure()`` | Return the transitive closure of the matching covered graph. + ``transitive_reduction()`` | Return a transitive reduction of the matching covered graph. + ``union()`` | Return the union of ``self`` and ``other``. Barriers and canonical partition: - - ``canonical_partition()`` | Return the canonical partition of the - (matching covered) graph. - - ``maximal_barrier()`` | Return the (unique) maximal barrier of the - (matching covered) graph containing the (provided) vertex. + .. csv-table:: + :class: contentstable + :widths: 30, 70 + :delim: | + + ``canonical_partition()`` | Return the canonical partition of the (matching covered) graph. + ``maximal_barrier()`` | Return the (unique) maximal barrier of the (matching covered) graph containing the (provided) vertex. Bricks, braces and tight cut decomposition: - - ``bricks_and_braces()`` | Return the list of (underlying simple graph of) - the bricks and braces of the (matching covered) graph. - - ``is_brace()`` | Check if the (matching covered) graph is a brace. - - ``is_brick()`` | Check if the (matching covered) graph is a brick. - - ``number_of_braces()`` | Return the number of braces. - - ``number_of_bricks()`` | Return the number of bricks. - - ``number_of_petersen_bricks()`` | Return the number of Petersen bricks. - - ``tight_cut_decomposition()`` | Return a tight cut decomposition. + .. csv-table:: + :class: contentstable + :widths: 30, 70 + :delim: | + + ``bricks_and_braces()`` | Return the list of (underlying simple graph of) the bricks and braces of the (matching covered) graph. + ``is_brace()`` | Check if the (matching covered) graph is a brace. + ``is_brick()`` | Check if the (matching covered) graph is a brick. + ``number_of_braces()`` | Return the number of braces. + ``number_of_bricks()`` | Return the number of bricks. + ``number_of_petersen_bricks()`` | Return the number of Petersen bricks. + ``tight_cut_decomposition()`` | Return a tight cut decomposition. Removability and ear decomposition: - - ``efficient_ear_decomposition()`` | Return a matching covered ear - decomposition computed at the fastest possible time. - - ``is_removable_double_ear()`` | Check whether the pair of ears form a - removable double ear. - - ``is_removable_doubleton()`` | Check whether the pair of edges constitute - a removable doubleton. - - ``is_removable_ear()`` | Check whether the ear is removable. - - ``is_removable_edge()`` | Check whether the edge is removable. - - ``optimal_ear_decomposition()`` | Return an optimal ear decomposition. - - ``removable_double_ears()`` | Return a list of removable double ears. - - ``removable_doubletons()`` | Return a list of removable doubletons. - - ``removable_ears()`` | Return a list of removable ears. - - ``removable_edges()`` | Return a :class:`~EdgesView` of removable edges. - - ``retract()`` | Compute the retract of the (matching covered) graph. + .. csv-table:: + :class: contentstable + :widths: 30, 70 + :delim: | + + ``add_ear()`` | Add an ear to the graph with the provided end vertices number of internal vertices. + ``bisubdivide_edge()`` | Bisubdivide an edge `k` times. + ``bisubdivide_edges()`` | Bisubdivide `k` times edges from an iterable container. + ``efficient_ear_decomposition()`` | Return a matching covered ear decomposition computed at the fastest possible time. + ``is_removable_double_ear()`` | Check whether the pair of ears form a removable double ear. + ``is_removable_doubleton()`` | Check whether the pair of edges constitute a removable doubleton. + ``is_removable_ear()`` | Check whether the ear is removable. + ``is_removable_edge()`` | Check whether the edge is removable. + ``optimal_ear_decomposition()`` | Return an optimal ear decomposition. + ``removable_double_ears()`` | Return a list of removable double ears. + ``removable_doubletons()`` | Return a list of removable doubletons. + ``removable_ears()`` | Return a list of removable ears. + ``removable_edges()`` | Return a :class:`~EdgesView` of removable edges. + ``retract()`` | Compute the retract of the (matching covered) graph. Generating bricks and braces: - - ``brace_generation_sequence()`` | Return a McCuaig brace generation - sequence of the (given) brace. - - ``brick_generation_sequence()`` | Return a Norine-Thomas brick generation - sequence of the (given) brick. - - ``is_mccuaig_brace()`` | Check if the brace is a McCuaig brace. - - ``is_norine_thomas_brick()`` | Check if the brick is a Norine-Thomas - brick. + .. csv-table:: + :class: contentstable + :widths: 30, 70 + :delim: | + + ``brace_generation_sequence()`` | Return a McCuaig brace generation sequence of the (provided) brace. + ``brick_generation_sequence()`` | Return a Norine-Thomas brick generation sequence of the (provided) brick. + ``is_mccuaig_brace()`` | Check if the brace is a McCuaig brace. + ``is_norine_thomas_brick()`` | Check if the brick is a Norine-Thomas brick. Methods From 62a051c268eaa86d47fddaea8ced49a6986666ae Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Tue, 5 Nov 2024 12:19:42 +0800 Subject: [PATCH 441/537] Remove non-existing environment files from bootstrap tar --- bootstrap | 3 --- 1 file changed, 3 deletions(-) diff --git a/bootstrap b/bootstrap index 5f04a1e208c..9d19e756a38 100755 --- a/bootstrap +++ b/bootstrap @@ -227,9 +227,6 @@ save () { 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 \ - src/environment-3.[89].yml src/environment-3.1[0-9].yml \ - environment-optional-3.[89].yml environment-optional-3.1[0-9].yml \ - src/environment-optional-3.[89].yml src/environment-optional-3.1[0-9].yml \ src/Pipfile \ src/pyproject.toml \ src/requirements.txt \ From 9abd55f6902e7666c00f2fd6060762c7facf8f72 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Tue, 5 Nov 2024 10:09:06 +0530 Subject: [PATCH 442/537] Corrected _latex_() doctest --- 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 0f0eea77f17..d694fac1dfb 100644 --- a/src/sage/matroids/chow_ring_ideal.py +++ b/src/sage/matroids/chow_ring_ideal.py @@ -195,7 +195,7 @@ def _latex_(self): sage: M1 = Matroid(groundset='abcd', bases=['ab','ad', 'bc']) sage: ch = M1.chow_ring(QQ, False) sage: ch.defining_ideal()._latex_() - I_{M} + J_{M} of matroid \text{\texttt{Matroid{ }of{ }rank{ }2{ }on{ }4{ }elements{ }with{ }3{ }bases}} + '(I_{\\text{\\texttt{Matroid{ }of{ }rank{ }2{ }on{ }4{ }elements{ }with{ }3{ }bases}}} + J_{\\text{\\texttt{Matroid{ }of{ }rank{ }2{ }on{ }4{ }elements{ }with{ }3{ }bases}}}' """ from sage.misc.latex import latex return '(I_{{{M}}} + J_{{{M}}}'.format(M=latex(self._matroid)) From ace86c164d89299d838dc89d419468f1917cc9b6 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Tue, 5 Nov 2024 11:15:19 +0530 Subject: [PATCH 443/537] Edited groebner_basis() for nonaug case --- src/sage/matroids/chow_ring_ideal.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/sage/matroids/chow_ring_ideal.py b/src/sage/matroids/chow_ring_ideal.py index d694fac1dfb..c9e9856de7a 100644 --- a/src/sage/matroids/chow_ring_ideal.py +++ b/src/sage/matroids/chow_ring_ideal.py @@ -247,7 +247,11 @@ def groebner_basis(self, algorithm='', *args, **kwargs): for G in lattice_flats.order_filter([F]): term += flats_gen[G] for G in lattice_flats.order_ideal([F]): - gb.append(flats_gen[G]*(term)**(ranks[F] - ranks[G])) + if G != F: + gb.append(flats_gen[G]*(term) ** (ranks[F] - ranks[G])) + + gb.append(term ** ranks[F]) + return PolynomialSequence(R, [gb]) def normal_basis(self, algorithm='', *args, **kwargs): From 73d6e59f199352d70def7768da1a542617979911 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Tue, 5 Nov 2024 11:17:01 +0530 Subject: [PATCH 444/537] Edited doctests --- 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 c9e9856de7a..ea8e05d4829 100644 --- a/src/sage/matroids/chow_ring_ideal.py +++ b/src/sage/matroids/chow_ring_ideal.py @@ -211,7 +211,7 @@ def groebner_basis(self, algorithm='', *args, **kwargs): [Aa*Abc, Aa, Abc, Aa*Aabc, Abc*Aabc, Aabc] sage: ch.defining_ideal().groebner_basis().is_groebner() True - sage: ch.defining_ideal().hilbert_series() == ch.defining_ideal().hilbert_series(algorithm='singular') + sage: ch.defining_ideal().hilbert_series() == ch.defining_ideal().gens().ideal().hilbert_series() True Another example would be the Groebner basis of the Chow ring ideal of From 770aa161d0f6509b272c955398823eafe440c244 Mon Sep 17 00:00:00 2001 From: Lorenz Panny Date: Tue, 5 Nov 2024 07:36:16 +0100 Subject: [PATCH 445/537] remove deprecated "starks" alias for "stark" algorithm --- src/sage/schemes/elliptic_curves/ell_curve_isogeny.py | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/sage/schemes/elliptic_curves/ell_curve_isogeny.py b/src/sage/schemes/elliptic_curves/ell_curve_isogeny.py index ba752e11c10..f25fbc20a7d 100755 --- a/src/sage/schemes/elliptic_curves/ell_curve_isogeny.py +++ b/src/sage/schemes/elliptic_curves/ell_curve_isogeny.py @@ -3580,10 +3580,6 @@ def compute_isogeny_stark(E1, E2, ell): return qn -from sage.misc.superseded import deprecated_function_alias -compute_isogeny_starks = deprecated_function_alias(34871, compute_isogeny_stark) - - def compute_isogeny_kernel_polynomial(E1, E2, ell, algorithm=None): r""" Return the kernel polynomial of a cyclic, separable, normalized @@ -3650,11 +3646,6 @@ def compute_isogeny_kernel_polynomial(E1, E2, ell, algorithm=None): sage: poly.factor() (x + 10) * (x + 12) * (x + 16) """ - if algorithm == 'starks': - from sage.misc.superseded import deprecation - deprecation(34871, 'The "starks" algorithm is being renamed to "stark".') - algorithm = 'stark' - if algorithm is None: char = E1.base_ring().characteristic() if char != 0 and char < 4*ell + 4: From 217827c60819bf53e2a99b4dbbea10492e7eeb19 Mon Sep 17 00:00:00 2001 From: Lorenz Panny Date: Tue, 5 Nov 2024 07:36:39 +0100 Subject: [PATCH 446/537] remove deprecated .multiplication_by_m_isogeny() --- .../schemes/elliptic_curves/ell_generic.py | 121 +++++------------- src/sage/schemes/elliptic_curves/hom.py | 10 +- .../schemes/elliptic_curves/hom_scalar.py | 3 +- 3 files changed, 34 insertions(+), 100 deletions(-) diff --git a/src/sage/schemes/elliptic_curves/ell_generic.py b/src/sage/schemes/elliptic_curves/ell_generic.py index 6ca3f1fdb46..6f2532e2b3b 100755 --- a/src/sage/schemes/elliptic_curves/ell_generic.py +++ b/src/sage/schemes/elliptic_curves/ell_generic.py @@ -2511,121 +2511,58 @@ def multiplication_by_m(self, m, x_only=False): return mx, my - def multiplication_by_m_isogeny(self, m): + def scalar_multiplication(self, m): r""" - Return the ``EllipticCurveIsogeny`` object associated to the - multiplication-by-`m` map on this elliptic curve. - - The resulting isogeny will - have the associated rational maps (i.e., those returned by - :meth:`multiplication_by_m`) already computed. - - NOTE: This function is currently *much* slower than the - result of ``self.multiplication_by_m()``, because - constructing an isogeny precomputes a significant amount - of information. See :issue:`7368` and :issue:`8014` for the - status of improving this situation. - - INPUT: - - - ``m`` -- nonzero integer + Return the scalar-multiplication map `[m]` on this elliptic + curve as a + :class:`sage.schemes.elliptic_curves.hom_scalar.EllipticCurveHom_scalar` + object. - OUTPUT: + EXAMPLES:: - - An ``EllipticCurveIsogeny`` object associated to the - multiplication-by-`m` map on this elliptic curve. + sage: E = EllipticCurve('77a1') + sage: m = E.scalar_multiplication(-7); m + Scalar-multiplication endomorphism [-7] + of Elliptic Curve defined by y^2 + y = x^3 + 2*x over Rational Field + sage: m.degree() + 49 + sage: P = E(2,3) + sage: m(P) + (-26/225 : -2132/3375 : 1) + sage: m.rational_maps() == E.multiplication_by_m(-7) + True - EXAMPLES:: + :: sage: E = EllipticCurve('11a1') - sage: E.multiplication_by_m_isogeny(7) - doctest:warning ... DeprecationWarning: ... - Isogeny of degree 49 - from Elliptic Curve defined by y^2 + y = x^3 - x^2 - 10*x - 20 - over Rational Field - to Elliptic Curve defined by y^2 + y = x^3 - x^2 - 10*x - 20 - over Rational Field + sage: E.scalar_multiplication(7) + Scalar-multiplication endomorphism [7] + of Elliptic Curve defined by y^2 + y = x^3 - x^2 - 10*x - 20 over Rational Field TESTS: Tests for :issue:`32490`:: sage: E = EllipticCurve(QQbar, [1,0]) # needs sage.rings.number_field - sage: E.multiplication_by_m_isogeny(1).rational_maps() # needs sage.rings.number_field + sage: E.scalar_multiplication(1).rational_maps() # needs sage.rings.number_field (x, y) :: sage: E = EllipticCurve_from_j(GF(31337).random_element()) # needs sage.rings.finite_rings sage: P = E.random_point() # needs sage.rings.finite_rings - sage: [E.multiplication_by_m_isogeny(m)(P) == m*P for m in (1,2,3,5,7,9)] # needs sage.rings.finite_rings + sage: [E.scalar_multiplication(m)(P) == m*P for m in (1,2,3,5,7,9)] # needs sage.rings.finite_rings [True, True, True, True, True, True] :: sage: E = EllipticCurve('99.a1') - sage: E.multiplication_by_m_isogeny(5) - Isogeny of degree 25 from Elliptic Curve defined by y^2 + x*y + y = x^3 - x^2 - 17*x + 30 over Rational Field to Elliptic Curve defined by y^2 + x*y + y = x^3 - x^2 - 17*x + 30 over Rational Field - sage: E.multiplication_by_m_isogeny(2).rational_maps() - ((1/4*x^4 + 33/4*x^2 - 121/2*x + 363/4)/(x^3 - 3/4*x^2 - 33/2*x + 121/4), - (-1/256*x^7 + 1/128*x^6*y - 7/256*x^6 - 3/256*x^5*y - 105/256*x^5 - 165/256*x^4*y + 1255/256*x^4 + 605/128*x^3*y - 473/64*x^3 - 1815/128*x^2*y - 10527/256*x^2 + 2541/128*x*y + 4477/32*x - 1331/128*y - 30613/256)/(1/16*x^6 - 3/32*x^5 - 519/256*x^4 + 341/64*x^3 + 1815/128*x^2 - 3993/64*x + 14641/256)) - - Test for :issue:`34727`:: - - sage: E = EllipticCurve([5,5]) - sage: E.multiplication_by_m_isogeny(-1) - Isogeny of degree 1 - from Elliptic Curve defined by y^2 = x^3 + 5*x + 5 over Rational Field - to Elliptic Curve defined by y^2 = x^3 + 5*x + 5 over Rational Field - sage: E.multiplication_by_m_isogeny(-2) - Isogeny of degree 4 - from Elliptic Curve defined by y^2 = x^3 + 5*x + 5 over Rational Field - to Elliptic Curve defined by y^2 = x^3 + 5*x + 5 over Rational Field - sage: E.multiplication_by_m_isogeny(-3) - Isogeny of degree 9 - from Elliptic Curve defined by y^2 = x^3 + 5*x + 5 over Rational Field - to Elliptic Curve defined by y^2 = x^3 + 5*x + 5 over Rational Field - sage: mu = E.multiplication_by_m_isogeny - sage: all(mu(-m) == -mu(m) for m in (1,2,3,5,7)) - True - """ - from sage.misc.superseded import deprecation - deprecation(32826, 'The .multiplication_by_m_isogeny() method is superseded by .scalar_multiplication().') - - mx, my = self.multiplication_by_m(m) - - torsion_poly = self.torsion_polynomial(abs(m)).monic() - phi = self.isogeny(torsion_poly, codomain=self) - phi._EllipticCurveIsogeny__initialize_rational_maps(precomputed_maps=(mx, my)) - - # trac 32490: using codomain=self can give a wrong isomorphism - for aut in self.automorphisms(): - psi = aut * phi - if psi.rational_maps() == (mx, my): - return psi - - assert False, 'bug in multiplication_by_m_isogeny()' - - def scalar_multiplication(self, m): - r""" - Return the scalar-multiplication map `[m]` on this elliptic - curve as a - :class:`sage.schemes.elliptic_curves.hom_scalar.EllipticCurveHom_scalar` - object. - - EXAMPLES:: - - sage: E = EllipticCurve('77a1') - sage: m = E.scalar_multiplication(-7); m - Scalar-multiplication endomorphism [-7] - of Elliptic Curve defined by y^2 + y = x^3 + 2*x over Rational Field - sage: m.degree() - 49 - sage: P = E(2,3) - sage: m(P) - (-26/225 : -2132/3375 : 1) - sage: m.rational_maps() == E.multiplication_by_m(-7) - True + sage: E.scalar_multiplication(5) + Scalar-multiplication endomorphism [5] + of Elliptic Curve defined by y^2 + x*y + y = x^3 - x^2 - 17*x + 30 over Rational Field + sage: E.scalar_multiplication(2).rational_maps() + ((x^4 + 33*x^2 - 242*x + 363)/(4*x^3 - 3*x^2 - 66*x + 121), + (-4*x^7 + 8*x^6*y - 28*x^6 - 12*x^5*y - 420*x^5 - 660*x^4*y + 5020*x^4 + 4840*x^3*y - 7568*x^3 - 14520*x^2*y - 42108*x^2 + 20328*x*y + 143264*x - 10648*y - 122452)/(64*x^6 - 96*x^5 - 2076*x^4 + 5456*x^3 + 14520*x^2 - 63888*x + 58564)) """ from sage.schemes.elliptic_curves.hom_scalar import EllipticCurveHom_scalar return EllipticCurveHom_scalar(self, m) diff --git a/src/sage/schemes/elliptic_curves/hom.py b/src/sage/schemes/elliptic_curves/hom.py index 22f87bfeed0..01112bc8bb2 100755 --- a/src/sage/schemes/elliptic_curves/hom.py +++ b/src/sage/schemes/elliptic_curves/hom.py @@ -238,12 +238,10 @@ def _richcmp_(self, other, op): sage: wE = identity_morphism(E) sage: wF = identity_morphism(F) sage: mE = E.scalar_multiplication(1) - sage: mF = F.multiplication_by_m_isogeny(1) - doctest:warning ... DeprecationWarning: ... - sage: [mE == wE, mF == wF] - [True, True] - sage: [a == b for a in (wE,mE) for b in (wF,mF)] - [False, False, False, False] + sage: mE == wE + True + sage: [a == wF for a in (wE,mE)] + [False, False] .. SEEALSO:: diff --git a/src/sage/schemes/elliptic_curves/hom_scalar.py b/src/sage/schemes/elliptic_curves/hom_scalar.py index de3a02c9b9d..04e50d8ee5c 100644 --- a/src/sage/schemes/elliptic_curves/hom_scalar.py +++ b/src/sage/schemes/elliptic_curves/hom_scalar.py @@ -396,8 +396,7 @@ def scaling_factor(self): sage: u = phi.scaling_factor() sage: u == phi.formal()[1] True - sage: u == E.multiplication_by_m_isogeny(5).scaling_factor() - doctest:warning ... DeprecationWarning: ... + sage: u == 5 True The scaling factor lives in the base ring:: From 4fdcbd948a6ce3c02993775a70bcddade4bf1bab Mon Sep 17 00:00:00 2001 From: Lorenz Panny Date: Tue, 5 Nov 2024 08:02:52 +0100 Subject: [PATCH 447/537] remove deprecated aliases from #33941 --- src/sage/rings/finite_rings/element_base.pyx | 3 --- src/sage/rings/finite_rings/finite_field_base.pyx | 3 --- src/sage/rings/finite_rings/finite_field_givaro.py | 3 --- src/sage/rings/finite_rings/finite_field_ntl_gf2e.py | 3 --- 4 files changed, 12 deletions(-) diff --git a/src/sage/rings/finite_rings/element_base.pyx b/src/sage/rings/finite_rings/element_base.pyx index aa0a66b4748..2ae6a855057 100755 --- a/src/sage/rings/finite_rings/element_base.pyx +++ b/src/sage/rings/finite_rings/element_base.pyx @@ -22,7 +22,6 @@ from sage.structure.element cimport Element from sage.structure.parent cimport Parent from sage.rings.integer_ring import ZZ from sage.rings.integer import Integer -from sage.misc.superseded import deprecated_function_alias def is_FiniteFieldElement(x): @@ -1104,8 +1103,6 @@ cdef class FinitePolyExtElement(FiniteRingElement): f = f.reverse(self.parent().degree() - 1) return f(p) - integer_representation = deprecated_function_alias(33941, to_integer) - def to_bytes(self, byteorder='big'): r""" Return an array of bytes representing an integer. diff --git a/src/sage/rings/finite_rings/finite_field_base.pyx b/src/sage/rings/finite_rings/finite_field_base.pyx index 085ce14ce87..305ed2ac341 100644 --- a/src/sage/rings/finite_rings/finite_field_base.pyx +++ b/src/sage/rings/finite_rings/finite_field_base.pyx @@ -41,7 +41,6 @@ from sage.misc.cachefunc import cached_method from sage.misc.prandom import randrange from sage.rings.integer cimport Integer import sage.rings.abc -from sage.misc.superseded import deprecation_cython as deprecation, deprecated_function_alias # Copied from sage.misc.fast_methods, used in __hash__() below. cdef int SIZEOF_VOID_P_SHIFT = 8*sizeof(void *) - 4 @@ -457,8 +456,6 @@ cdef class FiniteField(Field): r = r * g + self(d) return r - fetch_int = deprecated_function_alias(33941, from_integer) - def _is_valid_homomorphism_(self, codomain, im_gens, base_map=None): """ Return ``True`` if the map from ``self`` to codomain sending diff --git a/src/sage/rings/finite_rings/finite_field_givaro.py b/src/sage/rings/finite_rings/finite_field_givaro.py index ce61efb8edd..ea40970b276 100644 --- a/src/sage/rings/finite_rings/finite_field_givaro.py +++ b/src/sage/rings/finite_rings/finite_field_givaro.py @@ -23,7 +23,6 @@ from sage.rings.integer import Integer from sage.rings.finite_rings.element_givaro import Cache_givaro from sage.libs.pari.all import pari -from sage.misc.superseded import deprecated_function_alias class FiniteField_givaro(FiniteField): @@ -488,8 +487,6 @@ def from_integer(self, n): """ return self._cache.fetch_int(n) - fetch_int = deprecated_function_alias(33941, from_integer) - def _pari_modulus(self): """ Return the modulus of ``self`` in a format for PARI. diff --git a/src/sage/rings/finite_rings/finite_field_ntl_gf2e.py b/src/sage/rings/finite_rings/finite_field_ntl_gf2e.py index 2bfda7690d3..92404849b4e 100644 --- a/src/sage/rings/finite_rings/finite_field_ntl_gf2e.py +++ b/src/sage/rings/finite_rings/finite_field_ntl_gf2e.py @@ -18,7 +18,6 @@ from sage.rings.finite_rings.finite_field_base import FiniteField from sage.libs.pari.all import pari from sage.rings.integer import Integer -from sage.misc.superseded import deprecated_function_alias def late_import(): @@ -289,8 +288,6 @@ def from_integer(self, number): """ return self._cache.fetch_int(number) - fetch_int = deprecated_function_alias(33941, from_integer) - def _pari_modulus(self): """ Return PARI object which is equivalent to the From c8936d1775ff1216b719d7c5b079b774b7b0a095 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Tue, 5 Nov 2024 12:46:50 +0530 Subject: [PATCH 448/537] Edited doctests --- src/sage/matroids/chow_ring.py | 6 +++--- src/sage/matroids/chow_ring_ideal.py | 6 +++--- src/sage/matroids/matroid.pyx | 31 ++++++++++++++-------------- 3 files changed, 22 insertions(+), 21 deletions(-) diff --git a/src/sage/matroids/chow_ring.py b/src/sage/matroids/chow_ring.py index dbcdcdf4fde..427a7a8493b 100644 --- a/src/sage/matroids/chow_ring.py +++ b/src/sage/matroids/chow_ring.py @@ -192,9 +192,9 @@ def to_vector(self, order=None): sage: ch = matroids.Uniform(3, 6).chow_ring(QQ, False) sage: v = ch.an_element(); v - 0 + -A01 - A02 - A03 - A04 - A05 - A012345 sage: v.to_vector() - (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) + (0, -1, -1, 0, -1, 0, 0, -1, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0) """ P = self.parent() B = P.basis() @@ -253,7 +253,7 @@ def degree(self): A012345^2 2 sage: v = sum(ch.basis()) sage: v.degree() - 0 + 2 """ return self.lift().degree() diff --git a/src/sage/matroids/chow_ring_ideal.py b/src/sage/matroids/chow_ring_ideal.py index ea8e05d4829..0c5fd58d0e4 100644 --- a/src/sage/matroids/chow_ring_ideal.py +++ b/src/sage/matroids/chow_ring_ideal.py @@ -163,7 +163,7 @@ def _gens_constructor(self, poly_ring): term = poly_ring.one() for el in subset: term *= self._flats_generator[el] - I.append(term) #Stanley-Reisner Ideal + I.append(term) # Stanley-Reisner Ideal atoms = self._matroid.lattice_of_flats().atoms() atoms_gen = {a: poly_ring.zero() for a in atoms} for F in flats: @@ -208,7 +208,7 @@ def groebner_basis(self, algorithm='', *args, **kwargs): sage: ch = Matroid(groundset='abc', bases=['ab', 'ac']).chow_ring(QQ, False) sage: ch.defining_ideal().groebner_basis() - [Aa*Abc, Aa, Abc, Aa*Aabc, Abc*Aabc, Aabc] + [Aa*Abc, Aa + Aabc, Abc + Aabc, Aa*Aabc, Abc*Aabc, Aabc^2] sage: ch.defining_ideal().groebner_basis().is_groebner() True sage: ch.defining_ideal().hilbert_series() == ch.defining_ideal().gens().ideal().hilbert_series() @@ -219,7 +219,7 @@ def groebner_basis(self, algorithm='', *args, **kwargs): sage: ch = Matroid(graphs.CycleGraph(3)).chow_ring(QQ, False) sage: ch.defining_ideal().groebner_basis() - [A0*A1, A0*A2, A1*A2, A0, A1, A2, A0*A3, A1*A3, A2*A3, A3] + [A0*A1, A0*A2, A1*A2, A0 + A3, A1 + A3, A2 + A3, A0*A3, A1*A3, A2*A3, A3^2] sage: ch.defining_ideal().groebner_basis().is_groebner() True sage: ch.defining_ideal().hilbert_series() == ch.defining_ideal().gens().ideal().hilbert_series() diff --git a/src/sage/matroids/matroid.pyx b/src/sage/matroids/matroid.pyx index 0427af753de..a2d6ff57eb3 100644 --- a/src/sage/matroids/matroid.pyx +++ b/src/sage/matroids/matroid.pyx @@ -8078,22 +8078,23 @@ cdef class Matroid(SageObject): Next we get the non-trivial generators and do some computations:: sage: # needs sage.libs.singular sage.rings.finite_rings - sage: G = A.gens()[6:]; G - (Ag, Aabf, Aace, Aadg, Abcd, Abeg, Acfg, Adef) - sage: Ag, Aabf, Aace, Aadg, Abcd, Abeg, Acfg, Adef = G - sage: Ag*Ag - 2*Adef^2 - sage: Ag*Abeg - -Adef^2 + sage: G = A.gens()[7:]; G + (Aabf, Aace, Aadg, Abcd, Abeg, Acfg, Adef, Aabcdefg) + sage: Aabf, Aace, Aadg, Abcd, Abeg, Acfg Adef, Aabcdefg = G + sage: Aabf*Aabf + 2*Aabcdefgf^2 + sage: Aabf*Acfg + -Aabcdefg^2 sage: matrix([[x * y for x in G] for y in G]) - [2*Adef^2 0 0 -Adef^2 0 -Adef^2 -Adef^2 0] - [ 0 Adef^2 0 0 0 0 0 0] - [ 0 0 Adef^2 0 0 0 0 0] - [ -Adef^2 0 0 Adef^2 0 0 0 0] - [ 0 0 0 0 Adef^2 0 0 0] - [ -Adef^2 0 0 0 0 Adef^2 0 0] - [ -Adef^2 0 0 0 0 0 Adef^2 0] - [ 0 0 0 0 0 0 0 Adef^2] + [-2*Aabcdefg^2 0 0 Aabcdefg^2 0 Aabcdefg^2 Aabcdefg^2 0 -Aabcdefg^2] + [ 0 -Aabcdefg^2 0 0 0 0 0 0 0] + [ 0 0 -Aabcdefg^2 0 0 0 0 0 0] + [ Aabcdefg^2 0 0 -Aabcdefg^2 0 0 0 0 0] + [ 0 0 0 0 -Aabcdefg^2 0 0 0 0] + [ Aabcdefg^2 0 0 0 0 -Aabcdefg^2 0 0 0] + [ Aabcdefg^2 0 0 0 0 0 -Aabcdefg^2 0 0] + [ 0 0 0 0 0 0 0 -Aabcdefg^2 0] + [ -Aabcdefg^2 0 0 0 0 0 0 0 Aabcdefg^2] The augmented Chow ring can also be constructed with the Feitchner-Yuzvinsky and atom-free presentation:: From d841b58c354dc5416cc21b0cea0616f2f25ef9e5 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Tue, 5 Nov 2024 13:07:14 +0530 Subject: [PATCH 449/537] Resolved PEP8 changes and added matroid() method --- src/sage/matroids/chow_ring.py | 14 ++++++++++++++ src/sage/matroids/chow_ring_ideal.py | 14 +++++--------- src/sage/matroids/matroid.pyx | 19 +++++++++---------- 3 files changed, 28 insertions(+), 19 deletions(-) diff --git a/src/sage/matroids/chow_ring.py b/src/sage/matroids/chow_ring.py index 427a7a8493b..a404e32cf90 100644 --- a/src/sage/matroids/chow_ring.py +++ b/src/sage/matroids/chow_ring.py @@ -137,6 +137,20 @@ def _latex_(self): base += "^*" return base.format(latex(self._matroid), latex(self.base_ring())) + def matroid(self): + r""" + Return the matroid of ``self``. + + EXAMPLES:: + + 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}}} + """ + M = self._matroid + return M + def _coerce_map_from_base_ring(self): r""" Disable the coercion from the base ring from the category. diff --git a/src/sage/matroids/chow_ring_ideal.py b/src/sage/matroids/chow_ring_ideal.py index 0c5fd58d0e4..4d62ed233ab 100644 --- a/src/sage/matroids/chow_ring_ideal.py +++ b/src/sage/matroids/chow_ring_ideal.py @@ -155,8 +155,7 @@ def _gens_constructor(self, poly_ring): Ag + Aadg + Abeg + Acfg + Aabcdefg] """ flats = list(self._flats_generator) - reln = lambda x,y: x <= y - lattice_flats = Poset((flats, reln)) + lattice_flats = Poset((flats, lambda x, y: x <= y)) I = [] subsets = lattice_flats.antichains().elements_of_depth_iterator(2) for subset in subsets: @@ -231,11 +230,10 @@ def groebner_basis(self, algorithm='', *args, **kwargs): return super().groebner_basis(algorithm=algorithm, *args, **kwargs) flats = sorted(list(self._flats_generator), key=len) ranks = {F: self._matroid.rank(F) for F in flats} - gb = list() + gb = [] R = self.ring() - reln = lambda x,y: x <= y flats_gen = self._flats_generator - lattice_flats = Poset((flats, reln)) + lattice_flats = Poset((flats, lambda x, y: x <= y)) antichains = lattice_flats.antichains().elements_of_depth_iterator(2) for subset in antichains: # Taking antichains of size 2 term = R.one() @@ -447,8 +445,7 @@ def _gens_constructor(self, poly_ring): E = list(self._matroid.groundset()) Q = [] L = [] - reln = lambda x, y: x <= y - lattice_flats = Poset((self._flats, reln)) + lattice_flats = Poset((self._flats, lambda x, y: x <= y)) antichains = lattice_flats.antichains().elements_of_depth_iterator(2) for F, G in antichains: Q.append(self._flats_generator[F] * self._flats_generator[G]) # Quadratic generators @@ -735,8 +732,7 @@ def groebner_basis(self, algorithm='', *args, **kwargs): return super().groebner_basis(algorithm=algorithm, *args, **kwargs) gb = [] poly_ring = self.ring() - reln = lambda x,y: x <= y - lattice_flats = Poset((self._flats, reln)) + lattice_flats = Poset((self._flats, lambda x, y: x <= y)) antichains = lattice_flats.antichains().elements_of_depth_iterator(2) for F, G in antichains: gb.append(self._flats_generator[F]*self._flats_generator[G]) diff --git a/src/sage/matroids/matroid.pyx b/src/sage/matroids/matroid.pyx index a2d6ff57eb3..ad91bc392ab 100644 --- a/src/sage/matroids/matroid.pyx +++ b/src/sage/matroids/matroid.pyx @@ -8080,21 +8080,20 @@ cdef class Matroid(SageObject): sage: # needs sage.libs.singular sage.rings.finite_rings sage: G = A.gens()[7:]; G (Aabf, Aace, Aadg, Abcd, Abeg, Acfg, Adef, Aabcdefg) - sage: Aabf, Aace, Aadg, Abcd, Abeg, Acfg Adef, Aabcdefg = G + sage: Aabf, Aace, Aadg, Abcd, Abeg, Acfg, Adef, Aabcdefg = G sage: Aabf*Aabf 2*Aabcdefgf^2 sage: Aabf*Acfg -Aabcdefg^2 sage: matrix([[x * y for x in G] for y in G]) - [-2*Aabcdefg^2 0 0 Aabcdefg^2 0 Aabcdefg^2 Aabcdefg^2 0 -Aabcdefg^2] - [ 0 -Aabcdefg^2 0 0 0 0 0 0 0] - [ 0 0 -Aabcdefg^2 0 0 0 0 0 0] - [ Aabcdefg^2 0 0 -Aabcdefg^2 0 0 0 0 0] - [ 0 0 0 0 -Aabcdefg^2 0 0 0 0] - [ Aabcdefg^2 0 0 0 0 -Aabcdefg^2 0 0 0] - [ Aabcdefg^2 0 0 0 0 0 -Aabcdefg^2 0 0] - [ 0 0 0 0 0 0 0 -Aabcdefg^2 0] - [ -Aabcdefg^2 0 0 0 0 0 0 0 Aabcdefg^2] + [-Aabcdefg^2 0 0 0 0 0 0 0] + [ 0 -Aabcdefg^2 0 0 0 0 0 0] + [ 0 0 -Aabcdefg^2 0 0 0 0 0] + [ 0 0 0 -Aabcdefg^2 0 0 0 0] + [ 0 0 0 0 -Aabcdefg^2 0 0 0] + [ 0 0 0 0 0 -Aabcdefg^2 0 0] + [ 0 0 0 0 0 0 -Aabcdefg^2 0] + [ 0 0 0 0 0 0 0 Aabcdefg^2] The augmented Chow ring can also be constructed with the Feitchner-Yuzvinsky and atom-free presentation:: From 79d3371790e38cb44e91d0b808749279312da554 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Tue, 5 Nov 2024 13:26:30 +0530 Subject: [PATCH 450/537] Corrected doctests --- src/sage/matroids/matroid.pyx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/matroids/matroid.pyx b/src/sage/matroids/matroid.pyx index ad91bc392ab..e06f9b423cf 100644 --- a/src/sage/matroids/matroid.pyx +++ b/src/sage/matroids/matroid.pyx @@ -8082,9 +8082,9 @@ cdef class Matroid(SageObject): (Aabf, Aace, Aadg, Abcd, Abeg, Acfg, Adef, Aabcdefg) sage: Aabf, Aace, Aadg, Abcd, Abeg, Acfg, Adef, Aabcdefg = G sage: Aabf*Aabf - 2*Aabcdefgf^2 - sage: Aabf*Acfg -Aabcdefg^2 + sage: Aabf*Acfg + 0 sage: matrix([[x * y for x in G] for y in G]) [-Aabcdefg^2 0 0 0 0 0 0 0] [ 0 -Aabcdefg^2 0 0 0 0 0 0] From 851abeb0b8d1a294026c70c23ce9beb0319d9855 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Tue, 5 Nov 2024 09:11:42 +0100 Subject: [PATCH 451/537] avoid using "is_prime_field" in dynamics --- .../dynamics/arithmetic_dynamics/affine_ds.py | 26 +++++++++---------- .../arithmetic_dynamics/projective_ds.py | 2 +- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/sage/dynamics/arithmetic_dynamics/affine_ds.py b/src/sage/dynamics/arithmetic_dynamics/affine_ds.py index 2096d734c85..ecf61822ba9 100644 --- a/src/sage/dynamics/arithmetic_dynamics/affine_ds.py +++ b/src/sage/dynamics/arithmetic_dynamics/affine_ds.py @@ -25,7 +25,7 @@ class initialization directly. - Ben Hutz (2017) relocate code and create new class """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2011 Volker Braun # Copyright (C) 2006 David Kohel # Copyright (C) 2006 William Stein @@ -34,8 +34,8 @@ class initialization directly. # 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.categories.fields import Fields from sage.dynamics.arithmetic_dynamics.generic_ds import DynamicalSystem @@ -255,7 +255,7 @@ def __classcall_private__(cls, morphism_or_polys, domain=None): if isinstance(R, FiniteField): return DynamicalSystem_affine_finite_field(polys, domain) return DynamicalSystem_affine_field(polys, domain) - elif isinstance(morphism_or_polys,(list, tuple)): + elif isinstance(morphism_or_polys, (list, tuple)): polys = list(morphism_or_polys) else: polys = [morphism_or_polys] @@ -321,7 +321,7 @@ def __init__(self, polys_or_rat_fncts, domain): L = polys_or_rat_fncts # Next attribute needed for _fast_eval and _fastpolys R = L[0].base_ring() - self._is_prime_finite_field = isinstance(R, FiniteField) and R.is_prime_field() + self._is_prime_finite_field = isinstance(R, FiniteField) and R.degree() == 1 DynamicalSystem.__init__(self, L, domain) def __copy__(self): @@ -535,7 +535,7 @@ def dynatomic_polynomial(self, period): if isinstance(F.parent(), sage.rings.abc.SymbolicRing): from sage.symbolic.ring import var u = var(self.domain().coordinate_ring().variable_name()) - return F.subs({F.variables()[0]:u,F.variables()[1]:1}) + return F.subs({F.variables()[0]: u, F.variables()[1]: 1}) elif T(F.denominator()).degree() == 0: R = F.parent() phi = R.hom([S.gen(0), 1], S) @@ -543,7 +543,7 @@ def dynatomic_polynomial(self, period): else: R = F.numerator().parent() phi = R.hom([S.gen(0), 1], S) - return phi(F.numerator())/phi(F.denominator()) + return phi(F.numerator()) / phi(F.denominator()) def nth_iterate_map(self, n): r""" @@ -612,8 +612,8 @@ def nth_iterate_map(self, n): for i in range(len(D)): for k in range(D[i]): PHI = [poly(F) for poly in PHI] - if i != len(D)-1: #avoid extra iterate - F = [R(poly(F)) for poly in F] #'square' + if i != len(D) - 1: # avoid extra iterate + F = [R(poly(F)) for poly in F] # 'square' return DynamicalSystem_affine(PHI, domain=self.domain()) def nth_iterate(self, P, n): @@ -724,11 +724,11 @@ def orbit(self, P, n): if isinstance(n, (list, tuple)): bounds = list(n) else: - bounds = [0,n] - for i in range(1, bounds[0]+1): + bounds = [0, n] + for i in range(1, bounds[0] + 1): Q = self(Q) orb = [Q] - for i in range(bounds[0]+1, bounds[1]+1): + for i in range(bounds[0] + 1, bounds[1] + 1): Q = self(Q) orb.append(Q) return orb @@ -802,7 +802,7 @@ def multiplier(self, P, n, check=True): J = self.jacobian() for i in range(0, n): R = self(Q) - l = J(tuple(Q))*l #chain rule matrix multiplication + l = J(tuple(Q)) * l # chain rule matrix multiplication Q = R return l diff --git a/src/sage/dynamics/arithmetic_dynamics/projective_ds.py b/src/sage/dynamics/arithmetic_dynamics/projective_ds.py index 8cd24f6611d..38d6d129393 100644 --- a/src/sage/dynamics/arithmetic_dynamics/projective_ds.py +++ b/src/sage/dynamics/arithmetic_dynamics/projective_ds.py @@ -474,7 +474,7 @@ def __init__(self, polys, domain): """ # Next attribute needed for _fast_eval and _fastpolys R = polys[0].base_ring() - self._is_prime_finite_field = isinstance(R, FiniteField) and R.is_prime_field() + self._is_prime_finite_field = isinstance(R, FiniteField) and R.degree() == 1 DynamicalSystem.__init__(self, polys, domain) def __copy__(self): From d45dac9ef368239c7c8bca8981a656e2b26d24c3 Mon Sep 17 00:00:00 2001 From: dcoudert Date: Tue, 5 Nov 2024 09:40:40 +0100 Subject: [PATCH 452/537] PR #38919: fix documentation --- src/sage/graphs/base/graph_backends.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/graphs/base/graph_backends.pyx b/src/sage/graphs/base/graph_backends.pyx index bb07f948d4f..518fe1b6700 100644 --- a/src/sage/graphs/base/graph_backends.pyx +++ b/src/sage/graphs/base/graph_backends.pyx @@ -708,7 +708,7 @@ cdef class GenericGraphBackend(SageObject): TESTS: - Check that :issue:`38900` is fixed: + Check that :issue:`38900` is fixed:: sage: from itertools import product sage: for sparse, immutable in product([True, False], [True, False]): From 3bb7bc5212ad2485092b952c678b80eca254ae21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Tue, 5 Nov 2024 09:57:00 +0100 Subject: [PATCH 453/537] using pathlib in 3 files --- src/sage/rings/polynomial/pbori/nf.py | 19 ++++--- src/sage/sat/solvers/dimacs.py | 50 +++++++++---------- .../schemes/elliptic_curves/ec_database.py | 7 ++- 3 files changed, 36 insertions(+), 40 deletions(-) diff --git a/src/sage/rings/polynomial/pbori/nf.py b/src/sage/rings/polynomial/pbori/nf.py index 004abef5243..09d985f9885 100644 --- a/src/sage/rings/polynomial/pbori/nf.py +++ b/src/sage/rings/polynomial/pbori/nf.py @@ -1,3 +1,6 @@ +from pathlib import Path +from warnings import warn + from sage.rings.polynomial.pbori.pbori import mod_mon_set from .pbori import (BooleSet, GroebnerStrategy, ReductionStrategy, parallel_reduce, easy_linear_factors) @@ -6,8 +9,6 @@ from .easy_polynomials import (easy_linear_polynomials as easy_linear_polynomials_func) from .statistics import used_vars_set -from warnings import warn -import os class GeneratorLimitExceeded(Exception): @@ -69,9 +70,8 @@ def build_and_print_matrices(v, strat): assert j < cols im.putpixel((j, i), 0) - file_name = strat.matrix_prefix + str(mat_counter) + ".png" - if os.path.exists(file_name): - os.remove(file_name) + file_name = Path(strat.matrix_prefix + str(mat_counter) + ".png") + file_name.unlink(missing_ok=True) im.save(file_name) del im @@ -84,8 +84,8 @@ def multiply_polynomials(l, ring): TESTS:: sage: from sage.rings.polynomial.pbori import * - sage: r=Ring(1000) - sage: x=r.variable + sage: r = Ring(1000) + sage: x = r.variable sage: from sage.rings.polynomial.pbori.nf import multiply_polynomials sage: multiply_polynomials([x(3), x(2)+x(5)*x(6), x(0), x(0)+1], r) 0 @@ -149,9 +149,8 @@ def build_and_print_matrices_deg_colored(v, strat): assert j < cols hsl = str(270 - (270 * i2deg[j]) / max_deg) im.putpixel((j, i), ImageColor.getrgb("hsl(" + hsl + ",100%,50%)")) - file_name = strat.matrix_prefix + str(mat_counter) + ".png" - if os.path.exists(file_name): - os.remove(file_name) + file_name = Path(strat.matrix_prefix + str(mat_counter) + ".png") + file_name.unlink(missing_ok=True) im.save(file_name) del im diff --git a/src/sage/sat/solvers/dimacs.py b/src/sage/sat/solvers/dimacs.py index 61d5460d432..09ec052b914 100644 --- a/src/sage/sat/solvers/dimacs.py +++ b/src/sage/sat/solvers/dimacs.py @@ -28,14 +28,14 @@ # https://www.gnu.org/licenses/ ############################################################################## -import os +from pathlib import Path import sys import subprocess import shlex +from time import sleep from sage.sat.solvers.satsolver import SatSolver from sage.misc.temporary_file import tmp_filename -from time import sleep class DIMACS(SatSolver): @@ -44,7 +44,7 @@ class DIMACS(SatSolver): .. NOTE:: - Usually, users won't have to use this class directly but some + Usually, users will not have to use this class directly but some class which inherits from this class. .. automethod:: __init__ @@ -136,10 +136,9 @@ def __del__(self): """ if not self._tail.closed: self._tail.close() - if os.path.exists(self._tail.name): - os.unlink(self._tail.name) - if self._headname_file_created_during_init and os.path.exists(self._headname): - os.unlink(self._headname) + Path(self._tail.name).unlink(missing_ok=True) + if self._headname_file_created_during_init: + Path(self._headname).unlink(missing_ok=True) def var(self, decision=None): """ @@ -209,7 +208,7 @@ def add_clause(self, lits): self.var() l.append(str(lit)) l.append("0\n") - self._tail.write(" ".join(l) ) + self._tail.write(" ".join(l)) self._lit += 1 def write(self, filename=None): @@ -246,19 +245,19 @@ def write(self, filename=None): headname = self._headname if filename is None else filename head = open(headname, "w") head.truncate(0) - head.write("p cnf %d %d\n" % (self._var,self._lit)) + head.write("p cnf %d %d\n" % (self._var, self._lit)) head.close() tail = self._tail tail.close() - head = open(headname,"a") + head = open(headname, "a") tail = open(self._tail.name) head.write(tail.read()) tail.close() head.close() - self._tail = open(self._tail.name,"a") + self._tail = open(self._tail.name, "a") return headname def clauses(self, filename=None): @@ -313,7 +312,7 @@ def clauses(self, filename=None): if lit == 0: break clause.append(lit) - clauses.append( ( tuple(clause), False, None ) ) + clauses.append((tuple(clause), False, None)) tail.close() self._tail = open(self._tail.name, "a") return clauses @@ -362,20 +361,19 @@ def render_dimacs(clauses, filename, nlits): 1 2 -3 0 """ - fh = open(filename, "w") - fh.write("p cnf %d %d\n" % (nlits,len(clauses))) - for clause in clauses: - if len(clause) == 3 and clause[1] in (True, False) and clause[2] in (True,False,None): - lits, is_xor, rhs = clause - else: - lits, is_xor, rhs = clause, False, None - - if is_xor: - closing = lits[-1] if rhs else -lits[-1] - fh.write("x" + " ".join(map(str, lits[:-1])) + " %d 0\n" % closing) - else: - fh.write(" ".join(map(str, lits)) + " 0\n") - fh.close() + with open(filename, "w") as fh: + fh.write("p cnf %d %d\n" % (nlits, len(clauses))) + for clause in clauses: + if len(clause) == 3 and clause[1] in (True, False) and clause[2] in (True, False, None): + lits, is_xor, rhs = clause + else: + lits, is_xor, rhs = clause, False, None + + if is_xor: + closing = lits[-1] if rhs else -lits[-1] + fh.write("x" + " ".join(map(str, lits[:-1])) + " %d 0\n" % closing) + else: + fh.write(" ".join(map(str, lits)) + " 0\n") def _run(self): r""" diff --git a/src/sage/schemes/elliptic_curves/ec_database.py b/src/sage/schemes/elliptic_curves/ec_database.py index 7d418feb437..263e4ba930c 100755 --- a/src/sage/schemes/elliptic_curves/ec_database.py +++ b/src/sage/schemes/elliptic_curves/ec_database.py @@ -67,7 +67,7 @@ which enable easy looping through the Cremona elliptic curve database. """ -import os +from pathlib import Path from ast import literal_eval from .constructor import EllipticCurve @@ -132,10 +132,9 @@ def rank(self, rank, tors=0, n=10, labels=False): """ from sage.features.databases import DatabaseEllcurves db = DatabaseEllcurves() - data = os.path.join(os.path.dirname(db.absolute_filename()), - f'rank{rank}') + data = Path(db.absolute_filename()).parent / f'rank{rank}' try: - f = open(data) + f = data.open() except OSError: return [] v = [] From 3cfedc80a1e668ce29454ab77d8a516b7182f888 Mon Sep 17 00:00:00 2001 From: Verrel Rievaldo Wijaya Date: Tue, 5 Nov 2024 23:32:41 +0700 Subject: [PATCH 454/537] Add mark to long doctest --- src/sage/rings/semirings/tropical_mpolynomial.py | 2 +- src/sage/rings/semirings/tropical_variety.py | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/sage/rings/semirings/tropical_mpolynomial.py b/src/sage/rings/semirings/tropical_mpolynomial.py index ef39e165711..df482120291 100644 --- a/src/sage/rings/semirings/tropical_mpolynomial.py +++ b/src/sage/rings/semirings/tropical_mpolynomial.py @@ -509,7 +509,7 @@ def dual_subdivision(self): sage: p3 = (R(8) + R(4)*x + R(2)*y + R(1)*x^2 + x*y + R(1)*y^2 ....: + R(2)*x^3 + x^2*y + x*y^2 + R(4)*y^3 + R(8)*x^4 ....: + R(4)*x^3*y + x^2*y^2 + R(2)*x*y^3 + y^4) - sage: p3.dual_subdivision().plot() + sage: p3.dual_subdivision().plot() # long time Graphics object consisting of 10 graphics primitives .. PLOT:: diff --git a/src/sage/rings/semirings/tropical_variety.py b/src/sage/rings/semirings/tropical_variety.py index d3f8dbe36f9..9fb279e0d6a 100644 --- a/src/sage/rings/semirings/tropical_variety.py +++ b/src/sage/rings/semirings/tropical_variety.py @@ -899,7 +899,7 @@ def _polygon_vertices(self): sage: p2 = x^2 + x + y + z + R(1) sage: tv2 = p2.tropical_variety() - sage: tv2._polygon_vertices() + sage: tv2._polygon_vertices() # long time {0: {(0, 0, 0), (0, 0, 2), (1, 1, 1), (2, 2, 2)}, 1: {(0, 0, 0), (0, 2, 0), (1, 1, 1), (2, 2, 2)}, 2: {(0, 0, 0), (0, 0, 2), (0, 2, 0), (0, 2, 2)}, @@ -1043,7 +1043,7 @@ def plot(self, color='random'): sage: p2 = x^2 + x + y + z + R(1) sage: tv = p2.tropical_variety() - sage: tv.plot() + sage: tv.plot() # long time Graphics3d Object .. PLOT:: @@ -1602,7 +1602,7 @@ def plot(self): sage: p2 = (x^6 + R(4)*x^4*y^2 + R(2)*x^3*y^3 + R(3)*x^2*y^4 ....: + x*y^5 + R(7)*x^2 + R(5)*x*y + R(3)*y^2 + R(2)*x ....: + y + R(10)) - sage: p2.tropical_variety().plot() + sage: p2.tropical_variety().plot() # long time Graphics object consisting of 11 graphics primitives .. PLOT:: @@ -1621,7 +1621,7 @@ def plot(self): sage: p3 = (R(8) + R(4)*x + R(2)*y + R(1)*x^2 + x*y + R(1)*y^2 ....: + R(2)*x^3 + x^2*y + x*y^2 + R(4)*y^3 + R(8)*x^4 ....: + R(4)*x^3*y + x^2*y^2 + R(2)*x*y^3 + y^4) - sage: p3.tropical_variety().plot() + sage: p3.tropical_variety().plot() # long time Graphics object consisting of 23 graphics primitives .. PLOT:: From eb201659dde486749366dfd10fdc077c89e195d7 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Tue, 5 Nov 2024 22:07:02 +0530 Subject: [PATCH 455/537] Edited matroid() method --- src/sage/matroids/chow_ring.py | 3 +-- src/sage/matroids/chow_ring_ideal.py | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/sage/matroids/chow_ring.py b/src/sage/matroids/chow_ring.py index a404e32cf90..173c8db7f84 100644 --- a/src/sage/matroids/chow_ring.py +++ b/src/sage/matroids/chow_ring.py @@ -148,8 +148,7 @@ def matroid(self): U(3, 6): Matroid of rank 3 on 6 elements with circuit-closures {3: {{0, 1, 2, 3, 4, 5}}} """ - M = self._matroid - return M + return self._matroid def _coerce_map_from_base_ring(self): r""" diff --git a/src/sage/matroids/chow_ring_ideal.py b/src/sage/matroids/chow_ring_ideal.py index 4d62ed233ab..53bdfedd246 100644 --- a/src/sage/matroids/chow_ring_ideal.py +++ b/src/sage/matroids/chow_ring_ideal.py @@ -25,8 +25,7 @@ def matroid(self): U(3, 6): Matroid of rank 3 on 6 elements with circuit-closures {3: {{0, 1, 2, 3, 4, 5}}} """ - M = self._matroid - return M + return self._matroid def _lattice_flats(self): r""" From b67546e1b3311192877987813226f7cab00d5892 Mon Sep 17 00:00:00 2001 From: janmenjayap Date: Tue, 5 Nov 2024 22:10:52 +0530 Subject: [PATCH 456/537] updated delete_vertex() --- src/sage/graphs/matching_covered_graph.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sage/graphs/matching_covered_graph.py b/src/sage/graphs/matching_covered_graph.py index b24144f523b..cee61834794 100644 --- a/src/sage/graphs/matching_covered_graph.py +++ b/src/sage/graphs/matching_covered_graph.py @@ -1664,12 +1664,12 @@ def delete_vertex(self, vertex, in_order=False): ... ValueError: odd order is not allowed for matching covered graphs """ - if in_order: - vertex = self.vertices(sort=True)[vertex] - if vertex not in self: raise ValueError('vertex (%s) not in the graph' % str(vertex)) + if in_order: + vertex = self.vertices(sort=True)[vertex] + raise ValueError('odd order is not allowed for ' 'matching covered graphs') From b70350d80513097e1b134983602f3530a318d44c Mon Sep 17 00:00:00 2001 From: janmenjayap Date: Tue, 5 Nov 2024 22:11:59 +0530 Subject: [PATCH 457/537] added doctests for delete_vertex() --- src/sage/graphs/matching_covered_graph.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/sage/graphs/matching_covered_graph.py b/src/sage/graphs/matching_covered_graph.py index cee61834794..f145419dd28 100644 --- a/src/sage/graphs/matching_covered_graph.py +++ b/src/sage/graphs/matching_covered_graph.py @@ -1653,6 +1653,10 @@ def delete_vertex(self, vertex, in_order=False): Traceback (most recent call last): ... ValueError: vertex (100) not in the graph + sage: G.delete_vertex(vertex=u, in_order=True) + Traceback (most recent call last): + ... + ValueError: vertex (100) not in the graph Deleting an existing vertex:: @@ -1663,6 +1667,10 @@ def delete_vertex(self, vertex, in_order=False): Traceback (most recent call last): ... ValueError: odd order is not allowed for matching covered graphs + sage: G.delete_vertex(vertex=u, in_order=True) + Traceback (most recent call last): + ... + ValueError: odd order is not allowed for matching covered graphs """ if vertex not in self: raise ValueError('vertex (%s) not in the graph' % str(vertex)) From 6a68edfe6b2c2419a74351082739282a140a0f8f Mon Sep 17 00:00:00 2001 From: janmenjayap Date: Tue, 5 Nov 2024 22:22:39 +0530 Subject: [PATCH 458/537] updated the doctests for _subgraph_by_adding() --- src/sage/graphs/matching_covered_graph.py | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/sage/graphs/matching_covered_graph.py b/src/sage/graphs/matching_covered_graph.py index f145419dd28..ca36adb7ff0 100644 --- a/src/sage/graphs/matching_covered_graph.py +++ b/src/sage/graphs/matching_covered_graph.py @@ -743,8 +743,8 @@ def _subgraph_by_adding(self, vertices=None, edges=None, edge_property=None, imm EXAMPLES: - Ladder graphs are subgraphs of a staircase graph, that is - matching covered:: + Ladder graphs are matching covered subgraphs of a staircase graph, + which is also matching covered:: sage: G = MatchingCoveredGraph(graphs.StaircaseGraph(4)) sage: H = G._subgraph_by_adding(vertices=[0..5]) @@ -755,8 +755,8 @@ def _subgraph_by_adding(self, vertices=None, edges=None, edge_property=None, imm sage: H.is_isomorphic(graphs.LadderGraph(3)) True - Cycle graphs are subgraphs of a biwheel graph, that is - matching covered:: + Cycle graphs are matching covered subgraphs of a biwheel graph, which + is also matching covered:: sage: G = MatchingCoveredGraph(graphs.BiwheelGraph(5)) sage: H = G._subgraph_by_adding(vertices=[0..7], @@ -768,6 +768,15 @@ def _subgraph_by_adding(self, vertices=None, edges=None, edge_property=None, imm sage: H.is_isomorphic(graphs.CycleGraph(8)) True + One may pass no value for any of the input arguments; in such a case, + the whole matching covered graph will be returned:: + + sage: T = graphs.TwinplexGraph() + sage: G = MatchingCoveredGraph(T) + sage: J = G._subgraph_by_adding() + sage: G == J + True + One may use the ``edge_property`` argument:: sage: G = Graph(multiedges=True) From abb1b56a1e14f886676f6169214ee6e69ebd349b Mon Sep 17 00:00:00 2001 From: janmenjayap Date: Tue, 5 Nov 2024 22:29:31 +0530 Subject: [PATCH 459/537] added doctests for _subgraph_by_adding() --- src/sage/graphs/matching_covered_graph.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/sage/graphs/matching_covered_graph.py b/src/sage/graphs/matching_covered_graph.py index ca36adb7ff0..9e4ae0d38f7 100644 --- a/src/sage/graphs/matching_covered_graph.py +++ b/src/sage/graphs/matching_covered_graph.py @@ -812,6 +812,14 @@ def _subgraph_by_adding(self, vertices=None, edges=None, edge_property=None, imm True sage: H.is_immutable() True + sage: C = graphs.CubeplexGraph() + sage: D = MatchingCoveredGraph(C) + sage: I = D._subgraph_by_adding(immutable=True) + sage: (I == D) and (I.is_immutable()) + True + sage: J = D._subgraph_by_adding(vertices=D.vertices(), immutable=True) + sage: (J == D) and (J.is_immutable()) + True An error is thrown if the subgraph is not matching covered:: From 41e46b40fcf1c518f5622fa368bcbabb7dd7c8a1 Mon Sep 17 00:00:00 2001 From: janmenjayap Date: Tue, 5 Nov 2024 22:35:50 +0530 Subject: [PATCH 460/537] updated the doctests for add_edges() --- src/sage/graphs/matching_covered_graph.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/sage/graphs/matching_covered_graph.py b/src/sage/graphs/matching_covered_graph.py index 9e4ae0d38f7..8207842d346 100644 --- a/src/sage/graphs/matching_covered_graph.py +++ b/src/sage/graphs/matching_covered_graph.py @@ -1260,11 +1260,16 @@ def add_edges(self, edges, loops=False): sage: H = graphs.HexahedralGraph() sage: G = MatchingCoveredGraph(H) - sage: F = {(0, 5), (2, 7)} + sage: F = [(3, 8), (6, 9), (8, 9)] sage: G.add_edges(F) Traceback (most recent call last): ... ValueError: the resulting graph after the addition ofthe edges is not matching covered + sage: I = [(0, 8), (1, 9)] + sage: G.add_edges(I) + Traceback (most recent call last): + ... + ValueError: the resulting graph after the addition ofthe edges is not matching covered sage: J = [(u, 8) for u in range(8)] sage: G.add_edges(J) Traceback (most recent call last): From 17b6e3bf7582f72a6c059a730bf9491f03d2bd73 Mon Sep 17 00:00:00 2001 From: janmenjayap Date: Tue, 5 Nov 2024 22:38:10 +0530 Subject: [PATCH 461/537] updated the todo list --- src/sage/graphs/matching_covered_graph.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/sage/graphs/matching_covered_graph.py b/src/sage/graphs/matching_covered_graph.py index 8207842d346..2826d4b3974 100644 --- a/src/sage/graphs/matching_covered_graph.py +++ b/src/sage/graphs/matching_covered_graph.py @@ -36,7 +36,7 @@ ``__hash__()`` | Compute a hash for ``self``, if ``self`` is immutable. ``_subgraph_by_deleting()`` | Return the matching covered subgraph containing the provided vertices and edges. - Overwritten Methods: + **Overwritten Methods:** .. csv-table:: :class: contentstable @@ -89,7 +89,7 @@ ``transitive_reduction()`` | Return a transitive reduction of the matching covered graph. ``union()`` | Return the union of ``self`` and ``other``. - Barriers and canonical partition: + **Barriers and canonical partition:** .. csv-table:: :class: contentstable @@ -99,7 +99,7 @@ ``canonical_partition()`` | Return the canonical partition of the (matching covered) graph. ``maximal_barrier()`` | Return the (unique) maximal barrier of the (matching covered) graph containing the (provided) vertex. - Bricks, braces and tight cut decomposition: + **Bricks, braces and tight cut decomposition:** .. csv-table:: :class: contentstable @@ -114,7 +114,7 @@ ``number_of_petersen_bricks()`` | Return the number of Petersen bricks. ``tight_cut_decomposition()`` | Return a tight cut decomposition. - Removability and ear decomposition: + **Removability and ear decomposition:** .. csv-table:: :class: contentstable @@ -136,7 +136,7 @@ ``removable_edges()`` | Return a :class:`~EdgesView` of removable edges. ``retract()`` | Compute the retract of the (matching covered) graph. - Generating bricks and braces: + **Generating bricks and braces:** .. csv-table:: :class: contentstable From eb35d26ebf651da7b777a9b0fe58335d9359a08f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Tue, 5 Nov 2024 21:35:45 +0100 Subject: [PATCH 462/537] expunge is_commutative from plural --- src/sage/rings/polynomial/plural.pyx | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/src/sage/rings/polynomial/plural.pyx b/src/sage/rings/polynomial/plural.pyx index 35de7feefe5..698ac322b48 100644 --- a/src/sage/rings/polynomial/plural.pyx +++ b/src/sage/rings/polynomial/plural.pyx @@ -99,6 +99,17 @@ TESTS:: sage: TestSuite(P).run() sage: loads(dumps(P)) is P True + + sage: A. = FreeAlgebra(QQ, 3) + sage: P = A.g_algebra(relations={y*x:-x*y}, order = 'lex') + sage: P.is_commutative() + False + + sage: R. = FreeAlgebra(QQ, 3) + sage: P = R.g_algebra(relations={},order='lex') + sage: P.is_commutative() + True + """ from cysignals.memory cimport sig_malloc, sig_free @@ -676,22 +687,7 @@ cdef class NCPolynomialRing_plural(Ring): """ return self._term_order - def is_commutative(self): - """ - Return ``False``. - - .. TODO:: Provide a mathematically correct answer. - - EXAMPLES:: - - sage: A. = FreeAlgebra(QQ, 3) - sage: P = A.g_algebra(relations={y*x:-x*y}, order = 'lex') - sage: P.is_commutative() - False - """ - return False - - def is_field(self, *args, **kwargs): + def is_field(self, *args, **kwargs) -> bool: """ Return ``False``. From 2a457420c41bd9a745b9a42665266b0b2b07b7d6 Mon Sep 17 00:00:00 2001 From: "John H. Palmieri" Date: Tue, 5 Nov 2024 13:14:11 -0800 Subject: [PATCH 463/537] OS X: do not use -ld_classic. Filter out some ld warnings when doctesting. --- src/bin/sage-env | 26 -------------------------- src/sage/doctest/parsing.py | 15 +++++++++++++++ src/sage/tests/cmdline.py | 11 ++++++++++- 3 files changed, 25 insertions(+), 27 deletions(-) diff --git a/src/bin/sage-env b/src/bin/sage-env index b9221fe3567..942adc0445a 100644 --- a/src/bin/sage-env +++ b/src/bin/sage-env @@ -373,32 +373,6 @@ if [ -n "$SAGE_LOCAL" ]; then # Construct and export LDFLAGS if [ "$UNAME" = "Darwin" ]; then LDFLAGS="-L$SAGE_LOCAL/lib $LDFLAGS" - # On OS X, use the old linker if it is available. - # if "ld-classic" is present in the selected XCode - # toolchain, add "-Wl,-ld_classic" to LDFLAGS (see #36599) unless - # LD is already set, as it will be with conda on macOS. When the - # selected toolchain is in the Xcode app the output of "xcode-select -p" - # is "/Applications/Xcode.app/Contents/Developer", but "ld-classic" is - # not in the subdirectory "usr/bin/" but rather in the subdirectory - # "Toolchains/XcodeDefault.xctoolchain/usr/bin/". (See #37237.) - if [ -z "$LD" ]; then - # Running xcode-select on a system with no toolchain writes an - # error message to stderr, so redirect stderr to /dev/null. - XCODE_PATH=$(/usr/bin/xcode-select -p 2> /dev/null) - if [ -n $XCODE_PATH ]; then - if [ -x "$XCODE_PATH/usr/bin/ld-classic" -o \ - -x "$XCODE_PATH/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld-classic" ]; then - LDFLAGS="$LDFLAGS -Wl,-ld_classic" - fi - else - # On a macOS system with no toolchain we don't want this script - # to call gcc because that will also print an error message to - # stderr. We can avoid this by setting AS and LD to their - # default values. - AS=as - LD=ld - fi - fi fi if [ "$UNAME" = "Linux" ]; then LDFLAGS="-L$SAGE_LOCAL/lib -Wl,-rpath,$SAGE_LOCAL/lib $LDFLAGS" diff --git a/src/sage/doctest/parsing.py b/src/sage/doctest/parsing.py index 0bc4965cd09..20f6eb6ce69 100644 --- a/src/sage/doctest/parsing.py +++ b/src/sage/doctest/parsing.py @@ -1516,6 +1516,21 @@ def do_fixup(self, want, got): pythran_numpy_warning_regex = re.compile(r'WARNING: Overriding pythran description with argspec information for: numpy\.random\.[a-z_]+') got = pythran_numpy_warning_regex.sub('', got) did_fixup = True + + if "ld_classic is deprecated" in got: + # New warnings as of Oct '24, Xcode 16. + ld_warn_regex = re.compile("ld: warning: -ld_classic is deprecated and will be removed in a future release") + got = ld_warn_regex.sub('', got) + did_fixup = True + + if "duplicate libraries" in got: + # New warnings as of Sept '23, OS X 13.6, new command-line + # tools. In particular, these seem to come from ld in + # Xcode 15. + dup_lib_regex = re.compile("ld: warning: ignoring duplicate libraries: .*") + got = dup_lib_regex.sub('', got) + did_fixup = True + return did_fixup, want, got def output_difference(self, example, got, optionflags): diff --git a/src/sage/tests/cmdline.py b/src/sage/tests/cmdline.py index 406bf1befab..27c614d290f 100644 --- a/src/sage/tests/cmdline.py +++ b/src/sage/tests/cmdline.py @@ -776,4 +776,13 @@ def test_executable(args, input='', timeout=100.0, pydebug_ignore_warnings=False p.stderr.close() err.append(s) - return (''.join(out), ''.join(err), p.wait()) + # In case out or err contains a quoted string, force the use of + # double quotes so that the output is enclosed in single + # quotes. This avoids some doctest failures with some versions of + # OS X and Xcode. + out = ''.join(out) + out = out.replace("'", '"') + err = ''.join(err) + err = err.replace("'", '"') + + return (out, err, p.wait()) From f13aa2ec91b3b91dfd0bfce76ac90048025f155a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Wed, 6 Nov 2024 11:34:12 +0100 Subject: [PATCH 464/537] Apply suggestions from code review Co-authored-by: Martin Rubey --- src/sage/rings/polynomial/plural.pyx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/sage/rings/polynomial/plural.pyx b/src/sage/rings/polynomial/plural.pyx index 698ac322b48..adf127b5841 100644 --- a/src/sage/rings/polynomial/plural.pyx +++ b/src/sage/rings/polynomial/plural.pyx @@ -106,10 +106,9 @@ TESTS:: False sage: R. = FreeAlgebra(QQ, 3) - sage: P = R.g_algebra(relations={},order='lex') + sage: P = R.g_algebra(relations={}, order='lex') sage: P.is_commutative() True - """ from cysignals.memory cimport sig_malloc, sig_free From 7fa30e60a1ba5071a096ab5465e6c1f4ce2386d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Tue, 5 Nov 2024 21:35:45 +0100 Subject: [PATCH 465/537] switch to artifacts@v4 --- .github/workflows/ci-macos.yml | 6 +++--- .github/workflows/docker.yml | 4 ++-- .github/workflows/macos.yml | 8 ++++---- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/.github/workflows/ci-macos.yml b/.github/workflows/ci-macos.yml index 2f3a9cf6e4e..c62d259c286 100644 --- a/.github/workflows/ci-macos.yml +++ b/.github/workflows/ci-macos.yml @@ -95,7 +95,7 @@ jobs: - name: make dist run: | ./configure --enable-download-from-upstream-url && make dist - - uses: actions/upload-artifact@v3 + - uses: actions/upload-artifact@v4 with: path: "dist/*.tar.gz" name: dist @@ -119,7 +119,7 @@ jobs: steps: - uses: actions/checkout@v4 if: "!contains(matrix.tox_system_factor, 'nobootstrap')" - - uses: actions/download-artifact@v3 + - uses: actions/download-artifact@v4 with: path: . name: dist @@ -147,7 +147,7 @@ jobs: run: | mkdir -p "artifacts/$LOGS_ARTIFACT_NAME"; cp -r .tox/*/log "artifacts/$LOGS_ARTIFACT_NAME" if: always() - - uses: actions/upload-artifact@v3 + - uses: actions/upload-artifact@v4 with: path: artifacts name: ${{ env.LOGS_ARTIFACT_NAME }} diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 4f3d1441544..a7d5ecc8835 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -170,7 +170,7 @@ jobs: ref: ${{ inputs.sage_ref }} fetch-depth: 10000 - name: Download upstream artifact - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: path: upstream name: ${{ inputs.upstream_artifact }} @@ -260,7 +260,7 @@ jobs: cp -r .tox/$TOX_ENV/* "artifacts/$LOGS_ARTIFACT_NAME" rm -rf "artifacts/$LOGS_ARTIFACT_NAME"/{bin,lib,pyvenv.cfg} if: always() - - uses: actions/upload-artifact@v3 + - uses: actions/upload-artifact@v4 with: path: artifacts name: ${{ env.LOGS_ARTIFACT_NAME }} diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index 3d0732bcb7e..38c7feb9ad8 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -91,7 +91,7 @@ jobs: run: | "${{ steps.python.outputs.python-path }}" -m pip install pipx - name: Download upstream artifact - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: path: upstream name: ${{ inputs.upstream_artifact }} @@ -108,7 +108,7 @@ jobs: GH_TOKEN: ${{ github.token }} SAGE_CI_FIXES_FROM_REPOSITORIES: ${{ vars.SAGE_CI_FIXES_FROM_REPOSITORIES }} - - uses: actions/download-artifact@v3 + - uses: actions/download-artifact@v4 with: path: sage-local-artifact name: ${{ env.LOCAL_ARTIFACT_NAME }} @@ -147,7 +147,7 @@ jobs: run: | mkdir -p "artifacts/$LOGS_ARTIFACT_NAME"; cp -r .tox/*/log "artifacts/$LOGS_ARTIFACT_NAME" if: always() - - uses: actions/upload-artifact@v3 + - uses: actions/upload-artifact@v4 with: path: artifacts name: ${{ env.LOGS_ARTIFACT_NAME }} @@ -165,7 +165,7 @@ jobs: run: | mkdir -p sage-local-artifact && (cd .tox/$TOX_ENV && rm -f "local/lib64" && tar -cf - $(pwd)) > sage-local-artifact/sage-${{ env.TOX_ENV }}-${{ inputs.stage }}.tar if: contains(inputs.stage, '1') - - uses: actions/upload-artifact@v3 + - uses: actions/upload-artifact@v4 with: path: sage-local-artifact/sage-${{ env.TOX_ENV }}-${{ inputs.stage }}.tar name: ${{ env.LOCAL_ARTIFACT_NAME }} From a4cc208f4f8a1d5e347c313ab8bf16d78240798c Mon Sep 17 00:00:00 2001 From: janmenjayap Date: Wed, 6 Nov 2024 21:08:08 +0530 Subject: [PATCH 466/537] Updated the statement for doc index --- src/sage/graphs/matching_covered_graph.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/graphs/matching_covered_graph.py b/src/sage/graphs/matching_covered_graph.py index 2826d4b3974..760f7b146fd 100644 --- a/src/sage/graphs/matching_covered_graph.py +++ b/src/sage/graphs/matching_covered_graph.py @@ -2066,4 +2066,4 @@ def update_matching(self, matching): raise exception -__doc__ = __doc__.replace("{INDEX_OF_METHODS}", gen_thematic_rest_table_index(MatchingCoveredGraph)) \ No newline at end of file +__doc__ = __doc__.replace('{INDEX_OF_METHODS}', gen_thematic_rest_table_index(MatchingCoveredGraph, only_local_functions=False)) \ No newline at end of file From 91d517a78485744b5095cfc2a55e7e3baf1114ad Mon Sep 17 00:00:00 2001 From: janmenjayap Date: Wed, 6 Nov 2024 21:08:54 +0530 Subject: [PATCH 467/537] Updated the doc index for get_matching() --- src/sage/graphs/matching_covered_graph.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/graphs/matching_covered_graph.py b/src/sage/graphs/matching_covered_graph.py index 760f7b146fd..4223ca0196e 100644 --- a/src/sage/graphs/matching_covered_graph.py +++ b/src/sage/graphs/matching_covered_graph.py @@ -1855,7 +1855,7 @@ def delete_vertices(self, vertices): raise ValueError('the resulting graph after the removal of ' 'the vertices is not matching covered') - @doc_index('Overwritten methods') + @doc_index('Miscellaneous methods') def get_matching(self): r""" Return a :class:`~EdgesView` of ``self._matching`` (a perfect matching From ba562c9c467cd0588d911ae391fd0b45f9ec948e Mon Sep 17 00:00:00 2001 From: janmenjayap Date: Wed, 6 Nov 2024 21:09:34 +0530 Subject: [PATCH 468/537] Updated the import statement for Graph --- src/sage/graphs/matching_covered_graph.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/graphs/matching_covered_graph.py b/src/sage/graphs/matching_covered_graph.py index 4223ca0196e..55cff896cb9 100644 --- a/src/sage/graphs/matching_covered_graph.py +++ b/src/sage/graphs/matching_covered_graph.py @@ -162,7 +162,7 @@ # (at your option) any later version. # https://www.gnu.org/licenses/ # **************************************************************************** -from .graph import Graph +from sage.graphs.graph import Graph from sage.misc.rest_index_of_methods import doc_index, gen_thematic_rest_table_index class MatchingCoveredGraph(Graph): From 5cf46b1be954fe0d5a70bcc0a569e5ae24ce4aa4 Mon Sep 17 00:00:00 2001 From: Verrel Rievaldo Wijaya Date: Wed, 6 Nov 2024 22:40:30 +0700 Subject: [PATCH 469/537] Add the data for newton polytope and dual subdivision --- .../rings/semirings/tropical_mpolynomial.py | 91 ++++++++++++++++--- src/sage/rings/semirings/tropical_variety.py | 8 +- 2 files changed, 84 insertions(+), 15 deletions(-) diff --git a/src/sage/rings/semirings/tropical_mpolynomial.py b/src/sage/rings/semirings/tropical_mpolynomial.py index df482120291..f5635ca886b 100644 --- a/src/sage/rings/semirings/tropical_mpolynomial.py +++ b/src/sage/rings/semirings/tropical_mpolynomial.py @@ -11,6 +11,8 @@ sage: R. = PolynomialRing(T) sage: z.parent() Multivariate Tropical Polynomial Semiring in x, y, z over Rational Field + sage: R(2)*x + R(-1)*x + R(5)*y + R(-3) + (-1)*x + 5*y + (-3) sage: (x+y+z)^2 0*x^2 + 0*x*y + 0*y^2 + 0*x*z + 0*y*z + 0*z^2 @@ -211,7 +213,7 @@ def subs(self, fixed=None, **kwds): return self(tuple(variables)) def plot3d(self, color='random'): - """ + r""" Return the 3d plot of ``self``. Only implemented for tropical polynomial in two variables. @@ -406,7 +408,7 @@ def tropical_variety(self): return TropicalVariety(self) def newton_polytope(self): - """ + r""" Return the Newton polytope of ``self``. The Newton polytope is the convex hull of all the points @@ -424,6 +426,12 @@ def newton_polytope(self): sage: p1 = x + y sage: p1.newton_polytope() A 1-dimensional polyhedron in ZZ^2 defined as the convex hull of 2 vertices + sage: p1.newton_polytope().Vrepresentation() + (A vertex at (0, 1), A vertex at (1, 0)) + sage: p1.newton_polytope().Hrepresentation() + (An equation (1, 1) x - 1 == 0, + An inequality (0, -1) x + 1 >= 0, + An inequality (0, 1) x + 0 >= 0) .. PLOT:: :width: 300 px @@ -441,6 +449,19 @@ def newton_polytope(self): sage: p1 = x^2 + x*y*z + x + y + z + R(0) sage: p1.newton_polytope() A 3-dimensional polyhedron in ZZ^3 defined as the convex hull of 5 vertices + sage: p1.newton_polytope().Vrepresentation() + (A vertex at (0, 0, 0), + A vertex at (0, 0, 1), + A vertex at (0, 1, 0), + A vertex at (2, 0, 0), + A vertex at (1, 1, 1)) + sage: p1.newton_polytope().Hrepresentation() + (An inequality (0, 1, 0) x + 0 >= 0, + An inequality (0, 0, 1) x + 0 >= 0, + An inequality (1, 0, 0) x + 0 >= 0, + An inequality (1, -1, -1) x + 1 >= 0, + An inequality (-1, -2, 1) x + 2 >= 0, + An inequality (-1, 1, -2) x + 2 >= 0) .. PLOT:: :width: 300 px @@ -477,8 +498,13 @@ def dual_subdivision(self): sage: T = TropicalSemiring(QQ, use_min=False) sage: R. = PolynomialRing(T) sage: p1 = R(3) + R(2)*x + R(2)*y + R(3)*x*y + x^2 + y^2 - sage: p1.dual_subdivision() + sage: pc = p1.dual_subdivision(); pc Polyhedral complex with 4 maximal cells + sage: [p.Vrepresentation() for p in pc.maximal_cells_sorted()] + [(A vertex at (0, 0), A vertex at (0, 1), A vertex at (1, 1)), + (A vertex at (0, 0), A vertex at (1, 0), A vertex at (1, 1)), + (A vertex at (0, 1), A vertex at (0, 2), A vertex at (1, 1)), + (A vertex at (1, 0), A vertex at (1, 1), A vertex at (2, 0))] .. PLOT:: :width: 300 px @@ -492,8 +518,14 @@ def dual_subdivision(self): A subdivision of a pentagonal Newton polytope:: sage: p2 = R(3) + x^2 + R(-2)*y + R(1/2)*x^2*y + R(2)*x*y^3 + R(-1)*x^3*y^4 - sage: p2.dual_subdivision() + sage: pc = p2.dual_subdivision(); pc Polyhedral complex with 5 maximal cells + sage: [p.Vrepresentation() for p in pc.maximal_cells_sorted()] + [(A vertex at (0, 0), A vertex at (0, 1), A vertex at (1, 3)), + (A vertex at (0, 0), A vertex at (1, 3), A vertex at (2, 1)), + (A vertex at (0, 0), A vertex at (2, 0), A vertex at (2, 1)), + (A vertex at (1, 3), A vertex at (2, 1), A vertex at (3, 4)), + (A vertex at (2, 0), A vertex at (2, 1), A vertex at (3, 4))] .. PLOT:: :width: 300 px @@ -506,16 +538,32 @@ def dual_subdivision(self): A subdivision with many faces, not all of which are triangles:: + sage: T = TropicalSemiring(QQ) + sage: R. = PolynomialRing(T) sage: p3 = (R(8) + R(4)*x + R(2)*y + R(1)*x^2 + x*y + R(1)*y^2 ....: + R(2)*x^3 + x^2*y + x*y^2 + R(4)*y^3 + R(8)*x^4 ....: + R(4)*x^3*y + x^2*y^2 + R(2)*x*y^3 + y^4) - sage: p3.dual_subdivision().plot() # long time - Graphics object consisting of 10 graphics primitives + sage: pc = p3.dual_subdivision(); pc + Polyhedral complex with 10 maximal cells + sage: [p.Vrepresentation() for p in pc.maximal_cells_sorted()] + [(A vertex at (0, 0), A vertex at (0, 1), A vertex at (1, 0)), + (A vertex at (0, 1), A vertex at (0, 2), A vertex at (1, 1)), + (A vertex at (0, 1), A vertex at (1, 0), A vertex at (2, 0)), + (A vertex at (0, 1), A vertex at (1, 1), A vertex at (2, 0)), + (A vertex at (0, 2), A vertex at (0, 4), A vertex at (1, 1)), + (A vertex at (0, 4), + A vertex at (1, 1), + A vertex at (2, 1), + A vertex at (2, 2)), + (A vertex at (1, 1), A vertex at (2, 0), A vertex at (2, 1)), + (A vertex at (2, 0), A vertex at (2, 1), A vertex at (3, 0)), + (A vertex at (2, 1), A vertex at (2, 2), A vertex at (3, 0)), + (A vertex at (2, 2), A vertex at (3, 0), A vertex at (4, 0))] .. PLOT:: :width: 300 px - T = TropicalSemiring(QQ, use_min=False) + T = TropicalSemiring(QQ) R = PolynomialRing(T, ('x,y')) x, y = R.gen(), R.gen(1) p3 = (R(8) + R(4)*x + R(2)*y + R(1)*x**2 + x*y + R(1)*y**2 @@ -528,8 +576,16 @@ def dual_subdivision(self): sage: T = TropicalSemiring(QQ) sage: R. = PolynomialRing(T) sage: p1 = x + y + z + x^2 + R(1) - sage: p1.dual_subdivision() + sage: pc = p1.dual_subdivision(); pc Polyhedral complex with 7 maximal cells + sage: [p.Vrepresentation() for p in pc.maximal_cells_sorted()] + [(A vertex at (0, 0, 0), A vertex at (0, 0, 1), A vertex at (0, 1, 0)), + (A vertex at (0, 0, 0), A vertex at (0, 0, 1), A vertex at (1, 0, 0)), + (A vertex at (0, 0, 0), A vertex at (0, 1, 0), A vertex at (1, 0, 0)), + (A vertex at (0, 0, 1), A vertex at (0, 1, 0), A vertex at (1, 0, 0)), + (A vertex at (0, 0, 1), A vertex at (0, 1, 0), A vertex at (2, 0, 0)), + (A vertex at (0, 0, 1), A vertex at (1, 0, 0), A vertex at (2, 0, 0)), + (A vertex at (0, 1, 0), A vertex at (1, 0, 0), A vertex at (2, 0, 0))] .. PLOT:: :width: 300 px @@ -545,8 +601,21 @@ def dual_subdivision(self): sage: T = TropicalSemiring(QQ) sage: R. = PolynomialRing(T) sage: p1 = R(2)*a*b + R(3)*a*c + R(-1)*c^2 + R(-1/3)*a*d - sage: p1.dual_subdivision() + sage: pc = p1.dual_subdivision(); pc Polyhedral complex with 4 maximal cells + sage: [p.Vrepresentation() for p in pc.maximal_cells_sorted()] + [(A vertex at (0, 0, 2, 0), + A vertex at (1, 0, 0, 1), + A vertex at (1, 0, 1, 0)), + (A vertex at (0, 0, 2, 0), + A vertex at (1, 0, 0, 1), + A vertex at (1, 1, 0, 0)), + (A vertex at (0, 0, 2, 0), + A vertex at (1, 0, 1, 0), + A vertex at (1, 1, 0, 0)), + (A vertex at (1, 0, 0, 1), + 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 @@ -581,7 +650,7 @@ def dual_subdivision(self): def _repr_(self): r""" - Return string representation of ``self``. + Return a string representation of ``self``. EXAMPLES:: @@ -602,7 +671,7 @@ def _repr_(self): def _latex_(self): r""" - Return the latex representation of ``self``. + Return a latex representation of ``self``. EXAMPLES:: diff --git a/src/sage/rings/semirings/tropical_variety.py b/src/sage/rings/semirings/tropical_variety.py index 9fb279e0d6a..7a6f4cac787 100644 --- a/src/sage/rings/semirings/tropical_variety.py +++ b/src/sage/rings/semirings/tropical_variety.py @@ -542,10 +542,10 @@ def weight_vectors(self): Assume ``self`` is a `n`-dimensional tropical variety. Suppose `L` is an intersection lying within the components - `S_1, ldots, S_k` with respective weights `w_1, ldots, w_k`. + `S_1, \ldots, S_k` with respective weights `w_1, \ldots, w_k`. This `L` is a linear structure in `\RR^{n-1}` and has `n-1` direction vectors `d_1,d_2,\ldots, d_{n-1}`. Each component - `S_1, ldots, S_k` has a normal vector `n_1, \ldots, n_k`. + `S_1, \ldots, S_k` has a normal vector `n_1, \ldots, n_k`. Then, we scale each normal vector to an integer vector such that the greatest common divisor of its elements is 1. @@ -1303,12 +1303,12 @@ def weight_vectors(self): of the curve. Each vector corresponds to an edge emanating from that vertex and points in the direction of the edge. - Suppose `v` is a vertex adjacent to the edges `e_1, ldots, e_k` + Suppose `v` is a vertex adjacent to the edges `e_1, \ldots, e_k` with respective weights `w_1, \ldots, w_k`. Every edge `e_i` is contained in a line (component) defined by an equation. Therefore, there exists a unique integer vector `v_i = (\alpha, \beta)` in the direction of `e_i` such that `\gcd(\alpha, \beta)=1`. Then, - each vertex `v` yield the vectors `w_1 v_1, ldots, w_k v_k`. + each vertex `v` yield the vectors `w_1 v_1, \ldots, w_k v_k`. These vectors will satisfy the following balancing condition: `\sum_{i=1}^k w_i v_i = 0`. From e79ccb9721fa89bd3a8103694ea14285afbdedbd Mon Sep 17 00:00:00 2001 From: "John H. Palmieri" Date: Tue, 5 Nov 2024 21:53:39 -0800 Subject: [PATCH 470/537] Test whether "ld -ld_classic" has been deprecated --- src/bin/sage-env | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/src/bin/sage-env b/src/bin/sage-env index 942adc0445a..5a53ab1d2ce 100644 --- a/src/bin/sage-env +++ b/src/bin/sage-env @@ -373,6 +373,35 @@ if [ -n "$SAGE_LOCAL" ]; then # Construct and export LDFLAGS if [ "$UNAME" = "Darwin" ]; then LDFLAGS="-L$SAGE_LOCAL/lib $LDFLAGS" + # On OS X, use the old linker if it is available. + # if "ld-classic" is present in the selected XCode + # toolchain, add "-Wl,-ld_classic" to LDFLAGS (see #36599) unless + # LD is already set, as it will be with conda on macOS. When the + # selected toolchain is in the Xcode app the output of "xcode-select -p" + # is "/Applications/Xcode.app/Contents/Developer", but "ld-classic" is + # not in the subdirectory "usr/bin/" but rather in the subdirectory + # "Toolchains/XcodeDefault.xctoolchain/usr/bin/". (See #37237.) + if [ -z "$LD" ]; then + # Running xcode-select on a system with no toolchain writes an + # error message to stderr, so redirect stderr to /dev/null. + XCODE_PATH=$(/usr/bin/xcode-select -p 2> /dev/null) + if [ -n $XCODE_PATH ]; then + if [ -x "$XCODE_PATH/usr/bin/ld-classic" -o \ + -x "$XCODE_PATH/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld-classic" ]; then + # Add -ld_classic only if -ld_classic is not deprecated. + if [ -z "$(ld -ld_classic 2>&1 | grep 'ld_classic is deprecated')" ]; then + LDFLAGS="$LDFLAGS -Wl,-ld_classic" + fi + fi + else + # On a macOS system with no toolchain we don't want this script + # to call gcc because that will also print an error message to + # stderr. We can avoid this by setting AS and LD to their + # default values. + AS=as + LD=ld + fi + fi fi if [ "$UNAME" = "Linux" ]; then LDFLAGS="-L$SAGE_LOCAL/lib -Wl,-rpath,$SAGE_LOCAL/lib $LDFLAGS" From 62a7a8857e50f161871f7f3dd142a0b69efc3247 Mon Sep 17 00:00:00 2001 From: janmenjayap Date: Wed, 6 Nov 2024 23:34:29 +0530 Subject: [PATCH 471/537] updated the description of get_matching() --- src/sage/graphs/matching_covered_graph.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/sage/graphs/matching_covered_graph.py b/src/sage/graphs/matching_covered_graph.py index 55cff896cb9..983670d1058 100644 --- a/src/sage/graphs/matching_covered_graph.py +++ b/src/sage/graphs/matching_covered_graph.py @@ -1858,8 +1858,7 @@ def delete_vertices(self, vertices): @doc_index('Miscellaneous methods') def get_matching(self): r""" - Return a :class:`~EdgesView` of ``self._matching`` (a perfect matching - of the (matching covered) graph computed at the initialization). + Return an :class:`~EdgesView` of ``self._matching``. OUTPUT: From 0cd4391aac1d6025f96e3ac26ee08994427274ea Mon Sep 17 00:00:00 2001 From: janmenjayap Date: Thu, 7 Nov 2024 00:42:54 +0530 Subject: [PATCH 472/537] updated the todo list --- src/sage/graphs/matching_covered_graph.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/sage/graphs/matching_covered_graph.py b/src/sage/graphs/matching_covered_graph.py index 983670d1058..3d5492d1df3 100644 --- a/src/sage/graphs/matching_covered_graph.py +++ b/src/sage/graphs/matching_covered_graph.py @@ -36,7 +36,7 @@ ``__hash__()`` | Compute a hash for ``self``, if ``self`` is immutable. ``_subgraph_by_deleting()`` | Return the matching covered subgraph containing the provided vertices and edges. - **Overwritten Methods:** + **Overwritten Methods** .. csv-table:: :class: contentstable @@ -89,7 +89,7 @@ ``transitive_reduction()`` | Return a transitive reduction of the matching covered graph. ``union()`` | Return the union of ``self`` and ``other``. - **Barriers and canonical partition:** + **Barriers and canonical partition** .. csv-table:: :class: contentstable @@ -99,7 +99,7 @@ ``canonical_partition()`` | Return the canonical partition of the (matching covered) graph. ``maximal_barrier()`` | Return the (unique) maximal barrier of the (matching covered) graph containing the (provided) vertex. - **Bricks, braces and tight cut decomposition:** + **Bricks, braces and tight cut decomposition** .. csv-table:: :class: contentstable @@ -114,7 +114,7 @@ ``number_of_petersen_bricks()`` | Return the number of Petersen bricks. ``tight_cut_decomposition()`` | Return a tight cut decomposition. - **Removability and ear decomposition:** + **Removability and ear decomposition** .. csv-table:: :class: contentstable @@ -136,7 +136,7 @@ ``removable_edges()`` | Return a :class:`~EdgesView` of removable edges. ``retract()`` | Compute the retract of the (matching covered) graph. - **Generating bricks and braces:** + **Generating bricks and braces** .. csv-table:: :class: contentstable From 67f81b6b94100d1bf899e19fddb8e89e103d6220 Mon Sep 17 00:00:00 2001 From: Dima Pasechnik Date: Thu, 7 Nov 2024 05:06:24 +0000 Subject: [PATCH 473/537] keep meson.build file for ext/interpreters --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 53d2c689843..fcba88cff79 100644 --- a/Makefile +++ b/Makefile @@ -122,7 +122,7 @@ sagelib-clean: rm -rf c_lib .cython_version cython_debug; \ rm -rf build; find . -name '*.pyc' -o -name "*.so" | xargs rm -f; \ rm -f $$(find . -name "*.pyx" | sed 's/\(.*\)[.]pyx$$/\1.c \1.cpp/'); \ - rm -rf sage/ext/interpreters) \ + cd sage/ext/interpreters/; rm -f *.so *.c *.h *.py* *.pxd) \ && (cd "$(SAGE_ROOT)/build/pkgs/sagelib/src/" && rm -rf build); \ fi From b003c50c586232628137b6f86cca6c2721ae8ae7 Mon Sep 17 00:00:00 2001 From: Dima Pasechnik Date: Thu, 7 Nov 2024 07:35:53 -0600 Subject: [PATCH 474/537] safer "rm" (preceded by cd [..] &&), README about src/sage/ext/interpreters/ --- .gitignore | 1 + Makefile | 2 +- src/sage/ext/interpreters/README | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) create mode 100644 src/sage/ext/interpreters/README diff --git a/.gitignore b/.gitignore index 7d8c2f0adc4..0d216c36b8f 100644 --- a/.gitignore +++ b/.gitignore @@ -147,6 +147,7 @@ __pycache__/ # Generated by sage_setup.autogen /src/sage/ext/interpreters !/src/sage/ext/interpreters/meson.build +!/src/sage/ext/interpreters/README # Generated Cython files *.so diff --git a/Makefile b/Makefile index fcba88cff79..96d1ba62e94 100644 --- a/Makefile +++ b/Makefile @@ -122,7 +122,7 @@ sagelib-clean: rm -rf c_lib .cython_version cython_debug; \ rm -rf build; find . -name '*.pyc' -o -name "*.so" | xargs rm -f; \ rm -f $$(find . -name "*.pyx" | sed 's/\(.*\)[.]pyx$$/\1.c \1.cpp/'); \ - cd sage/ext/interpreters/; rm -f *.so *.c *.h *.py* *.pxd) \ + cd sage/ext/interpreters/ && rm -f *.so *.c *.h *.py* *.pxd) \ && (cd "$(SAGE_ROOT)/build/pkgs/sagelib/src/" && rm -rf build); \ fi diff --git a/src/sage/ext/interpreters/README b/src/sage/ext/interpreters/README new file mode 100644 index 00000000000..1e42d921e68 --- /dev/null +++ b/src/sage/ext/interpreters/README @@ -0,0 +1 @@ +The files in this directory, except meson.build, are autogenerated by sage_setup.autogen From 4598eda6eb8e1680fc0c634fb0ceae60fbcd3e93 Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Thu, 7 Nov 2024 18:56:01 +0100 Subject: [PATCH 475/537] make MolecularSpecies.__classcall__ sane --- src/sage/rings/species.py | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/src/sage/rings/species.py b/src/sage/rings/species.py index cb48673d21c..0a362c0b4fb 100644 --- a/src/sage/rings/species.py +++ b/src/sage/rings/species.py @@ -766,7 +766,7 @@ class MolecularSpecies(IndexedFreeAbelianMonoid): The monoid of (multivariate) molecular species. """ @staticmethod - def __classcall__(cls, *args, **kwds): + def __classcall__(cls, names): """ Normalize the arguments. @@ -779,17 +779,10 @@ def __classcall__(cls, *args, **kwds): sage: MolecularSpecies("X,Y") == MolecularSpecies(["X", "Z"]) False """ - if isinstance(args[0], AtomicSpecies): - indices = args[0] - else: - assert "names" not in kwds or kwds["names"] is None - indices = AtomicSpecies(args[0]) - category = Monoids().Commutative() & SetsWithGrading().Infinite() - return super().__classcall__(cls, indices, - prefix='', bracket=False, - category=category) + names = normalize_names(-1, names) + return UniqueRepresentation.__classcall__(cls, names) - def __init__(self, *args, **kwds): + def __init__(self, names): r""" Initialize the class of (multivariate) molecular species. @@ -817,8 +810,11 @@ def __init__(self, *args, **kwds): sage: M2 = MolecularSpecies(["X", "Y"]) sage: TestSuite(M2).run(skip="_test_graded_components") """ - IndexedFreeAbelianMonoid.__init__(self, *args, **kwds) - self._arity = args[0]._arity + indices = AtomicSpecies(names) + category = Monoids().Commutative() & SetsWithGrading().Infinite() + IndexedFreeAbelianMonoid.__init__(self, indices, prefix='', + bracket=False, category=category) + self._arity = indices._arity def _repr_(self): r""" From ade63cc61213736f849d4790fec49907e5939d04 Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Thu, 7 Nov 2024 20:59:06 +0100 Subject: [PATCH 476/537] improve documentation --- src/sage/rings/species.py | 119 +++++++++++++++++++++++++++----------- 1 file changed, 86 insertions(+), 33 deletions(-) diff --git a/src/sage/rings/species.py b/src/sage/rings/species.py index 0a362c0b4fb..b1b66f7351a 100644 --- a/src/sage/rings/species.py +++ b/src/sage/rings/species.py @@ -1,3 +1,36 @@ +r""" +Polynomial virtual weighted multisort species + +A combinatorial species, as introduced by Joyal, is a functor from +the category of finite sets with bijections to the category of finite +sets with bijections. Alternatively, we can regard a combinatorial +species as a formal sum of group actions of the symmetric groups +`\mathfrak S_n`, for `n\in\NN`. For example, the trivial action of +`\mathfrak S_n` corresponds to the species `\mathcal E_n$ of sets of +cardinality `n`. + +More generally, a weighted multisort species in `k` sorts is a +functor from the category of `k`-tuples of finite sets with +bijections to the category of weighted finite sets with +weight-preserving bijections. We may think of the sorts as +variables, traditionally denoted by `X, Y, Z`. + +Such a species is equivalent to a formal sum of group actions of +groups `\mathfrak S_{n_1}\times\cdots\mathfrak S_{n_k}` with +`(n_1,\dots,n_k)\in\NN^k`, together with a weight on the orbits of +each group action. Yet more generally, a virtual weighted multisort +species is a formal difference of weighted multisort species. + +The class :class:`PolynomialSpecies` represents polynomial virtual +weighted multisort species, that is, formal sums of finitely many +actions. + +AUTHORS: + +- Mainak Roy and Martin Rubey (2024-11): Initial version + +""" + from itertools import accumulate, chain from sage.categories.graded_algebras_with_basis import GradedAlgebrasWithBasis @@ -314,8 +347,13 @@ def __le__(self, other): class AtomicSpecies(UniqueRepresentation, Parent): - """ - The class of atomic species. + r""" + The set of multisort atomic species. + + INPUT: + + - ``names`` -- an iterable of strings for the sorts of the + species """ @staticmethod def __classcall__(cls, names): @@ -339,12 +377,7 @@ def __classcall__(cls, names): def __init__(self, names): r""" - Initialize the class of (multivariate) atomic species. - - INPUT: - - - ``names`` -- an iterable of strings for the sorts of the - species + Initialize the class of (multisort) atomic species. TESTS: @@ -762,8 +795,21 @@ def _stabilizer_subgroups(G, X, a): class MolecularSpecies(IndexedFreeAbelianMonoid): - """ - The monoid of (multivariate) molecular species. + r""" + The monoid of multisort molecular species. + + INPUT: + + - ``names`` -- an iterable of strings for the sorts of the + species + + EXAMPLES:: + + sage: from sage.rings.species import MolecularSpecies + sage: M = MolecularSpecies("X,Y") + sage: G = PermutationGroup([[(1,2),(3,4)], [(5,6)]]) + sage: M(G, {0: [5,6], 1: [1,2,3,4]}) + E_2(X)*{((1,2)(3,4),): ({}, {1, 2, 3, 4})} """ @staticmethod def __classcall__(cls, names): @@ -784,20 +830,7 @@ def __classcall__(cls, names): def __init__(self, names): r""" - Initialize the class of (multivariate) molecular species. - - INPUT: - - - ``names`` -- an iterable of ``k`` strings for the sorts of - the species - - EXAMPLES:: - - sage: from sage.rings.species import MolecularSpecies - sage: M = MolecularSpecies("X,Y") - sage: G = PermutationGroup([[(1,2),(3,4)], [(5,6)]]) - sage: M(G, {0: [5,6], 1: [1,2,3,4]}) - E_2(X)*{((1,2)(3,4),): ({}, {1, 2, 3, 4})} + Initialize the monoid of (multisort) molecular species. TESTS: @@ -805,6 +838,7 @@ def __init__(self, names): :meth:`~sage.combinat.integer_vector.IntegerVectors.some_elements` yields degrees that are too large:: + sage: from sage.rings.species import MolecularSpecies sage: M1 = MolecularSpecies("X") sage: TestSuite(M1).run(skip="_test_graded_components") sage: M2 = MolecularSpecies(["X", "Y"]) @@ -1368,7 +1402,7 @@ def __call__(self, *args): sage: (X*Y)(X, Y^2) X*Y^2 - A multivariate example:: + A multisort example:: sage: M1 = MolecularSpecies("X") sage: M2 = MolecularSpecies("X, Y") @@ -1959,6 +1993,23 @@ def _from_etuple(e): class PolynomialSpecies(CombinatorialFreeModule): + r""" + The ring of polynomial weighted virtual multisort species. + + INPUT: + + - ``base_ring`` -- a ring + - ``names`` -- an iterable of strings for the sorts of the + species + + EXAMPLES:: + + sage: from sage.rings.species import PolynomialSpecies + sage: P. = PolynomialSpecies(QQ) + sage: G = SymmetricGroup(5).young_subgroup([2, 3]) + sage: P(G, ([1,2], [3,4,5])) + E_2(X)*E_3(Y) + """ def __classcall__(cls, base_ring, names): r""" Normalize the arguments. @@ -1979,7 +2030,7 @@ def __classcall__(cls, base_ring, names): def __init__(self, base_ring, names): r""" - Ring of `k`-variate polynomial (virtual) species. + Initialize the ring of (multisort) polynomial species. TESTS:: @@ -2016,13 +2067,14 @@ def _repr_(self): def _element_constructor_(self, G, pi=None, check=True): r""" - Construct the `k`-variate polynomial species with the given data. + Construct the `k`-variate polynomial species with the + given data. INPUT: - - ``G`` -- element of ``self`` (in this case ``pi`` must be ``None``) - permutation group, or pair ``(X, a)`` consisting of a - finite set and an action + - ``G`` -- element of ``self`` (in this case ``pi`` must be + ``None``), permutation group, or pair ``(X, a)`` consisting + of a finite set and an action - ``pi`` -- ``dict`` mapping sorts to iterables whose union is the domain of ``G`` (if ``G`` is a permutation group) or the domain of the acting symmetric group (if ``G`` is a @@ -2094,6 +2146,7 @@ def _element_constructor_(self, G, pi=None, check=True): ....: raise ValueError sage: P((X, lambda g, x: act(x[0], x[1], g)), pi) 2*Y*E_2(X) + """ if parent(G) is self: # pi cannot be None because of framework @@ -2242,9 +2295,9 @@ def _powersum(self, s, n): .. TODO:: - This is really a univariate species, so it would be better - to have a fast way to change all the variables of a - univariate species into a new sort. + This is really a species of a single sort, so it might be + better to have a fast way to turn a single sort species + into a multisort species EXAMPLES:: From f34b3cf653f02e0f599382b61c6adbd14a93cfe1 Mon Sep 17 00:00:00 2001 From: user202729 <25191436+user202729@users.noreply.github.com> Date: Wed, 7 Aug 2024 15:42:55 +0700 Subject: [PATCH 477/537] Eisenstein series: Small documentation improvement --- src/sage/lfunctions/dokchitser.py | 6 ++++-- src/sage/modular/modform/eis_series.py | 21 +++++++++++++-------- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/src/sage/lfunctions/dokchitser.py b/src/sage/lfunctions/dokchitser.py index cc06d96c503..8877636f395 100644 --- a/src/sage/lfunctions/dokchitser.py +++ b/src/sage/lfunctions/dokchitser.py @@ -42,6 +42,8 @@ class Dokchitser(SageObject): r""" Dokchitser's `L`-functions Calculator. + PARI code can be found on + `Dokchitser's homepage `_. Create a Dokchitser `L`-series with @@ -153,7 +155,7 @@ class Dokchitser(SageObject): We redefine the default bound on the coefficients: Deligne's estimate on tau(n) is better than the default - coefgrow(n)=`(4n)^{11/2}` (by a factor 1024), so + coefgrow(n)= `(4n)^{11/2}` (by a factor 1024), so re-defining coefgrow() improves efficiency (slightly faster). :: sage: L.num_coeffs() @@ -571,7 +573,7 @@ def taylor_series(self, a=0, k=6, var='z'): - ``a`` -- complex number (default: 0); point about which to expand - - ``k`` -- integer (default: 6); series is `O(``var``^k)` + - ``k`` -- integer (default: 6); series is `O(\texttt{var}^k)` - ``var`` -- string (default: ``'z'``); variable of power series diff --git a/src/sage/modular/modform/eis_series.py b/src/sage/modular/modform/eis_series.py index 73ea6dcaf1c..f259b69b685 100644 --- a/src/sage/modular/modform/eis_series.py +++ b/src/sage/modular/modform/eis_series.py @@ -388,7 +388,8 @@ def eisenstein_series_lseries(weight, prec=53, on `\SL_2(\ZZ)`. This actually returns an interface to Tim Dokchitser's program - for computing with the `L`-series of the Eisenstein series + for computing with the `L`-series of the Eisenstein series. + See :class:`~sage.lfunctions.dokchitser.Dokchitser`. INPUT: @@ -400,18 +401,22 @@ def eisenstein_series_lseries(weight, prec=53, - ``max_asymp_coeffs`` -- integer - OUTPUT: the `L`-series of the Eisenstein series + OUTPUT: the `L`-series of the Eisenstein series. This can be + evaluated at argument `s`, or have + :meth:`~sage.lfunctions.dokchitser.Dokchitser.derivative` called, etc. EXAMPLES: We compute with the `L`-series of `E_{16}` and then `E_{20}`:: - sage: L = eisenstein_series_lseries(16) - sage: L(1) - -0.291657724743874 - sage: L = eisenstein_series_lseries(20) - sage: L(2) - -5.02355351645998 + sage: L = eisenstein_series_lseries(16) + sage: L(1) + -0.291657724743874 + sage: L.derivative(1) + 0.0756072194360656 + sage: L = eisenstein_series_lseries(20) + sage: L(2) + -5.02355351645998 Now with higher precision:: From d029739194197e1a0a1b5cae0c60aceddf7d0d9f Mon Sep 17 00:00:00 2001 From: user202729 <25191436+user202729@users.noreply.github.com> Date: Thu, 8 Aug 2024 13:45:01 +0700 Subject: [PATCH 478/537] Another minor change --- src/sage/modular/modform/eis_series.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/modular/modform/eis_series.py b/src/sage/modular/modform/eis_series.py index f259b69b685..5676bf0507a 100644 --- a/src/sage/modular/modform/eis_series.py +++ b/src/sage/modular/modform/eis_series.py @@ -384,7 +384,7 @@ def eisenstein_series_lseries(weight, prec=53, max_imaginary_part=0, max_asymp_coeffs=40): r""" - Return the `L`-series of the weight `2k` Eisenstein series + Return the `L`-series of the weight `2k` Eisenstein series `E_{2k}` on `\SL_2(\ZZ)`. This actually returns an interface to Tim Dokchitser's program From 0a58e70f6b7090f440140d3d37cc346798aafcb0 Mon Sep 17 00:00:00 2001 From: user202729 <25191436+user202729@users.noreply.github.com> Date: Fri, 8 Nov 2024 06:46:31 +0700 Subject: [PATCH 479/537] Apply suggested change --- src/sage/lfunctions/dokchitser.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/sage/lfunctions/dokchitser.py b/src/sage/lfunctions/dokchitser.py index 8877636f395..500a9a57fd0 100644 --- a/src/sage/lfunctions/dokchitser.py +++ b/src/sage/lfunctions/dokchitser.py @@ -42,6 +42,7 @@ class Dokchitser(SageObject): r""" Dokchitser's `L`-functions Calculator. + PARI code can be found on `Dokchitser's homepage `_. From a05f3468c69e75806dca892d25435fbaf3a9ce39 Mon Sep 17 00:00:00 2001 From: user202729 <25191436+user202729@users.noreply.github.com> Date: Fri, 8 Nov 2024 07:40:56 +0700 Subject: [PATCH 480/537] Sanity check parent of Vector_numpy_integer_dense --- src/sage/modules/vector_numpy_integer_dense.pyx | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/sage/modules/vector_numpy_integer_dense.pyx b/src/sage/modules/vector_numpy_integer_dense.pyx index ba3537436d5..58beac4636c 100644 --- a/src/sage/modules/vector_numpy_integer_dense.pyx +++ b/src/sage/modules/vector_numpy_integer_dense.pyx @@ -13,6 +13,13 @@ EXAMPLES:: sage: v.numpy() array([ 0, 42, 0]) # 64-bit array([ 0, 42, 0], dtype=int64) # 32-bit + +TESTS:: + + sage: Vector_numpy_integer_dense(FreeModule(GF(2), 3), [0, 0, 0]) + Traceback (most recent call last): + ... + ValueError: parent must have base ring ZZ """ # **************************************************************************** @@ -36,6 +43,8 @@ numpy.import_array() cdef class Vector_numpy_integer_dense(Vector_numpy_dense): def __cinit__(self, parent, entries, coerce=True, copy=True): + if parent.base_ring() is not ZZ: + raise ValueError("parent must have base ring ZZ") self._numpy_dtype = numpy.dtype('int64') self._numpy_dtypeint = numpy.NPY_INT64 self._python_dtype = int From 727d4d22e43c6ca6e607439777c97da40a4ca26a Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Fri, 8 Nov 2024 02:30:57 +0100 Subject: [PATCH 481/537] Update src/sage/rings/species.py Co-authored-by: Travis Scrimshaw --- src/sage/rings/species.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/rings/species.py b/src/sage/rings/species.py index b1b66f7351a..ad42ae4b284 100644 --- a/src/sage/rings/species.py +++ b/src/sage/rings/species.py @@ -6,7 +6,7 @@ sets with bijections. Alternatively, we can regard a combinatorial species as a formal sum of group actions of the symmetric groups `\mathfrak S_n`, for `n\in\NN`. For example, the trivial action of -`\mathfrak S_n` corresponds to the species `\mathcal E_n$ of sets of +`\mathfrak S_n` corresponds to the species `\mathcal E_n` of sets of cardinality `n`. More generally, a weighted multisort species in `k` sorts is a From ff604c827f1f315a36cb96b47bd9439f3180edad Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Fri, 8 Nov 2024 02:31:36 +0100 Subject: [PATCH 482/537] Update src/sage/rings/species.py Co-authored-by: Travis Scrimshaw --- src/sage/rings/species.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/rings/species.py b/src/sage/rings/species.py index ad42ae4b284..7ead92ba16f 100644 --- a/src/sage/rings/species.py +++ b/src/sage/rings/species.py @@ -16,8 +16,8 @@ variables, traditionally denoted by `X, Y, Z`. Such a species is equivalent to a formal sum of group actions of -groups `\mathfrak S_{n_1}\times\cdots\mathfrak S_{n_k}` with -`(n_1,\dots,n_k)\in\NN^k`, together with a weight on the orbits of +groups `\mathfrak S_{n_1} \times \cdots \times \mathfrak S_{n_k}` with +`(n_1,\ldots,n_k)\in\NN^k`, together with a weight on the orbits of each group action. Yet more generally, a virtual weighted multisort species is a formal difference of weighted multisort species. From affa033f1dc12c547d16d326168d4294267e9108 Mon Sep 17 00:00:00 2001 From: user202729 <25191436+user202729@users.noreply.github.com> Date: Sun, 28 Jul 2024 07:16:51 +0700 Subject: [PATCH 483/537] number_field_elements_from_algebraics: Fix CyclotomicField embedding when embedding=False --- src/sage/rings/qqbar.py | 96 +++++++++++++++++++++++++++++++++++------ 1 file changed, 84 insertions(+), 12 deletions(-) diff --git a/src/sage/rings/qqbar.py b/src/sage/rings/qqbar.py index 300d64b8279..fe37ea15fd7 100644 --- a/src/sage/rings/qqbar.py +++ b/src/sage/rings/qqbar.py @@ -2556,7 +2556,8 @@ def number_field_elements_from_algebraics(numbers, minimal=False, - ``same_field`` -- boolean (default: ``False``); see below - ``embedded`` -- boolean (default: ``False``); whether to make the - NumberField embedded + NumberField embedded, note that this has no effect when the + resulting field is ``QQ`` because there is only one ``QQ`` instance - ``name`` -- string (default: ``'a'``); name of the primitive element @@ -2827,6 +2828,69 @@ def number_field_elements_from_algebraics(numbers, minimal=False, To: Algebraic Real Field Defn: 1 |--> 1) + Test ``embedded`` for quadratic and cyclotomic fields:: + + sage: number_field_elements_from_algebraics([QQbar((-1)^(2/3))], embedded=False, minimal=True) + (Number Field in zeta6 with defining polynomial x^2 - x + 1, + [zeta6 - 1], + Ring morphism: + From: Number Field in zeta6 with defining polynomial x^2 - x + 1 + To: Algebraic Field + Defn: zeta6 |--> 0.500000000000000? + 0.866025403784439?*I) + sage: _[0].coerce_embedding() + sage: number_field_elements_from_algebraics([QQbar((-1)^(2/3))], embedded=True, minimal=True) + (Cyclotomic Field of order 6 and degree 2, + [zeta6 - 1], + Ring morphism: + From: Cyclotomic Field of order 6 and degree 2 + To: Algebraic Field + Defn: zeta6 |--> 0.500000000000000? + 0.866025403784439?*I) + sage: _[0].coerce_embedding() + Generic morphism: + From: Cyclotomic Field of order 6 and degree 2 + To: Complex Lazy Field + Defn: zeta6 -> 0.500000000000000? + 0.866025403784439?*I + sage: number_field_elements_from_algebraics([QQbar((-1)^(1/2))], embedded=False, minimal=True) + (Number Field in I with defining polynomial x^2 + 1, + [I], + Ring morphism: + From: Number Field in I with defining polynomial x^2 + 1 + To: Algebraic Field + Defn: I |--> 1*I) + sage: _[0].coerce_embedding() + sage: number_field_elements_from_algebraics([QQbar((-1)^(1/2))], embedded=True, minimal=True) + (Number Field in I with defining polynomial x^2 + 1 with I = 1*I, + [I], + Ring morphism: + From: Number Field in I with defining polynomial x^2 + 1 with I = 1*I + To: Algebraic Field + Defn: I |--> 1*I) + sage: _[0].coerce_embedding() + Generic morphism: + From: Number Field in I with defining polynomial x^2 + 1 with I = 1*I + To: Complex Lazy Field + Defn: I -> 1*I + sage: number_field_elements_from_algebraics([QQbar((-1)^(1/5))], embedded=False, minimal=True) + (Number Field in zeta10 with defining polynomial x^4 - x^3 + x^2 - x + 1, + [zeta10], + Ring morphism: + From: Number Field in zeta10 with defining polynomial x^4 - x^3 + x^2 - x + 1 + To: Algebraic Field + Defn: zeta10 |--> 0.8090169943749474? + 0.5877852522924731?*I) + sage: _[0].coerce_embedding() + sage: number_field_elements_from_algebraics([QQbar((-1)^(1/5))], embedded=True, minimal=True) + (Cyclotomic Field of order 10 and degree 4, + [zeta10], + Ring morphism: + From: Cyclotomic Field of order 10 and degree 4 + To: Algebraic Field + Defn: zeta10 |--> 0.8090169943749474? + 0.5877852522924731?*I) + sage: _[0].coerce_embedding() + Generic morphism: + From: Cyclotomic Field of order 10 and degree 4 + To: Complex Lazy Field + Defn: zeta10 -> 0.809016994374948? + 0.587785252292473?*I + Tests more complicated combinations:: sage: # needs sage.libs.gap sage.symbolic @@ -2905,17 +2969,25 @@ def mk_algebraic(x): exact_generator = gen.root_as_algebraic() hom = fld.hom([exact_generator]) - if fld is not QQ and embedded: - # creates the embedded field - embedded_field = NumberField(fld.defining_polynomial(), fld.variable_name(), embedding=exact_generator) - - # embeds the numbers - inter_hom = fld.hom([embedded_field.gen(0)]) - nums = [inter_hom(n) for n in nums] - - # get the field and homomorphism - hom = embedded_field.hom([exact_generator]) - fld = embedded_field + if fld is QQ: + # ignore embedded parameter + pass + else: + # cyclotomic fields are embedded by default + # number fields are not embedded by default + # if the default embedding is different from what is expected then modify the field + if embedded != (fld.coerce_embedding() is not None): + # creates the modified field + modified_field = NumberField(fld.defining_polynomial(), fld.variable_name(), + embedding=exact_generator if embedded else None) + + # embeds the numbers + inter_hom = fld.hom([modified_field.gen(0)]) + nums = [inter_hom(n) for n in nums] + + # get the field and homomorphism + hom = modified_field.hom([exact_generator]) + fld = modified_field if single_number: nums = nums[0] From b16a160f667aab5e4bcb72282ba83ebbb48f9c98 Mon Sep 17 00:00:00 2001 From: user202729 <25191436+user202729@users.noreply.github.com> Date: Fri, 8 Nov 2024 07:09:10 +0700 Subject: [PATCH 484/537] Update src/sage/rings/qqbar.py Co-authored-by: Travis Scrimshaw --- src/sage/rings/qqbar.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/sage/rings/qqbar.py b/src/sage/rings/qqbar.py index fe37ea15fd7..4f26e0063a2 100644 --- a/src/sage/rings/qqbar.py +++ b/src/sage/rings/qqbar.py @@ -2969,10 +2969,8 @@ def mk_algebraic(x): exact_generator = gen.root_as_algebraic() hom = fld.hom([exact_generator]) - if fld is QQ: - # ignore embedded parameter - pass - else: + if fld is not QQ: + # ignore the embedded parameter for QQ # cyclotomic fields are embedded by default # number fields are not embedded by default # if the default embedding is different from what is expected then modify the field From 01452e65ca0038034627ddd0cda4dcfeaf9eef07 Mon Sep 17 00:00:00 2001 From: user202729 <25191436+user202729@users.noreply.github.com> Date: Fri, 8 Nov 2024 09:28:11 +0700 Subject: [PATCH 485/537] Explicitly name return value in test case --- src/sage/rings/qqbar.py | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/sage/rings/qqbar.py b/src/sage/rings/qqbar.py index 4f26e0063a2..3939b06651f 100644 --- a/src/sage/rings/qqbar.py +++ b/src/sage/rings/qqbar.py @@ -2830,62 +2830,62 @@ def number_field_elements_from_algebraics(numbers, minimal=False, Test ``embedded`` for quadratic and cyclotomic fields:: - sage: number_field_elements_from_algebraics([QQbar((-1)^(2/3))], embedded=False, minimal=True) + sage: v = number_field_elements_from_algebraics([QQbar((-1)^(2/3))], embedded=False, minimal=True); v (Number Field in zeta6 with defining polynomial x^2 - x + 1, [zeta6 - 1], Ring morphism: From: Number Field in zeta6 with defining polynomial x^2 - x + 1 To: Algebraic Field Defn: zeta6 |--> 0.500000000000000? + 0.866025403784439?*I) - sage: _[0].coerce_embedding() - sage: number_field_elements_from_algebraics([QQbar((-1)^(2/3))], embedded=True, minimal=True) + sage: v[0].coerce_embedding() + sage: v = number_field_elements_from_algebraics([QQbar((-1)^(2/3))], embedded=True, minimal=True); v (Cyclotomic Field of order 6 and degree 2, [zeta6 - 1], Ring morphism: From: Cyclotomic Field of order 6 and degree 2 To: Algebraic Field Defn: zeta6 |--> 0.500000000000000? + 0.866025403784439?*I) - sage: _[0].coerce_embedding() + sage: v[0].coerce_embedding() Generic morphism: From: Cyclotomic Field of order 6 and degree 2 To: Complex Lazy Field Defn: zeta6 -> 0.500000000000000? + 0.866025403784439?*I - sage: number_field_elements_from_algebraics([QQbar((-1)^(1/2))], embedded=False, minimal=True) + sage: v = number_field_elements_from_algebraics([QQbar((-1)^(1/2))], embedded=False, minimal=True); v (Number Field in I with defining polynomial x^2 + 1, [I], Ring morphism: From: Number Field in I with defining polynomial x^2 + 1 To: Algebraic Field Defn: I |--> 1*I) - sage: _[0].coerce_embedding() - sage: number_field_elements_from_algebraics([QQbar((-1)^(1/2))], embedded=True, minimal=True) + sage: v[0].coerce_embedding() + sage: v = number_field_elements_from_algebraics([QQbar((-1)^(1/2))], embedded=True, minimal=True); v (Number Field in I with defining polynomial x^2 + 1 with I = 1*I, [I], Ring morphism: From: Number Field in I with defining polynomial x^2 + 1 with I = 1*I To: Algebraic Field Defn: I |--> 1*I) - sage: _[0].coerce_embedding() + sage: v[0].coerce_embedding() Generic morphism: From: Number Field in I with defining polynomial x^2 + 1 with I = 1*I To: Complex Lazy Field Defn: I -> 1*I - sage: number_field_elements_from_algebraics([QQbar((-1)^(1/5))], embedded=False, minimal=True) + sage: v = number_field_elements_from_algebraics([QQbar((-1)^(1/5))], embedded=False, minimal=True); v (Number Field in zeta10 with defining polynomial x^4 - x^3 + x^2 - x + 1, [zeta10], Ring morphism: From: Number Field in zeta10 with defining polynomial x^4 - x^3 + x^2 - x + 1 To: Algebraic Field Defn: zeta10 |--> 0.8090169943749474? + 0.5877852522924731?*I) - sage: _[0].coerce_embedding() - sage: number_field_elements_from_algebraics([QQbar((-1)^(1/5))], embedded=True, minimal=True) + sage: v[0].coerce_embedding() + sage: v = number_field_elements_from_algebraics([QQbar((-1)^(1/5))], embedded=True, minimal=True); v (Cyclotomic Field of order 10 and degree 4, [zeta10], Ring morphism: From: Cyclotomic Field of order 10 and degree 4 To: Algebraic Field Defn: zeta10 |--> 0.8090169943749474? + 0.5877852522924731?*I) - sage: _[0].coerce_embedding() + sage: v[0].coerce_embedding() Generic morphism: From: Cyclotomic Field of order 10 and degree 4 To: Complex Lazy Field From 6c56c15dbdcd8dfc4daa1f13c5a4623da92cdc19 Mon Sep 17 00:00:00 2001 From: user202729 <25191436+user202729@users.noreply.github.com> Date: Fri, 8 Nov 2024 10:23:28 +0700 Subject: [PATCH 486/537] Fix failed test case --- src/sage/rings/qqbar.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/rings/qqbar.py b/src/sage/rings/qqbar.py index 3939b06651f..72df892337b 100644 --- a/src/sage/rings/qqbar.py +++ b/src/sage/rings/qqbar.py @@ -2911,10 +2911,10 @@ def number_field_elements_from_algebraics(numbers, minimal=False, sage: AA((-1)^(2/3)) 1 sage: number_field_elements_from_algebraics([(-1)^(2/3)]) - (Cyclotomic Field of order 6 and degree 2, + (Number Field in zeta6 with defining polynomial x^2 - x + 1, [zeta6 - 1], Ring morphism: - From: Cyclotomic Field of order 6 and degree 2 + From: Number Field in zeta6 with defining polynomial x^2 - x + 1 To: Algebraic Field Defn: zeta6 |--> 0.500000000000000? + 0.866025403784439?*I) """ From 8d7ab18cbb9ac26d3691a72594471a69371b8d50 Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Fri, 8 Nov 2024 08:30:31 +0100 Subject: [PATCH 487/537] Apply suggestions from code review Co-authored-by: Travis Scrimshaw --- src/sage/rings/species.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sage/rings/species.py b/src/sage/rings/species.py index 7ead92ba16f..d838afe3340 100644 --- a/src/sage/rings/species.py +++ b/src/sage/rings/species.py @@ -1374,7 +1374,7 @@ def cycle_type(g): def __call__(self, *args): r""" - Substitute `M_1,\dots, M_k` into ``self``. + Substitute `M_1,\ldots, M_k` into ``self``. The arguments must all have the same parent and must all be molecular. The number of arguments must be equal to @@ -1671,8 +1671,8 @@ def _compose_with_singletons(self, names, args): OUTPUT: - - the polynomial species `self(X_1 + \dots + X_{m_1}, Y_1 - + \dots + Y_{m_2}, \dots)`, where `m_i` is the number + - the polynomial species `self(X_1 + \cdots + X_{m_1}, Y_1 + + \cdots + Y_{m_2}, \ldots)`, where `m_i` is the number of parts of the `i`-th composition, restricted to the degrees given by ``args``. From 622d08e446fd41abe60d37b8f5f90362bd8a2bb0 Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Fri, 8 Nov 2024 08:34:19 +0100 Subject: [PATCH 488/537] docfixes --- src/sage/rings/species.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/sage/rings/species.py b/src/sage/rings/species.py index d838afe3340..0acfecbc593 100644 --- a/src/sage/rings/species.py +++ b/src/sage/rings/species.py @@ -79,6 +79,13 @@ class AtomicSpeciesElement(WithEqualityById, Two atomic species are equal if the underlying groups are conjugate, and their domain partitions are equal under the conjugating element. + + INPUT: + + - ``dis`` -- a directly indecomposable permutation group + - ``domain_partition`` -- a `k`-tuple of ``frozenset`` entries, + where `k` is the arity, representing the assignment of each + element of the domain of ``dis`` to a sort """ @staticmethod def __classcall__(cls, parent, C, dompart): @@ -217,13 +224,6 @@ def __init__(self, parent, dis, domain_partition): r""" Initialize an atomic species. - INPUT: - - - ``dis`` -- a directly indecomposable permutation group - - ``domain_partition`` -- a `k`-tuple of ``frozenset``s, - where `k` is the arity, representing the assignment of each - element of the domain of ``dis`` to a sort - TESTS:: sage: from sage.rings.species import AtomicSpecies @@ -377,7 +377,7 @@ def __classcall__(cls, names): def __init__(self, names): r""" - Initialize the class of (multisort) atomic species. + Initialize the class of atomic species. TESTS: @@ -830,7 +830,7 @@ def __classcall__(cls, names): def __init__(self, names): r""" - Initialize the monoid of (multisort) molecular species. + Initialize the monoid of molecular species. TESTS: @@ -2030,7 +2030,7 @@ def __classcall__(cls, base_ring, names): def __init__(self, base_ring, names): r""" - Initialize the ring of (multisort) polynomial species. + Initialize the ring of polynomial species. TESTS:: From 9ef4cdbf2279e6301484d6053d008479ba6955a1 Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Fri, 8 Nov 2024 09:07:34 +0100 Subject: [PATCH 489/537] avoid recursion in _element_constructor_ --- src/sage/rings/species.py | 98 ++++++++++++++++++++++----------------- 1 file changed, 56 insertions(+), 42 deletions(-) diff --git a/src/sage/rings/species.py b/src/sage/rings/species.py index 0acfecbc593..bcda9a9f510 100644 --- a/src/sage/rings/species.py +++ b/src/sage/rings/species.py @@ -416,7 +416,7 @@ def _repr_(self): def _element_constructor_(self, G, pi=None, check=True): r""" - Construct the `k`-variate atomic species with the given data. + Construct the atomic species with the given data. INPUT: @@ -868,7 +868,7 @@ def _repr_(self): def _element_constructor_(self, G, pi=None, check=True): r""" - Construct the `k`-variate molecular species with the given data. + Construct the molecular species with the given data. INPUT: @@ -960,13 +960,24 @@ def _element_constructor_(self, G, pi=None, check=True): sage: M(0) Traceback (most recent call last): ... - ValueError: 0 must be a permutation group or a pair specifying a - group action on the given domain pi=None + ValueError: 0 must be a permutation group or a pair (X, a) + specifying a group action of the symmetric group on pi=None """ if parent(G) is self: # pi cannot be None because of framework raise ValueError("cannot reassign sorts to a molecular species") + if isinstance(G, tuple): + X, a = G + dompart = [sorted(pi.get(s, [])) for s in range(self._arity)] + S = PermutationGroup([tuple(b) for b in dompart if len(b) > 2] + + [(b[0], b[1]) for b in dompart if len(b) > 1], + domain=list(chain(*dompart))) + H = _stabilizer_subgroups(S, X, a) + if len(H) > 1: + raise ValueError("action is not transitive") + G = H[0] + if isinstance(G, PermutationGroup_generic): if pi is None: if self._arity == 1: @@ -993,18 +1004,7 @@ def _element_constructor_(self, G, pi=None, check=True): elm *= self.gen(a) return elm - try: - X, a = G - except TypeError: - raise ValueError(f"{G} must be a permutation group or a pair specifying a group action on the given domain pi={pi}") - dompart = [sorted(pi.get(s, [])) for s in range(self._arity)] - S = PermutationGroup([tuple(b) for b in dompart if len(b) > 2] - + [(b[0], b[1]) for b in dompart if len(b) > 1], - domain=list(chain(*dompart))) - H = _stabilizer_subgroups(S, X, a) - if len(H) > 1: - raise ValueError("action is not transitive") - return self(H[0], pi, check=check) + raise ValueError(f"{G} must be a permutation group or a pair (X, a) specifying a group action of the symmetric group on pi={pi}") def grading_set(self): r""" @@ -2067,8 +2067,7 @@ def _repr_(self): def _element_constructor_(self, G, pi=None, check=True): r""" - Construct the `k`-variate polynomial species with the - given data. + Construct the polynomial species with the given data. INPUT: @@ -2113,22 +2112,6 @@ def _element_constructor_(self, G, pi=None, check=True): sage: P((X, act), {0: range(1, n+1)}) 4*E_4 + 4*P_4 + E_2^2 + 2*X*E_3 - TESTS:: - - sage: P = PolynomialSpecies(ZZ, "X, Y") - sage: G = PermutationGroup([(1,2), (3,4)]) - sage: P(G) - Traceback (most recent call last): - ... - ValueError: the assignment of sorts to the domain elements must be provided - sage: f = P(G, {0: [1, 2], 1: [3, 4]}) - sage: P(f) is f - True - sage: P(f, {0: [1,2,3,4]}) - Traceback (most recent call last): - ... - ValueError: cannot reassign sorts to a polynomial species - Create a multisort species given an action:: sage: P = PolynomialSpecies(QQ, "X,Y") @@ -2147,10 +2130,48 @@ def _element_constructor_(self, G, pi=None, check=True): sage: P((X, lambda g, x: act(x[0], x[1], g)), pi) 2*Y*E_2(X) + TESTS:: + + sage: P = PolynomialSpecies(ZZ, "X, Y") + sage: G = PermutationGroup([(1,2), (3,4)]) + sage: P(G) + Traceback (most recent call last): + ... + ValueError: the assignment of sorts to the domain elements must be provided + sage: f = P(G, {0: [1, 2], 1: [3, 4]}) + sage: P(f) is f + True + sage: P(f, {0: [1,2,3,4]}) + Traceback (most recent call last): + ... + ValueError: cannot reassign sorts to a polynomial species + + Elements of the base ring are coerced correctly:: + + sage: P(2) + 2 + + sage: P(1/2) + Traceback (most recent call last): + ... + ValueError: 1/2 must be an element of the base ring, a permutation + group or a pair (X, a) specifying a group action of the symmetric + group on pi=None """ if parent(G) is self: # pi cannot be None because of framework raise ValueError("cannot reassign sorts to a polynomial species") + + if isinstance(G, tuple): + X, a = G + dompart = [sorted(pi.get(s, [])) for s in range(self._arity)] + S = PermutationGroup([tuple(b) for b in dompart if len(b) > 2] + + [(b[0], b[1]) for b in dompart if len(b) > 1], + domain=list(chain(*dompart))) + Hs = _stabilizer_subgroups(S, X, a) + return self.sum_of_terms((self._indices(H, pi, check=check), ZZ.one()) + for H in Hs) + if isinstance(G, PermutationGroup_generic): if pi is None: if self._arity == 1: @@ -2160,14 +2181,7 @@ def _element_constructor_(self, G, pi=None, check=True): pi = {i: v for i, v in enumerate(pi)} return self._from_dict({self._indices(G, pi, check=check): ZZ.one()}) - X, a = G - dompart = [sorted(pi.get(s, [])) for s in range(self._arity)] - S = PermutationGroup([tuple(b) for b in dompart if len(b) > 2] - + [(b[0], b[1]) for b in dompart if len(b) > 1], - domain=list(chain(*dompart))) - Hs = _stabilizer_subgroups(S, X, a) - return self.sum_of_terms((self._indices(H, pi, check=check), ZZ.one()) - for H in Hs) + raise ValueError(f"{G} must be an element of the base ring, a permutation group or a pair (X, a) specifying a group action of the symmetric group on pi={pi}") def _first_ngens(self, n): r""" From 8f011a7095aed5f5481928728f8a73e45f17a1cd Mon Sep 17 00:00:00 2001 From: janmenjayap Date: Fri, 8 Nov 2024 17:52:25 +0530 Subject: [PATCH 490/537] added doctests for **kwds --- src/sage/graphs/matching_covered_graph.py | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/src/sage/graphs/matching_covered_graph.py b/src/sage/graphs/matching_covered_graph.py index 3d5492d1df3..6b31008c600 100644 --- a/src/sage/graphs/matching_covered_graph.py +++ b/src/sage/graphs/matching_covered_graph.py @@ -374,6 +374,21 @@ class MatchingCoveredGraph(Graph): sage: sorted(H.get_matching()) == sorted(M) True + One may specify some keyword arguments:: + + sage: G = Graph([(0, 1, 5)], {'weighted': True}) + sage: kwds = { + ....: 'loops': False, + ....: 'multiedges': True, + ....: 'pos': {0: (0, 0), 1: (1, 1)} + ....: } + sage: H = MatchingCoveredGraph(G, **kwds) + sage: H + Matching covered multi-graph on 2 vertices + sage: H.add_edge(0, 1) + sage: H.edges() + [(0, 1, None), (0, 1, 5)] + TESTS: An empty graph is not matching covered:: @@ -402,6 +417,11 @@ class MatchingCoveredGraph(Graph): Make sure that self-loops are not allowed for a matching covered graph:: sage: P = graphs.PetersenGraph() + sage: kwds = {'loops': True} + sage: G = MatchingCoveredGraph(P, **kwds) + Traceback (most recent call last): + ... + ValueError: loops are not allowed in matching covered graphs sage: G = MatchingCoveredGraph(P) sage: G.allows_loops() False @@ -604,7 +624,7 @@ def __init__(self, data=None, matching=None, algorithm='Edmonds', """ success = False - if kwds is None: + if not kwds: kwds = {'loops': False} else: if 'loops' in kwds and kwds['loops']: From 7a2793be1b79e5b8bf64d661c89db9fd688342e1 Mon Sep 17 00:00:00 2001 From: janmenjayap Date: Fri, 8 Nov 2024 17:54:43 +0530 Subject: [PATCH 491/537] updated __init__() --- src/sage/graphs/matching_covered_graph.py | 23 ++++------------------- 1 file changed, 4 insertions(+), 19 deletions(-) diff --git a/src/sage/graphs/matching_covered_graph.py b/src/sage/graphs/matching_covered_graph.py index 6b31008c600..8280224435f 100644 --- a/src/sage/graphs/matching_covered_graph.py +++ b/src/sage/graphs/matching_covered_graph.py @@ -636,12 +636,9 @@ def __init__(self, data=None, matching=None, algorithm='Edmonds', raise ValueError('the graph is trivial') elif isinstance(data, MatchingCoveredGraph): - try: - Graph.__init__(self, data, *args, **kwds) - success = True + Graph.__init__(self, data, *args, **kwds) + success = True - except Exception as exception: - raise exception elif isinstance(data, Graph): try: @@ -657,21 +654,9 @@ def __init__(self, data=None, matching=None, algorithm='Edmonds', if success: if matching: - # The input matching must be a valid perfect matching of the graph - M = Graph(matching) - - if any(d != 1 for d in M.degree()): - raise ValueError("the input is not a matching") - - G = Graph(self, multiedges=False) - - if any(not G.has_edge(edge) for edge in M.edge_iterator()): - raise ValueError("the input is not a matching of the graph") - - if (G.order() != M.order()): - raise ValueError("the input is not a perfect matching of the graph") - + # The input matching is a valid perfect matching of the graph self._matching = matching + else: self._matching = Graph(self).matching() From 83a1be988642fe9e395ce2a05874cd8a63fbedc5 Mon Sep 17 00:00:00 2001 From: janmenjayap Date: Fri, 8 Nov 2024 17:56:05 +0530 Subject: [PATCH 492/537] added doctests for add_edge() --- src/sage/graphs/matching_covered_graph.py | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/sage/graphs/matching_covered_graph.py b/src/sage/graphs/matching_covered_graph.py index 8280224435f..01b301c7034 100644 --- a/src/sage/graphs/matching_covered_graph.py +++ b/src/sage/graphs/matching_covered_graph.py @@ -1019,6 +1019,21 @@ def add_edge(self, u, v=None, label=None): (3, 6, None), (4, 5, None), (4, 6, 'label'), (4, 7, 'label'), (5, 7, None), (6, 7, None)] + Note that the ``weight`` of the edge shall be input as the ``label``:: + + sage: G.add_edge((1, 3), label=5) + sage: G.edges() + [(0, 1, None), (0, 3, None), (0, 4, None), (0, 5, None), + (0, 6, None), (1, 2, None), (1, 3, 5), (1, 4, None), + (2, 3, None), (2, 4, 'label'), (2, 5, None), (2, 7, None), + (3, 4, None), (3, 6, None), (4, 5, None), (4, 6, 'label'), + (4, 7, 'label'), (5, 7, None), (6, 7, None)] + sage: G.add_edge((2, 4, 6), label=6) + Traceback (most recent call last): + ... + ValueError: the graph obtained after the addition of edge + (((2, 4, 6), None, 6)) is not matching covered + Vertex name cannot be ``None``, so:: sage: W = graphs.WheelGraph(6) @@ -1051,6 +1066,12 @@ def add_edge(self, u, v=None, label=None): sage: G.add_edge(next(G.edge_iterator())) sage: P == G True + sage: G.size() + 15 + sage: G.allow_multiple_edges(True) + sage: G.add_edge(0, 1) + sage: G.size() + 16 Adding an edge such that the resulting graph is matching covered:: From 7c5c047b584b7784e66a5b1711fc9deb5013bdef Mon Sep 17 00:00:00 2001 From: janmenjayap Date: Fri, 8 Nov 2024 17:59:38 +0530 Subject: [PATCH 493/537] updated M_alternating_even_mark() --- src/sage/graphs/matching.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/sage/graphs/matching.py b/src/sage/graphs/matching.py index 2c129dbdde2..e6baf7c3323 100644 --- a/src/sage/graphs/matching.py +++ b/src/sage/graphs/matching.py @@ -1567,7 +1567,8 @@ def M_alternating_even_mark(G, vertex, matching): M = Graph(matching) if any(d != 1 for d in M.degree()): raise ValueError("the input is not a matching") - if any(not G_simple.has_edge(edge) for edge in M.edge_iterator()): + + if any(not G.has_edge(edge) for edge in M.edge_iterator()): raise ValueError("the input is not a matching of the graph") # Build an M-alternating tree T rooted at vertex @@ -1602,8 +1603,10 @@ def M_alternating_even_mark(G, vertex, matching): while ancestor_x[-1] != ancestor_y[-1]: if rank[ancestor_x[-1]] > rank[ancestor_y[-1]]: ancestor_x.append(predecessor[ancestor_x[-1]]) + elif rank[ancestor_x[-1]] < rank[ancestor_y[-1]]: ancestor_y.append(predecessor[ancestor_y[-1]]) + else: ancestor_x.append(predecessor[ancestor_x[-1]]) ancestor_y.append(predecessor[ancestor_y[-1]]) @@ -1613,6 +1616,7 @@ def M_alternating_even_mark(G, vertex, matching): # Set t as pred of all vertices of the chains and add # vertices marked odd to the queue next_rank_to_lcs_rank = rank[lcs] + 1 + for a in itertools.chain(ancestor_x, ancestor_y): predecessor[a] = lcs rank[a] = next_rank_to_lcs_rank From bcfe65ea50a8bedc5b7ee8a572a248ce867a5958 Mon Sep 17 00:00:00 2001 From: janmenjayap Date: Fri, 8 Nov 2024 18:02:31 +0530 Subject: [PATCH 494/537] updated is_matching_covered() --- src/sage/graphs/matching.py | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/src/sage/graphs/matching.py b/src/sage/graphs/matching.py index e6baf7c3323..9bdbd1bf836 100644 --- a/src/sage/graphs/matching.py +++ b/src/sage/graphs/matching.py @@ -977,27 +977,26 @@ def is_matching_covered(G, matching=None, algorithm='Edmonds', coNP_certificate= if G.order() == 2: return (True, None) if coNP_certificate else True - # A graph (without a self-loop) is matching covered if and only if the - # underlying simple graph is matching covered - G_simple = G.to_simple() - from sage.graphs.graph import Graph if matching: # The input matching must be a valid perfect matching of the graph M = Graph(matching) + if any(d != 1 for d in M.degree()): raise ValueError("the input is not a matching") - if any(not G_simple.has_edge(edge) for edge in M.edge_iterator()): + + if any(not G.has_edge(edge) for edge in M.edge_iterator()): raise ValueError("the input is not a matching of the graph") - if (G_simple.order() != M.order()) or (G_simple.order() != 2*M.size()): + + if (G.order() != M.order()) or (G.order() != 2*M.size()): raise ValueError("the input is not a perfect matching of the graph") else: # A maximum matching of the graph is computed - M = Graph(G_simple.matching(algorithm=algorithm, solver=solver, verbose=verbose, + M = Graph(G.matching(algorithm=algorithm, solver=solver, verbose=verbose, integrality_tolerance=integrality_tolerance)) # It must be a perfect matching - if G_simple.order() != M.order(): + if G.order() != M.order(): return (False, next(M.edge_iterator())) if coNP_certificate else False # Biparite graph: @@ -1008,17 +1007,17 @@ def is_matching_covered(G, matching=None, algorithm='Edmonds', coNP_certificate= # if it is in M or otherwise direct it from B to A. The graph G is # matching covered if and only if D is strongly connected. - if G_simple.is_bipartite(): - A, _ = G_simple.bipartite_sets() + if G.is_bipartite(): + A, _ = G.bipartite_sets() color = dict() - for u in G_simple: + for u in G: color[u] = 0 if u in A else 1 from sage.graphs.digraph import DiGraph H = DiGraph() - for u, v in G_simple.edge_iterator(labels=False): + for u, v in G.edge_iterator(labels=False): if color[u]: u, v = v, u @@ -1072,12 +1071,12 @@ def dfs(J, v, visited, orientation): # an M-alternating odd length uv-path starting and ending with edges not # in M. - for u in G_simple: + for u in G: v = next(M.neighbor_iterator(u)) - even = M_alternating_even_mark(G_simple, u, M) + even = M_alternating_even_mark(G, u, M) - for w in G_simple.neighbor_iterator(v): + for w in G.neighbor_iterator(v): if w != u and w not in even: return (False, (v, w)) if coNP_certificate else False From 9f32514f290a769566dbc9ed75f014ed74e305a7 Mon Sep 17 00:00:00 2001 From: janmenjayap Date: Fri, 8 Nov 2024 18:03:56 +0530 Subject: [PATCH 495/537] updated is_bicritical() --- src/sage/graphs/matching.py | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/src/sage/graphs/matching.py b/src/sage/graphs/matching.py index 9bdbd1bf836..c8eea2bb005 100644 --- a/src/sage/graphs/matching.py +++ b/src/sage/graphs/matching.py @@ -446,27 +446,25 @@ def is_bicritical(G, matching=None, algorithm='Edmonds', coNP_certificate=False, return (False, set(list(A)[:2])) return (False, set(list(B)[:2])) - # A graph (without a self-loop) is bicritical if and only if the underlying - # simple graph is bicritical - G_simple = G.to_simple() - from sage.graphs.graph import Graph if matching: # The input matching must be a valid perfect matching of the graph M = Graph(matching) if any(d != 1 for d in M.degree()): raise ValueError("the input is not a matching") - if any(not G_simple.has_edge(edge) for edge in M.edge_iterator()): + + if any(not G.has_edge(edge) for edge in M.edge_iterator()): raise ValueError("the input is not a matching of the graph") - if (G_simple.order() != M.order()) or (G_simple.order() != 2*M.size()): + + if (G.order() != M.order()) or (G.order() != 2*M.size()): raise ValueError("the input is not a perfect matching of the graph") else: # A maximum matching of the graph is computed - M = Graph(G_simple.matching(algorithm=algorithm, solver=solver, verbose=verbose, + M = Graph(G.matching(algorithm=algorithm, solver=solver, verbose=verbose, integrality_tolerance=integrality_tolerance)) # It must be a perfect matching - if G_simple.order() != M.order(): + if G.order() != M.order(): u, v = next(M.edge_iterator(labels=False)) return (False, set([u, v])) if coNP_certificate else False @@ -474,12 +472,12 @@ def is_bicritical(G, matching=None, algorithm='Edmonds', coNP_certificate=False, # every vertex of the graph distinct from v must be reachable from u through an even length # M-alternating uv-path starting with an edge not in M and ending with an edge in M - for u in G_simple: + for u in G: v = next(M.neighbor_iterator(u)) - even = M_alternating_even_mark(G_simple, u, M) + even = M_alternating_even_mark(G, u, M) - for w in G_simple: + for w in G: if w != v and w not in even: return (False, set([v, w])) if coNP_certificate else False From c63a2bb45c367f2cd78d65161b7377b8d3749242 Mon Sep 17 00:00:00 2001 From: janmenjayap Date: Fri, 8 Nov 2024 18:11:19 +0530 Subject: [PATCH 496/537] removed an unnecessary blank line --- src/sage/graphs/matching_covered_graph.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/sage/graphs/matching_covered_graph.py b/src/sage/graphs/matching_covered_graph.py index 01b301c7034..2a9b8916c90 100644 --- a/src/sage/graphs/matching_covered_graph.py +++ b/src/sage/graphs/matching_covered_graph.py @@ -639,7 +639,6 @@ def __init__(self, data=None, matching=None, algorithm='Edmonds', Graph.__init__(self, data, *args, **kwds) success = True - elif isinstance(data, Graph): try: self._upgrade_from_graph(data=data, matching=matching, From ea18381785f67eaca2daa38b2c1f461d6592a4b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Fri, 8 Nov 2024 17:43:38 +0100 Subject: [PATCH 497/537] small fixes in yang baxter --- src/sage/combinat/yang_baxter_graph.py | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/sage/combinat/yang_baxter_graph.py b/src/sage/combinat/yang_baxter_graph.py index 33552e4cc46..5642b58e087 100644 --- a/src/sage/combinat/yang_baxter_graph.py +++ b/src/sage/combinat/yang_baxter_graph.py @@ -45,8 +45,8 @@ def YangBaxterGraph(partition=None, root=None, operators=None): OUTPUT: either: - - :class:`YangBaxterGraph_partition` -- if partition is defined - - :class:`YangBaxterGraph_generic` -- if partition is ``None`` + - :class:`YangBaxterGraph_partition` -- if partition is defined + - :class:`YangBaxterGraph_generic` -- if partition is ``None`` EXAMPLES: @@ -108,8 +108,7 @@ def YangBaxterGraph(partition=None, root=None, operators=None): """ if partition is None: return YangBaxterGraph_generic(root=root, operators=operators) - else: - return YangBaxterGraph_partition(partition=Partition(partition)) + return YangBaxterGraph_partition(partition=Partition(partition)) # *********** General class for Yang-Baxter Graphs *********** @@ -203,7 +202,7 @@ def _digraph(self): digraph.add_edge(u, v, l) return digraph - def __hash__(self): + def __hash__(self) -> int: r""" TESTS:: @@ -236,7 +235,7 @@ def __eq__(self, other) -> bool: sage: Y3.__eq__(Y2) False """ - return type(self) is type(other) and self._digraph == other._digraph + return isinstance(other, YangBaxterGraph_generic) and self._digraph == other._digraph def __ne__(self, other) -> bool: r""" @@ -634,7 +633,7 @@ def _digraph(self): [((0, 1, 0), (1, 0, 0), Swap positions 0 and 1)] """ digraph = super()._digraph - for (u, v, op) in digraph.edges(sort=True): + for u, v, op in digraph.edges(sort=True): digraph.set_edge_label(u, v, SwapOperator(op.position())) return digraph @@ -777,7 +776,7 @@ def __init__(self, i): """ self._position = i - def __hash__(self): + def __hash__(self) -> int: r""" TESTS:: From f6af14fd7b4d833d2cb1927156883af917858fc1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Fri, 8 Nov 2024 20:35:32 +0100 Subject: [PATCH 498/537] deprecate is_generator for is_gen --- .../rings/polynomial/multi_polynomial.pyx | 31 +++++++++++++------ .../polynomial/multi_polynomial_element.py | 24 ++++++++++---- .../multi_polynomial_libsingular.pyx | 2 +- .../rings/polynomial/polynomial_element.pyx | 4 +-- 4 files changed, 42 insertions(+), 19 deletions(-) diff --git a/src/sage/rings/polynomial/multi_polynomial.pyx b/src/sage/rings/polynomial/multi_polynomial.pyx index ca25adc23f0..b44fb53a9ec 100644 --- a/src/sage/rings/polynomial/multi_polynomial.pyx +++ b/src/sage/rings/polynomial/multi_polynomial.pyx @@ -11,14 +11,14 @@ Base class for elements of multivariate polynomial rings # (at your option) any later version. # https://www.gnu.org/licenses/ # ******************************************************************** +from itertools import chain from sage.rings.integer cimport Integer from sage.rings.integer_ring import ZZ from sage.structure.coerce cimport coercion_model from sage.misc.derivative import multi_derivative -from itertools import chain - from sage.misc.misc_c import prod +from sage.misc.superseded import deprecated_function_alias def is_MPolynomial(x): @@ -1284,28 +1284,39 @@ cdef class MPolynomial(CommutativePolynomial): """ return self.base_ring().ideal(self.coefficients()) - def is_generator(self): + def is_gen(self): r""" Return ``True`` if this polynomial is a generator of its parent. EXAMPLES:: sage: R. = ZZ[] - sage: x.is_generator() + sage: x.is_gen() True - sage: (x + y - y).is_generator() + sage: (x + y - y).is_gen() True - sage: (x*y).is_generator() + sage: (x*y).is_gen() False sage: R. = QQ[] - sage: x.is_generator() + sage: x.is_gen() True - sage: (x + y - y).is_generator() + sage: (x + y - y).is_gen() True - sage: (x*y).is_generator() + sage: (x*y).is_gen() False + + TESTS:: + + sage: R. = ZZ[] + sage: x.is_generator() + doctest:warning...: + DeprecationWarning: is_generator is deprecated. Please use is_gen instead. + See https://github.com/sagemath/sage/issues/38888 for details. + True """ - return (self in self.parent().gens()) + return self in self.parent().gens() + + is_generator = deprecated_function_alias(38888, is_gen) def map_coefficients(self, f, new_base_ring=None): r""" diff --git a/src/sage/rings/polynomial/multi_polynomial_element.py b/src/sage/rings/polynomial/multi_polynomial_element.py index 6c4ec02c1b1..81748038ae0 100644 --- a/src/sage/rings/polynomial/multi_polynomial_element.py +++ b/src/sage/rings/polynomial/multi_polynomial_element.py @@ -70,7 +70,7 @@ from .multi_polynomial import MPolynomial, is_MPolynomial from sage.categories.morphism import Morphism from sage.misc.lazy_attribute import lazy_attribute - +from sage.misc.superseded import deprecated_function_alias from sage.rings.rational_field import QQ from sage.rings.fraction_field import FractionField @@ -693,7 +693,7 @@ def degree(self, x=None, std_grading=False): x = self.parent().coerce(x) except TypeError: raise TypeError("x must canonically coerce to parent") - if not x.is_generator(): + if not x.is_gen(): raise TypeError("x must be one of the generators of the parent") else: raise TypeError("x must be one of the generators of the parent") @@ -1349,7 +1349,7 @@ def _homogenize(self, var): R = self.parent() return R(X) - def is_generator(self): + def is_gen(self) -> bool: """ Return ``True`` if ``self`` is a generator of its parent. @@ -1357,12 +1357,22 @@ def is_generator(self): sage: # needs sage.rings.number_field sage: R. = QQbar[] - sage: x.is_generator() + sage: x.is_gen() True - sage: (x + y - y).is_generator() + sage: (x + y - y).is_gen() True - sage: (x*y).is_generator() + sage: (x*y).is_gen() False + + TESTS:: + + sage: # needs sage.rings.number_field + sage: R. = QQbar[] + sage: x.is_generator() + doctest:warning...: + DeprecationWarning: is_generator is deprecated. Please use is_gen instead. + See https://github.com/sagemath/sage/issues/38888 for details. + True """ elt = self.element() if len(elt) == 1: @@ -1370,6 +1380,8 @@ def is_generator(self): return e.nonzero_values() == [1] and c.is_one() return False + is_generator = deprecated_function_alias(38888, is_gen) + def is_monomial(self): """ Return ``True`` if ``self`` is a monomial, which we define to be a diff --git a/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx b/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx index d05760d84cd..f96e3974752 100644 --- a/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx +++ b/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx @@ -2700,7 +2700,7 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): x = self.parent().coerce(x) except TypeError: raise TypeError("argument is not coercible to the parent") - if not x.is_generator(): + if not x.is_gen(): raise TypeError("argument is not a generator") return Integer(singular_polynomial_deg(p, x._poly, r)) diff --git a/src/sage/rings/polynomial/polynomial_element.pyx b/src/sage/rings/polynomial/polynomial_element.pyx index 7c1ca199ced..7e9d2216221 100644 --- a/src/sage/rings/polynomial/polynomial_element.pyx +++ b/src/sage/rings/polynomial/polynomial_element.pyx @@ -13078,7 +13078,7 @@ cpdef bint polynomial_is_variable(x) noexcept: .. SEEALSO:: - :meth:`sage.rings.polynomial.polynomial_element.Polynomial.is_gen` - - :meth:`sage.rings.polynomial.multi_polynomial.MPolynomial.is_generator` + - :meth:`sage.rings.polynomial.multi_polynomial.MPolynomial.is_gen` EXAMPLES:: @@ -13116,5 +13116,5 @@ cpdef bint polynomial_is_variable(x) noexcept: return (x.is_gen() or (x.degree() == 1 and x[0].is_zero() and x[1].is_one())) if isinstance(x, MPolynomial): - return x.is_generator() + return x.is_gen() return False From a8cbe3006d41b00801c7a3372543c1f963caa993 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Fri, 8 Nov 2024 20:37:33 +0100 Subject: [PATCH 499/537] fix number --- src/sage/rings/polynomial/multi_polynomial.pyx | 4 ++-- src/sage/rings/polynomial/multi_polynomial_element.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/sage/rings/polynomial/multi_polynomial.pyx b/src/sage/rings/polynomial/multi_polynomial.pyx index b44fb53a9ec..4653e3c6f02 100644 --- a/src/sage/rings/polynomial/multi_polynomial.pyx +++ b/src/sage/rings/polynomial/multi_polynomial.pyx @@ -1311,12 +1311,12 @@ cdef class MPolynomial(CommutativePolynomial): sage: x.is_generator() doctest:warning...: DeprecationWarning: is_generator is deprecated. Please use is_gen instead. - See https://github.com/sagemath/sage/issues/38888 for details. + See https://github.com/sagemath/sage/issues/38942 for details. True """ return self in self.parent().gens() - is_generator = deprecated_function_alias(38888, is_gen) + is_generator = deprecated_function_alias(38942, is_gen) def map_coefficients(self, f, new_base_ring=None): r""" diff --git a/src/sage/rings/polynomial/multi_polynomial_element.py b/src/sage/rings/polynomial/multi_polynomial_element.py index 81748038ae0..2e6aecdecc5 100644 --- a/src/sage/rings/polynomial/multi_polynomial_element.py +++ b/src/sage/rings/polynomial/multi_polynomial_element.py @@ -1371,7 +1371,7 @@ def is_gen(self) -> bool: sage: x.is_generator() doctest:warning...: DeprecationWarning: is_generator is deprecated. Please use is_gen instead. - See https://github.com/sagemath/sage/issues/38888 for details. + See https://github.com/sagemath/sage/issues/38942 for details. True """ elt = self.element() @@ -1380,7 +1380,7 @@ def is_gen(self) -> bool: return e.nonzero_values() == [1] and c.is_one() return False - is_generator = deprecated_function_alias(38888, is_gen) + is_generator = deprecated_function_alias(38942, is_gen) def is_monomial(self): """ From 8ddb51bca6662d784488ea71abe7057b03306694 Mon Sep 17 00:00:00 2001 From: Michael Orlitzky Date: Thu, 31 Oct 2024 22:24:09 -0400 Subject: [PATCH 500/537] src/sage/features/info.py: new feature for GNU Info Before we can replace our hand-rolled parser for Singular's info file, we need to be able to detect the "info" program from the GNU Info package. The goal is to politely disable access to Singular's info if GNU Info is unavailable. This avoids a hard dependency on GNU Info in the sage library. We require v7 or later because a bugfix in Texinfo v7.0.0 corrects the exit code from "info" when the requested node is not found. This allows us to separate the "expected failures" from the truly unexpected ones. --- src/sage/features/info.py | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 src/sage/features/info.py diff --git a/src/sage/features/info.py b/src/sage/features/info.py new file mode 100644 index 00000000000..eeaf0118c0d --- /dev/null +++ b/src/sage/features/info.py @@ -0,0 +1,30 @@ +# sage_setup: distribution = sagemath-environment +r""" +Feature for testing the presence of ``info``, from GNU Info +""" + +from . import Executable + +class Info(Executable): + r""" + A :class:`~sage.features.Feature` describing the presence of :ref:`info `. + + EXAMPLES:: + + sage: from sage.features.info import Info + sage: Info() + Feature('info') + """ + def __init__(self): + r""" + TESTS:: + + sage: from sage.features.info import Info + sage: isinstance(Info(), Info) + True + """ + Executable.__init__(self, 'info', executable='info', + spkg='info', type='standard') + +def all_features(): + return [Info()] From f133116b40697803c502fa7613586db5b11cf459 Mon Sep 17 00:00:00 2001 From: Michael Orlitzky Date: Thu, 31 Oct 2024 18:34:26 -0400 Subject: [PATCH 501/537] src/sage/interfaces/singular.py: use GNU Info to read Singular's info Our Singular interface currently contains a hand-written parser for Singular's "info" file. This commit eliminates the custom parser in favor of launching GNU Info. GNU Info (or its superset, Texinfo) are widespread, portable, and easy to install on all of the systems we support, so in most cases this should be a "free" improvement. The hand-written parser has several drawbacks: * The extra code is a maintenance burden. We should not be wasting our time reimplementing standard tools. * The custom parser is buggy. For example, it is supposed to raise a KeyError when documentation for a non-existent function is requested. However, the parser does not keep track of what section it's in, so, for example, get_docstring("Preface") returns the contents of the preface even though "Preface" is not a Singular function. * The first time documentation is requested, the entire info file is loaded into a dictionary. This wastes a few megabytes of memory for the duration of the Sage session. * The custom parser does not handle compression (GNU Info does transparently), and the end user or people packaging Singular may not be aware of that. If the system installation of Singular has a compressed info file, Sage won't be able to read it. For contrast, the one downside to using GNU Info is that it adds a new runtime dependency to sagelib. To mitigate that, we do not technically require it, and instead raise a warning if the user (a) tries to read the Singular documentation and (b) has managed to find a system without GNU Info. Our singular_console() itself tries to launch GNU Info to display its interactive help, so the additional optional dependency is not so additional except in corner cases, such as a pypi installation of a subset of Sage linked against libsingular but without a full Singular install. --- src/sage/interfaces/singular.py | 191 +++++++++++++++++++------------- 1 file changed, 113 insertions(+), 78 deletions(-) diff --git a/src/sage/interfaces/singular.py b/src/sage/interfaces/singular.py index ed883b07105..74bd20faf07 100644 --- a/src/sage/interfaces/singular.py +++ b/src/sage/interfaces/singular.py @@ -2269,11 +2269,9 @@ def _instancedoc_(self): """ EXAMPLES:: - sage: 'groebner' in singular.groebner.__doc__ + sage: 'groebner' in singular.groebner.__doc__ # needs info True """ - if not nodes: - generate_docstring_dictionary() prefix = """ This function is an automatically generated pexpect wrapper around the Singular @@ -2288,15 +2286,9 @@ def _instancedoc_(self): x+y, y^2-y """ % (self._name,) - prefix2 = """ - -The Singular documentation for '%s' is given below. -""" % (self._name,) - - try: - return prefix + prefix2 + nodes[node_names[self._name]] - except KeyError: - return prefix + return prefix + get_docstring(self._name, + prefix=True, + code=True) @instancedoc @@ -2307,15 +2299,10 @@ def _instancedoc_(self): sage: R = singular.ring(0, '(x,y,z)', 'dp') sage: A = singular.matrix(2,2) - sage: 'matrix_expression' in A.nrows.__doc__ + sage: 'matrix_expression' in A.nrows.__doc__ # needs info True """ - if not nodes: - generate_docstring_dictionary() - try: - return nodes[node_names[self._name]] - except KeyError: - return "" + return get_docstring(self._name, code=True) def is_SingularElement(x): @@ -2341,82 +2328,125 @@ def is_SingularElement(x): return isinstance(x, SingularElement) -nodes = {} -node_names = {} - - -def generate_docstring_dictionary(): - """ - Generate global dictionaries which hold the docstrings for - Singular functions. - - EXAMPLES:: - - sage: from sage.interfaces.singular import generate_docstring_dictionary - sage: generate_docstring_dictionary() +def get_docstring(name, prefix=False, code=False): """ + Return the docstring for the function ``name``. - global nodes - global node_names - - nodes.clear() - node_names.clear() + INPUT: - new_node = re.compile(r"File: singular\.[a-z]*, Node: ([^,]*),.*") - new_lookup = re.compile(r"\* ([^:]*):*([^.]*)\..*") + - ``name`` -- a Singular function name + - ``prefix`` -- boolean (default: False); whether or not to include + the prefix stating that what follows is from the Singular + documentation. + - ``code`` -- boolean (default: False); whether or not to format the + result as a reStructuredText code block. This is intended to support + the feature requested in :issue:`11268`. + + OUTPUT: + + A string describing the Singular function ``name``. A + :class:`KeyError` is raised if the function was not found in the + Singular documentation. If the "info" is not on the user's + ``PATH``, an :class:`OSError` will be raised. If "info" was found + but failed to execute, a :class:`subprocess.CalledProcessError` + will be raised instead. - L, in_node, curr_node = [], False, None + EXAMPLES:: - from sage.libs.singular.singular import get_resource - singular_info_file = get_resource('i') + sage: from sage.interfaces.singular import get_docstring + sage: 'groebner' in get_docstring('groebner') # needs_info + True + sage: 'standard.lib' in get_docstring('groebner') # needs info + True - # singular.hlp contains a few iso-8859-1 encoded special characters - with open(singular_info_file, - encoding='latin-1') as f: - for line in f: - m = re.match(new_node, line) - if m: - # a new node starts - in_node = True - nodes[curr_node] = "".join(L) - L = [] - curr_node, = m.groups() - elif in_node: # we are in a node - L.append(line) - else: - m = re.match(new_lookup, line) - if m: - a, b = m.groups() - node_names[a] = b.strip() + The ``prefix=True`` form is used in Sage's generated docstrings:: - if line in ("6 Index\n", "F Index\n"): - in_node = False + sage: from sage.interfaces.singular import get_docstring + sage: print(get_docstring("factorize", prefix=True)) # needs info + The Singular documentation for "factorize" is given below. + ... - nodes[curr_node] = "".join(L) # last node + TESTS: + Non-existent functions raise a :class:`KeyError`:: -def get_docstring(name): - """ - Return the docstring for the function ``name``. + sage: from sage.interfaces.singular import get_docstring + sage: get_docstring("mysql_real_escape_string") # needs info + Traceback (most recent call last): + ... + KeyError: 'mysql_real_escape_string' - INPUT: + This is true also for nodes that exist in the documentation but + are not function nodes:: - - ``name`` -- a Singular function name + sage: from sage.interfaces.singular import get_docstring + sage: get_docstring("Preface") # needs info + Traceback (most recent call last): + ... + KeyError: 'Preface' - EXAMPLES:: + If GNU Info is not installed, we politely decline to do anything:: sage: from sage.interfaces.singular import get_docstring - sage: 'groebner' in get_docstring('groebner') - True - sage: 'standard.lib' in get_docstring('groebner') - True + sage: from sage.features.info import Info + sage: Info().hide() + sage: get_docstring('groebner') + Traceback (most recent call last): + ... + OSError: GNU Info is not installed. Singular's documentation + will not be available. + sage: Info().unhide() """ - if not nodes: - generate_docstring_dictionary() + from sage.features.info import Info + + if not Info().is_present(): + raise OSError("GNU Info is not installed. Singular's " + "documentation will not be available.") + import subprocess + cmd_and_args = ["info", f"--node={name}", "singular"] try: - return nodes[node_names[name]] - except KeyError: - return "" + result = subprocess.run(cmd_and_args, + capture_output=True, + check=True, + text=True) + except subprocess.CalledProcessError as e: + # Before Texinfo v7.0.0, the "info" program would exit + # successfully even if the desired node was not found. + if e.returncode == 1: + raise KeyError(name) from e + else: + # Something else bad happened + raise e + + # The subprocess call can succeed if the given node exists but is + # not a function node (example: "Preface"). All function nodes + # should live in the "Functions" section, and we can determine the + # current section by the presence of "Up:
" on the first + # line of the output, in the navigation header. + # + # There is a small risk of ambiguity here if there are two + # sections with the same name, but it's a trade-off: specifying + # the full path down to the intended function would be much more + # fragile; it would break whenever a subsection name was tweaked + # upstream. + offset = result.stdout.find("\n") + line0 = result.stdout[:offset] + if "Up: Functions" not in line0: + raise KeyError(name) + + # If the first line was the navigation header, the second line should + # be blank; by incrementing the offset by two, we're skipping over it. + offset += 2 + result = result.stdout[offset:] + + if code: + result = "::\n\n " + "\n ".join(result.split('\n')) + + if prefix: + result = (f'The Singular documentation for "{name}" is given below.' + + "\n\n" + result) + + return result singular = Singular() @@ -2456,6 +2486,11 @@ def singular_version(): """ Return the version of Singular being used. + OUTPUT: + + A string describing the Singular function ``name``. A ``KeyError`` + is raised if no such function was found in the Singular documentation. + EXAMPLES:: sage: singular.version() From 1045e49a1e088e0ce5dcb68e2688def90b7ea8de Mon Sep 17 00:00:00 2001 From: Michael Orlitzky Date: Fri, 8 Nov 2024 05:25:12 -0500 Subject: [PATCH 502/537] src/sage/libs/singular/function.pyx: use new get_docstring() features The rewritten get_docstring() in sage.interfaces.singular supports formatting the output as reStructuredText, so we no longer need to do it "by hand" in the library interface. --- src/sage/libs/singular/function.pyx | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/src/sage/libs/singular/function.pyx b/src/sage/libs/singular/function.pyx index c6f65eb718a..d9d70203908 100644 --- a/src/sage/libs/singular/function.pyx +++ b/src/sage/libs/singular/function.pyx @@ -1314,7 +1314,7 @@ cdef class SingularFunction(SageObject): sage: from sage.libs.singular.function import singular_function sage: groebner = singular_function('groebner') - sage: 'groebner' in groebner.__doc__ + sage: 'groebner' in groebner.__doc__ # needs info True """ @@ -1360,14 +1360,9 @@ EXAMPLES:: [x2, x1^2], [x2, x1^2]] -The Singular documentation for '%s' is given below. -"""%(self._name,self._name) - # Github issue #11268: Include the Singular documentation as a block of code - singular_doc = get_docstring(self._name).split('\n') - if len(singular_doc) > 1: - return prefix + "\n::\n\n"+'\n'.join([" "+L for L in singular_doc]) - else: - return prefix + "\n::\n\n"+" Singular documentation not found" +"""%(self._name) + from sage.interfaces.singular import get_docstring + return prefix + get_docstring(self._name, prefix=True, code=True) cdef common_ring(self, tuple args, ring=None): """ From 2f030e9e68c8f78263b24a51272f0eb17856f42b Mon Sep 17 00:00:00 2001 From: Michael Orlitzky Date: Fri, 8 Nov 2024 08:28:51 -0500 Subject: [PATCH 503/537] src/sage/misc/sageinspect.py: raise exceptions in _sage_getdoc_unformatted Our _sage_getdoc_unformatted() catches all exceptions and turns them into the empty string. The side effects of this are pretty bad: this function is used to generate the help? strings in the sage REPL, and if something goes wrong, the user will get a confusing blank docstring rather than the error. The change was introduced in issue 19671 as a workaround for a runtime error raised inside flask. But we are no longer using flask, and hopefully no other parts of the Sage library raise an exception during the documentation build. We are about to find out! --- src/sage/misc/sageinspect.py | 20 +------------------- 1 file changed, 1 insertion(+), 19 deletions(-) diff --git a/src/sage/misc/sageinspect.py b/src/sage/misc/sageinspect.py index 1f2a39d7c78..faea717ba52 100644 --- a/src/sage/misc/sageinspect.py +++ b/src/sage/misc/sageinspect.py @@ -1865,28 +1865,10 @@ def _sage_getdoc_unformatted(obj): sage: _sage_getdoc_unformatted(isinstance.__class__) '' - Construct an object raising an exception when accessing the - ``__doc__`` attribute. This should not give an error in - ``_sage_getdoc_unformatted``, see :issue:`19671`:: - - sage: class NoSageDoc(): - ....: @property - ....: def __doc__(self): - ....: raise Exception("no doc here") - sage: obj = NoSageDoc() - sage: obj.__doc__ - Traceback (most recent call last): - ... - Exception: no doc here - sage: _sage_getdoc_unformatted(obj) - '' """ if obj is None: return '' - try: - r = obj.__doc__ - except Exception: - return '' + r = obj.__doc__ # Check if the __doc__ attribute was actually a string, and # not a 'getset_descriptor' or similar. From 5f8f5257d5c5f26bfb5b6c57889edaf463478a76 Mon Sep 17 00:00:00 2001 From: Michael Orlitzky Date: Fri, 8 Nov 2024 19:40:06 -0500 Subject: [PATCH 504/537] src/sage/algebras/letterplace: define singular functions locally These modules use singular_function() from sage.libs.singular.function to create top-level aliases for a few singular functions. The docbuild however tries to build documentation for these functions, and it can raise an error if GNU info is not installed. There's no good reason to define them globally in the first place (they are only used locally), so an easy fix is to move the imports and variables local. --- .../letterplace/free_algebra_element_letterplace.pyx | 5 +++-- .../algebras/letterplace/free_algebra_letterplace.pyx | 5 +++-- src/sage/algebras/letterplace/letterplace_ideal.pyx | 8 +++++--- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/sage/algebras/letterplace/free_algebra_element_letterplace.pyx b/src/sage/algebras/letterplace/free_algebra_element_letterplace.pyx index 2a977b1a513..aa164d6a4ce 100644 --- a/src/sage/algebras/letterplace/free_algebra_element_letterplace.pyx +++ b/src/sage/algebras/letterplace/free_algebra_element_letterplace.pyx @@ -17,13 +17,12 @@ AUTHOR: # **************************************************************************** from sage.groups.perm_gps.permgroup_named import CyclicPermutationGroup -from sage.libs.singular.function import lib, singular_function +from sage.libs.singular.function import lib from sage.rings.polynomial.multi_polynomial_ideal import MPolynomialIdeal from cpython.object cimport PyObject_RichCompare # Define some singular functions lib("freegb.lib") -poly_reduce = singular_function("NF") ##################### # Free algebra elements @@ -695,6 +694,8 @@ cdef class FreeAlgebraElement_letterplace(AlgebraElement): bck = (libsingular_options['redTail'], libsingular_options['redSB']) libsingular_options['redTail'] = True libsingular_options['redSB'] = True + from sage.libs.singular.function import singular_function + poly_reduce = singular_function("NF") poly = poly_reduce(C(self._poly), gI, ring=C, attributes={gI: {"isSB": 1}}) libsingular_options['redTail'] = bck[0] diff --git a/src/sage/algebras/letterplace/free_algebra_letterplace.pyx b/src/sage/algebras/letterplace/free_algebra_letterplace.pyx index 7a57922d24a..10146c36aeb 100644 --- a/src/sage/algebras/letterplace/free_algebra_letterplace.pyx +++ b/src/sage/algebras/letterplace/free_algebra_letterplace.pyx @@ -121,7 +121,7 @@ TESTS:: algebras with different term orderings, yet. """ from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing -from sage.libs.singular.function import lib, singular_function +from sage.libs.singular.function import lib from sage.libs.singular.function cimport RingWrap from sage.libs.singular.ring cimport singular_ring_delete, singular_ring_reference from sage.categories.algebras import Algebras @@ -132,7 +132,6 @@ from sage.misc.cachefunc import cached_method ##################### # Define some singular functions lib("freegb.lib") -freeAlgebra = singular_function("freeAlgebra") # unfortunately we cannot set Singular attributes for MPolynomialRing_libsingular # Hence, we must constantly work around Letterplace's sanity checks, @@ -892,6 +891,8 @@ cdef class FreeAlgebra_letterplace_libsingular(): def __cinit__(self, MPolynomialRing_libsingular commutative_ring, int degbound): + from sage.libs.singular.function import singular_function + freeAlgebra = singular_function("freeAlgebra") cdef RingWrap rw = freeAlgebra(commutative_ring, degbound) self._lp_ring = singular_ring_reference(rw._ring) # `_lp_ring` viewed as `MPolynomialRing_libsingular` with additional diff --git a/src/sage/algebras/letterplace/letterplace_ideal.pyx b/src/sage/algebras/letterplace/letterplace_ideal.pyx index 77d0107ba07..060c89c3df0 100644 --- a/src/sage/algebras/letterplace/letterplace_ideal.pyx +++ b/src/sage/algebras/letterplace/letterplace_ideal.pyx @@ -41,7 +41,7 @@ AUTHOR: # https://www.gnu.org/licenses/ # **************************************************************************** from sage.rings.noncommutative_ideals import Ideal_nc -from sage.libs.singular.function import lib, singular_function +from sage.libs.singular.function import lib from sage.algebras.letterplace.free_algebra_letterplace cimport FreeAlgebra_letterplace, FreeAlgebra_letterplace_libsingular from sage.algebras.letterplace.free_algebra_element_letterplace cimport FreeAlgebraElement_letterplace from sage.rings.infinity import Infinity @@ -49,8 +49,6 @@ from sage.rings.infinity import Infinity ##################### # Define some singular functions lib("freegb.lib") -singular_twostd = singular_function("twostd") -poly_reduce = singular_function("NF") class LetterplaceIdeal(Ideal_nc): @@ -321,6 +319,8 @@ class LetterplaceIdeal(Ideal_nc): to_L = P.hom(L.gens(), L, check=False) from_L = L.hom(P.gens(), P, check=False) I = L.ideal([to_L(x._poly) for x in self.__GB.gens()]) + from sage.libs.singular.function import singular_function + singular_twostd = singular_function("twostd") gb = singular_twostd(I) out = [FreeAlgebraElement_letterplace(A, from_L(X), check=False) for X in gb] @@ -398,6 +398,8 @@ class LetterplaceIdeal(Ideal_nc): bck = (libsingular_options['redTail'], libsingular_options['redSB']) libsingular_options['redTail'] = True libsingular_options['redSB'] = True + from sage.libs.singular.function import singular_function + poly_reduce = singular_function("NF") sI = poly_reduce(sI, gI, ring=C, attributes={gI: {"isSB": 1}}) libsingular_options['redTail'] = bck[0] libsingular_options['redSB'] = bck[1] From e93a360277f381d83487fdac4bfe57ade8899a5d Mon Sep 17 00:00:00 2001 From: dcoudert Date: Sat, 9 Nov 2024 11:07:54 +0100 Subject: [PATCH 505/537] don't ignore errors in method union of DisjointSet --- src/sage/sets/disjoint_set.pxd | 2 +- src/sage/sets/disjoint_set.pyx | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/sage/sets/disjoint_set.pxd b/src/sage/sets/disjoint_set.pxd index 4d981718568..98f02ad4897 100644 --- a/src/sage/sets/disjoint_set.pxd +++ b/src/sage/sets/disjoint_set.pxd @@ -29,7 +29,7 @@ cdef class DisjointSet_of_hashables(DisjointSet_class): cdef list _int_to_el cdef dict _el_to_int cpdef find(self, e) - cpdef void union(self, e, f) noexcept + cpdef void union(self, e, f) except * cpdef root_to_elements_dict(self) cpdef element_to_root_dict(self) cpdef to_digraph(self) diff --git a/src/sage/sets/disjoint_set.pyx b/src/sage/sets/disjoint_set.pyx index ddd9a95a310..c2cce67037f 100644 --- a/src/sage/sets/disjoint_set.pyx +++ b/src/sage/sets/disjoint_set.pyx @@ -833,7 +833,7 @@ cdef class DisjointSet_of_hashables(DisjointSet_class): cdef int r = OP_find(self._nodes, i) return self._int_to_el[r] - cpdef void union(self, e, f) noexcept: + cpdef void union(self, e, f) except *: r""" Combine the set of ``e`` and the set of ``f`` into one. @@ -861,8 +861,9 @@ cdef class DisjointSet_of_hashables(DisjointSet_class): sage: e {{'a', 'b', 'c', 'e'}, {'d'}} sage: e.union('a', 2**10) - KeyError: 1024 + Traceback (most recent call last): ... + KeyError: 1024 """ cdef int i = self._el_to_int[e] cdef int j = self._el_to_int[f] From a06a1a252f5059e1dc6b3caa0662ea1a96114258 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Sat, 9 Nov 2024 11:27:20 +0100 Subject: [PATCH 506/537] further simplifications in Yang-Baxter --- src/sage/combinat/yang_baxter_graph.py | 30 +++++++++----------------- 1 file changed, 10 insertions(+), 20 deletions(-) diff --git a/src/sage/combinat/yang_baxter_graph.py b/src/sage/combinat/yang_baxter_graph.py index 5642b58e087..0a9661fdfff 100644 --- a/src/sage/combinat/yang_baxter_graph.py +++ b/src/sage/combinat/yang_baxter_graph.py @@ -15,6 +15,7 @@ # # https://www.gnu.org/licenses/ # **************************************************************************** +from copy import copy from sage.graphs.digraph import DiGraph from sage.structure.sage_object import SageObject @@ -310,7 +311,6 @@ def __copy__(self): sage: Y == B True """ - from copy import copy Y = self.__class__(self._root, self._operators) Y._digraph = copy(self._digraph) return Y @@ -420,9 +420,7 @@ def vertices(self, sort=False) -> list: sage: Y.vertices(sort=True) [(0, 2, 1, 0), (2, 0, 1, 0), (2, 1, 0, 0)] """ - if sort: - return sorted(self) - return list(self) + return sorted(self) if sort else list(self) def edges(self): r""" @@ -504,7 +502,6 @@ def relabel_vertices(self, v, relabel_operator, inplace=True): sage: Y.vertices(sort=True) [(1, 2, 3, 4), (2, 1, 3, 4), (2, 3, 1, 4)] """ - from copy import copy relabelling = self.vertex_relabelling_dict(v, relabel_operator) Y = self if inplace else copy(self) Y._root = relabelling[Y._root] @@ -539,11 +536,7 @@ def relabel_edges(self, edge_dict, inplace=True): sage: Y.edges() [((0, 2, 1, 0), (2, 0, 1, 0), 17), ((2, 0, 1, 0), (2, 1, 0, 0), 27)] """ - if inplace: - Y = self - else: - from copy import copy - Y = copy(self) + Y = self if inplace else copy(self) digraph = Y._digraph for u, v in digraph.edges(sort=False, labels=False): digraph.set_edge_label(u, v, edge_dict[u, v]) @@ -613,7 +606,6 @@ def __copy__(self): sage: Y == B True """ - from copy import copy Y = self.__class__(self._partition) Y._digraph = copy(self._digraph) return Y @@ -633,7 +625,7 @@ def _digraph(self): [((0, 1, 0), (1, 0, 0), Swap positions 0 and 1)] """ digraph = super()._digraph - for u, v, op in digraph.edges(sort=True): + for u, v, op in digraph.edges(): digraph.set_edge_label(u, v, SwapOperator(op.position())) return digraph @@ -753,11 +745,10 @@ def relabel_vertices(self, v, inplace=True): Y._digraph.relabel(relabelling, inplace=inplace) Y._vertex_ordering = Y._digraph.vertices(sort=True) return - else: - from copy import copy - Y = copy(self) - Y._root = relabelling[Y._root] - return Y._digraph.relabel(relabelling, inplace=inplace) + + Y = copy(self) + Y._root = relabelling[Y._root] + return Y._digraph.relabel(relabelling, inplace=inplace) # ------------- Some Yang-Baxter operators ------------------ @@ -924,9 +915,8 @@ def __call__(self, u): j = i + 1 if u[i] < u[j]: v = list(u) - (v[j], v[i]) = (v[i], v[j]) + v[j], v[i] = (v[i], v[j]) if isinstance(u, Permutation): return Permutation(v) return type(u)(v) - else: - return u + return u From 5f083f0b4558e57fe4e8d0492e83155f3fbd4326 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Sat, 9 Nov 2024 12:02:12 +0100 Subject: [PATCH 507/537] micro-detail --- src/sage/combinat/yang_baxter_graph.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/combinat/yang_baxter_graph.py b/src/sage/combinat/yang_baxter_graph.py index 0a9661fdfff..3fb02420f27 100644 --- a/src/sage/combinat/yang_baxter_graph.py +++ b/src/sage/combinat/yang_baxter_graph.py @@ -915,7 +915,7 @@ def __call__(self, u): j = i + 1 if u[i] < u[j]: v = list(u) - v[j], v[i] = (v[i], v[j]) + v[j], v[i] = v[i], v[j] if isinstance(u, Permutation): return Permutation(v) return type(u)(v) From fbd173ac83a491f35f86a9c74c352f83332c8cb0 Mon Sep 17 00:00:00 2001 From: Michael Orlitzky Date: Sat, 9 Nov 2024 09:24:17 -0500 Subject: [PATCH 508/537] src/sage/interfaces/singular.py: False -> ``False`` in documentation --- src/sage/interfaces/singular.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/sage/interfaces/singular.py b/src/sage/interfaces/singular.py index 74bd20faf07..18c73b3dc90 100644 --- a/src/sage/interfaces/singular.py +++ b/src/sage/interfaces/singular.py @@ -2335,12 +2335,12 @@ def get_docstring(name, prefix=False, code=False): INPUT: - ``name`` -- a Singular function name - - ``prefix`` -- boolean (default: False); whether or not to include - the prefix stating that what follows is from the Singular - documentation. - - ``code`` -- boolean (default: False); whether or not to format the - result as a reStructuredText code block. This is intended to support - the feature requested in :issue:`11268`. + - ``prefix`` -- boolean (default: ``False``); whether or not to + include the prefix stating that what follows is from the + Singular documentation. + - ``code`` -- boolean (default: ``False``); whether or not to + format the result as a reStructuredText code block. This is + intended to support the feature requested in :issue:`11268`. OUTPUT: From 0275387606364b1be0836da096f628bf3df7631b Mon Sep 17 00:00:00 2001 From: Michael Orlitzky Date: Sat, 9 Nov 2024 10:13:43 -0500 Subject: [PATCH 509/537] src/sage/interfaces/singular.py: remove nonsense OUTPUT block It looks like the OUTPUT block for singular_version() was copy/pasted from somewhere else -- it doesn't make sense. We delete it; the remaining short description of this function is sufficient. --- src/sage/interfaces/singular.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/sage/interfaces/singular.py b/src/sage/interfaces/singular.py index 18c73b3dc90..fdb4d093c55 100644 --- a/src/sage/interfaces/singular.py +++ b/src/sage/interfaces/singular.py @@ -2486,11 +2486,6 @@ def singular_version(): """ Return the version of Singular being used. - OUTPUT: - - A string describing the Singular function ``name``. A ``KeyError`` - is raised if no such function was found in the Singular documentation. - EXAMPLES:: sage: singular.version() From 375b69bd5b917a7607ac3f8a8e2998f8fdb04dd7 Mon Sep 17 00:00:00 2001 From: Dima Pasechnik Date: Sat, 9 Nov 2024 09:18:16 -0600 Subject: [PATCH 510/537] move spkg tarballs from user.ox.ac.uk These tarballs are now hosted at a release of sagemath/sage-package as "assets", as user.ox.ac.uk/~coml0531 is to be removed --- build/pkgs/cunningham_tables/checksums.ini | 2 +- build/pkgs/graphs/checksums.ini | 2 +- build/pkgs/planarity/checksums.ini | 2 +- build/pkgs/rubiks/checksums.ini | 2 +- build/pkgs/symmetrica/checksums.ini | 2 +- build/pkgs/tachyon/checksums.ini | 2 +- build/pkgs/topcom/checksums.ini | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/build/pkgs/cunningham_tables/checksums.ini b/build/pkgs/cunningham_tables/checksums.ini index 47cb1afb35b..afcf3c0ae55 100644 --- a/build/pkgs/cunningham_tables/checksums.ini +++ b/build/pkgs/cunningham_tables/checksums.ini @@ -1,4 +1,4 @@ tarball=cunningham_tables-VERSION.tar.gz sha1=8bea1a113d85bb9c37d8f213dd19525d9d026f22 sha256=ef39ab25bef5b1813071c9bd96abe3a9e683d5595c9654a3ffde5b07b7fe52b0 -upstream_url=http://users.ox.ac.uk/~coml0531/sage/cunningham_tables-VERSION.tar.gz +upstream_url=https://github.com/sagemath/sage-package/releases/download/tars/cunningham_tables-VERSION.tar.gz diff --git a/build/pkgs/graphs/checksums.ini b/build/pkgs/graphs/checksums.ini index 002c07affac..a5c9941eb96 100644 --- a/build/pkgs/graphs/checksums.ini +++ b/build/pkgs/graphs/checksums.ini @@ -1,4 +1,4 @@ tarball=graphs-VERSION.tar.bz2 sha1=c3b9fcbc92482efd6b7f6f3a33df5a78e1256aa1 sha256=07237c0d9853611505c389fd7bb92500c8743f5631babb4d0f45dfd8332f3741 -upstream_url=http://users.ox.ac.uk/~coml0531/sage/graphs-VERSION.tar.bz2 +upstream_url=https://github.com/sagemath/sage-package/releases/download/tars/graphs-VERSION.tar.bz2 diff --git a/build/pkgs/planarity/checksums.ini b/build/pkgs/planarity/checksums.ini index 06b8d7622c6..3caec0cca3f 100644 --- a/build/pkgs/planarity/checksums.ini +++ b/build/pkgs/planarity/checksums.ini @@ -1,4 +1,4 @@ tarball=planarity-VERSION.tar.gz sha1=8407bccf33c07bf0dae22d79b5e6ac7d89c62ea3 sha256=63e979d37e7160e4e72a286a8dd7ba74e4795f63742f417c8ba1cea2b2a51280 -upstream_url=http://users.ox.ac.uk/~coml0531/sage/planarity-VERSION.tar.gz +upstream_url=https://github.com/sagemath/sage-package/releases/download/tars/planarity-VERSION.tar.gz diff --git a/build/pkgs/rubiks/checksums.ini b/build/pkgs/rubiks/checksums.ini index f53803060f1..fb245dbae8e 100644 --- a/build/pkgs/rubiks/checksums.ini +++ b/build/pkgs/rubiks/checksums.ini @@ -1,4 +1,4 @@ tarball=rubiks-VERSION-unix.tar.bz2 sha1=c12069ed1eb0fc19f80a474b1c4bad2d845f5e40 sha256=aae4c88c0f1cf84718c1a6e31e027a2886e9eaea65051385339fd98be8693e07 -upstream_url=https://users.ox.ac.uk/~coml0531/tmp/rubiks-VERSION-unix.tar.bz2 +upstream_url=https://github.com/sagemath/sage-package/releases/download/tars/rubiks-VERSION-unix.tar.bz2 diff --git a/build/pkgs/symmetrica/checksums.ini b/build/pkgs/symmetrica/checksums.ini index 07664bc3183..74b01f40d36 100644 --- a/build/pkgs/symmetrica/checksums.ini +++ b/build/pkgs/symmetrica/checksums.ini @@ -1,4 +1,4 @@ tarball=symmetrica-VERSION.tar.xz sha1=0044cc087ff04267c246e730c6570d89f6e593af sha256=05ae107ec41f38cada19c26b6d7884970cbafae6e3b55ec3964896230358b456 -upstream_url=http://users.ox.ac.uk/~coml0531/sage/symmetrica-VERSION.tar.xz +upstream_url=https://github.com/sagemath/sage-package/releases/download/tars/symmetrica-VERSION.tar.xz diff --git a/build/pkgs/tachyon/checksums.ini b/build/pkgs/tachyon/checksums.ini index ad06308b255..99985331ee0 100644 --- a/build/pkgs/tachyon/checksums.ini +++ b/build/pkgs/tachyon/checksums.ini @@ -1,4 +1,4 @@ tarball=tachyon-VERSION.tar.gz sha1=28ac9dc28ba90b47ab7e03c81bb2170ddbb1c248 sha256=09203c102311149f5df5cc367409f96c725742666d19c24db5ba994d5a81a6f5 -upstream_url=https://users.ox.ac.uk/~coml0531/tmp/tachyon-VERSION.tar.gz +upstream_url=https://github.com/sagemath/sage-package/releases/download/tars/tachyon-VERSION.tar.gz diff --git a/build/pkgs/topcom/checksums.ini b/build/pkgs/topcom/checksums.ini index 1a00b4da1ec..6d3c1ef9331 100644 --- a/build/pkgs/topcom/checksums.ini +++ b/build/pkgs/topcom/checksums.ini @@ -1,4 +1,4 @@ tarball=TOPCOM-1_1_2.tgz sha1=65db8c00309f3bf8467ee5ba9da109c196db3461 sha256=4fb10754ee5b76056441fea98f2c8dee5db6f2984d8c14283b49239ad4378ab6 -upstream_url=https://users.ox.ac.uk/~coml0531/tmp/TOPCOM-1_1_2.tgz +upstream_url=https://github.com/sagemath/sage-package/releases/download/tars/TOPCOM-1_1_2.tgz From 3a5b0b123198632a08a423458f3be1b4fd4217c0 Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Sun, 3 Nov 2024 12:33:37 +0800 Subject: [PATCH 511/537] Meson: Improve handling of dependencies --- src/meson.build | 8 +- src/sage/coding/codecan/meson.build | 2 +- src/sage/combinat/meson.build | 7 +- src/sage/combinat/root_system/meson.build | 7 +- src/sage/geometry/meson.build | 7 +- src/sage/groups/matrix_gps/meson.build | 7 +- src/sage/groups/meson.build | 2 +- .../groups/perm_gps/partn_ref2/meson.build | 2 +- src/sage/libs/mpmath/meson.build | 2 +- src/sage/matrix/meson.build | 26 ++----- src/sage/misc/meson.build | 7 +- src/sage/rings/finite_rings/meson.build | 8 +- src/sage/rings/meson.build | 77 +++++++++++-------- src/sage/rings/number_field/meson.build | 7 +- src/sage/rings/polynomial/meson.build | 30 +++++--- src/sage/structure/meson.build | 7 +- src/sage/symbolic/meson.build | 11 --- 17 files changed, 128 insertions(+), 89 deletions(-) diff --git a/src/meson.build b/src/meson.build index 12d82fa91c3..fc3be1fd9bc 100644 --- a/src/meson.build +++ b/src/meson.build @@ -85,11 +85,15 @@ gsl = dependency( required: true, ) gd = cc.find_library('gd') -m = cc.find_library('m') +# Only some platforms have a standalone math library (https://mesonbuild.com/howtox.html#add-math-library-lm-portably) +m = cc.find_library('m', required : false) m4ri = cc.find_library('m4ri') m4rie = cc.find_library('m4rie') mtx = cc.find_library('mtx', required: false, disabler: true) -png = cc.find_library('png') +png = cc.find_library('png', required: false) +if not png.found() + png = cc.find_library('png16') +endif zlib = cc.find_library('z') # Cannot be found via pkg-config ec = cc.find_library('ec') diff --git a/src/sage/coding/codecan/meson.build b/src/sage/coding/codecan/meson.build index ac3a94a1edd..8749207de4b 100644 --- a/src/sage/coding/codecan/meson.build +++ b/src/sage/coding/codecan/meson.build @@ -17,7 +17,7 @@ foreach name, pyx : extension_data inc_partn_ref2, inc_rings, ], - dependencies: [py_dep, cysignals, gmp], + dependencies: [py_dep, cysignals, gap, gmp], ) endforeach diff --git a/src/sage/combinat/meson.build b/src/sage/combinat/meson.build index c0e9fe15d8b..8c1aba5bd50 100644 --- a/src/sage/combinat/meson.build +++ b/src/sage/combinat/meson.build @@ -145,13 +145,18 @@ extension_data = { } foreach name, pyx : extension_data + deps = [py_dep, cysignals, gmp] + if name == 'enumeration_mod_permgroup' + deps += [gap] + endif + py.extension_module( name, sources: pyx, subdir: 'sage/combinat', install: true, include_directories: [inc_cpython, inc_data_structures, inc_rings], - dependencies: [py_dep, cysignals, gmp], + dependencies: deps, ) endforeach diff --git a/src/sage/combinat/root_system/meson.build b/src/sage/combinat/root_system/meson.build index a8827403c7e..35e7bfb1950 100644 --- a/src/sage/combinat/root_system/meson.build +++ b/src/sage/combinat/root_system/meson.build @@ -64,13 +64,18 @@ extension_data = { } foreach name, pyx : extension_data + deps = [py_dep, cysignals, gmp] + if name.startswith('reflection_group') + deps += [gap] + endif + py.extension_module( name, sources: pyx, subdir: 'sage/combinat/root_system', install: true, include_directories: [inc_cpython, inc_rings], - dependencies: [py_dep, cysignals, gmp], + dependencies: deps, ) endforeach diff --git a/src/sage/geometry/meson.build b/src/sage/geometry/meson.build index 826ca9ef1db..8906b859dde 100644 --- a/src/sage/geometry/meson.build +++ b/src/sage/geometry/meson.build @@ -32,13 +32,18 @@ extension_data = { } foreach name, pyx : extension_data + deps = [py_dep, cysignals, flint, gmp] + if name == 'palp_normal_form' + deps += [gap] + endif + py.extension_module( name, sources: pyx, subdir: 'sage/geometry', install: true, include_directories: [inc_cpython, inc_ext, inc_flint, inc_rings], - dependencies: [py_dep, cysignals, flint, gmp], + dependencies: deps, ) endforeach diff --git a/src/sage/groups/matrix_gps/meson.build b/src/sage/groups/matrix_gps/meson.build index 43968d8ed59..41a436b06a7 100644 --- a/src/sage/groups/matrix_gps/meson.build +++ b/src/sage/groups/matrix_gps/meson.build @@ -33,13 +33,18 @@ extension_data = { } foreach name, pyx : extension_data + deps = [py_dep, gmp] + if name == 'group_element_gap' + deps += [gap] + endif + py.extension_module( name, sources: pyx, subdir: 'sage/groups/matrix_gps', install: true, include_directories: [inc_cpython], - dependencies: [py_dep, gmp], + dependencies: deps, ) endforeach diff --git a/src/sage/groups/meson.build b/src/sage/groups/meson.build index 3e2ffbb471c..a1876172c4d 100644 --- a/src/sage/groups/meson.build +++ b/src/sage/groups/meson.build @@ -43,7 +43,7 @@ foreach name, pyx : extension_data subdir: 'sage/groups', install: true, include_directories: [inc_cpython], - dependencies: [py_dep, gmp], + dependencies: [py_dep, gmp, gap], ) endforeach diff --git a/src/sage/groups/perm_gps/partn_ref2/meson.build b/src/sage/groups/perm_gps/partn_ref2/meson.build index ca6fadbfda9..ef97195574e 100644 --- a/src/sage/groups/perm_gps/partn_ref2/meson.build +++ b/src/sage/groups/perm_gps/partn_ref2/meson.build @@ -13,7 +13,7 @@ foreach name, pyx : extension_data subdir: 'sage/groups/perm_gps/partn_ref2', install: true, include_directories: [inc_cpython, inc_data_structures, inc_partn_ref2], - dependencies: [py_dep, cysignals, gmp], + dependencies: [py_dep, cysignals, gmp, gap], ) endforeach diff --git a/src/sage/libs/mpmath/meson.build b/src/sage/libs/mpmath/meson.build index 4659da1563a..a197516f9f1 100644 --- a/src/sage/libs/mpmath/meson.build +++ b/src/sage/libs/mpmath/meson.build @@ -21,7 +21,7 @@ foreach name, pyx : extension_data subdir: 'sage/libs/mpmath', install: true, include_directories: [inc_cpython, inc_ext, inc_rings], - dependencies: [py_dep, cypari2, cysignals, gmp, mpfr], + dependencies: [py_dep, cysignals, gmp, mpfr], ) endforeach diff --git a/src/sage/matrix/meson.build b/src/sage/matrix/meson.build index c0841d77f34..4e1cb41fac6 100644 --- a/src/sage/matrix/meson.build +++ b/src/sage/matrix/meson.build @@ -98,29 +98,19 @@ extension_data = { foreach name, pyx : extension_data dependencies = [ py_dep, - blas, - cypari2, cysignals, - fflas, - flint, - gd, - givaro, gmp, - gmpxx, - iml, - linbox, - m, - m4ri, - m4rie, - mpfi, - mpfr, - ntl, - pari, - png, - zlib, ] if name == 'matrix_gfpn_dense' dependencies += [mtx, meataxe] + elif name == 'matrix_gap' + dependencies += [gap] + elif name == 'misc_mpfr' + dependencies += [mpfr] + elif name == 'matrix_complex_ball_dense' + dependencies += [mpfi] + elif name == 'misc_flint' or name == 'matrix_rational_sparse' + dependencies += [flint] endif py.extension_module( diff --git a/src/sage/misc/meson.build b/src/sage/misc/meson.build index bd05d525252..f4ba17ef30a 100644 --- a/src/sage/misc/meson.build +++ b/src/sage/misc/meson.build @@ -124,13 +124,18 @@ extension_data = { } foreach name, pyx : extension_data + deps = [py_dep, gmp] + if name == 'binary_tree' + deps += [cysignals] + endif + py.extension_module( name, sources: pyx, subdir: 'sage/misc', install: true, include_directories: [inc_cpython, inc_rings], - dependencies: [py_dep, cysignals, gmp], + dependencies: deps, ) endforeach diff --git a/src/sage/rings/finite_rings/meson.build b/src/sage/rings/finite_rings/meson.build index 896d69651cf..e81724aa5c8 100644 --- a/src/sage/rings/finite_rings/meson.build +++ b/src/sage/rings/finite_rings/meson.build @@ -39,6 +39,12 @@ extension_data = { } foreach name, pyx : extension_data + deps = [py_dep, cysignals, gmp] + if name == 'element_pari_ffelt' + deps += [cypari2] + elif name == 'residue_field_pari_ffelt' + deps += [cypari2] + endif py.extension_module( name, sources: pyx, @@ -51,7 +57,7 @@ foreach name, pyx : extension_data inc_rings, inc_rings_finite, ], - dependencies: [py_dep, cypari2, cysignals, givaro, gmp, m, ntl, pari], + dependencies: deps, ) endforeach diff --git a/src/sage/rings/meson.build b/src/sage/rings/meson.build index 9aff2d7c8f3..a06dd098c06 100644 --- a/src/sage/rings/meson.build +++ b/src/sage/rings/meson.build @@ -1,5 +1,3 @@ -pthread = cc.find_library('pthread') - py.install_sources( 'abc.pxd', 'algebraic_closure_finite_field.py', @@ -124,6 +122,36 @@ extension_data = { } foreach name, pyx : extension_data + deps = [py_dep, cysignals, gmp] + if name == 'complex_arb' + deps += [flint, mpfi] + elif name == 'complex_conversion' + deps += [gsl, mpfr] + elif name == 'complex_double' + deps += [gmpy2, gsl] + elif name == 'complex_interval' + deps += [mpfi] + elif name == 'complex_mpc' + deps += [gmpy2, mpfr, mpc] + elif name == 'complex_mpfr' + deps += [gmpy2, mpfr] + elif name == 'factorint_flint' + deps += [flint] + elif name == 'integer' + deps += [gmpy2] + elif name == 'power_series_pari' + deps += [cypari2] + elif name == 'real_arb' + deps += [flint, mpfi] + elif name == 'real_double' + deps += [gmpy2] + elif name == 'real_double_element_gsl' + deps += [gsl] + elif name == 'real_mpfi' + deps += [mpfi] + elif name == 'real_mpfr' + deps += [gmpy2, mpfr] + endif py.extension_module( name, sources: pyx, @@ -138,22 +166,7 @@ foreach name, pyx : extension_data inc_rings, inc_rings_finite, ], - dependencies: [ - py_dep, - cypari2, - cysignals, - flint, - gmp, - gmpy2, - gsl, - m, - mpc, - mpfi, - mpfr, - ntl, - pari, - pthread, - ], + dependencies: deps, ) endforeach @@ -170,6 +183,17 @@ extension_data_cpp = { } foreach name, pyx : extension_data_cpp + deps = [py_dep, cysignals, gmp] + if name == 'bernmm' + deps += [ntl] + elif name == 'bernoulli_mod_p' + deps += [ntl] + elif name == 'fraction_field_FpT' + deps += [flint] + elif name == 'rational' + deps += [gmpy2] + endif + py.extension_module( name, sources: pyx, @@ -186,22 +210,7 @@ foreach name, pyx : extension_data_cpp inc_rings, inc_rings_finite, ], - dependencies: [ - py_dep, - cypari2, - cysignals, - flint, - gmp, - gmpy2, - gsl, - m, - mpc, - mpfi, - mpfr, - ntl, - pari, - pthread, - ], + dependencies: deps, ) endforeach diff --git a/src/sage/rings/number_field/meson.build b/src/sage/rings/number_field/meson.build index 077c1d918e6..46162077eb8 100644 --- a/src/sage/rings/number_field/meson.build +++ b/src/sage/rings/number_field/meson.build @@ -37,13 +37,18 @@ extension_data = { } foreach name, pyx : extension_data + deps = [py_dep, cysignals, gmp] + if name == 'totallyreal' + deps += [cypari2] + endif + py.extension_module( name, sources: pyx, subdir: 'sage/rings/number_field', install: true, include_directories: [inc_cpython, inc_ext, inc_flint, inc_ntl, inc_rings], - dependencies: [py_dep, cypari2, cysignals, flint, gmp, mpfi, mpfr, ntl], + dependencies: deps, ) endforeach diff --git a/src/sage/rings/polynomial/meson.build b/src/sage/rings/polynomial/meson.build index c1625c5eb94..2a82bea5e58 100644 --- a/src/sage/rings/polynomial/meson.build +++ b/src/sage/rings/polynomial/meson.build @@ -92,6 +92,23 @@ extension_data = { } foreach name, pyx : extension_data + deps = [ + py_dep, + cysignals, + gmp, + ] + if name == 'evaluation_flint' + deps += [flint, mpfi] + elif name == 'polynomial_complex_arb' + deps += [flint, mpfi] + elif name == 'polynomial_real_mpfr_dense' + deps += [mpfr] + elif name == 'real_roots' + deps += [mpfi] + elif name == 'hilbert' + deps += [mpfi] + endif + py.extension_module( name, sources: pyx, @@ -106,18 +123,7 @@ foreach name, pyx : extension_data inc_rings, inc_rings_finite, ], - dependencies: [ - py_dep, - cypari2, - cysignals, - flint, - givaro, - gmp, - mpfi, - mpfr, - ntl, - pari, - ], + dependencies: deps, ) endforeach diff --git a/src/sage/structure/meson.build b/src/sage/structure/meson.build index 6f4c75d58a4..9d0076ef53d 100644 --- a/src/sage/structure/meson.build +++ b/src/sage/structure/meson.build @@ -60,13 +60,18 @@ extension_data = { } foreach name, pyx : extension_data + deps = [py_dep, cysignals, gmp] + if name == 'coerce' + deps += [gmpy2] + endif + py.extension_module( name, sources: pyx, subdir: 'sage/structure', install: true, include_directories: [inc_cpython, inc_ext, inc_rings], - dependencies: [py_dep, cysignals, gmp, gmpy2, mpc, mpfr], + dependencies: deps, ) endforeach diff --git a/src/sage/symbolic/meson.build b/src/sage/symbolic/meson.build index a9ca57ebf43..6c8550a93f9 100644 --- a/src/sage/symbolic/meson.build +++ b/src/sage/symbolic/meson.build @@ -49,14 +49,8 @@ foreach name, pyx : extension_data ], dependencies: [ py_dep, - cypari2, cysignals, - flint, gmp, - gsl, - mpfr, - pari, - singular, ], ) endforeach @@ -136,14 +130,9 @@ foreach name, pyx : extension_data_cpp ], dependencies: [ py_dep, - cypari2, cysignals, gmp, - flint, gsl, - m, - mpfr, - pari, singular, ], ) From b0bd8f8c9760ae8f7b207a1b491db107828a36db Mon Sep 17 00:00:00 2001 From: Marc Culler Date: Sat, 9 Nov 2024 14:45:53 -0600 Subject: [PATCH 512/537] Add flex to build/_prereq/distros/debian.txt, --- build/pkgs/_prereq/distros/debian.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/build/pkgs/_prereq/distros/debian.txt b/build/pkgs/_prereq/distros/debian.txt index 785739528b4..c6598935e3c 100644 --- a/build/pkgs/_prereq/distros/debian.txt +++ b/build/pkgs/_prereq/distros/debian.txt @@ -11,6 +11,8 @@ binutils make m4 perl +# flex is needed to build gcc +flex # python3-minimal is not enough on debian buster, ubuntu bionic - it does not have urllib # system python for bootstrapping the build python3 From edd5553a59dd8b45b51f6c541cddd9e241fa36f3 Mon Sep 17 00:00:00 2001 From: Marc Culler Date: Sat, 9 Nov 2024 21:31:00 -0600 Subject: [PATCH 513/537] Add flex to build/pkgs/_prereq/distros/fedora.txt --- build/pkgs/_prereq/distros/fedora.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/build/pkgs/_prereq/distros/fedora.txt b/build/pkgs/_prereq/distros/fedora.txt index 2716e7eb0cd..a61a5523437 100644 --- a/build/pkgs/_prereq/distros/fedora.txt +++ b/build/pkgs/_prereq/distros/fedora.txt @@ -29,3 +29,5 @@ which diffutils # Needed for openssl 3.0 perl-IPC-Cmd +# Needed to build gcc +flex From f882056dab82ba5c59713c70b08ca53b3df83092 Mon Sep 17 00:00:00 2001 From: Volker Braun Date: Sun, 10 Nov 2024 12:46:58 +0100 Subject: [PATCH 514/537] Fix configure script generated by pkgconf-2.3.0 Pkgconf 2.3.0 changes the PKG_PROG_PKG_CONFIG macro to error out instead of marking it as not found. Arguably this is the correct default for most but not for us, since we support building on macos where Apple, in their infinite wisdom, decided not to ship their dev tools with it. See also: https://github.com/pkgconf/pkgconf/blob/master/NEWS dnl PKG_PROG_PKG_CONFIG([MIN-VERSION], [ACTION-IF-NOT-FOUND]) dnl --------------------------------------------------------- dnl Since: 0.16 dnl dnl Search for the pkg-config tool and set the PKG_CONFIG variable to dnl first found in the path. Checks that the version of pkg-config found dnl is at least MIN-VERSION. If MIN-VERSION is not specified, 0.9.0 is dnl used since that's the first version where most current features of dnl pkg-config existed. dnl dnl If pkg-config is not found or older than specified, it will result dnl in an empty PKG_CONFIG variable. To avoid widespread issues with dnl scripts not checking it, ACTION-IF-NOT-FOUND defaults to aborting. dnl You can specify [PKG_CONFIG=false] as an action instead, which would dnl result in pkg-config tests failing, but no bogus error messages. --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 5c12ff36ac9..1bf79ed7333 100644 --- a/configure.ac +++ b/configure.ac @@ -222,7 +222,7 @@ dnl Exit autoconf with exit code 16 in this case. This will be dnl caught by the bootstrap script. m4_exit(16)]) -PKG_PROG_PKG_CONFIG([0.29]) +PKG_PROG_PKG_CONFIG([0.29], [PKG_CONFIG=false]) AC_CHECK_PROG(found_ranlib, ranlib, yes, no) if test x$found_ranlib != xyes From 220a0b97d87b8b4fd8d9835bb6c4872a5b0d5ed5 Mon Sep 17 00:00:00 2001 From: Verrel Rievaldo Wijaya Date: Mon, 11 Nov 2024 02:58:16 +0700 Subject: [PATCH 515/537] Add example; update docstring --- src/sage/rings/semirings/tropical_mpolynomial.py | 2 +- src/sage/rings/semirings/tropical_polynomial.py | 10 ++++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/sage/rings/semirings/tropical_mpolynomial.py b/src/sage/rings/semirings/tropical_mpolynomial.py index f5635ca886b..d8011d2b033 100644 --- a/src/sage/rings/semirings/tropical_mpolynomial.py +++ b/src/sage/rings/semirings/tropical_mpolynomial.py @@ -415,7 +415,7 @@ def newton_polytope(self): corresponding to the exponents of the monomials of tropical polynomial. - OUTPUT: :class:`~sage.geometry.polyhedron.constructor.Polyhedron` + OUTPUT: :func:`~sage.geometry.polyhedron.constructor.Polyhedron` EXAMPLES: diff --git a/src/sage/rings/semirings/tropical_polynomial.py b/src/sage/rings/semirings/tropical_polynomial.py index 39786045faf..7a36049668f 100644 --- a/src/sage/rings/semirings/tropical_polynomial.py +++ b/src/sage/rings/semirings/tropical_polynomial.py @@ -11,10 +11,12 @@ sage: R. = PolynomialRing(T) sage: x.parent() Univariate Tropical Polynomial Semiring in x over Rational Field - sage: (R(3)*x + R(1)) * (x^2 + x) - 3*x^3 + 3*x^2 + 1*x - sage: (x^2 + x + R(0))^2 - 0*x^4 + 0*x^3 + 0*x^2 + 0*x + 0 + sage: (x + R(3)*x) * (x^2 + x) + 3*x^3 + 3*x^2 + sage: (x^2 + R(1)*x + R(-1))^2 + 0*x^4 + 1*x^3 + 2*x^2 + 0*x + (-2) + sage: (x^2 + x + R(0))^4 + 0*x^8 + 0*x^7 + 0*x^6 + 0*x^5 + 0*x^4 + 0*x^3 + 0*x^2 + 0*x + 0 REFERENCES: From 0416a96604451f996ab3df48d8bae3574def77a3 Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Mon, 11 Nov 2024 11:59:18 +0800 Subject: [PATCH 516/537] Add a few runtime dependencies --- src/meson.build | 2 +- src/sage/groups/matrix_gps/meson.build | 2 +- src/sage/matrix/meson.build | 6 +----- src/sage/rings/finite_rings/meson.build | 5 ++++- src/sage/rings/meson.build | 11 +++++++++-- src/sage/rings/polynomial/meson.build | 6 +----- src/sage/symbolic/meson.build | 14 ++------------ 7 files changed, 19 insertions(+), 27 deletions(-) diff --git a/src/meson.build b/src/meson.build index fc3be1fd9bc..26a6e3a4688 100644 --- a/src/meson.build +++ b/src/meson.build @@ -86,7 +86,7 @@ gsl = dependency( ) gd = cc.find_library('gd') # Only some platforms have a standalone math library (https://mesonbuild.com/howtox.html#add-math-library-lm-portably) -m = cc.find_library('m', required : false) +m = cc.find_library('m', required: false) m4ri = cc.find_library('m4ri') m4rie = cc.find_library('m4rie') mtx = cc.find_library('mtx', required: false, disabler: true) diff --git a/src/sage/groups/matrix_gps/meson.build b/src/sage/groups/matrix_gps/meson.build index 41a436b06a7..30b8e2379c0 100644 --- a/src/sage/groups/matrix_gps/meson.build +++ b/src/sage/groups/matrix_gps/meson.build @@ -36,7 +36,7 @@ foreach name, pyx : extension_data deps = [py_dep, gmp] if name == 'group_element_gap' deps += [gap] - endif + endif py.extension_module( name, diff --git a/src/sage/matrix/meson.build b/src/sage/matrix/meson.build index 4e1cb41fac6..932ac4c40c2 100644 --- a/src/sage/matrix/meson.build +++ b/src/sage/matrix/meson.build @@ -96,11 +96,7 @@ extension_data = { } foreach name, pyx : extension_data - dependencies = [ - py_dep, - cysignals, - gmp, - ] + dependencies = [py_dep, cysignals, gmp] if name == 'matrix_gfpn_dense' dependencies += [mtx, meataxe] elif name == 'matrix_gap' diff --git a/src/sage/rings/finite_rings/meson.build b/src/sage/rings/finite_rings/meson.build index e81724aa5c8..7f7a5744a1f 100644 --- a/src/sage/rings/finite_rings/meson.build +++ b/src/sage/rings/finite_rings/meson.build @@ -41,7 +41,10 @@ extension_data = { foreach name, pyx : extension_data deps = [py_dep, cysignals, gmp] if name == 'element_pari_ffelt' - deps += [cypari2] + deps += [ + cypari2, + pari, # Runtime dependency + ] elif name == 'residue_field_pari_ffelt' deps += [cypari2] endif diff --git a/src/sage/rings/meson.build b/src/sage/rings/meson.build index a06dd098c06..14ed48a7c7a 100644 --- a/src/sage/rings/meson.build +++ b/src/sage/rings/meson.build @@ -124,13 +124,20 @@ extension_data = { foreach name, pyx : extension_data deps = [py_dep, cysignals, gmp] if name == 'complex_arb' - deps += [flint, mpfi] + deps += [ + flint, + mpfi, + gsl, # Runtime dependency + ] elif name == 'complex_conversion' deps += [gsl, mpfr] elif name == 'complex_double' deps += [gmpy2, gsl] elif name == 'complex_interval' - deps += [mpfi] + deps += [ + mpfi, + flint, # Runtime dependency + ] elif name == 'complex_mpc' deps += [gmpy2, mpfr, mpc] elif name == 'complex_mpfr' diff --git a/src/sage/rings/polynomial/meson.build b/src/sage/rings/polynomial/meson.build index 2a82bea5e58..94a0a0c8b9a 100644 --- a/src/sage/rings/polynomial/meson.build +++ b/src/sage/rings/polynomial/meson.build @@ -92,11 +92,7 @@ extension_data = { } foreach name, pyx : extension_data - deps = [ - py_dep, - cysignals, - gmp, - ] + deps = [py_dep, cysignals, gmp] if name == 'evaluation_flint' deps += [flint, mpfi] elif name == 'polynomial_complex_arb' diff --git a/src/sage/symbolic/meson.build b/src/sage/symbolic/meson.build index 6c8550a93f9..0ba39cb4d45 100644 --- a/src/sage/symbolic/meson.build +++ b/src/sage/symbolic/meson.build @@ -47,11 +47,7 @@ foreach name, pyx : extension_data inc_pynac, inc_rings, ], - dependencies: [ - py_dep, - cysignals, - gmp, - ], + dependencies: [py_dep, cysignals, gmp], ) endforeach @@ -128,13 +124,7 @@ foreach name, pyx : extension_data_cpp inc_rings, include_directories('../libs/gmp'), ], - dependencies: [ - py_dep, - cysignals, - gmp, - gsl, - singular, - ], + dependencies: [py_dep, cysignals, gmp, gsl, singular], ) endforeach From 51f66ddf8ab0e25e2bf76ec599d259b75b15122b Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Mon, 11 Nov 2024 10:54:58 +0530 Subject: [PATCH 517/537] Corrected _gens_constructor() doctest --- src/sage/matroids/chow_ring_ideal.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sage/matroids/chow_ring_ideal.py b/src/sage/matroids/chow_ring_ideal.py index 53bdfedd246..46d4d39031e 100644 --- a/src/sage/matroids/chow_ring_ideal.py +++ b/src/sage/matroids/chow_ring_ideal.py @@ -130,7 +130,7 @@ def _gens_constructor(self, poly_ring): EXAMPLES:: sage: ch = matroids.catalog.NonFano().chow_ring(QQ, False) - sage: ch.defining_ideal()._gens_constructor(ch.defining_ideal().ring()) + sage: sorted(ch.defining_ideal()._gens_constructor(ch.defining_ideal().ring())) [Aa*Ab, Aa*Ac, Aa*Ae, Aa*Ad, Aa*Ade, Aa*Abcd, Aa*Af, Aa*Adf, Aa*Aef, Aa*Ag, Aa*Abeg, Aa*Acfg, Ab*Ac, Ab*Ae, Ab*Aace, Ab*Ad, Ab*Ade, Ab*Af, Ab*Adf, Ab*Aef, Ab*Ag, Ab*Aadg, Ab*Acfg, Ac*Ae, @@ -412,7 +412,7 @@ def _gens_constructor(self, poly_ring): EXAMPLES:: sage: ch = matroids.Wheel(3).chow_ring(QQ, True, 'fy') - sage: ch.defining_ideal()._gens_constructor(ch.defining_ideal().ring()) + sage: sorted(ch.defining_ideal()._gens_constructor(ch.defining_ideal().ring())) [B0*B1, B0*B2, B0*B3, B0*B23, B0*B4, B0*B124, B0*B5, B0*B15, B0*B345, B1*B2, B1*B3, B1*B23, B1*B4, B1*B04, B1*B5, B1*B025, B1*B345, B2*B3, B2*B013, B2*B4, B2*B04, B2*B5, B2*B15, B2*B345, @@ -657,7 +657,7 @@ def _gens_constructor(self, poly_ring): sage: M1 = Matroid(graphs.CycleGraph(3)) sage: ch = M1.chow_ring(QQ, True, 'atom-free') - sage: ch.defining_ideal()._gens_constructor(ch.defining_ideal().ring()) + sage: sorted(ch.defining_ideal()._gens_constructor(ch.defining_ideal().ring())) [A0*A1, A0*A2, A1*A2, A0^2 + 2*A0*A3 + A3^2, A1^2 + 2*A1*A3 + A3^2, A0*A1 + A0*A3, A2^2 + 2*A2*A3 + A3^2, A0*A2 + A0*A3, A0*A1 + A1*A3, A1*A2 + A1*A3, A0*A2 + A2*A3, A1*A2 + A2*A3] From a7eec7ba8bcf557e40565651af3d2dbc8a24ee94 Mon Sep 17 00:00:00 2001 From: Shriya M <25shriya@gmail.com> Date: Mon, 11 Nov 2024 12:01:44 +0530 Subject: [PATCH 518/537] Formatted doctests --- src/sage/matroids/chow_ring_ideal.py | 89 ++++++++++++++-------------- 1 file changed, 45 insertions(+), 44 deletions(-) diff --git a/src/sage/matroids/chow_ring_ideal.py b/src/sage/matroids/chow_ring_ideal.py index 46d4d39031e..d0ac04a23ee 100644 --- a/src/sage/matroids/chow_ring_ideal.py +++ b/src/sage/matroids/chow_ring_ideal.py @@ -131,27 +131,27 @@ def _gens_constructor(self, poly_ring): sage: ch = matroids.catalog.NonFano().chow_ring(QQ, False) sage: sorted(ch.defining_ideal()._gens_constructor(ch.defining_ideal().ring())) - [Aa*Ab, Aa*Ac, Aa*Ae, Aa*Ad, Aa*Ade, Aa*Abcd, Aa*Af, Aa*Adf, - Aa*Aef, Aa*Ag, Aa*Abeg, Aa*Acfg, Ab*Ac, Ab*Ae, Ab*Aace, Ab*Ad, - Ab*Ade, Ab*Af, Ab*Adf, Ab*Aef, Ab*Ag, Ab*Aadg, Ab*Acfg, Ac*Ae, - Ac*Ad, Ac*Ade, Ac*Af, Ac*Aabf, Ac*Adf, Ac*Aef, Ac*Ag, Ac*Aadg, - Ac*Abeg, Ad*Ae, Ae*Abcd, Ae*Af, Ae*Aabf, Ae*Adf, Ae*Ag, Ae*Aadg, - Ae*Acfg, Ad*Aace, Aace*Ade, Aace*Abcd, Af*Aace, Aabf*Aace, - Aace*Adf, Aace*Aef, Ag*Aace, Aace*Aadg, Aace*Abeg, Aace*Acfg, - Ad*Af, Ad*Aabf, Ad*Aef, Ad*Ag, Ad*Abeg, Ad*Acfg, Abcd*Ade, Af*Ade, - Aabf*Ade, Ade*Adf, Ade*Aef, Ag*Ade, Aadg*Ade, Abeg*Ade, Acfg*Ade, - Af*Abcd, Aabf*Abcd, Abcd*Adf, Abcd*Aef, Ag*Abcd, Aadg*Abcd, - Abcd*Abeg, Abcd*Acfg, Af*Ag, Af*Aadg, Af*Abeg, Aabf*Adf, Aabf*Aef, - Ag*Aabf, Aabf*Aadg, Aabf*Abeg, Aabf*Acfg, Adf*Aef, Ag*Adf, - Aadg*Adf, Abeg*Adf, Acfg*Adf, Ag*Aef, Aadg*Aef, Abeg*Aef, - Acfg*Aef, Aadg*Abeg, Aadg*Acfg, Abeg*Acfg, - Aa + Aabf + Aace + Aadg + Aabcdefg, - Ab + Aabf + Abcd + Abeg + Aabcdefg, - Ac + Aace + Abcd + Acfg + Aabcdefg, - Ad + Aadg + Abcd + Ade + Adf + Aabcdefg, - Ae + Aace + Abeg + Ade + Aef + Aabcdefg, + [Ag + Aadg + Abeg + Acfg + Aabcdefg, Af + Aabf + Acfg + Adf + Aef + Aabcdefg, - Ag + Aadg + Abeg + Acfg + Aabcdefg] + Ae + Aace + Abeg + Ade + Aef + Aabcdefg, + Ad + Aadg + Abcd + Ade + Adf + Aabcdefg, + Ac + Aace + Abcd + Acfg + Aabcdefg, + Ab + Aabf + Abcd + Abeg + Aabcdefg, + Aa + Aabf + Aace + Aadg + Aabcdefg, + Adf*Aef, Ade*Aef, Acfg*Aef, Abeg*Aef, Abcd*Aef, Aadg*Aef, + Aace*Aef, Aabf*Aef, Ag*Aef, Ad*Aef, Ac*Aef, Ab*Aef, Aa*Aef, + Ade*Adf, Acfg*Adf, Abeg*Adf, Abcd*Adf, Aadg*Adf, Aace*Adf, + Aabf*Adf, Ag*Adf, Ae*Adf, Ac*Adf, Ab*Adf, Aa*Adf, Acfg*Ade, + Abeg*Ade, Abcd*Ade, Aadg*Ade, Aace*Ade, Aabf*Ade, Ag*Ade, Af*Ade, + Ac*Ade, Ab*Ade, Aa*Ade, Abeg*Acfg, Abcd*Acfg, Aadg*Acfg, + Aace*Acfg, Aabf*Acfg, Ae*Acfg, Ad*Acfg, Ab*Acfg, Aa*Acfg, + Abcd*Abeg, Aadg*Abeg, Aace*Abeg, Aabf*Abeg, Af*Abeg, Ad*Abeg, + Ac*Abeg, Aa*Abeg, Aadg*Abcd, Aace*Abcd, Aabf*Abcd, Ag*Abcd, + Af*Abcd, Ae*Abcd, Aa*Abcd, Aace*Aadg, Aabf*Aadg, Af*Aadg, Ae*Aadg, + Ac*Aadg, Ab*Aadg, Aabf*Aace, Ag*Aace, Af*Aace, Ad*Aace, Ab*Aace, + Ag*Aabf, Ae*Aabf, Ad*Aabf, Ac*Aabf, Af*Ag, Ae*Ag, Ad*Ag, Ac*Ag, + Ab*Ag, Aa*Ag, Ae*Af, Ad*Af, Ac*Af, Ab*Af, Aa*Af, Ad*Ae, Ac*Ae, + Ab*Ae, Aa*Ae, Ac*Ad, Ab*Ad, Aa*Ad, Ab*Ac, Aa*Ac, Aa*Ab] """ flats = list(self._flats_generator) lattice_flats = Poset((flats, lambda x, y: x <= y)) @@ -413,33 +413,34 @@ def _gens_constructor(self, poly_ring): sage: ch = matroids.Wheel(3).chow_ring(QQ, True, 'fy') sage: sorted(ch.defining_ideal()._gens_constructor(ch.defining_ideal().ring())) - [B0*B1, B0*B2, B0*B3, B0*B23, B0*B4, B0*B124, B0*B5, B0*B15, - B0*B345, B1*B2, B1*B3, B1*B23, B1*B4, B1*B04, B1*B5, B1*B025, - B1*B345, B2*B3, B2*B013, B2*B4, B2*B04, B2*B5, B2*B15, B2*B345, - B3*B4, B3*B04, B3*B124, B3*B5, B3*B025, B3*B15, B013*B23, B4*B013, - B013*B04, B013*B124, B5*B013, B013*B025, B013*B15, B013*B345, - B4*B23, B04*B23, B124*B23, B5*B23, B025*B23, B15*B23, B23*B345, - B4*B5, B4*B025, B4*B15, B04*B124, B5*B04, B025*B04, B04*B15, - B04*B345, B5*B124, B025*B124, B124*B15, B124*B345, B025*B15, - B025*B345, B15*B345, A0*B, A0*B1, A0*B2, A0*B3, A0*B4, A0*B5, - A0*B124, A0*B15, A0*B23, A0*B345, A1*B, A1*B0, A1*B2, A1*B3, - A1*B4, A1*B5, A1*B025, A1*B04, A1*B23, A1*B345, A2*B, A2*B0, - A2*B1, A2*B3, A2*B4, A2*B5, A2*B013, A2*B04, A2*B15, A2*B345, - A3*B, A3*B0, A3*B1, A3*B2, A3*B4, A3*B5, A3*B025, A3*B04, A3*B124, - A3*B15, A4*B, A4*B0, A4*B1, A4*B2, A4*B3, A4*B5, A4*B013, A4*B025, - A4*B15, A4*B23, A5*B, A5*B0, A5*B1, A5*B2, A5*B3, A5*B4, A5*B013, - A5*B04, A5*B124, A5*B23, A0 + B0 + B013 + B025 + B04 + B012345, + [B + B0 + B1 + B2 + B3 + B4 + B5 + B013 + B025 + B04 + B124 + B15 + B23 + B345 + B012345, B + B0 + B1 + B2 + B3 + B4 + B5 + B013 + B025 + B04 + B124 + B15 + B23 + B345 + B012345, - A1 + B1 + B013 + B124 + B15 + B012345, B + B0 + B1 + B2 + B3 + B4 + B5 + B013 + B025 + B04 + B124 + B15 + B23 + B345 + B012345, - A2 + B2 + B025 + B124 + B23 + B012345, B + B0 + B1 + B2 + B3 + B4 + B5 + B013 + B025 + B04 + B124 + B15 + B23 + B345 + B012345, - A3 + B3 + B013 + B23 + B345 + B012345, B + B0 + B1 + B2 + B3 + B4 + B5 + B013 + B025 + B04 + B124 + B15 + B23 + B345 + B012345, - A4 + B4 + B04 + B124 + B345 + B012345, B + B0 + B1 + B2 + B3 + B4 + B5 + B013 + B025 + B04 + B124 + B15 + B23 + B345 + B012345, A5 + B5 + B025 + B15 + B345 + B012345, - B + B0 + B1 + B2 + B3 + B4 + B5 + B013 + B025 + B04 + B124 + B15 + B23 + B345 + B012345] + A4 + B4 + B04 + B124 + B345 + B012345, + A3 + B3 + B013 + B23 + B345 + B012345, + A2 + B2 + B025 + B124 + B23 + B012345, + A1 + B1 + B013 + B124 + B15 + B012345, + A0 + B0 + B013 + B025 + B04 + B012345, + B23*B345, B15*B345, B124*B345, B04*B345, B025*B345, B013*B345, + B2*B345, B1*B345, B0*B345, A2*B345, A1*B345, A0*B345, B15*B23, + B124*B23, B04*B23, B025*B23, B013*B23, B5*B23, B4*B23, B1*B23, + B0*B23, A5*B23, A4*B23, A1*B23, A0*B23, B124*B15, B04*B15, + B025*B15, B013*B15, B4*B15, B3*B15, B2*B15, B0*B15, A4*B15, + A3*B15, A2*B15, A0*B15, B04*B124, B025*B124, B013*B124, B5*B124, + B3*B124, B0*B124, A5*B124, A3*B124, A0*B124, B025*B04, B013*B04, + B5*B04, B3*B04, B2*B04, B1*B04, A5*B04, A3*B04, A2*B04, A1*B04, + B013*B025, B4*B025, B3*B025, B1*B025, A4*B025, A3*B025, A1*B025, + B5*B013, B4*B013, B2*B013, A5*B013, A4*B013, A2*B013, B4*B5, + B3*B5, B2*B5, B1*B5, B0*B5, A4*B5, A3*B5, A2*B5, A1*B5, A0*B5, + B3*B4, B2*B4, B1*B4, B0*B4, A5*B4, A3*B4, A2*B4, A1*B4, A0*B4, + B2*B3, B1*B3, B0*B3, A5*B3, A4*B3, A2*B3, A1*B3, A0*B3, B1*B2, + B0*B2, A5*B2, A4*B2, A3*B2, A1*B2, A0*B2, B0*B1, A5*B1, A4*B1, + A3*B1, A2*B1, A0*B1, A5*B0, A4*B0, A3*B0, A2*B0, A1*B0, A5*B, + A4*B, A3*B, A2*B, A1*B, A0*B] """ E = list(self._matroid.groundset()) Q = [] @@ -658,9 +659,9 @@ def _gens_constructor(self, poly_ring): sage: M1 = Matroid(graphs.CycleGraph(3)) sage: ch = M1.chow_ring(QQ, True, 'atom-free') sage: sorted(ch.defining_ideal()._gens_constructor(ch.defining_ideal().ring())) - [A0*A1, A0*A2, A1*A2, A0^2 + 2*A0*A3 + A3^2, A1^2 + 2*A1*A3 + A3^2, - A0*A1 + A0*A3, A2^2 + 2*A2*A3 + A3^2, A0*A2 + A0*A3, - A0*A1 + A1*A3, A1*A2 + A1*A3, A0*A2 + A2*A3, A1*A2 + A2*A3] + [A2^2 + 2*A2*A3 + A3^2, A1*A2, A1*A2 + A2*A3, A1*A2 + A1*A3, A0*A2, + A0*A2 + A2*A3, A0*A2 + A0*A3, A1^2 + 2*A1*A3 + A3^2, A0*A1, + A0*A1 + A1*A3, A0*A1 + A0*A3, A0^2 + 2*A0*A3 + A3^2] """ E = list(self._matroid.groundset()) Q = [] # Quadratic generators From c6db03a09ed5cc3d14e2b38f8ecc2193279d6440 Mon Sep 17 00:00:00 2001 From: user202729 <25191436+user202729@users.noreply.github.com> Date: Wed, 7 Aug 2024 15:35:58 +0700 Subject: [PATCH 519/537] Dokchitser: Pass internal parameter over properly --- src/sage/lfunctions/dokchitser.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/sage/lfunctions/dokchitser.py b/src/sage/lfunctions/dokchitser.py index cc06d96c503..262f2a8ba66 100644 --- a/src/sage/lfunctions/dokchitser.py +++ b/src/sage/lfunctions/dokchitser.py @@ -486,6 +486,10 @@ def __call__(self, s, c=None): - ``s`` -- complex number + - ``c`` -- internal parameter, call with `c>1` to get the same value + with a different cutoff point (`c` close to `1`); should return the + same answer, good to check if everything works with right precision + .. NOTE:: Evaluation of the function takes a long time, so each @@ -509,7 +513,10 @@ def __call__(self, s, c=None): self.__values = {} except KeyError: pass - z = self._gp_call_inst('L', s) + if c is None: + z = self._gp_call_inst('L', s) + else: + z = self._gp_call_inst('L', s, c) CC = self.__CC if 'pole' in z: print(z) From 6495e5fb2baa965189976a605cdf6ade67db96ed Mon Sep 17 00:00:00 2001 From: user202729 <25191436+user202729@users.noreply.github.com> Date: Wed, 7 Aug 2024 22:37:21 +0700 Subject: [PATCH 520/537] Fix GrossZagierLseries --- src/sage/modular/modform/l_series_gross_zagier.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/sage/modular/modform/l_series_gross_zagier.py b/src/sage/modular/modform/l_series_gross_zagier.py index 7959c346a2e..96bc2b24959 100644 --- a/src/sage/modular/modform/l_series_gross_zagier.py +++ b/src/sage/modular/modform/l_series_gross_zagier.py @@ -73,7 +73,7 @@ def __call__(self, s, der=0): - ``s`` -- complex number - - ``der`` -- (default: 0) + - ``der`` -- order of derivative (default: 0) EXAMPLES:: @@ -84,8 +84,10 @@ def __call__(self, s, der=0): sage: G = GrossZagierLseries(e, A) sage: G(3) -0.272946890617590 + sage: G(3, 1) + 0.212442670030741 """ - return self._dokchister(s, der) + return self._dokchister.derivative(s, der) def taylor_series(self, s=1, series_prec=6, var='z'): r""" From d8a89d07605ee4c66c5220a055ac624c5c0b2d37 Mon Sep 17 00:00:00 2001 From: user202729 <25191436+user202729@users.noreply.github.com> Date: Fri, 9 Aug 2024 14:33:48 +0700 Subject: [PATCH 521/537] Fix a cache bug and add coverage test --- src/sage/lfunctions/dokchitser.py | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/sage/lfunctions/dokchitser.py b/src/sage/lfunctions/dokchitser.py index 262f2a8ba66..83a38792f9b 100644 --- a/src/sage/lfunctions/dokchitser.py +++ b/src/sage/lfunctions/dokchitser.py @@ -504,11 +504,20 @@ def __call__(self, s, c=None): 0.00000000000000000000000000000 sage: L(1+I) -1.3085436607849493358323930438 + 0.81298000036784359634835412129*I + sage: L(1+I, 1.2) + -1.3085436607849493358323930438 + 0.81298000036784359634835412129*I + + TESTS:: + + sage: L(1+I, 0) + Traceback (most recent call last): + ... + RuntimeError """ self.__check_init() s = self.__CC(s) try: - return self.__values[s] + return self.__values[s, c] except AttributeError: self.__values = {} except KeyError: @@ -529,10 +538,10 @@ def __call__(self, s, c=None): msg = z[:i].replace('digits', 'decimal digits') verbose(msg, level=-1) ans = CC(z[i + 1:]) - self.__values[s] = ans + self.__values[s, c] = ans return ans ans = CC(z) - self.__values[s] = ans + self.__values[s, c] = ans return ans def derivative(self, s, k=1): From 99e8af57692c63c3bb420890d0d4b0a0f5f0d365 Mon Sep 17 00:00:00 2001 From: Verrel Rievaldo Wijaya Date: Tue, 12 Nov 2024 01:17:38 +0700 Subject: [PATCH 522/537] Fix documentation --- src/sage/rings/semirings/tropical_polynomial.py | 4 ++-- src/sage/rings/semirings/tropical_variety.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sage/rings/semirings/tropical_polynomial.py b/src/sage/rings/semirings/tropical_polynomial.py index 7a36049668f..4e4e239edd2 100644 --- a/src/sage/rings/semirings/tropical_polynomial.py +++ b/src/sage/rings/semirings/tropical_polynomial.py @@ -473,7 +473,7 @@ def plot(self, xmin=None, xmax=None): T = TropicalSemiring(QQ, use_min=False) R = PolynomialRing(T, 'x') - p1 = p1 = R([4,2,1,3]) + p1 = R([4,2,1,3]) sphinx_plot(p1.plot()) A different result will be obtained if the tropical semiring employs @@ -494,7 +494,7 @@ def plot(self, xmin=None, xmax=None): T = TropicalSemiring(QQ, use_min=True) R = PolynomialRing(T, 'x') p1 = R([4,2,1,3]) - sphinx_plot(plot(p1, xmin=-4, xmax=4)) + sphinx_plot(p1.plot()) TESTS: diff --git a/src/sage/rings/semirings/tropical_variety.py b/src/sage/rings/semirings/tropical_variety.py index 7a6f4cac787..dbc1b85cd52 100644 --- a/src/sage/rings/semirings/tropical_variety.py +++ b/src/sage/rings/semirings/tropical_variety.py @@ -1611,7 +1611,7 @@ def plot(self): T = TropicalSemiring(QQ) R = PolynomialRing(T, ('x,y')) x, y = R.gen(), R.gen(1) - p2 = (x**6 + R(4)*x**4*y^2 + R(2)*x**3*y**3 + R(3)*x**2*y**4 + p2 = (x**6 + R(4)*x**4*y**2 + R(2)*x**3*y**3 + R(3)*x**2*y**4 + x*y**5 + R(7)*x**2 + R(5)*x*y + R(3)*y**2 + R(2)*x + y + R(10)) sphinx_plot(p2.tropical_variety().plot()) From 5e86fcdc39e56140174abe031de92ebf82abfa47 Mon Sep 17 00:00:00 2001 From: Kwankyu Lee Date: Tue, 12 Nov 2024 08:06:22 +0900 Subject: [PATCH 523/537] Remove more spurious diffs --- .github/workflows/doc-build.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/doc-build.yml b/.github/workflows/doc-build.yml index 7b4ea38e044..5eb5e932da9 100644 --- a/.github/workflows/doc-build.yml +++ b/.github/workflows/doc-build.yml @@ -168,7 +168,7 @@ jobs: # Wipe out chronic diffs between old doc and new doc (cd doc && \ find . -name "*.html" | xargs sed -i -e '/class="sidebar-brand-text"/ s/Sage [0-9a-z.]* /Sage '"$new_version"' /' \ - -e '/;,\;; d' \ -e 's;#L[0-9]*";";' \ @@ -221,7 +221,7 @@ jobs: # Wipe out chronic diffs of new doc against old doc before creating CHANGES.html (cd doc && \ find . -name "*.html" | xargs sed -i -e '/This is documentation/ s/ built with GitHub PR .* for development/ for development/' \ - -e '/;,\;; d' \ -e 's;#L[0-9]*";";' \ -e 's;tab-set--[0-9]*-;tab-set-;' \ From 183ea892919abd3c535c637558d2ec41e32cedc0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Bissey?= Date: Tue, 12 Nov 2024 19:47:11 +1300 Subject: [PATCH 524/537] rebase sage_autodoc to sphinx 8.1.3 --- src/sage_docbuild/ext/sage_autodoc.py | 87 ++++++++++++++++++--------- 1 file changed, 60 insertions(+), 27 deletions(-) diff --git a/src/sage_docbuild/ext/sage_autodoc.py b/src/sage_docbuild/ext/sage_autodoc.py index 87e4e69d7bd..b9d6dbae0c9 100644 --- a/src/sage_docbuild/ext/sage_autodoc.py +++ b/src/sage_docbuild/ext/sage_autodoc.py @@ -35,6 +35,8 @@ - François Bissey (2024-08-24): rebased on Sphinx 8.0.2 - François Bissey (2024-09-10): Tweaks to support python 3.9 (and older sphinx) as well + +- François Bissey (2024-11-12): rebased on Sphinx 8.1.3 (while trying to keep python 3.9 compatibility) """ from __future__ import annotations @@ -44,7 +46,7 @@ import sys import re from inspect import Parameter, Signature -from typing import TYPE_CHECKING, Any, ClassVar, NewType, TypeVar +from typing import TYPE_CHECKING, Any, NewType, TypeVar from docutils.statemachine import StringList @@ -86,11 +88,19 @@ def getdoc(obj, *args, **kwargs): if TYPE_CHECKING: from collections.abc import Callable, Iterator, Sequence from types import ModuleType + from typing import ClassVar, Literal, TypeAlias from sphinx.application import Sphinx from sphinx.environment import BuildEnvironment from sphinx.ext.autodoc.directive import DocumenterBridge + _AutodocObjType = Literal[ + 'module', 'class', 'exception', 'function', 'method', 'attribute' + ] + _AutodocProcessDocstringListener: TypeAlias = Callable[ + [Sphinx, _AutodocObjType, str, Any, dict[str, bool], list[str]], None + ] + logger = logging.getLogger(__name__) @@ -225,7 +235,9 @@ def merge_members_option(options: dict) -> None: # Some useful event listener factories for autodoc-process-docstring. -def cut_lines(pre: int, post: int = 0, what: str | None = None) -> Callable: +def cut_lines( + pre: int, post: int = 0, what: Sequence[str] | None = None +) -> _AutodocProcessDocstringListener: """Return a listener that removes the first *pre* and last *post* lines of every docstring. If *what* is a sequence of strings, only docstrings of a type in *what* will be processed. @@ -233,7 +245,7 @@ def cut_lines(pre: int, post: int = 0, what: str | None = None) -> Callable: Use like this (e.g. in the ``setup()`` function of :file:`conf.py`):: from sphinx.ext.autodoc import cut_lines - app.connect('autodoc-process-docstring', cut_lines(4, what=['module'])) + app.connect('autodoc-process-docstring', cut_lines(4, what={'module'})) This can (and should) be used in place of ``automodule_skip_lines``. """ @@ -250,9 +262,22 @@ def cut_lines(pre: int, post: int = 0, what: str | None = None) -> Callable: # # ... in place of ``automodule_skip_lines``. # ------------------------------------------------------------------------- - def process(app: Sphinx, what_: str, name: str, obj: Any, options: Any, lines: list[str], - ) -> None: - if what and what_ not in what: + if not what: + what_unique: frozenset[str] = frozenset() + elif isinstance(what, str): # strongly discouraged + what_unique = frozenset({what}) + else: + what_unique = frozenset(what) + + def process( + app: Sphinx, + what_: _AutodocObjType, + name: str, + obj: Any, + options: dict[str, bool], + lines: list[str], + ) -> None: + if what_unique and what_ not in what_unique: return del lines[:pre] if post: @@ -271,7 +296,7 @@ def between( what: Sequence[str] | None = None, keepempty: bool = False, exclude: bool = False, -) -> Callable: +) -> _AutodocProcessDocstringListener: """Return a listener that either keeps, or if *exclude* is True excludes, lines between lines that match the *marker* regular expression. If no line matches, the resulting docstring would be empty, so no change will be made @@ -282,8 +307,14 @@ def between( """ marker_re = re.compile(marker) - def process(app: Sphinx, what_: str, name: str, obj: Any, options: Any, lines: list[str], - ) -> None: + def process( + app: Sphinx, + what_: _AutodocObjType, + name: str, + obj: Any, + options: dict[str, bool], + lines: list[str], + ) -> None: if what and what_ not in what: return deleted = 0 @@ -308,7 +339,7 @@ def process(app: Sphinx, what_: str, name: str, obj: Any, options: Any, lines: l # This class is used only in ``sphinx.ext.autodoc.directive``, # But we define this class here to keep compatibility (see #4538) -class Options(dict): +class Options(dict[str, Any]): """A dict/attribute hybrid that returns None on nonexisting keys.""" def copy(self) -> Options: @@ -476,9 +507,10 @@ def import_object(self, raiseerror: bool = False) -> bool: """ with mock(self.config.autodoc_mock_imports): try: - ret = import_object(self.modname, self.objpath, self.objtype, - attrgetter=self.get_attr, - warningiserror=self.config.autodoc_warningiserror) + ret = import_object( + self.modname, self.objpath, self.objtype, + attrgetter=self.get_attr, + ) self.module, self.parent, self.object_name, self.object = ret if ismock(self.object): self.object = undecorate(self.object) @@ -1145,7 +1177,8 @@ def get_object_members(self, want_all: bool) -> tuple[bool, list[ObjectMember]]: else: logger.warning(__('missing attribute mentioned in :members: option: ' 'module %s, attribute %s'), - safe_getattr(self.object, '__name__', '???', name), + safe_getattr(self.object, '__name__', '???'), + name, type='autodoc') return False, ret @@ -2179,7 +2212,7 @@ def import_object(self, raiseerror: bool = False) -> bool: # annotation only instance variable (PEP-526) try: with mock(self.config.autodoc_mock_imports): - parent = import_module(self.modname, self.config.autodoc_warningiserror) + parent = import_module(self.modname) annotations = get_type_hints(parent, None, self.config.autodoc_type_aliases, include_extras=True) @@ -2629,9 +2662,10 @@ def import_object(self, raiseerror: bool = False) -> bool: except ImportError as exc: try: with mock(self.config.autodoc_mock_imports): - ret = import_object(self.modname, self.objpath[:-1], 'class', - attrgetter=self.get_attr, # type: ignore[attr-defined] - warningiserror=self.config.autodoc_warningiserror) + ret = import_object( + self.modname, self.objpath[:-1], 'class', + attrgetter=self.get_attr, # type: ignore[attr-defined] + ) parent = ret[3] if self.is_runtime_instance_attribute(parent): self.object = self.RUNTIME_INSTANCE_ATTRIBUTE @@ -2676,16 +2710,17 @@ def is_uninitialized_instance_attribute(self, parent: Any) -> bool: return self.objpath[-1] in annotations def import_object(self, raiseerror: bool = False) -> bool: - """Check the exisitence of uninitialized instance attribute when failed to import + """Check the existence of uninitialized instance attribute when failed to import the attribute. """ try: return super().import_object(raiseerror=True) # type: ignore[misc] except ImportError as exc: try: - ret = import_object(self.modname, self.objpath[:-1], 'class', - attrgetter=self.get_attr, # type: ignore[attr-defined] - warningiserror=self.config.autodoc_warningiserror) + ret = import_object( + self.modname, self.objpath[:-1], 'class', + attrgetter=self.get_attr, # type: ignore[attr-defined] + ) parent = ret[3] if self.is_uninitialized_instance_attribute(parent): self.object = UNINITIALIZED_ATTR @@ -2760,9 +2795,7 @@ def can_document_member( if isinstance(type(member), ClasscallMetaclass): return True # --------------------------------------------------------------------- - if not inspect.isroutine(member) and not isinstance(member, type): - return True - return False + return not inspect.isroutine(member) and not isinstance(member, type) def document_members(self, all_members: bool = False) -> None: pass @@ -2918,7 +2951,7 @@ def can_document_member( return False def import_object(self, raiseerror: bool = False) -> bool: - """Check the exisitence of uninitialized instance attribute when failed to import + """Check the existence of uninitialized instance attribute when failed to import the attribute. """ ret = super().import_object(raiseerror) @@ -2991,7 +3024,7 @@ def _get_property_getter(self) -> Callable | None: def autodoc_attrgetter(app: Sphinx, obj: Any, name: str, *defargs: Any) -> Any: """Alternative getattr() for types""" - for typ, func in app.registry.autodoc_attrgettrs.items(): + for typ, func in app.registry.autodoc_attrgetters.items(): if isinstance(obj, typ): return func(obj, name, *defargs) From 9783ba7d3c4b8b8ead33dc109718bea0ffd60a9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Bissey?= Date: Tue, 12 Nov 2024 20:29:30 +1300 Subject: [PATCH 525/537] try supporting old autodoc_attrgettrs attribute as well as new autodoc_attrgetters attribute --- src/sage_docbuild/ext/sage_autodoc.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/sage_docbuild/ext/sage_autodoc.py b/src/sage_docbuild/ext/sage_autodoc.py index b9d6dbae0c9..6f048222437 100644 --- a/src/sage_docbuild/ext/sage_autodoc.py +++ b/src/sage_docbuild/ext/sage_autodoc.py @@ -3024,9 +3024,14 @@ def _get_property_getter(self) -> Callable | None: def autodoc_attrgetter(app: Sphinx, obj: Any, name: str, *defargs: Any) -> Any: """Alternative getattr() for types""" - for typ, func in app.registry.autodoc_attrgetters.items(): - if isinstance(obj, typ): - return func(obj, name, *defargs) + try: + for typ, func in app.registry.autodoc_attrgetters.items(): + if isinstance(obj, typ): + return func(obj, name, *defargs) + except AttributeError: + for typ, func in app.registry.autodoc_attrgettrs.items(): + if isinstance(obj, typ): + return func(obj, name, *defargs) return safe_getattr(obj, name, *defargs) From 71b35bb572a74ed13f53b8a001189615041da22c Mon Sep 17 00:00:00 2001 From: Dave Witte Morris Date: Tue, 12 Nov 2024 20:09:43 -0500 Subject: [PATCH 526/537] 30751 iteration over infinite groups --- src/sage/groups/abelian_gps/abelian_group.py | 21 ++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/src/sage/groups/abelian_gps/abelian_group.py b/src/sage/groups/abelian_gps/abelian_group.py index 0ad20d9d4fa..f9d1c93e3f2 100644 --- a/src/sage/groups/abelian_gps/abelian_group.py +++ b/src/sage/groups/abelian_gps/abelian_group.py @@ -1301,10 +1301,27 @@ def __iter__(self): (1,) sage: list(G) [1] + + We can also iterate over infinite groups:: + + sage: A = AbelianGroup([3,0,5,0]) + sage: for a in A: + ....: if a^2 == A([1, 2, 3, 4]): + ....: print(a, a^2) + ....: break + f0^2*f1*f2^4*f3^2 f0*f1^2*f2^3*f3^4 """ invs = self.gens_orders() - for t in mrange(invs): - yield self(t) + if 0 not in invs: + # The group is finite + for t in mrange(invs): + yield self(t) + else: + # A similar approach works for infinite groups. + # (This would also work for finite groups, but is more complicated.) + from sage.misc.mrange import cantor_product + for t in cantor_product(*[range(n) if n > 0 else ZZ for n in invs]): + yield self(t) def number_of_subgroups(self, order=None): r""" From ae698fbf121fc73fa9b33156769dbf00f94af286 Mon Sep 17 00:00:00 2001 From: Sebastian Spindler Date: Wed, 13 Nov 2024 20:53:11 +0100 Subject: [PATCH 527/537] Disallow scaling fractional ideals by zero Also check in other tests that random scalars are nonzero --- .../algebras/quatalg/quaternion_algebra.py | 23 +++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/src/sage/algebras/quatalg/quaternion_algebra.py b/src/sage/algebras/quatalg/quaternion_algebra.py index f85f282c0bb..2409db3840b 100644 --- a/src/sage/algebras/quatalg/quaternion_algebra.py +++ b/src/sage/algebras/quatalg/quaternion_algebra.py @@ -2609,7 +2609,7 @@ def scale(self, alpha, left=False): INPUT: - - `\alpha` -- element of quaternion algebra + - `\alpha` -- nonzero element of quaternion algebra - ``left`` -- boolean (default: ``False``); if ``True`` multiply `\alpha` on the left, otherwise multiply `\alpha` on the right @@ -2632,6 +2632,15 @@ def scale(self, alpha, left=False): sage: I.gens()[0] * i 4*i + The scaling element must be nonzero:: + + sage: B. = QuaternionAlgebra(419) + sage: O = B.quaternion_order([1/2 + 3/2*j, 1/6*i + 2/3*j + 1/2*k, 3*j, k]) + sage: O * O.zero() + Traceback (most recent call last): + ... + ValueError: the scaling factor must be nonzero + TESTS: Scaling by `1` should not change anything (see :issue:`32245`):: @@ -2657,6 +2666,8 @@ def scale(self, alpha, left=False): """ Q = self.quaternion_algebra() alpha = Q(alpha) + if alpha.is_zero(): + raise ValueError("the scaling factor must be nonzero") if left: gens = basis_for_quaternion_lattice([alpha * b for b in self.basis()]) else: @@ -3657,7 +3668,9 @@ def is_right_equivalent(self, J, B=10, certificate=False): sage: B = QuaternionAlgebra(101) sage: i,j,k = B.gens() sage: I = B.maximal_order().unit_ideal() - sage: beta = B.random_element() # random + sage: beta = B.random_element() + sage: while beta.is_zero(): + ....: beta = B.random_element() sage: J = beta*I sage: bool, alpha = I.is_right_equivalent(J, certificate=True) sage: bool @@ -3711,7 +3724,9 @@ def is_principal(self, certificate=False): sage: B. = QuaternionAlgebra(419) sage: O = B.quaternion_order([1/2 + 3/2*j, 1/6*i + 2/3*j + 1/2*k, 3*j, k]) - sage: beta = O.random_element() # random + sage: beta = O.random_element() + sage: while beta.is_zero(): + ....: beta = O.random_element() sage: I = O*beta sage: bool, alpha = I.is_principal(True) sage: bool @@ -3951,7 +3966,7 @@ def primitive_decomposition(self): Check that randomly generated ideals decompose as expected:: - sage: for d in ( m for m in range(400, 750) if is_squarefree(m) ): + sage: for d in ( m for m in range(400, 750) if is_squarefree(m) ): # long time (7s) ....: A = QuaternionAlgebra(d) ....: O = A.maximal_order() ....: for _ in range(10): From b192330d4253f2eb25a4df04daf0fd17fae265d8 Mon Sep 17 00:00:00 2001 From: Sebastian Spindler Date: Wed, 13 Nov 2024 21:41:00 +0100 Subject: [PATCH 528/537] Avoid non-invertible scaling and zero endomorphism --- .../function_field/drinfeld_modules/drinfeld_module.py | 10 +++++++++- .../rings/function_field/drinfeld_modules/morphism.py | 6 ++++-- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/sage/rings/function_field/drinfeld_modules/drinfeld_module.py b/src/sage/rings/function_field/drinfeld_modules/drinfeld_module.py index c4ad9f1376d..e29626593b4 100644 --- a/src/sage/rings/function_field/drinfeld_modules/drinfeld_module.py +++ b/src/sage/rings/function_field/drinfeld_modules/drinfeld_module.py @@ -1855,7 +1855,7 @@ def rank(self): def velu(self, isog): r""" - Return a new Drinfeld module such that input is an + Return a new Drinfeld module such that ``isog`` defines an isogeny to this module with domain ``self``; if no such isogeny exists, raise an exception. @@ -2018,11 +2018,19 @@ def hom(self, x, codomain=None): Traceback (most recent call last): ... ValueError: Ore polynomial does not define a morphism + + Check that x = 0 (without specified codomain) gives the zero endomorphism:: + + sage: phi.hom(K.zero()) + Endomorphism of Drinfeld module defined by ... + Defn: 0 """ # When `x` is in the function ring (or something that coerces to it): if self.function_ring().has_coerce_map_from(x.parent()): return self.Hom(self)(x) if codomain is None: + if x.is_zero(): + return self.Hom(self)(0) try: codomain = self.velu(x) except TypeError: diff --git a/src/sage/rings/function_field/drinfeld_modules/morphism.py b/src/sage/rings/function_field/drinfeld_modules/morphism.py index 82c1d7a0da1..26d90ae625a 100644 --- a/src/sage/rings/function_field/drinfeld_modules/morphism.py +++ b/src/sage/rings/function_field/drinfeld_modules/morphism.py @@ -536,9 +536,11 @@ def __invert__(self): sage: K. = Fq.extension(3) sage: coeffs = [z] + [K.random_element() for _ in range(10)] sage: phi = DrinfeldModule(A, coeffs) - sage: f = phi.hom(K.random_element()) + sage: a = K.random_element() + sage: while a.is_zero(): + ....: a = K.random_element() + sage: f = phi.hom(a) sage: g = ~f - sage: (f*g).is_identity() True sage: (g*f).is_identity() From a0346c913fb5ba196bcbeae1a253f03b994e04ec Mon Sep 17 00:00:00 2001 From: Michael Orlitzky Date: Wed, 13 Nov 2024 17:14:35 -0500 Subject: [PATCH 529/537] build/bin/sage-guess-package-system: drop cygwin case --- build/bin/sage-guess-package-system | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/build/bin/sage-guess-package-system b/build/bin/sage-guess-package-system index 8e679c2eac9..33a7e2ad587 100755 --- a/build/bin/sage-guess-package-system +++ b/build/bin/sage-guess-package-system @@ -32,12 +32,5 @@ elif xbps-install --version > /dev/null 2>&1; then elif pkg -v > /dev/null 2>&1; then echo freebsd else - case `uname -s` in - CYGWIN*) - echo cygwin - ;; - *) - echo unknown - ;; - esac + echo unknown fi From 92300f8afb2d8cb8ff41620caadc1ed7cb25e744 Mon Sep 17 00:00:00 2001 From: Michael Orlitzky Date: Wed, 13 Nov 2024 17:15:12 -0500 Subject: [PATCH 530/537] build/bin/sage-print-system-package-command: drop cygwin cases --- build/bin/sage-print-system-package-command | 6 ------ 1 file changed, 6 deletions(-) diff --git a/build/bin/sage-print-system-package-command b/build/bin/sage-print-system-package-command index daf61c48c09..5af7740e229 100755 --- a/build/bin/sage-print-system-package-command +++ b/build/bin/sage-print-system-package-command @@ -182,12 +182,6 @@ case $system:$command in slackware*:install) [ -n "$system_packages" ] && print_shell_command ${SUDO}slackpkg install $system_packages ;; - cygwin*:update) - print_comment "first install apt-cyg from https://github.com/transcode-open/apt-cyg" - ;; - cygwin*:install) - [ -n "$system_packages" ] && print_shell_command apt-cyg install $system_packages - ;; freebsd*:install) [ -n "$system_packages" ] && print_shell_command ${SUDO}pkg install $system_packages ;; From 4c3ea02d4fab2601313023d3dec1551a5a200d4e Mon Sep 17 00:00:00 2001 From: Michael Orlitzky Date: Wed, 13 Nov 2024 17:15:56 -0500 Subject: [PATCH 531/537] build/bin/sage-spkg-info: drop cygwin case --- build/bin/sage-spkg-info | 1 - 1 file changed, 1 deletion(-) diff --git a/build/bin/sage-spkg-info b/build/bin/sage-spkg-info index 29d833a29bf..09b4ea8c1be 100755 --- a/build/bin/sage-spkg-info +++ b/build/bin/sage-spkg-info @@ -85,7 +85,6 @@ for system in $systems; do alpine) tab "Alpine";; arch) tab "Arch Linux";; conda) tab "conda-forge";; - cygwin) tab "Cygwin";; debian) tab "Debian/Ubuntu";; fedora) tab "Fedora/Redhat/CentOS";; freebsd) tab "FreeBSD";; From 8d96a6a4f57c5f526ceb05a3f57568d237fbd1cd Mon Sep 17 00:00:00 2001 From: Michael Orlitzky Date: Wed, 13 Nov 2024 17:16:55 -0500 Subject: [PATCH 532/537] build/pkgs: delete all cygwin.txt files --- build/pkgs/4ti2/distros/cygwin.txt | 2 -- build/pkgs/_bootstrap/distros/cygwin.txt | 4 --- build/pkgs/_develop/distros/cygwin.txt | 1 - build/pkgs/_prereq/distros/cygwin.txt | 28 ------------------- build/pkgs/_python3.10/distros/cygwin.txt | 1 - build/pkgs/_python3.11/distros/cygwin.txt | 1 - build/pkgs/_python3.12/distros/cygwin.txt | 1 - build/pkgs/_python3.9/distros/cygwin.txt | 1 - build/pkgs/boost_cropped/distros/cygwin.txt | 1 - build/pkgs/bzip2/distros/cygwin.txt | 2 -- build/pkgs/cddlib/distros/cygwin.txt | 2 -- build/pkgs/cmake/distros/cygwin.txt | 1 - build/pkgs/curl/distros/cygwin.txt | 2 -- build/pkgs/flint/distros/cygwin.txt | 1 - build/pkgs/freetype/distros/cygwin.txt | 1 - build/pkgs/gc/distros/cygwin.txt | 1 - build/pkgs/gcc/distros/cygwin.txt | 3 -- build/pkgs/gengetopt/distros/cygwin.txt | 1 - build/pkgs/gfortran/distros/cygwin.txt | 1 - build/pkgs/git/distros/cygwin.txt | 1 - build/pkgs/glpk/distros/cygwin.txt | 2 -- build/pkgs/gmp/distros/cygwin.txt | 1 - build/pkgs/graphviz/distros/cygwin.txt | 1 - build/pkgs/gsl/distros/cygwin.txt | 1 - build/pkgs/iconv/distros/cygwin.txt | 1 - build/pkgs/imagemagick/distros/cygwin.txt | 1 - build/pkgs/info/distros/cygwin.txt | 1 - build/pkgs/isl/distros/cygwin.txt | 1 - build/pkgs/libatomic_ops/distros/cygwin.txt | 1 - build/pkgs/libffi/distros/cygwin.txt | 1 - build/pkgs/libgd/distros/cygwin.txt | 1 - build/pkgs/libgraphviz/distros/cygwin.txt | 1 - build/pkgs/liblzma/distros/cygwin.txt | 2 -- build/pkgs/libxml2/distros/cygwin.txt | 1 - build/pkgs/llvm/distros/cygwin.txt | 1 - build/pkgs/maxima/distros/cygwin.txt | 1 - build/pkgs/mpc/distros/cygwin.txt | 1 - build/pkgs/mpfr/distros/cygwin.txt | 1 - build/pkgs/ncurses/distros/cygwin.txt | 1 - build/pkgs/ninja_build/distros/cygwin.txt | 1 - build/pkgs/ntl/distros/cygwin.txt | 1 - build/pkgs/openblas/distros/cygwin.txt | 2 -- build/pkgs/openssl/distros/cygwin.txt | 1 - build/pkgs/patch/distros/cygwin.txt | 1 - .../perl_term_readline_gnu/distros/cygwin.txt | 1 - build/pkgs/python3/distros/cygwin.txt | 5 ---- build/pkgs/qhull/distros/cygwin.txt | 1 - build/pkgs/r/distros/cygwin.txt | 2 -- build/pkgs/readline/distros/cygwin.txt | 1 - build/pkgs/sbcl/distros/cygwin.txt | 1 - build/pkgs/singular/distros/cygwin.txt | 2 -- build/pkgs/sqlite/distros/cygwin.txt | 2 -- build/pkgs/suitesparse/distros/cygwin.txt | 1 - build/pkgs/texlive/distros/cygwin.txt | 1 - build/pkgs/texlive_luatex/distros/cygwin.txt | 1 - build/pkgs/xz/distros/cygwin.txt | 1 - build/pkgs/zeromq/distros/cygwin.txt | 1 - build/pkgs/zlib/distros/cygwin.txt | 1 - 58 files changed, 104 deletions(-) delete mode 100644 build/pkgs/4ti2/distros/cygwin.txt delete mode 100644 build/pkgs/_bootstrap/distros/cygwin.txt delete mode 100644 build/pkgs/_develop/distros/cygwin.txt delete mode 100644 build/pkgs/_prereq/distros/cygwin.txt delete mode 100644 build/pkgs/_python3.10/distros/cygwin.txt delete mode 100644 build/pkgs/_python3.11/distros/cygwin.txt delete mode 100644 build/pkgs/_python3.12/distros/cygwin.txt delete mode 100644 build/pkgs/_python3.9/distros/cygwin.txt delete mode 100644 build/pkgs/boost_cropped/distros/cygwin.txt delete mode 100644 build/pkgs/bzip2/distros/cygwin.txt delete mode 100644 build/pkgs/cddlib/distros/cygwin.txt delete mode 100644 build/pkgs/cmake/distros/cygwin.txt delete mode 100644 build/pkgs/curl/distros/cygwin.txt delete mode 100644 build/pkgs/flint/distros/cygwin.txt delete mode 100644 build/pkgs/freetype/distros/cygwin.txt delete mode 100644 build/pkgs/gc/distros/cygwin.txt delete mode 100644 build/pkgs/gcc/distros/cygwin.txt delete mode 100644 build/pkgs/gengetopt/distros/cygwin.txt delete mode 100644 build/pkgs/gfortran/distros/cygwin.txt delete mode 100644 build/pkgs/git/distros/cygwin.txt delete mode 100644 build/pkgs/glpk/distros/cygwin.txt delete mode 100644 build/pkgs/gmp/distros/cygwin.txt delete mode 100644 build/pkgs/graphviz/distros/cygwin.txt delete mode 100644 build/pkgs/gsl/distros/cygwin.txt delete mode 100644 build/pkgs/iconv/distros/cygwin.txt delete mode 100644 build/pkgs/imagemagick/distros/cygwin.txt delete mode 100644 build/pkgs/info/distros/cygwin.txt delete mode 100644 build/pkgs/isl/distros/cygwin.txt delete mode 100644 build/pkgs/libatomic_ops/distros/cygwin.txt delete mode 100644 build/pkgs/libffi/distros/cygwin.txt delete mode 100644 build/pkgs/libgd/distros/cygwin.txt delete mode 100644 build/pkgs/libgraphviz/distros/cygwin.txt delete mode 100644 build/pkgs/liblzma/distros/cygwin.txt delete mode 100644 build/pkgs/libxml2/distros/cygwin.txt delete mode 100644 build/pkgs/llvm/distros/cygwin.txt delete mode 100644 build/pkgs/maxima/distros/cygwin.txt delete mode 100644 build/pkgs/mpc/distros/cygwin.txt delete mode 100644 build/pkgs/mpfr/distros/cygwin.txt delete mode 100644 build/pkgs/ncurses/distros/cygwin.txt delete mode 100644 build/pkgs/ninja_build/distros/cygwin.txt delete mode 100644 build/pkgs/ntl/distros/cygwin.txt delete mode 100644 build/pkgs/openblas/distros/cygwin.txt delete mode 100644 build/pkgs/openssl/distros/cygwin.txt delete mode 100644 build/pkgs/patch/distros/cygwin.txt delete mode 100644 build/pkgs/perl_term_readline_gnu/distros/cygwin.txt delete mode 100644 build/pkgs/python3/distros/cygwin.txt delete mode 100644 build/pkgs/qhull/distros/cygwin.txt delete mode 100644 build/pkgs/r/distros/cygwin.txt delete mode 100644 build/pkgs/readline/distros/cygwin.txt delete mode 100644 build/pkgs/sbcl/distros/cygwin.txt delete mode 100644 build/pkgs/singular/distros/cygwin.txt delete mode 100644 build/pkgs/sqlite/distros/cygwin.txt delete mode 100644 build/pkgs/suitesparse/distros/cygwin.txt delete mode 100644 build/pkgs/texlive/distros/cygwin.txt delete mode 100644 build/pkgs/texlive_luatex/distros/cygwin.txt delete mode 100644 build/pkgs/xz/distros/cygwin.txt delete mode 100644 build/pkgs/zeromq/distros/cygwin.txt delete mode 100644 build/pkgs/zlib/distros/cygwin.txt diff --git a/build/pkgs/4ti2/distros/cygwin.txt b/build/pkgs/4ti2/distros/cygwin.txt deleted file mode 100644 index fab3a09f46e..00000000000 --- a/build/pkgs/4ti2/distros/cygwin.txt +++ /dev/null @@ -1,2 +0,0 @@ -lib4ti2_0 -lib4ti2-devel diff --git a/build/pkgs/_bootstrap/distros/cygwin.txt b/build/pkgs/_bootstrap/distros/cygwin.txt deleted file mode 100644 index bde788ee5d9..00000000000 --- a/build/pkgs/_bootstrap/distros/cygwin.txt +++ /dev/null @@ -1,4 +0,0 @@ -# Packages needed for ./bootstrap -autoconf -automake -libtool diff --git a/build/pkgs/_develop/distros/cygwin.txt b/build/pkgs/_develop/distros/cygwin.txt deleted file mode 100644 index 239772ed91d..00000000000 --- a/build/pkgs/_develop/distros/cygwin.txt +++ /dev/null @@ -1 +0,0 @@ -gnupg2 diff --git a/build/pkgs/_prereq/distros/cygwin.txt b/build/pkgs/_prereq/distros/cygwin.txt deleted file mode 100644 index 7a05e1aaa54..00000000000 --- a/build/pkgs/_prereq/distros/cygwin.txt +++ /dev/null @@ -1,28 +0,0 @@ -# This file, build/pkgs/_prereq/distros/cygwin.txt, contains names of -# Cygwin packages needed for installation of Sage from source. -# -# In addition, the files build/pkgs/SPKG/distros/cygwin.txt contain -# the names of packages that provide the equivalent of SPKG. -# -# One package per line. No need to escape special characters. -# Everything on a line after a # character is ignored. -# -binutils -make -m4 -# a system python is needed for downloading the sage packages, https://github.com/sagemath/sage/issues/29090 -python39-urllib3 -python39 -perl -perl-ExtUtils-MakeMaker -tar -gcc-core -gcc-g++ -# Needed according to embray at https://github.com/sagemath/sage/issues/26964: -# The need for which comes [...] from MPIR's configure script -findutils -which -# For python3 build -libcrypt-devel -# For R build -libiconv-devel diff --git a/build/pkgs/_python3.10/distros/cygwin.txt b/build/pkgs/_python3.10/distros/cygwin.txt deleted file mode 100644 index 92826c681b4..00000000000 --- a/build/pkgs/_python3.10/distros/cygwin.txt +++ /dev/null @@ -1 +0,0 @@ -python310 diff --git a/build/pkgs/_python3.11/distros/cygwin.txt b/build/pkgs/_python3.11/distros/cygwin.txt deleted file mode 100644 index 1d66f45569a..00000000000 --- a/build/pkgs/_python3.11/distros/cygwin.txt +++ /dev/null @@ -1 +0,0 @@ -python311 diff --git a/build/pkgs/_python3.12/distros/cygwin.txt b/build/pkgs/_python3.12/distros/cygwin.txt deleted file mode 100644 index a1bf1c64c82..00000000000 --- a/build/pkgs/_python3.12/distros/cygwin.txt +++ /dev/null @@ -1 +0,0 @@ -python312 diff --git a/build/pkgs/_python3.9/distros/cygwin.txt b/build/pkgs/_python3.9/distros/cygwin.txt deleted file mode 100644 index 6a2d05c5edb..00000000000 --- a/build/pkgs/_python3.9/distros/cygwin.txt +++ /dev/null @@ -1 +0,0 @@ -python39 diff --git a/build/pkgs/boost_cropped/distros/cygwin.txt b/build/pkgs/boost_cropped/distros/cygwin.txt deleted file mode 100644 index 444ab77a410..00000000000 --- a/build/pkgs/boost_cropped/distros/cygwin.txt +++ /dev/null @@ -1 +0,0 @@ -libboost-devel diff --git a/build/pkgs/bzip2/distros/cygwin.txt b/build/pkgs/bzip2/distros/cygwin.txt deleted file mode 100644 index 8ef7f4d0734..00000000000 --- a/build/pkgs/bzip2/distros/cygwin.txt +++ /dev/null @@ -1,2 +0,0 @@ -bzip2 -libbz2-devel diff --git a/build/pkgs/cddlib/distros/cygwin.txt b/build/pkgs/cddlib/distros/cygwin.txt deleted file mode 100644 index d406d903210..00000000000 --- a/build/pkgs/cddlib/distros/cygwin.txt +++ /dev/null @@ -1,2 +0,0 @@ -cddlib-devel -cddlib-tools diff --git a/build/pkgs/cmake/distros/cygwin.txt b/build/pkgs/cmake/distros/cygwin.txt deleted file mode 100644 index a3ea3e4380f..00000000000 --- a/build/pkgs/cmake/distros/cygwin.txt +++ /dev/null @@ -1 +0,0 @@ -cmake diff --git a/build/pkgs/curl/distros/cygwin.txt b/build/pkgs/curl/distros/cygwin.txt deleted file mode 100644 index 26bfd4d1186..00000000000 --- a/build/pkgs/curl/distros/cygwin.txt +++ /dev/null @@ -1,2 +0,0 @@ -libcurl-devel -curl diff --git a/build/pkgs/flint/distros/cygwin.txt b/build/pkgs/flint/distros/cygwin.txt deleted file mode 100644 index cf5b84dbc05..00000000000 --- a/build/pkgs/flint/distros/cygwin.txt +++ /dev/null @@ -1 +0,0 @@ -libflint-devel diff --git a/build/pkgs/freetype/distros/cygwin.txt b/build/pkgs/freetype/distros/cygwin.txt deleted file mode 100644 index efdffca75b2..00000000000 --- a/build/pkgs/freetype/distros/cygwin.txt +++ /dev/null @@ -1 +0,0 @@ -libfreetype-devel diff --git a/build/pkgs/gc/distros/cygwin.txt b/build/pkgs/gc/distros/cygwin.txt deleted file mode 100644 index 3d9787221be..00000000000 --- a/build/pkgs/gc/distros/cygwin.txt +++ /dev/null @@ -1 +0,0 @@ -libgc-devel diff --git a/build/pkgs/gcc/distros/cygwin.txt b/build/pkgs/gcc/distros/cygwin.txt deleted file mode 100644 index dde4bb418b6..00000000000 --- a/build/pkgs/gcc/distros/cygwin.txt +++ /dev/null @@ -1,3 +0,0 @@ -gcc-core -gcc-g++ -gcc-fortran diff --git a/build/pkgs/gengetopt/distros/cygwin.txt b/build/pkgs/gengetopt/distros/cygwin.txt deleted file mode 100644 index 2865264cd70..00000000000 --- a/build/pkgs/gengetopt/distros/cygwin.txt +++ /dev/null @@ -1 +0,0 @@ -gengetopt diff --git a/build/pkgs/gfortran/distros/cygwin.txt b/build/pkgs/gfortran/distros/cygwin.txt deleted file mode 100644 index 8f962328b1e..00000000000 --- a/build/pkgs/gfortran/distros/cygwin.txt +++ /dev/null @@ -1 +0,0 @@ -gcc-fortran diff --git a/build/pkgs/git/distros/cygwin.txt b/build/pkgs/git/distros/cygwin.txt deleted file mode 100644 index 5664e303b5d..00000000000 --- a/build/pkgs/git/distros/cygwin.txt +++ /dev/null @@ -1 +0,0 @@ -git diff --git a/build/pkgs/glpk/distros/cygwin.txt b/build/pkgs/glpk/distros/cygwin.txt deleted file mode 100644 index 0fbb959079e..00000000000 --- a/build/pkgs/glpk/distros/cygwin.txt +++ /dev/null @@ -1,2 +0,0 @@ -glpk -libglpk-devel diff --git a/build/pkgs/gmp/distros/cygwin.txt b/build/pkgs/gmp/distros/cygwin.txt deleted file mode 100644 index bde3aa97bd3..00000000000 --- a/build/pkgs/gmp/distros/cygwin.txt +++ /dev/null @@ -1 +0,0 @@ -libgmp-devel diff --git a/build/pkgs/graphviz/distros/cygwin.txt b/build/pkgs/graphviz/distros/cygwin.txt deleted file mode 100644 index 4d95609306f..00000000000 --- a/build/pkgs/graphviz/distros/cygwin.txt +++ /dev/null @@ -1 +0,0 @@ -graphviz diff --git a/build/pkgs/gsl/distros/cygwin.txt b/build/pkgs/gsl/distros/cygwin.txt deleted file mode 100644 index 3f55673dfe6..00000000000 --- a/build/pkgs/gsl/distros/cygwin.txt +++ /dev/null @@ -1 +0,0 @@ -libgsl-devel diff --git a/build/pkgs/iconv/distros/cygwin.txt b/build/pkgs/iconv/distros/cygwin.txt deleted file mode 100644 index df78e31976a..00000000000 --- a/build/pkgs/iconv/distros/cygwin.txt +++ /dev/null @@ -1 +0,0 @@ -libiconv-devel diff --git a/build/pkgs/imagemagick/distros/cygwin.txt b/build/pkgs/imagemagick/distros/cygwin.txt deleted file mode 100644 index 7a33d03ff73..00000000000 --- a/build/pkgs/imagemagick/distros/cygwin.txt +++ /dev/null @@ -1 +0,0 @@ -ImageMagick diff --git a/build/pkgs/info/distros/cygwin.txt b/build/pkgs/info/distros/cygwin.txt deleted file mode 100644 index 55021245387..00000000000 --- a/build/pkgs/info/distros/cygwin.txt +++ /dev/null @@ -1 +0,0 @@ -info diff --git a/build/pkgs/isl/distros/cygwin.txt b/build/pkgs/isl/distros/cygwin.txt deleted file mode 100644 index a922268ab95..00000000000 --- a/build/pkgs/isl/distros/cygwin.txt +++ /dev/null @@ -1 +0,0 @@ -libisl-devel diff --git a/build/pkgs/libatomic_ops/distros/cygwin.txt b/build/pkgs/libatomic_ops/distros/cygwin.txt deleted file mode 100644 index 56dbd90c363..00000000000 --- a/build/pkgs/libatomic_ops/distros/cygwin.txt +++ /dev/null @@ -1 +0,0 @@ -libatomic_ops-devel diff --git a/build/pkgs/libffi/distros/cygwin.txt b/build/pkgs/libffi/distros/cygwin.txt deleted file mode 100644 index 31d794ff28d..00000000000 --- a/build/pkgs/libffi/distros/cygwin.txt +++ /dev/null @@ -1 +0,0 @@ -libffi-devel diff --git a/build/pkgs/libgd/distros/cygwin.txt b/build/pkgs/libgd/distros/cygwin.txt deleted file mode 100644 index 3094bd88c2e..00000000000 --- a/build/pkgs/libgd/distros/cygwin.txt +++ /dev/null @@ -1 +0,0 @@ -libgd-devel diff --git a/build/pkgs/libgraphviz/distros/cygwin.txt b/build/pkgs/libgraphviz/distros/cygwin.txt deleted file mode 100644 index 4d95609306f..00000000000 --- a/build/pkgs/libgraphviz/distros/cygwin.txt +++ /dev/null @@ -1 +0,0 @@ -graphviz diff --git a/build/pkgs/liblzma/distros/cygwin.txt b/build/pkgs/liblzma/distros/cygwin.txt deleted file mode 100644 index c5fa156f8a0..00000000000 --- a/build/pkgs/liblzma/distros/cygwin.txt +++ /dev/null @@ -1,2 +0,0 @@ -xz -liblzma-devel diff --git a/build/pkgs/libxml2/distros/cygwin.txt b/build/pkgs/libxml2/distros/cygwin.txt deleted file mode 100644 index 313ee711738..00000000000 --- a/build/pkgs/libxml2/distros/cygwin.txt +++ /dev/null @@ -1 +0,0 @@ -libxml2-devel diff --git a/build/pkgs/llvm/distros/cygwin.txt b/build/pkgs/llvm/distros/cygwin.txt deleted file mode 100644 index e671fa21003..00000000000 --- a/build/pkgs/llvm/distros/cygwin.txt +++ /dev/null @@ -1 +0,0 @@ -clang diff --git a/build/pkgs/maxima/distros/cygwin.txt b/build/pkgs/maxima/distros/cygwin.txt deleted file mode 100644 index f5fe3fdc6cb..00000000000 --- a/build/pkgs/maxima/distros/cygwin.txt +++ /dev/null @@ -1 +0,0 @@ -maxima diff --git a/build/pkgs/mpc/distros/cygwin.txt b/build/pkgs/mpc/distros/cygwin.txt deleted file mode 100644 index 279a55fdb8b..00000000000 --- a/build/pkgs/mpc/distros/cygwin.txt +++ /dev/null @@ -1 +0,0 @@ -libmpc-devel diff --git a/build/pkgs/mpfr/distros/cygwin.txt b/build/pkgs/mpfr/distros/cygwin.txt deleted file mode 100644 index e02bb1bdbb1..00000000000 --- a/build/pkgs/mpfr/distros/cygwin.txt +++ /dev/null @@ -1 +0,0 @@ -libmpfr-devel diff --git a/build/pkgs/ncurses/distros/cygwin.txt b/build/pkgs/ncurses/distros/cygwin.txt deleted file mode 100644 index d29f30ce45b..00000000000 --- a/build/pkgs/ncurses/distros/cygwin.txt +++ /dev/null @@ -1 +0,0 @@ -libncurses-devel diff --git a/build/pkgs/ninja_build/distros/cygwin.txt b/build/pkgs/ninja_build/distros/cygwin.txt deleted file mode 100644 index 63730036fd3..00000000000 --- a/build/pkgs/ninja_build/distros/cygwin.txt +++ /dev/null @@ -1 +0,0 @@ -ninja diff --git a/build/pkgs/ntl/distros/cygwin.txt b/build/pkgs/ntl/distros/cygwin.txt deleted file mode 100644 index fe822a6c887..00000000000 --- a/build/pkgs/ntl/distros/cygwin.txt +++ /dev/null @@ -1 +0,0 @@ -libntl-devel diff --git a/build/pkgs/openblas/distros/cygwin.txt b/build/pkgs/openblas/distros/cygwin.txt deleted file mode 100644 index 055fa2733d1..00000000000 --- a/build/pkgs/openblas/distros/cygwin.txt +++ /dev/null @@ -1,2 +0,0 @@ -liblapack-devel -libopenblas diff --git a/build/pkgs/openssl/distros/cygwin.txt b/build/pkgs/openssl/distros/cygwin.txt deleted file mode 100644 index 77c51ef8194..00000000000 --- a/build/pkgs/openssl/distros/cygwin.txt +++ /dev/null @@ -1 +0,0 @@ -libssl-devel diff --git a/build/pkgs/patch/distros/cygwin.txt b/build/pkgs/patch/distros/cygwin.txt deleted file mode 100644 index 9eb7b90ed50..00000000000 --- a/build/pkgs/patch/distros/cygwin.txt +++ /dev/null @@ -1 +0,0 @@ -patch diff --git a/build/pkgs/perl_term_readline_gnu/distros/cygwin.txt b/build/pkgs/perl_term_readline_gnu/distros/cygwin.txt deleted file mode 100644 index 3b6a90263dd..00000000000 --- a/build/pkgs/perl_term_readline_gnu/distros/cygwin.txt +++ /dev/null @@ -1 +0,0 @@ -perl-Term-ReadLine-Gnu diff --git a/build/pkgs/python3/distros/cygwin.txt b/build/pkgs/python3/distros/cygwin.txt deleted file mode 100644 index 8e0df5adb0d..00000000000 --- a/build/pkgs/python3/distros/cygwin.txt +++ /dev/null @@ -1,5 +0,0 @@ -# as of #27824, we use python3 for venv as well -python39-devel -# #34088 - make ensurepip work -python-pip-wheel -python-setuptools-wheel diff --git a/build/pkgs/qhull/distros/cygwin.txt b/build/pkgs/qhull/distros/cygwin.txt deleted file mode 100644 index 95d316779cf..00000000000 --- a/build/pkgs/qhull/distros/cygwin.txt +++ /dev/null @@ -1 +0,0 @@ -qhull diff --git a/build/pkgs/r/distros/cygwin.txt b/build/pkgs/r/distros/cygwin.txt deleted file mode 100644 index f532411f70a..00000000000 --- a/build/pkgs/r/distros/cygwin.txt +++ /dev/null @@ -1,2 +0,0 @@ -R -libtirpc-devel # needed for building extensions diff --git a/build/pkgs/readline/distros/cygwin.txt b/build/pkgs/readline/distros/cygwin.txt deleted file mode 100644 index 1698f0e86b8..00000000000 --- a/build/pkgs/readline/distros/cygwin.txt +++ /dev/null @@ -1 +0,0 @@ -libreadline-devel diff --git a/build/pkgs/sbcl/distros/cygwin.txt b/build/pkgs/sbcl/distros/cygwin.txt deleted file mode 100644 index 0e94cb07231..00000000000 --- a/build/pkgs/sbcl/distros/cygwin.txt +++ /dev/null @@ -1 +0,0 @@ -sbcl diff --git a/build/pkgs/singular/distros/cygwin.txt b/build/pkgs/singular/distros/cygwin.txt deleted file mode 100644 index 774625930f9..00000000000 --- a/build/pkgs/singular/distros/cygwin.txt +++ /dev/null @@ -1,2 +0,0 @@ -singular-devel -singular diff --git a/build/pkgs/sqlite/distros/cygwin.txt b/build/pkgs/sqlite/distros/cygwin.txt deleted file mode 100644 index ef624919561..00000000000 --- a/build/pkgs/sqlite/distros/cygwin.txt +++ /dev/null @@ -1,2 +0,0 @@ -libsqlite3-devel -sqlite3 diff --git a/build/pkgs/suitesparse/distros/cygwin.txt b/build/pkgs/suitesparse/distros/cygwin.txt deleted file mode 100644 index fe7b2c3f23c..00000000000 --- a/build/pkgs/suitesparse/distros/cygwin.txt +++ /dev/null @@ -1 +0,0 @@ -libsuitesparseconfig-devel diff --git a/build/pkgs/texlive/distros/cygwin.txt b/build/pkgs/texlive/distros/cygwin.txt deleted file mode 100644 index ba0ee3a029f..00000000000 --- a/build/pkgs/texlive/distros/cygwin.txt +++ /dev/null @@ -1 +0,0 @@ -texlive diff --git a/build/pkgs/texlive_luatex/distros/cygwin.txt b/build/pkgs/texlive_luatex/distros/cygwin.txt deleted file mode 100644 index ba0ee3a029f..00000000000 --- a/build/pkgs/texlive_luatex/distros/cygwin.txt +++ /dev/null @@ -1 +0,0 @@ -texlive diff --git a/build/pkgs/xz/distros/cygwin.txt b/build/pkgs/xz/distros/cygwin.txt deleted file mode 100644 index d66e95ca507..00000000000 --- a/build/pkgs/xz/distros/cygwin.txt +++ /dev/null @@ -1 +0,0 @@ -xz diff --git a/build/pkgs/zeromq/distros/cygwin.txt b/build/pkgs/zeromq/distros/cygwin.txt deleted file mode 100644 index 57737d06afb..00000000000 --- a/build/pkgs/zeromq/distros/cygwin.txt +++ /dev/null @@ -1 +0,0 @@ -libzmq-devel diff --git a/build/pkgs/zlib/distros/cygwin.txt b/build/pkgs/zlib/distros/cygwin.txt deleted file mode 100644 index f47c16b504b..00000000000 --- a/build/pkgs/zlib/distros/cygwin.txt +++ /dev/null @@ -1 +0,0 @@ -zlib-devel From bcf4fc997be3f5ca640f2aa26b5b93340de29c09 Mon Sep 17 00:00:00 2001 From: Michael Orlitzky Date: Wed, 13 Nov 2024 17:17:54 -0500 Subject: [PATCH 533/537] src/doc/en/developer/portability_testing.rst: don't mention cygwin.txt --- src/doc/en/developer/portability_testing.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/en/developer/portability_testing.rst b/src/doc/en/developer/portability_testing.rst index 55cefd0bf60..0f8d9e4b30f 100644 --- a/src/doc/en/developer/portability_testing.rst +++ b/src/doc/en/developer/portability_testing.rst @@ -259,7 +259,7 @@ This information comes from Sage's database of equivalent system packages. For example:: $ ls build/pkgs/flint/distros/ - alpine.txt cygwin.txt fedora.txt gentoo.txt macports.txt opensuse.txt void.txt + alpine.txt fedora.txt gentoo.txt macports.txt opensuse.txt void.txt conda.txt debian.txt freebsd.txt homebrew.txt nix.txt repology.txt $ cat build/pkgs/flint/distros/debian.txt libflint-dev From db1b0befe6d4fbcfdf37b932e414cae765909b3d Mon Sep 17 00:00:00 2001 From: Michael Orlitzky Date: Wed, 13 Nov 2024 17:20:53 -0500 Subject: [PATCH 534/537] build/pkgs/sqlite/spkg-configure.m4: drop cygwin case --- build/pkgs/sqlite/spkg-configure.m4 | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/build/pkgs/sqlite/spkg-configure.m4 b/build/pkgs/sqlite/spkg-configure.m4 index 901e27f19e3..5fe929ea03b 100644 --- a/build/pkgs/sqlite/spkg-configure.m4 +++ b/build/pkgs/sqlite/spkg-configure.m4 @@ -33,15 +33,8 @@ SAGE_SPKG_CONFIGURE([sqlite], [ m4_popdef([SAGE_SQLITE3_MIN_VERSION_MICRO]) m4_popdef([SAGE_SQLITE3_MIN_VERSION]) ], [dnl REQUIRED-CHECK - AS_CASE([$host], - [*-*-cygwin*], [ - dnl sqlite SetDllDirectory in sage_ostools.pyx - sage_require_sqlite=yes - ], [ - AC_REQUIRE([SAGE_SPKG_CONFIGURE_PYTHON3]) - AS_IF([test x$sage_spkg_install_python3 = xno], [ - sage_require_sqlite=no - ]) - ]) -] -) + AC_REQUIRE([SAGE_SPKG_CONFIGURE_PYTHON3]) + AS_IF([test x$sage_spkg_install_python3 = xno], [ + sage_require_sqlite=no + ]) +]) From 704bad02a1165f65b43a584518a0aaf44e462608 Mon Sep 17 00:00:00 2001 From: Michael Orlitzky Date: Wed, 13 Nov 2024 17:22:02 -0500 Subject: [PATCH 535/537] build/pkgs/python3/spkg-configure.m4: delete cygwin case --- build/pkgs/python3/spkg-configure.m4 | 6 ------ 1 file changed, 6 deletions(-) diff --git a/build/pkgs/python3/spkg-configure.m4 b/build/pkgs/python3/spkg-configure.m4 index a51e2394e51..c6938ea7080 100644 --- a/build/pkgs/python3/spkg-configure.m4 +++ b/build/pkgs/python3/spkg-configure.m4 @@ -70,12 +70,6 @@ SAGE_SPKG_CONFIGURE([python3], [ sage_spkg_install_python3=yes ]) ]) - AS_CASE([$host], - [*-*-cygwin*], [AS_VAR_IF([sage_spkg_install_python3], [yes], [ - AS_VAR_APPEND([SAGE_SPKG_ERRORS], [" - On Cygwin, python3 must be installed as a system package. This is an error."]) - ]) - ]) ],, [ dnl PRE ], [ From 4c5a738deda59e42381c344a66f0c5d2efa93b58 Mon Sep 17 00:00:00 2001 From: Dave Witte Morris Date: Tue, 12 Nov 2024 20:09:43 -0500 Subject: [PATCH 536/537] 30751 iteration over infinite groups --- src/sage/groups/abelian_gps/abelian_group.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/sage/groups/abelian_gps/abelian_group.py b/src/sage/groups/abelian_gps/abelian_group.py index f9d1c93e3f2..ec5bc722d64 100644 --- a/src/sage/groups/abelian_gps/abelian_group.py +++ b/src/sage/groups/abelian_gps/abelian_group.py @@ -1314,14 +1314,13 @@ def __iter__(self): invs = self.gens_orders() if 0 not in invs: # The group is finite - for t in mrange(invs): - yield self(t) + yield from map(self, mrange(invs)) else: # A similar approach works for infinite groups. # (This would also work for finite groups, but is more complicated.) from sage.misc.mrange import cantor_product - for t in cantor_product(*[range(n) if n > 0 else ZZ for n in invs]): - yield self(t) + yield from map(self, cantor_product(*[range(n) if n + else ZZ for n in invs])) def number_of_subgroups(self, order=None): r""" From 39ebbe45ca5cdf87d8ae23a28b3f784130be3d1a Mon Sep 17 00:00:00 2001 From: Release Manager Date: Sat, 16 Nov 2024 12:19:10 +0100 Subject: [PATCH 537/537] Updated SageMath version to 10.5.rc0 --- 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 27b5af6ac84..c2d778402ac 100644 --- a/CITATION.cff +++ b/CITATION.cff @@ -4,8 +4,8 @@ title: SageMath abstract: SageMath is a free open-source mathematics software system. authors: - name: "The SageMath Developers" -version: 10.5.beta9 +version: 10.5.rc0 doi: 10.5281/zenodo.8042260 -date-released: 2024-11-03 +date-released: 2024-11-16 repository-code: "https://github.com/sagemath/sage" url: "https://www.sagemath.org/" diff --git a/VERSION.txt b/VERSION.txt index 01ace814c72..539643e825a 100644 --- a/VERSION.txt +++ b/VERSION.txt @@ -1 +1 @@ -SageMath version 10.5.beta9, Release Date: 2024-11-03 +SageMath version 10.5.rc0, Release Date: 2024-11-16 diff --git a/build/pkgs/configure/checksums.ini b/build/pkgs/configure/checksums.ini index 0fb7b14c641..f8bbaed10be 100644 --- a/build/pkgs/configure/checksums.ini +++ b/build/pkgs/configure/checksums.ini @@ -1,3 +1,3 @@ tarball=configure-VERSION.tar.gz -sha1=b57fc7a6adb26a01f6b49cd5599221d8fb369a77 -sha256=da2ce0e892f28c583f6f43238d295375db66275d9196222e3859743260296674 +sha1=87648980fa41bbd38f9bf45beb7bcdb90e12d613 +sha256=cb5129b2e60af70968a6d8de8937b0f9365a2146762bf34a09b4ad7a88c56b8b diff --git a/build/pkgs/configure/package-version.txt b/build/pkgs/configure/package-version.txt index 60a050122d9..91cad63eb79 100644 --- a/build/pkgs/configure/package-version.txt +++ b/build/pkgs/configure/package-version.txt @@ -1 +1 @@ -20ad1c640949d5999c11148295ef4f856b2e745e +d9c38a7c581e6ed54fbe420122b8bba488b16074 diff --git a/build/pkgs/sage_conf/version_requirements.txt b/build/pkgs/sage_conf/version_requirements.txt index 7b7d288febd..75a00f0f83b 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.5b9 +sage-conf ~= 10.5rc0 diff --git a/build/pkgs/sage_docbuild/version_requirements.txt b/build/pkgs/sage_docbuild/version_requirements.txt index 20be798e7f9..6e02f12a485 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.5b9 +sage-docbuild ~= 10.5rc0 diff --git a/build/pkgs/sage_setup/version_requirements.txt b/build/pkgs/sage_setup/version_requirements.txt index 83c89067e18..af4273ca5a6 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.5b9 +sage-setup ~= 10.5rc0 diff --git a/build/pkgs/sage_sws2rst/version_requirements.txt b/build/pkgs/sage_sws2rst/version_requirements.txt index ddd53c64619..f6461b249ee 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.5b9 +sage-sws2rst ~= 10.5rc0 diff --git a/build/pkgs/sagelib/version_requirements.txt b/build/pkgs/sagelib/version_requirements.txt index d831508e352..a5764ac2ff3 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.5b9 +sagemath-standard ~= 10.5rc0 diff --git a/build/pkgs/sagemath_bliss/version_requirements.txt b/build/pkgs/sagemath_bliss/version_requirements.txt index 045266674e4..54e31199a21 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.5b9 +sagemath-bliss ~= 10.5rc0 diff --git a/build/pkgs/sagemath_categories/version_requirements.txt b/build/pkgs/sagemath_categories/version_requirements.txt index 811a813dea6..24190dcde29 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.5b9 +sagemath-categories ~= 10.5rc0 diff --git a/build/pkgs/sagemath_coxeter3/version_requirements.txt b/build/pkgs/sagemath_coxeter3/version_requirements.txt index 79c22b51001..d583b886874 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.5b9 +sagemath-coxeter3 ~= 10.5rc0 diff --git a/build/pkgs/sagemath_environment/version_requirements.txt b/build/pkgs/sagemath_environment/version_requirements.txt index 825be89f4b7..4c460e8258e 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.5b9 +sagemath-environment ~= 10.5rc0 diff --git a/build/pkgs/sagemath_mcqd/version_requirements.txt b/build/pkgs/sagemath_mcqd/version_requirements.txt index e2f53c39eda..394ab1ab42c 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.5b9 +sagemath-mcqd ~= 10.5rc0 diff --git a/build/pkgs/sagemath_meataxe/version_requirements.txt b/build/pkgs/sagemath_meataxe/version_requirements.txt index 511fc349e39..e3b1b8d80dd 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.5b9 +sagemath-meataxe ~= 10.5rc0 diff --git a/build/pkgs/sagemath_objects/version_requirements.txt b/build/pkgs/sagemath_objects/version_requirements.txt index e76dace4ebf..84f9308c624 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.5b9 +sagemath-objects ~= 10.5rc0 diff --git a/build/pkgs/sagemath_repl/version_requirements.txt b/build/pkgs/sagemath_repl/version_requirements.txt index ddb705e31f7..124091c62c1 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.5b9 +sagemath-repl ~= 10.5rc0 diff --git a/build/pkgs/sagemath_sirocco/version_requirements.txt b/build/pkgs/sagemath_sirocco/version_requirements.txt index 05b07a6349c..57ed9f87891 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.5b9 +sagemath-sirocco ~= 10.5rc0 diff --git a/build/pkgs/sagemath_tdlib/version_requirements.txt b/build/pkgs/sagemath_tdlib/version_requirements.txt index fa143114867..ea110e02460 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.5b9 +sagemath-tdlib ~= 10.5rc0 diff --git a/pkgs/sage-conf/VERSION.txt b/pkgs/sage-conf/VERSION.txt index 99613807a73..9228dedd0ce 100644 --- a/pkgs/sage-conf/VERSION.txt +++ b/pkgs/sage-conf/VERSION.txt @@ -1 +1 @@ -10.5.beta9 +10.5.rc0 diff --git a/pkgs/sage-conf_conda/VERSION.txt b/pkgs/sage-conf_conda/VERSION.txt index 99613807a73..9228dedd0ce 100644 --- a/pkgs/sage-conf_conda/VERSION.txt +++ b/pkgs/sage-conf_conda/VERSION.txt @@ -1 +1 @@ -10.5.beta9 +10.5.rc0 diff --git a/pkgs/sage-conf_pypi/VERSION.txt b/pkgs/sage-conf_pypi/VERSION.txt index 99613807a73..9228dedd0ce 100644 --- a/pkgs/sage-conf_pypi/VERSION.txt +++ b/pkgs/sage-conf_pypi/VERSION.txt @@ -1 +1 @@ -10.5.beta9 +10.5.rc0 diff --git a/pkgs/sage-docbuild/VERSION.txt b/pkgs/sage-docbuild/VERSION.txt index 99613807a73..9228dedd0ce 100644 --- a/pkgs/sage-docbuild/VERSION.txt +++ b/pkgs/sage-docbuild/VERSION.txt @@ -1 +1 @@ -10.5.beta9 +10.5.rc0 diff --git a/pkgs/sage-setup/VERSION.txt b/pkgs/sage-setup/VERSION.txt index 99613807a73..9228dedd0ce 100644 --- a/pkgs/sage-setup/VERSION.txt +++ b/pkgs/sage-setup/VERSION.txt @@ -1 +1 @@ -10.5.beta9 +10.5.rc0 diff --git a/pkgs/sage-sws2rst/VERSION.txt b/pkgs/sage-sws2rst/VERSION.txt index 99613807a73..9228dedd0ce 100644 --- a/pkgs/sage-sws2rst/VERSION.txt +++ b/pkgs/sage-sws2rst/VERSION.txt @@ -1 +1 @@ -10.5.beta9 +10.5.rc0 diff --git a/pkgs/sagemath-bliss/VERSION.txt b/pkgs/sagemath-bliss/VERSION.txt index 99613807a73..9228dedd0ce 100644 --- a/pkgs/sagemath-bliss/VERSION.txt +++ b/pkgs/sagemath-bliss/VERSION.txt @@ -1 +1 @@ -10.5.beta9 +10.5.rc0 diff --git a/pkgs/sagemath-categories/VERSION.txt b/pkgs/sagemath-categories/VERSION.txt index 99613807a73..9228dedd0ce 100644 --- a/pkgs/sagemath-categories/VERSION.txt +++ b/pkgs/sagemath-categories/VERSION.txt @@ -1 +1 @@ -10.5.beta9 +10.5.rc0 diff --git a/pkgs/sagemath-coxeter3/VERSION.txt b/pkgs/sagemath-coxeter3/VERSION.txt index 99613807a73..9228dedd0ce 100644 --- a/pkgs/sagemath-coxeter3/VERSION.txt +++ b/pkgs/sagemath-coxeter3/VERSION.txt @@ -1 +1 @@ -10.5.beta9 +10.5.rc0 diff --git a/pkgs/sagemath-environment/VERSION.txt b/pkgs/sagemath-environment/VERSION.txt index 99613807a73..9228dedd0ce 100644 --- a/pkgs/sagemath-environment/VERSION.txt +++ b/pkgs/sagemath-environment/VERSION.txt @@ -1 +1 @@ -10.5.beta9 +10.5.rc0 diff --git a/pkgs/sagemath-mcqd/VERSION.txt b/pkgs/sagemath-mcqd/VERSION.txt index 99613807a73..9228dedd0ce 100644 --- a/pkgs/sagemath-mcqd/VERSION.txt +++ b/pkgs/sagemath-mcqd/VERSION.txt @@ -1 +1 @@ -10.5.beta9 +10.5.rc0 diff --git a/pkgs/sagemath-meataxe/VERSION.txt b/pkgs/sagemath-meataxe/VERSION.txt index 99613807a73..9228dedd0ce 100644 --- a/pkgs/sagemath-meataxe/VERSION.txt +++ b/pkgs/sagemath-meataxe/VERSION.txt @@ -1 +1 @@ -10.5.beta9 +10.5.rc0 diff --git a/pkgs/sagemath-objects/VERSION.txt b/pkgs/sagemath-objects/VERSION.txt index 99613807a73..9228dedd0ce 100644 --- a/pkgs/sagemath-objects/VERSION.txt +++ b/pkgs/sagemath-objects/VERSION.txt @@ -1 +1 @@ -10.5.beta9 +10.5.rc0 diff --git a/pkgs/sagemath-repl/VERSION.txt b/pkgs/sagemath-repl/VERSION.txt index 99613807a73..9228dedd0ce 100644 --- a/pkgs/sagemath-repl/VERSION.txt +++ b/pkgs/sagemath-repl/VERSION.txt @@ -1 +1 @@ -10.5.beta9 +10.5.rc0 diff --git a/pkgs/sagemath-sirocco/VERSION.txt b/pkgs/sagemath-sirocco/VERSION.txt index 99613807a73..9228dedd0ce 100644 --- a/pkgs/sagemath-sirocco/VERSION.txt +++ b/pkgs/sagemath-sirocco/VERSION.txt @@ -1 +1 @@ -10.5.beta9 +10.5.rc0 diff --git a/pkgs/sagemath-tdlib/VERSION.txt b/pkgs/sagemath-tdlib/VERSION.txt index 99613807a73..9228dedd0ce 100644 --- a/pkgs/sagemath-tdlib/VERSION.txt +++ b/pkgs/sagemath-tdlib/VERSION.txt @@ -1 +1 @@ -10.5.beta9 +10.5.rc0 diff --git a/src/VERSION.txt b/src/VERSION.txt index 99613807a73..9228dedd0ce 100644 --- a/src/VERSION.txt +++ b/src/VERSION.txt @@ -1 +1 @@ -10.5.beta9 +10.5.rc0 diff --git a/src/bin/sage-version.sh b/src/bin/sage-version.sh index e420ab80e2f..9c1fb9c0309 100644 --- a/src/bin/sage-version.sh +++ b/src/bin/sage-version.sh @@ -4,6 +4,6 @@ # which stops "setup.py develop" from rewriting it as a Python file. : # This file is auto-generated by the sage-update-version script, do not edit! -SAGE_VERSION='10.5.beta9' -SAGE_RELEASE_DATE='2024-11-03' -SAGE_VERSION_BANNER='SageMath version 10.5.beta9, Release Date: 2024-11-03' +SAGE_VERSION='10.5.rc0' +SAGE_RELEASE_DATE='2024-11-16' +SAGE_VERSION_BANNER='SageMath version 10.5.rc0, Release Date: 2024-11-16' diff --git a/src/sage/version.py b/src/sage/version.py index 12c31b89416..d05ce0beb53 100644 --- a/src/sage/version.py +++ b/src/sage/version.py @@ -1,5 +1,5 @@ # Sage version information for Python scripts # This file is auto-generated by the sage-update-version script, do not edit! -version = '10.5.beta9' -date = '2024-11-03' -banner = 'SageMath version 10.5.beta9, Release Date: 2024-11-03' +version = '10.5.rc0' +date = '2024-11-16' +banner = 'SageMath version 10.5.rc0, Release Date: 2024-11-16'