diff --git a/src/sage/combinat/tuple.py b/src/sage/combinat/tuple.py index 26c1b4ec074..95ae68b040c 100644 --- a/src/sage/combinat/tuple.py +++ b/src/sage/combinat/tuple.py @@ -16,12 +16,12 @@ # https://www.gnu.org/licenses/ # **************************************************************************** -from sage.libs.gap.libgap import libgap +from sage.arith.misc import binomial from sage.rings.integer_ring import ZZ from sage.structure.parent import Parent from sage.structure.unique_representation import UniqueRepresentation from sage.categories.finite_enumerated_sets import FiniteEnumeratedSets - +from itertools import product, combinations_with_replacement class Tuples(Parent, UniqueRepresentation): """ @@ -35,23 +35,23 @@ class Tuples(Parent, UniqueRepresentation): sage: S = [1,2] sage: Tuples(S,3).list() - [[1, 1, 1], [2, 1, 1], [1, 2, 1], [2, 2, 1], [1, 1, 2], - [2, 1, 2], [1, 2, 2], [2, 2, 2]] + [(1, 1, 1), (2, 1, 1), (1, 2, 1), (2, 2, 1), (1, 1, 2), + (2, 1, 2), (1, 2, 2), (2, 2, 2)] sage: mset = ["s","t","e","i","n"] sage: Tuples(mset,2).list() - [['s', 's'], ['t', 's'], ['e', 's'], ['i', 's'], ['n', 's'], - ['s', 't'], ['t', 't'], ['e', 't'], ['i', 't'], ['n', 't'], - ['s', 'e'], ['t', 'e'], ['e', 'e'], ['i', 'e'], ['n', 'e'], - ['s', 'i'], ['t', 'i'], ['e', 'i'], ['i', 'i'], ['n', 'i'], - ['s', 'n'], ['t', 'n'], ['e', 'n'], ['i', 'n'], ['n', 'n']] + [('s', 's'), ('t', 's'), ('e', 's'), ('i', 's'), ('n', 's'), + ('s', 't'), ('t', 't'), ('e', 't'), ('i', 't'), ('n', 't'), + ('s', 'e'), ('t', 'e'), ('e', 'e'), ('i', 'e'), ('n', 'e'), + ('s', 'i'), ('t', 'i'), ('e', 'i'), ('i', 'i'), ('n', 'i'), + ('s', 'n'), ('t', 'n'), ('e', 'n'), ('i', 'n'), ('n', 'n')] :: sage: K.<a> = GF(4, 'a') # optional - sage.rings.finite_rings sage: mset = [x for x in K if x != 0] # optional - sage.rings.finite_rings sage: Tuples(mset,2).list() # optional - sage.rings.finite_rings - [[a, a], [a + 1, a], [1, a], [a, a + 1], [a + 1, a + 1], [1, a + 1], - [a, 1], [a + 1, 1], [1, 1]] + [(a, a), (a + 1, a), (1, a), (a, a + 1), (a + 1, a + 1), (1, a + 1), + (a, 1), (a + 1, 1), (1, 1)] """ @staticmethod def __classcall_private__(cls, S, k): @@ -75,7 +75,7 @@ def __init__(self, S, k): """ self.S = S self.k = k - self._index_list = [S.index(s) for s in S] + self._index_list = list(set(S.index(s) for s in S)) category = FiniteEnumeratedSets() Parent.__init__(self, category=category) @@ -94,33 +94,21 @@ def __iter__(self): sage: S = [1,2] sage: Tuples(S,3).list() - [[1, 1, 1], [2, 1, 1], [1, 2, 1], [2, 2, 1], [1, 1, 2], - [2, 1, 2], [1, 2, 2], [2, 2, 2]] + [(1, 1, 1), (2, 1, 1), (1, 2, 1), (2, 2, 1), (1, 1, 2), + (2, 1, 2), (1, 2, 2), (2, 2, 2)] sage: mset = ["s","t","e","i","n"] sage: Tuples(mset,2).list() - [['s', 's'], ['t', 's'], ['e', 's'], ['i', 's'], ['n', 's'], - ['s', 't'], ['t', 't'], ['e', 't'], ['i', 't'], - ['n', 't'], ['s', 'e'], ['t', 'e'], ['e', 'e'], ['i', 'e'], - ['n', 'e'], ['s', 'i'], ['t', 'i'], ['e', 'i'], - ['i', 'i'], ['n', 'i'], ['s', 'n'], ['t', 'n'], ['e', 'n'], - ['i', 'n'], ['n', 'n']] - """ - S = self.S - k = self.k - import copy - if k <= 0: - yield [] - return - if k == 1: - for x in S: - yield [x] - return - - for s in S: - for x in Tuples(S, k - 1): - y = copy.copy(x) - y.append(s) - yield y + [('s', 's'), ('t', 's'), ('e', 's'), ('i', 's'), ('n', 's'), + ('s', 't'), ('t', 't'), ('e', 't'), ('i', 't'), ('n', 't'), + ('s', 'e'), ('t', 'e'), ('e', 'e'), ('i', 'e'), ('n', 'e'), + ('s', 'i'), ('t', 'i'), ('e', 'i'), ('i', 'i'), ('n', 'i'), + ('s', 'n'), ('t', 'n'), ('e', 'n'), ('i', 'n'), ('n', 'n')] + sage: Tuples((1,1,2),3).list() + [(1, 1, 1), (2, 1, 1), (1, 2, 1), (2, 2, 1), (1, 1, 2), + (2, 1, 2), (1, 2, 2), (2, 2, 2)] + """ + for p in product(self._index_list, repeat=self.k): + yield tuple(self.S[i] for i in reversed(p)) def cardinality(self): """ @@ -133,7 +121,7 @@ def cardinality(self): sage: Tuples(S,2).cardinality() # optional - sage.libs.gap 25 """ - return ZZ(libgap.NrTuples(self._index_list, ZZ(self.k))) + return ZZ(len(self._index_list)).__pow__(self.k) Tuples_sk = Tuples @@ -151,10 +139,10 @@ class UnorderedTuples(Parent, UniqueRepresentation): sage: S = [1,2] sage: UnorderedTuples(S,3).list() - [[1, 1, 1], [1, 1, 2], [1, 2, 2], [2, 2, 2]] + [(1, 1, 1), (1, 1, 2), (1, 2, 2), (2, 2, 2)] sage: UnorderedTuples(["a","b","c"],2).list() - [['a', 'a'], ['a', 'b'], ['a', 'c'], ['b', 'b'], ['b', 'c'], - ['c', 'c']] + [('a', 'a'), ('a', 'b'), ('a', 'c'), ('b', 'b'), ('b', 'c'), + ('c', 'c')] """ @staticmethod def __classcall_private__(cls, S, k): @@ -178,7 +166,7 @@ def __init__(self, S, k): """ self.S = S self.k = k - self._index_list = [S.index(s) for s in S] + self._index_list = list(set(S.index(s) for s in S)) category = FiniteEnumeratedSets() Parent.__init__(self, category=category) @@ -191,19 +179,21 @@ def __repr__(self): """ return "Unordered tuples of %s of length %s" % (self.S, self.k) - def list(self): + def __iter__(self): """ EXAMPLES:: sage: S = [1,2] sage: UnorderedTuples(S,3).list() - [[1, 1, 1], [1, 1, 2], [1, 2, 2], [2, 2, 2]] + [(1, 1, 1), (1, 1, 2), (1, 2, 2), (2, 2, 2)] sage: UnorderedTuples(["a","b","c"],2).list() - [['a', 'a'], ['a', 'b'], ['a', 'c'], ['b', 'b'], ['b', 'c'], - ['c', 'c']] + [('a', 'a'), ('a', 'b'), ('a', 'c'), ('b', 'b'), ('b', 'c'), + ('c', 'c')] + sage: UnorderedTuples([1,1,2],3).list() + [(1, 1, 1), (1, 1, 2), (1, 2, 2), (2, 2, 2)] """ - ans = libgap.UnorderedTuples(self._index_list, ZZ(self.k)) - return [[self.S[i] for i in l] for l in ans] + for ans in combinations_with_replacement(self._index_list, self.k): + yield tuple(self.S[i] for i in ans) def cardinality(self): """ @@ -213,7 +203,7 @@ def cardinality(self): sage: UnorderedTuples(S,2).cardinality() # optional - sage.libs.gap 15 """ - return ZZ(libgap.NrUnorderedTuples(self._index_list, ZZ(self.k))) + return binomial(len(self._index_list) + self.k - 1, self.k) UnorderedTuples_sk = UnorderedTuples diff --git a/src/sage/schemes/projective/projective_space.py b/src/sage/schemes/projective/projective_space.py index 221dca45981..744cb779fc4 100644 --- a/src/sage/schemes/projective/projective_space.py +++ b/src/sage/schemes/projective/projective_space.py @@ -2068,7 +2068,7 @@ def subscheme_from_Chow_form(self, Ch, dim): L1 = [] for t in UnorderedTuples(list(range(n + 1)), dim + 1): if all(t[i] < t[i + 1] for i in range(dim)): - L1.append(t) + L1.append(list(t)) # create the dual brackets L2 = [] signs = [] @@ -2374,7 +2374,7 @@ def rational_points(self, bound=0): for ai in R: P[i] = ai for tup in S[i - 1]: - if gcd([ai] + tup) == 1: + if gcd((ai,) + tup) == 1: for j in range(i): P[j] = tup[j] pts.append(self(P))