def binary_factorizations(self, predicate=ConstantFunction(True)): """ Returns the set of all the factorizations `self = u v` such that `l(self) = l(u) + l(v)`. Iterating through this set is Constant Amortized Time (counting arithmetic operations in the coxeter group as constant time) complexity, and memory linear in the length of `self`. One can pass as optional argument a predicate p such that `p(u)` implies `p(u')` for any `u` left factor of `self` and `u'` left factor of `u`. Then this returns only the factorizations `self = uv` such `p(u)` holds. EXAMPLES: We construct the set of all factorizations of the maximal element of the group:: sage: W = WeylGroup(['A',3]) sage: s = W.simple_reflections() sage: w0 = W.from_reduced_word([1,2,3,1,2,1]) sage: w0.binary_factorizations().cardinality() 24 The same number of factorizations, by bounded length:: sage: [w0.binary_factorizations(lambda u: u.length() <= l).cardinality() for l in [-1,0,1,2,3,4,5,6]] [0, 1, 4, 9, 15, 20, 23, 24] The number of factorizations of the elements just below the maximal element:: sage: [(s[i]*w0).binary_factorizations().cardinality() for i in [1,2,3]] [12, 12, 12] sage: w0.binary_factorizations(lambda u: False).cardinality() 0 TESTS:: sage: w0.binary_factorizations().category() Category of finite enumerated sets """ W = self.parent() if not predicate(W.one()): return FiniteCombinatorialClass([]) s = W.simple_reflections() def succ((u, v)): for i in v.descents(side='left'): u1 = u * s[i] if i == u1.first_descent() and predicate(u1): yield (u1, s[i] * v) return SearchForest(((W.one(), self), ), succ, category=FiniteEnumeratedSets())
def __iter__(self): r""" TESTS:: sage: I = IntegerVectorsModPermutationGroup(PermutationGroup([[(1,2,3,4)]]),4) sage: for i in I: i [4, 0, 0, 0] [3, 1, 0, 0] [3, 0, 1, 0] [3, 0, 0, 1] [2, 2, 0, 0] [2, 1, 1, 0] [2, 1, 0, 1] [2, 0, 2, 0] [2, 0, 1, 1] [1, 1, 1, 1] sage: I = IntegerVectorsModPermutationGroup(PermutationGroup([[(1,2,3,4)]]), sum=7, max_part=3) sage: for i in I: i [3, 3, 1, 0] [3, 3, 0, 1] [3, 2, 2, 0] [3, 2, 1, 1] [3, 2, 0, 2] [3, 1, 3, 0] [3, 1, 2, 1] [3, 1, 1, 2] [3, 0, 2, 2] [2, 2, 2, 1] """ if self._max_part < 0: return self.elements_of_depth_iterator(self._sum) else: SF = SearchForest( (self([0] * (self.n), check=False), ), lambda x: [ self(y, check=False) for y in canonical_children(self._sgs, x, self._max_part) ], algorithm='breadth') if self._sum is None: return iter(SF) else: return SF.elements_of_depth_iterator(self._sum)
def affine_grassmannian_elements_of_given_length(self, k): """ Return the affine Grassmannian elements of length `k`. This is returned as a finite enumerated set. EXAMPLES:: sage: W = WeylGroup(['A',3,1]) sage: [x.reduced_word() for x in W.affine_grassmannian_elements_of_given_length(3)] [[2, 1, 0], [3, 1, 0], [2, 3, 0]] .. SEEALSO:: :meth:`AffineWeylGroups.ElementMethods.is_affine_grassmannian` """ from sage.combinat.backtrack import SearchForest def select_length(pair): u, length = pair if length == k: return u def succ(pair): u, length = pair for i in u.descents(positive=True, side="left"): u1 = u.apply_simple_reflection(i, "left") if (length < k and i == u1.first_descent(side="left") and u1.is_affine_grassmannian()): yield (u1, length + 1) return return SearchForest(((self.one(), 0), ), succ, algorithm='breadth', category=FiniteEnumeratedSets(), post_process=select_length)