Ejemplo n.º 1
0
    def __init__(self, R, names):
        """
        Initialize ``self``.

        EXAMPLES::

            sage: D = ShuffleAlgebra(QQ, 'ab').dual_pbw_basis()
            sage: TestSuite(D).run()
        """
        self._alphabet = names
        self._alg = ShuffleAlgebra(R, names)
        CombinatorialFreeModule.__init__(self,
                                         R,
                                         Words(names),
                                         prefix='S',
                                         category=(AlgebrasWithBasis(R),
                                                   CommutativeAlgebras(R),
                                                   CoalgebrasWithBasis(R)))
    def __init__(self, w=ZZ_1, r=ZZ_2, h1=ZZ_1, h2=ZZ_1):
        from sage.combinat.words.words import Words

        field = Sequence([w, r, h1, h2]).universe()
        if not field.is_field():
            field = field.fraction_field()
        self._w = field(w)
        self._r = field(r)
        self._h1 = field(h1)
        self._h2 = field(h2)
        self._words = Words('LR', finite=True, infinite=False)
        self._wL = self._words('L')
        self._wR = self._words('R')

        base_label = self.polygon_labels()._cartesian_product_of_elements(
            (self._words(''), 0))

        Surface.__init__(self, field, base_label, finite=False)
Ejemplo n.º 3
0
    def __init__(self, R, n, names):
        """
        Initialize ``self``.

        EXAMPLES::

            sage: Z.<x,y,z> = algebras.FreeZinbiel(QQ)
            sage: TestSuite(Z).run()
        """
        if R not in Rings:
            raise TypeError("argument R must be a ring")
        indices = Words(Alphabet(n, names=names))
        cat = MagmaticAlgebras(R).WithBasis()
        self._n = n
        CombinatorialFreeModule.__init__(self,
                                         R,
                                         indices,
                                         prefix='Z',
                                         category=cat)
        self._assign_names(names)
Ejemplo n.º 4
0
    def algebra_generators(self):
        r"""
        Return the generators of this algebra.

        EXAMPLES::

            sage: A = ShuffleAlgebra(ZZ,'fgh'); A
            Shuffle Algebra on 3 generators ['f', 'g', 'h'] over Integer Ring
            sage: A.algebra_generators()
            Family (B[word: f], B[word: g], B[word: h])

            sage: A = ShuffleAlgebra(QQ, ['x1','x2'])
            sage: A.algebra_generators()
            Family (B[word: x1], B[word: x2])

        TESTS::

            sage: A = ShuffleAlgebra(ZZ,[0,1])
            sage: A.algebra_generators()
            Family (B[word: 0], B[word: 1])
        """
        Words = self.basis().keys()
        return Family([self.monomial(Words([a])) for a in self._alphabet])
Ejemplo n.º 5
0
    def from_finite_word(self, w):
        r"""
        Return the unique ordered set partition of `\{1, 2, \ldots, n\}` corresponding
        to a word `w` of length `n`.

        .. SEEALSO::

            :meth:`Word.to_ordered_set_partition`

        EXAMPLES::

            sage: A = OrderedSetPartitions().from_finite_word('abcabcabd'); A
            [{1, 4, 7}, {2, 5, 8}, {3, 6}, {9}]
            sage: B = OrderedSetPartitions().from_finite_word([1,2,3,1,2,3,1,2,4])
            sage: A == B
            True
        """
        # TODO: fix this if statement.
        #       In fact, what we need is for the underlying alphabet to be sortable.
        if isinstance(w, (list, tuple, str, FiniteWord_class)):
            return self.element_class(self, Words()(w).to_ordered_set_partition())
        else:
            raise ValueError("Something is wrong: `from_finite_word` expects an object of type list/tuple/str/Word representing a finite word, received {}.".format(str(w)))
Ejemplo n.º 6
0
    def to_packed_word(self):
        r"""
        Return the packed word on alphabet `\{1,2,3,\ldots\}`
        corresponding to ``self``.

        A *packed word* on alphabet `\{1,2,3,\ldots\}` is any word whose
        maximum letter is the same as its total number of distinct letters.
        Let `P` be an ordered set partition of a set `X`.
        The corresponding packed word `w_1 w_2 \cdots w_n` is constructed
        by having letter `w_i = j` if the `i`-th smallest entry in `X`
        occurs in the `j`-th block of `P`.

        .. SEEALSO::

            :meth:`Word.to_ordered_set_partition`

        .. WARNING::

            This assumes there is a total order on the underlying
            set (``self._base_set``).

        EXAMPLES::

            sage: S = OrderedSetPartitions()
            sage: x = S([[3,5], [2], [1,4,6]])
            sage: x.to_packed_word()
            word: 321313
            sage: x = S([['a', 'c', 'e'], ['b', 'd']])
            sage: x.to_packed_word()
            word: 12121
        """
        X = sorted(self._base_set)
        out = {}
        for i in range(len(self)):
            for letter in self[i]:
                out[letter] = i
        return Words()([out[letter] + 1 for letter in X])
