def __init__(self, n, k, constraints, category=None): """ EXAMPLES:: sage: IV = IntegerVectors(2,3,min_slope=0) sage: IV == loads(dumps(IV)) True sage: v = IntegerVectors(2,3,min_slope=0).first(); v [0, 1, 1] sage: type(v) <type 'list'> TESTS:: sage: IV.min_length 3 sage: IV.max_length 3 sage: floor = IV.floor sage: [floor(i) for i in range(1,10)] [0, 0, 0, 0, 0, 0, 0, 0, 0] sage: ceiling = IV.ceiling sage: [ceiling(i) for i in range(1,5)] [inf, inf, inf, inf] sage: IV.min_slope 0 sage: IV.max_slope inf sage: IV = IntegerVectors(3, 10, inner=[4,1,3], min_part=2) sage: floor = IV.floor sage: floor(0), floor(1), floor(2) (4, 2, 3) sage: IV = IntegerVectors(3, 10, outer=[4,1,3], max_part=3) sage: ceiling = IV.ceiling sage: ceiling(0), ceiling(1), ceiling(2) (3, 1, 3) """ self.n = n self.k = k args = constraints.copy() if self.k >= 0: args['length'] = self.k if 'outer' in args: args['ceiling'] = args['outer'] del args['outer'] if 'inner' in args: args['floor'] = args['inner'] del args['inner'] self._constraints = constraints IntegerListsLex.__init__(self, n, element_constructor=list, category=category, **args)
def one(self): """ Return the element `1` of ``self``. EXAMPLES:: sage: S = SchurAlgebra(ZZ, 2, 2) sage: e = S.one(); e S((1, 1), (1, 1)) + S((1, 2), (1, 2)) + S((2, 2), (2, 2)) sage: x = S.an_element() sage: x * e == x True sage: all(e * x == x for x in S.basis()) True sage: S = SchurAlgebra(ZZ, 4, 4) sage: e = S.one() sage: x = S.an_element() sage: x * e == x True """ tt = IntegerListsLex(length=self._r, min_part=1, max_part=self._n, min_slope=0) words = [tuple(u) for u in tt] return self.sum(self._monomial((w, w)) for w in words)
def integer_matrices_generator(row_sums, column_sums): r""" Recursively generate the integer matrices with the prescribed row sums and column sums. INPUT: - ``row_sums`` -- list or tuple - ``column_sums`` -- list or tuple OUTPUT: - an iterator producing a list of lists EXAMPLES:: sage: from sage.combinat.integer_matrices import integer_matrices_generator sage: iter = integer_matrices_generator([3,2,2], [2,5]); iter <generator object integer_matrices_generator at ...> sage: for m in iter: print(m) [[2, 1], [0, 2], [0, 2]] [[1, 2], [1, 1], [0, 2]] [[1, 2], [0, 2], [1, 1]] [[0, 3], [2, 0], [0, 2]] [[0, 3], [1, 1], [1, 1]] [[0, 3], [0, 2], [2, 0]] """ row_sums = list(row_sums) column_sums = list(column_sums) if sum(row_sums) != sum(column_sums): raise StopIteration if len(row_sums) == 0: yield [] elif len(row_sums) == 1: yield [column_sums] else: for comp in IntegerListsLex(n=row_sums[0], length=len(column_sums), ceiling=column_sums): t = [column_sums[i] - ci for (i, ci) in enumerate(comp)] for mat in integer_matrices_generator(row_sums[1:], t): yield [list(comp)] + mat
def IntegerListsNN(**kwds): """ Lists of nonnegative integers with constraints. This function returns the union of ``IntegerListsLex(n, **kwds)`` where `n` ranges over all nonnegative integers. EXAMPLES:: sage: from sage.combinat.integer_lists.nn import IntegerListsNN sage: L = IntegerListsNN(max_length=3, max_slope=-1) sage: L Disjoint union of Lazy family (<lambda>(i))_{i in Non negative integer semiring} sage: it = iter(L) sage: for _ in range(20): ....: print(next(it)) [] [1] [2] [3] [2, 1] [4] [3, 1] [5] [4, 1] [3, 2] [6] [5, 1] [4, 2] [3, 2, 1] [7] [6, 1] [5, 2] [4, 3] [4, 2, 1] [8] """ return DisjointUnionEnumeratedSets( Family(NN, lambda i: IntegerListsLex(i, **kwds)))
def cantor_product(*args, **kwds): r""" Return an iterator over the product of the inputs along the diagonals a la :wikipedia:`Cantor pairing <Pairing_function#Cantor_pairing_function>`. INPUT: - a certain number of iterables - ``repeat`` -- an optional integer. If it is provided, the input is repeated ``repeat`` times. Other keyword arguments are passed to :class:`sage.combinat.integer_lists.invlex.IntegerListsLex`. EXAMPLES:: sage: from sage.misc.mrange import cantor_product sage: list(cantor_product([0, 1], repeat=3)) [(0, 0, 0), (1, 0, 0), (0, 1, 0), (0, 0, 1), (1, 1, 0), (1, 0, 1), (0, 1, 1), (1, 1, 1)] sage: list(cantor_product([0, 1], [0, 1, 2, 3])) [(0, 0), (1, 0), (0, 1), (1, 1), (0, 2), (1, 2), (0, 3), (1, 3)] Infinite iterators are valid input as well:: sage: from itertools import islice sage: list(islice(cantor_product(ZZ, QQ), 14r)) [(0, 0), (1, 0), (0, 1), (-1, 0), (1, 1), (0, -1), (2, 0), (-1, 1), (1, -1), (0, 1/2), (-2, 0), (2, 1), (-1, -1), (1, 1/2)] TESTS:: sage: C = cantor_product([0, 1], [0, 1, 2, 3], [0, 1, 2]) sage: sum(1 for _ in C) == 2*4*3 True sage: from itertools import count sage: list(cantor_product([], count())) [] sage: list(cantor_product(count(), [], count())) [] sage: list(cantor_product(count(), repeat=0)) [()] sage: next(cantor_product(count(), repeat=-1)) Traceback (most recent call last): ... ValueError: repeat argument cannot be negative sage: next(cantor_product(count(), toto='hey')) Traceback (most recent call last): ... TypeError: __init__() got an unexpected keyword argument 'toto' :: sage: list(cantor_product(srange(5), repeat=2, min_slope=1)) [(0, 1), (0, 2), (1, 2), (0, 3), (1, 3), (0, 4), (2, 3), (1, 4), (2, 4), (3, 4)] Check that :trac:`24897` is fixed:: sage: from sage.misc.mrange import cantor_product sage: list(cantor_product([1])) [(1,)] sage: list(cantor_product([1], repeat=2)) [(1, 1)] sage: list(cantor_product([1], [1,2])) [(1, 1), (1, 2)] sage: list(cantor_product([1,2], [1])) [(1, 1), (2, 1)] """ from itertools import count from sage.combinat.integer_lists import IntegerListsLex m = len(args) # numer of factors lengths = [None] * m # None or length of factors data = [[] for _ in range(m)] # the initial slice of each factor iterators = [iter(a) for a in args] # the iterators repeat = int(kwds.pop('repeat', 1)) if repeat == 0: yield () return elif repeat < 0: raise ValueError("repeat argument cannot be negative") mm = m * repeat for n in count(0): # try to add one more term to each bin for i, a in enumerate(iterators): if lengths[i] is None: try: data[i].append(next(a)) except StopIteration: assert len(data[i]) == n if n == 0: return lengths[i] = n # iterate through what we have ceiling = [n if lengths[i] is None else lengths[i] - 1 for i in range(m)] * repeat for v in IntegerListsLex(n, length=mm, ceiling=ceiling, **kwds): yield tuple(data[i % m][v[i]] for i in range(mm)) if all(l is not None for l in lengths) and repeat * sum(l - 1 for l in lengths) <= n: return
def __iter__(self): """ EXAMPLES:: sage: IntegerVectors(-1, 0, min_part = 1).list() [] sage: IntegerVectors(-1, 2, min_part = 1).list() [] sage: IntegerVectors(0, 0, min_part=1).list() [[]] sage: IntegerVectors(3, 0, min_part=1).list() [] sage: IntegerVectors(0, 1, min_part=1).list() [] sage: IntegerVectors(2, 2, min_part=1).list() [[1, 1]] sage: IntegerVectors(2, 3, min_part=1).list() [] sage: IntegerVectors(4, 2, min_part=1).list() [[3, 1], [2, 2], [1, 3]] :: sage: IntegerVectors(0, 3, outer=[0,0,0]).list() [[0, 0, 0]] sage: IntegerVectors(1, 3, outer=[0,0,0]).list() [] sage: IntegerVectors(2, 3, outer=[0,2,0]).list() [[0, 2, 0]] sage: IntegerVectors(2, 3, outer=[1,2,1]).list() [[1, 1, 0], [1, 0, 1], [0, 2, 0], [0, 1, 1]] sage: IntegerVectors(2, 3, outer=[1,1,1]).list() [[1, 1, 0], [1, 0, 1], [0, 1, 1]] sage: IntegerVectors(2, 5, outer=[1,1,1,1,1]).list() [[1, 1, 0, 0, 0], [1, 0, 1, 0, 0], [1, 0, 0, 1, 0], [1, 0, 0, 0, 1], [0, 1, 1, 0, 0], [0, 1, 0, 1, 0], [0, 1, 0, 0, 1], [0, 0, 1, 1, 0], [0, 0, 1, 0, 1], [0, 0, 0, 1, 1]] :: sage: iv = [ IntegerVectors(n, k) for n in range(-2, 7) for k in range(7) ] sage: all(map(lambda x: x.cardinality() == len(x.list()), iv)) True sage: essai = [[1,1,1], [2,5,6], [6,5,2]] sage: iv = [ IntegerVectors(x[0], x[1], max_part = x[2]-1) for x in essai ] sage: all(map(lambda x: x.cardinality() == len(x.list()), iv)) True """ if self.n is None: if self.k is not None and 'max_part' in self.constraints: n_list = range((self.constraints['max_part'] + 1) * self.k) else: n_list = NN else: n_list = [self.n] for n in n_list: for x in IntegerListsLex(n, check=False, **self.constraints): yield self.element_class(self, x, check=False)