def _int_list_to_substitutions(self, words): A = self._start._alphabet W = FiniteWords(A) s = {} for i, w in enumerate(words): s[A.unrank(i)] = [A.unrank(j) for j in w] return WordMorphism(s, domain=W, codomain=W)
def __init__(self, e): """ TESTS:: sage: LW21 = LyndonWords([2,1]); LW21 Lyndon words with evaluation [2, 1] sage: LW21 == loads(dumps(LW21)) True """ self._e = e self._words = FiniteWords(len(e)) from sage.categories.enumerated_sets import EnumeratedSets Parent.__init__(self, category=EnumeratedSets().Finite(), facade=(self._words, ))
def iter_pisot_irreductible(d=3, arg=None): r""" Return an iterator over Pisot irreductible substitutions INPUT: - ``d`` -- size of alphabet, [0,1,...,d-1] - "arg" -- (optional, default: None) It can be one of the following : * "None" -- then the method iterates through all morphisms. * tuple (a, b) of two integers - It specifies the range "range(a, b)" of values to consider for the sum of the length EXAMPLES:: sage: from slabbe.word_morphisms import iter_pisot_irreductible sage: it = iter_pisot_irreductible(3) sage: for _ in range(4): next(it) WordMorphism: 0->01, 1->2, 2->0 WordMorphism: 0->02, 1->0, 2->1 WordMorphism: 0->10, 1->2, 2->0 WordMorphism: 0->12, 1->0, 2->1 Pour linstant, avec le tuple, il y a un bogue:: sage: it = iter_pisot_irreductible(3, (5,10)) sage: for _ in range(4): next(it) WordMorphism: 0->0000001, 1->2, 2->0 WordMorphism: 0->0000002, 1->0, 2->1 WordMorphism: 0->0000010, 1->2, 2->0 WordMorphism: 0->0000012, 1->0, 2->1 """ from slabbe.matrices import is_pisot W = FiniteWords(range(d)) for m in W.iter_morphisms(arg): incidence_matrix = m.incidence_matrix() if not incidence_matrix.det() == 1: continue if not m.is_primitive(): # mathematiquement non necessaire continue if not is_pisot(incidence_matrix): continue yield m
def __init__(self, alphabet): ''' This would be hidden without the ``.. automethod::`` INPUT: - ``alphabet`` -- alphabet or number for len of Alphabet to construct OUTPUT: instance of FreeGoupWord ''' if not isinstance(alphabet, AlphabetWithInverses): alphabet = AlphabetWithInverses(alphabet) FiniteWords.__init__(self, alphabet) self.element_class = FreeGroupWord
def __init__(self, n, k): """ Initialize ``self``. TESTS:: sage: LW23 = LyndonWords(2,3); LW23 Lyndon words from an alphabet of size 2 of length 3 sage: LW23== loads(dumps(LW23)) True """ self._n = n self._k = k self._words = FiniteWords(self._n) from sage.categories.enumerated_sets import EnumeratedSets Parent.__init__(self, category=EnumeratedSets().Finite(), facade=(self._words, ))
def __init__(self, alphabet=None): r""" INPUT: - ``alphabet`` -- the underlying alphabet TESTS:: sage: loads(dumps(LyndonWords())) is LyndonWords() True """ from sage.categories.sets_cat import Sets self._words = FiniteWords() Parent.__init__(self, category=Sets().Infinite(), facade=(self._words))
def standard_unbracketing(sblw): """ Return flattened ``sblw`` if it is a standard bracketing of a Lyndon word, otherwise raise an error. EXAMPLES:: sage: from sage.combinat.words.lyndon_word import standard_unbracketing sage: standard_unbracketing([1, [2, 3]]) word: 123 sage: standard_unbracketing([[1, 2], 3]) Traceback (most recent call last): ... ValueError: not a standard bracketing of a Lyndon word TESTS:: sage: standard_unbracketing(1) # Letters don't use brackets. word: 1 sage: standard_unbracketing([1]) Traceback (most recent call last): ... ValueError: not a standard bracketing of a Lyndon word """ # Nested helper function that not only returns (flattened) w, but also its # right factor in the standard Lyndon factorization. def standard_unbracketing_rec(w): if not isinstance(w, list): return [w], [] if len(w) != 2: raise ValueError("not a standard bracketing of a Lyndon word") x, t = standard_unbracketing_rec(w[0]) y, _ = standard_unbracketing_rec(w[1]) # If x = st is a standard Lyndon factorization, and y is a Lyndon word # such that y <= t, then xy is standard (but not necessarily Lyndon). if x < y and (len(t) == 0 or y <= t): x += y return x, y else: raise ValueError("not a standard bracketing of a Lyndon word") lw, _ = standard_unbracketing_rec(sblw) return FiniteWords(list(set(lw)))(lw, datatype='list', check=False)
class LyndonWords_nk(UniqueRepresentation, Parent): r""" Lyndon words of fixed length `k` over the alphabet `\{1, 2, \ldots, n\}`. INPUT: - ``n`` -- the size of the alphabet - ``k`` -- the length of the words EXAMPLES:: sage: L = LyndonWords(3, 4) sage: L.list() [word: 1112, word: 1113, word: 1122, word: 1123, ... word: 1333, word: 2223, word: 2233, word: 2333] """ def __init__(self, n, k): """ Initialize ``self``. TESTS:: sage: LW23 = LyndonWords(2,3); LW23 Lyndon words from an alphabet of size 2 of length 3 sage: LW23== loads(dumps(LW23)) True """ self._n = n self._k = k self._words = FiniteWords(self._n) from sage.categories.enumerated_sets import EnumeratedSets Parent.__init__(self, category=EnumeratedSets().Finite(), facade=(self._words, )) def __repr__(self): """ TESTS:: sage: repr(LyndonWords(2, 3)) 'Lyndon words from an alphabet of size 2 of length 3' """ return "Lyndon words from an alphabet of size %s of length %s" % ( self._n, self._k) def __call__(self, *args, **kwds): r""" TESTS:: sage: L = LyndonWords(3,3) sage: L([1,2,3]) word: 123 sage: L([2,3,4]) Traceback (most recent call last): ... ValueError: 4 not in alphabet! sage: L([2,1,3]) Traceback (most recent call last): ... ValueError: not a Lyndon word sage: L([1,2,2,3,3]) Traceback (most recent call last): ... ValueError: length is not k=3 Make sure that the correct length is checked (:trac:`30186`):: sage: L = LyndonWords(2, 4) sage: _ = L(L.random_element()) """ w = self._words(*args, **kwds) if kwds.get('check', True) and not w.is_lyndon(): raise ValueError("not a Lyndon word") if kwds.get('check', True) and w.length() != self._k: raise ValueError("length is not k={}".format(self._k)) return w def __contains__(self, w): """ TESTS:: sage: LW33 = LyndonWords(3,3) sage: all(lw in LW33 for lw in LW33) True """ if isinstance(w, list): w = self._words(w, check=False) return isinstance(w, FiniteWord_class) and w.length() == self._k \ and all(x in self._words.alphabet() for x in w) and w.is_lyndon() def cardinality(self): """ TESTS:: sage: [ LyndonWords(3,i).cardinality() for i in range(1, 11) ] [3, 3, 8, 18, 48, 116, 312, 810, 2184, 5880] """ if self._k == 0: return Integer(1) else: s = Integer(0) for d in divisors(self._k): s += moebius(d) * self._n**(self._k // d) return s // self._k def __iter__(self): """ TESTS:: sage: LyndonWords(3,3).list() # indirect doctest [word: 112, word: 113, word: 122, word: 123, word: 132, word: 133, word: 223, word: 233] sage: sum(1 for lw in LyndonWords(11, 6)) 295020 sage: sum(1 for lw in LyndonWords(1000, 1)) 1000 sage: sum(1 for lw in LyndonWords(1, 1000)) 0 sage: list(LyndonWords(1, 1)) [word: 1] """ W = self._words._element_classes['list'] for lw in lyndon_word_iterator(self._n, self._k): yield W(self._words, [i + 1 for i in lw])
class LyndonWords_evaluation(UniqueRepresentation, Parent): r""" The set of Lyndon words on a fixed multiset of letters. EXAMPLES:: sage: L = LyndonWords([1,2,1]) sage: L Lyndon words with evaluation [1, 2, 1] sage: L.list() [word: 1223, word: 1232, word: 1322] """ def __init__(self, e): """ TESTS:: sage: LW21 = LyndonWords([2,1]); LW21 Lyndon words with evaluation [2, 1] sage: LW21 == loads(dumps(LW21)) True """ self._e = e self._words = FiniteWords(len(e)) from sage.categories.enumerated_sets import EnumeratedSets Parent.__init__(self, category=EnumeratedSets().Finite(), facade=(self._words, )) def __repr__(self): """ TESTS:: sage: repr(LyndonWords([2,1,1])) 'Lyndon words with evaluation [2, 1, 1]' """ return "Lyndon words with evaluation %s" % self._e def __call__(self, *args, **kwds): r""" TESTS:: sage: L = LyndonWords([1,2,1]) sage: L([1,2,2,3]) word: 1223 sage: L([2,1,2,3]) Traceback (most recent call last): ... ValueError: not a Lyndon word sage: L([1,2]) Traceback (most recent call last): ... ValueError: evaluation is not [1, 2, 1] """ w = self._words(*args, **kwds) if kwds.get('check', True) and not w.is_lyndon(): raise ValueError("not a Lyndon word") if kwds.get('check', True) and w.evaluation() != self._e: raise ValueError("evaluation is not {}".format(self._e)) return w def __contains__(self, w): """ EXAMPLES:: sage: [1,2,1,2] in LyndonWords([2,2]) False sage: [1,1,2,2] in LyndonWords([2,2]) True sage: all(lw in LyndonWords([2,1,3,1]) for lw in LyndonWords([2,1,3,1])) True """ if isinstance(w, list): w = self._words(w, check=False) if isinstance(w, FiniteWord_class) and all(x in self._words.alphabet() for x in w): ev_dict = w.evaluation_dict() evaluation = [ev_dict.get(x, 0) for x in self._words.alphabet()] return evaluation == self._e and w.is_lyndon() else: return False def cardinality(self): """ Return the number of Lyndon words with the evaluation e. EXAMPLES:: sage: LyndonWords([]).cardinality() 0 sage: LyndonWords([2,2]).cardinality() 1 sage: LyndonWords([2,3,2]).cardinality() 30 Check to make sure that the count matches up with the number of Lyndon words generated:: sage: comps = [[],[2,2],[3,2,7],[4,2]] + Compositions(4).list() sage: lws = [LyndonWords(comp) for comp in comps] sage: all(lw.cardinality() == len(lw.list()) for lw in lws) True """ evaluation = self._e le = list(evaluation) if not evaluation: return Integer(0) n = sum(evaluation) return sum( moebius(j) * multinomial([ni // j for ni in evaluation]) for j in divisors(gcd(le))) // n def __iter__(self): """ An iterator for the Lyndon words with evaluation e. EXAMPLES:: sage: LyndonWords([1]).list() #indirect doctest [word: 1] sage: LyndonWords([2]).list() #indirect doctest [] sage: LyndonWords([3]).list() #indirect doctest [] sage: LyndonWords([3,1]).list() #indirect doctest [word: 1112] sage: LyndonWords([2,2]).list() #indirect doctest [word: 1122] sage: LyndonWords([1,3]).list() #indirect doctest [word: 1222] sage: LyndonWords([3,3]).list() #indirect doctest [word: 111222, word: 112122, word: 112212] sage: LyndonWords([4,3]).list() #indirect doctest [word: 1111222, word: 1112122, word: 1112212, word: 1121122, word: 1121212] TESTS: Check that :trac:`12997` is fixed:: sage: LyndonWords([0,1]).list() [word: 2] sage: LyndonWords([0,2]).list() [] sage: LyndonWords([0,0,1,0,1]).list() [word: 35] """ if not self._e: return k = 0 while self._e[k] == 0: k += 1 for z in _sfc(self._e[k:], equality=True): yield self._words([i + k + 1 for i in z], check=False)