Ejemplo n.º 7
0
    def __init__(self, parent=None):
        r"""
        Constructor. See documentation of WordDatatype_Kolakoski for more
        details.

        EXAMPLES::

            sage: from slabbe import KolakoskiWord
            sage: K = KolakoskiWord()
            sage: K
            word: 1221121221221121122121121221121121221221...

        TESTS:

        Pickle is supported::

            sage: K = KolakoskiWord()
            sage: loads(dumps(K))
            word: 1221121221221121122121121221121121221221...
        """
        if parent is None:
            from sage.combinat.words.words import Words
            parent = Words([1, 2])
        WordDatatype_Kolakoski.__init__(self, parent)
Ejemplo n.º 8
0
    def __init__(self, R, names):
        r"""
        Initialize ``self``.

        EXAMPLES::

            sage: F = ShuffleAlgebra(QQ, 'xyz'); F
            Shuffle Algebra on 3 generators ['x', 'y', 'z'] over Rational Field
            sage: TestSuite(F).run()

        TESTS::

            sage: ShuffleAlgebra(24, 'toto')
            Traceback (most recent call last):
            ...
            TypeError: argument R must be a ring
        """
        if R not in Rings():
            raise TypeError("argument R must be a ring")
        self._alphabet = names
        self.__ngens = self._alphabet.cardinality()
        CombinatorialFreeModule.__init__(self, R, Words(names, infinite=False),
            latex_prefix="",
            category=(AlgebrasWithBasis(R), CommutativeAlgebras(R), CoalgebrasWithBasis(R)))
Ejemplo n.º 9
0
def Subwords(w, k=None, element_constructor=None):
    """
    Return the set of subwords of ``w``.

    INPUT:

    - ``w`` -- a word (can be a list, a string, a tuple or a word)

    - ``k`` -- an optional integer to specify the length of subwords

    - ``element_constructor`` -- an optional function that will be used
      to build the subwords

    EXAMPLES::

        sage: S = Subwords(['a','b','c']); S
        Subwords of ['a', 'b', 'c']
        sage: S.first()
        []
        sage: S.last()
        ['a', 'b', 'c']
        sage: S.list()
        [[], ['a'], ['b'], ['c'], ['a', 'b'], ['a', 'c'], ['b', 'c'], ['a', 'b', 'c']]

    The same example using string, tuple or a word::

        sage: S = Subwords('abc'); S
        Subwords of 'abc'
        sage: S.list()
        ['', 'a', 'b', 'c', 'ab', 'ac', 'bc', 'abc']

        sage: S = Subwords((1,2,3)); S
        Subwords of (1, 2, 3)
        sage: S.list()
        [(), (1,), (2,), (3,), (1, 2), (1, 3), (2, 3), (1, 2, 3)]

        sage: w = Word([1,2,3])
        sage: S = Subwords(w); S
        Subwords of word: 123
        sage: S.list()
        [word: , word: 1, word: 2, word: 3, word: 12, word: 13, word: 23, word: 123]

    Using word with specified length::

        sage: S = Subwords(['a','b','c'], 2); S
        Subwords of ['a', 'b', 'c'] of length 2
        sage: S.list()
        [['a', 'b'], ['a', 'c'], ['b', 'c']]

    An example that uses the ``element_constructor`` argument::

        sage: p = Permutation([3,2,1])
        sage: Subwords(p, element_constructor=tuple).list()
        [(), (3,), (2,), (1,), (3, 2), (3, 1), (2, 1), (3, 2, 1)]
        sage: Subwords(p, 2, element_constructor=tuple).list()
        [(3, 2), (3, 1), (2, 1)]
    """
    if element_constructor is None:
        datatype = type(w)  # 'datatype' is the type of w
        if datatype is list or datatype is tuple:
            element_constructor = datatype
        elif datatype is str:
            element_constructor = _stringification
        else:
            from sage.combinat.words.words import Words
            try:
                alphabet = w.parent().alphabet()
                element_constructor = Words(alphabet)
            except AttributeError:
                element_constructor = list

    if k is None:
        return Subwords_w(w, element_constructor)
    if not isinstance(k, (int, Integer)):
        raise ValueError("k should be an integer")
    if k < 0 or k > len(w):
        return FiniteEnumeratedSet([])
    return Subwords_wk(w, k, element_constructor)
Ejemplo n.º 10
0
    def Kautz(self, k, D, vertices='strings'):
        r"""
        Returns the Kautz digraph of degree `d` and diameter `D`.

        The Kautz digraph has been defined in [Kautz68]_. The Kautz digraph of
        degree `d` and diameter `D` has `d^{D-1}(d+1)` vertices. This digraph is
        build upon a set of vertices equal to the set of words of length `D`
        from an alphabet of `d+1` letters such that consecutive letters are
        differents. There is an arc from vertex `u` to vertex `v` if `v` can be
        obtained from `u` by removing the leftmost letter and adding a new
        letter, distinct from the rightmost letter of `u`, at the right end.

        The Kautz digraph of degree `d` and diameter `D` is isomorphic to the
        digraph of Imase and Itoh [II83]_ of degree `d` and order
        `d^{D-1}(d+1)`.

        See also the
        :wikipedia:`Wikipedia article on Kautz Graphs <Kautz_graph>`.

        INPUTS:

        - ``k`` -- Two possibilities for this parameter :
            - An integer equal to the degree of the digraph to be produced, that
              is the cardinality minus one of the alphabet to use.
            - An iterable object to be used as the set of letters. The degree of
              the resulting digraph is the cardinality of the set of letters
              minus one.

        - ``D`` -- An integer equal to the diameter of the digraph, and also to
              the length of a vertex label when ``vertices == 'strings'``.

        - ``vertices`` -- 'strings' (default) or 'integers', specifying whether
                      the vertices are words build upon an alphabet or integers.


        EXAMPLES::

            sage: K = digraphs.Kautz(2, 3)
            sage: K.is_isomorphic(digraphs.ImaseItoh(12, 2), certify = True)
            (True,
             {'010': 0,
              '012': 1,
              '020': 3,
              '021': 2,
              '101': 11,
              '102': 10,
              '120': 9,
              '121': 8,
              '201': 5,
              '202': 4,
              '210': 6,
              '212': 7})

            sage: K = digraphs.Kautz([1,'a','B'], 2)
            sage: K.edges()
            [('1B', 'B1', '1'), ('1B', 'Ba', 'a'), ('1a', 'a1', '1'), ('1a', 'aB', 'B'), ('B1', '1B', 'B'), ('B1', '1a', 'a'), ('Ba', 'a1', '1'), ('Ba', 'aB', 'B'), ('a1', '1B', 'B'), ('a1', '1a', 'a'), ('aB', 'B1', '1'), ('aB', 'Ba', 'a')]

            sage: K = digraphs.Kautz([1,'aA','BB'], 2)
            sage: K.edges()
            [('1,BB', 'BB,1', '1'), ('1,BB', 'BB,aA', 'aA'), ('1,aA', 'aA,1', '1'), ('1,aA', 'aA,BB', 'BB'), ('BB,1', '1,BB', 'BB'), ('BB,1', '1,aA', 'aA'), ('BB,aA', 'aA,1', '1'), ('BB,aA', 'aA,BB', 'BB'), ('aA,1', '1,BB', 'BB'), ('aA,1', '1,aA', 'aA'), ('aA,BB', 'BB,1', '1'), ('aA,BB', 'BB,aA', 'aA')]


        TESTS:

        An exception is raised when the degree is less than one::

            sage: G = digraphs.Kautz(0, 2)
            Traceback (most recent call last):
            ...
            ValueError: Kautz digraphs are defined for degree at least one.

            sage: G = digraphs.Kautz(['a'], 2)
            Traceback (most recent call last):
            ...
            ValueError: Kautz digraphs are defined for degree at least one.

        An exception is raised when the diameter of the graph is less than one::

            sage: G = digraphs.Kautz(2, 0)
            Traceback (most recent call last):
            ...
            ValueError: Kautz digraphs are defined for diameter at least one.


        REFERENCE:

        .. [Kautz68] W. H. Kautz. Bounds on directed (d, k) graphs. Theory of
          cellular logic networks and machines, AFCRL-68-0668, SRI Project 7258,
          Final Rep., pp. 20-28, 1968.
        """
        if D < 1:
            raise ValueError(
                "Kautz digraphs are defined for diameter at least one.")

        from sage.combinat.words.words import Words
        from sage.rings.integer import Integer

        my_alphabet = Words(
            [str(i) for i in range(k + 1)] if isinstance(k, Integer) else k, 1)
        if my_alphabet.size_of_alphabet() < 2:
            raise ValueError(
                "Kautz digraphs are defined for degree at least one.")

        if vertices == 'strings':

            # We start building the set of vertices
            V = [i for i in my_alphabet]
            for i in range(D - 1):
                VV = []
                for w in V:
                    VV += [w * a for a in my_alphabet if not w.has_suffix(a)]
                V = VV

            # We now build the set of arcs
            G = DiGraph()
            for u in V:
                for a in my_alphabet:
                    if not u.has_suffix(a):
                        G.add_edge(u.string_rep(), (u[1:] * a).string_rep(),
                                   a.string_rep())

        else:
            d = my_alphabet.size_of_alphabet() - 1
            G = digraphs.ImaseItoh((d + 1) * (d**(D - 1)), d)

        G.name("Kautz digraph (k=%s, D=%s)" % (k, D))
        return G
Ejemplo n.º 11
0
    def DeBruijn(self, k, n, vertices='strings'):
        r"""
        Returns the De Bruijn digraph with parameters `k,n`.

        The De Bruijn digraph with parameters `k,n` is built upon a set of
        vertices equal to the set of words of length `n` from a dictionary of
        `k` letters.

        In this digraph, there is an arc `w_1w_2` if `w_2` can be obtained from
        `w_1` by removing the leftmost letter and adding a new letter at its
        right end.  For more information, see the
        :wikipedia:`Wikipedia article on De Bruijn graph <De_Bruijn_graph>`.

        INPUT:

        - ``k`` -- Two possibilities for this parameter :
              - An integer equal to the cardinality of the alphabet to use, that
                is the degree of the digraph to be produced.
              - An iterable object to be used as the set of letters. The degree
                of the resulting digraph is the cardinality of the set of
                letters.

        - ``n`` -- An integer equal to the length of words in the De Bruijn
          digraph when ``vertices == 'strings'``, and also to the diameter of
          the digraph.

        - ``vertices`` -- 'strings' (default) or 'integers', specifying whether
          the vertices are words build upon an alphabet or integers.

        EXAMPLES::

            sage: db=digraphs.DeBruijn(2,2); db
            De Bruijn digraph (k=2, n=2): Looped digraph on 4 vertices
            sage: db.order()
            4
            sage: db.size()
            8

        TESTS::

            sage: digraphs.DeBruijn(5,0)
            De Bruijn digraph (k=5, n=0): Looped multi-digraph on 1 vertex
            sage: digraphs.DeBruijn(0,0)
            De Bruijn digraph (k=0, n=0): Looped multi-digraph on 0 vertices
        """
        from sage.combinat.words.words import Words
        from sage.rings.integer import Integer

        W = Words(range(k) if isinstance(k, Integer) else k, n)
        A = Words(range(k) if isinstance(k, Integer) else k, 1)
        g = DiGraph(loops=True)

        if vertices == 'strings':
            if n == 0:
                g.allow_multiple_edges(True)
                v = W[0]
                for a in A:
                    g.add_edge(v.string_rep(), v.string_rep(), a.string_rep())
            else:
                for w in W:
                    ww = w[1:]
                    for a in A:
                        g.add_edge(w.string_rep(), (ww * a).string_rep(),
                                   a.string_rep())
        else:
            d = W.size_of_alphabet()
            g = digraphs.GeneralizedDeBruijn(d**n, d)

        g.name("De Bruijn digraph (k=%s, n=%s)" % (k, n))
        return g
Ejemplo n.º 12
0
    def DeBruijn(self,k,n):
        r"""
        Returns the De Bruijn diraph with parameters `k,n`.

        The De Bruijn digraph with parameters `k,n` is built
        upon a set of vertices equal to the set of words of
        length `n` from a dictionary of `k` letters.

        In this digraph, there is an arc `w_1w_2` if `w_2`
        can be obtained from `w_1` by removing the leftmost
        letter and adding a new letter at its right end.
        For more information, see the
        `Wikipedia article on De Bruijn graph
        <http://en.wikipedia.org/wiki/De_Bruijn_graph>`_.

        INPUT:

        - ``k`` -- Two possibilities for this parameter :
              - an integer equal to the cardinality of the
                alphabet to use.
              - An iterable object to be used as the set
                of letters
        - ``n`` -- An integer equal to the length of words in
          the De Bruijn digraph.

        EXAMPLES::

            sage: db=digraphs.DeBruijn(2,2); db
            De Bruijn digraph (k=2, n=2): Looped digraph on 4 vertices
            sage: db.order()
            4
            sage: db.size()
            8

        TESTS::

            sage: digraphs.DeBruijn(5,0)
            De Bruijn digraph (k=5, n=0): Looped multi-digraph on 1 vertex
            sage: digraphs.DeBruijn(0,0)
            De Bruijn digraph (k=0, n=0): Looped multi-digraph on 0 vertices

        """
        from sage.combinat.words.words import Words
        from sage.rings.integer import Integer

        W = Words(range(k) if isinstance(k, Integer) else k, n)
        A = Words(range(k) if isinstance(k, Integer) else k, 1)
        g = DiGraph(loops=True)

        if n == 0 :
            g.allow_multiple_edges(True)
            v = W[0]
            for a in A:
                g.add_edge(v.string_rep(), v.string_rep(), a.string_rep())
        else:
            for w in W:
                ww = w[1:]
                for a in A:
                    g.add_edge(w.string_rep(), (ww*a).string_rep(), a.string_rep())

        g.name( "De Bruijn digraph (k=%s, n=%s)"%(k,n) )
        return g