Beispiel #1
0
    def __init__(self, permutation=None, lengths=None):
        r"""
        INPUT:

        - ``permutation`` - a permutation (LabelledPermutationIET)

        - ``lengths`` - the list of lengths

        TEST::

            sage: p=iet.IntervalExchangeTransformation(('a','a'),[1])
            sage: p == loads(dumps(p))
            True
        """
        from labelled import LabelledPermutationIET
        if permutation is None or lengths is None:
            self._permutation = LabelledPermutationIET()
            self._lengths = []
        else:
            self._permutation = permutation
            self._lengths = lengths
Beispiel #2
0
def Permutation(*args,**kargs):
    r"""
    Returns a permutation of an interval exchange transformation.

    Those permutations are the combinatoric part of an interval exchange
    transformation (IET). The combinatorial study of those objects starts with
    Gerard Rauzy [R79]_ and William Veech [V78]_.

    The combinatoric part of interval exchange transformation can be taken
    independently from its dynamical origin. It has an important link with
    strata of Abelian differential (see :mod:`~sage.combinat.iet.strata`)

    INPUT:
        
    - ``intervals`` - string, two strings, list, tuples that can be converted to
      two lists

    - ``reduced`` - boolean (default: False) specifies reduction. False means
      labelled permutation and True means reduced permutation.

    - ``flips`` -  iterable (default: None) the letters which correspond to
      flipped intervals.

    OUTPUT:

    permutation -- the output type depends of the data.

    EXAMPLES:

    Creation of labelled permutations ::

        sage: iet.Permutation('a b c d','d c b a')
        a b c d
        d c b a
        sage: iet.Permutation([[0,1,2,3],[2,1,3,0]])
        0 1 2 3
        2 1 3 0
        sage: iet.Permutation([0, 'A', 'B', 1], ['B', 0, 1, 'A'])
        0 A B 1
        B 0 1 A

    Creation of reduced permutations::
    
        sage: iet.Permutation('a b c', 'c b a', reduced = True)
        a b c
        c b a
        sage: iet.Permutation([0, 1, 2, 3], [1, 3, 0, 2])
        0 1 2 3
        1 3 0 2

    Creation of flipped permutations::
    
        sage: iet.Permutation('a b c', 'c b a', flips=['a','b'])
        -a -b  c
         c -b -a
        sage: iet.Permutation('a b c', 'c b a', flips=['a'], reduced=True)
        -a  b  c
         c  b -a

    TESTS:

    ::

        sage: p = iet.Permutation('a b c','c b a')
        sage: iet.Permutation(p) == p
        True
        sage: iet.Permutation(p, reduced=True) == p.reduced()
        True

    ::

        sage: p = iet.Permutation('a','a',flips='a',reduced=True)
        sage: iet.Permutation(p) == p
        True

    ::

        sage: p = iet.Permutation('a b c','c b a',flips='a')
        sage: iet.Permutation(p) == p
        True
        sage: iet.Permutation(p, reduced=True) == p.reduced()
        True

    ::

        sage: p = iet.Permutation('a b c','c b a',reduced=True)
        sage: iet.Permutation(p) == p
        True
    """
    from labelled import LabelledPermutation
    from labelled import LabelledPermutationIET
    from labelled import FlippedLabelledPermutationIET

    from reduced import ReducedPermutation
    from reduced import ReducedPermutationIET
    from reduced import FlippedReducedPermutationIET

    if 'reduced' not in kargs :
        reduction = None
    elif not isinstance(kargs["reduced"], bool) :
        raise TypeError("reduced must be of type boolean")
    else :
        if kargs["reduced"] == True : reduction = True
        else : reduction = False

    if 'flips' not in kargs :
        flips = []
    else :
        flips = list(kargs['flips'])


    if 'alphabet' not in kargs :
        alphabet = None
    else :
        alphabet = kargs['alphabet']

    if len(args) == 1:
        args = args[0]
        if isinstance(args, LabelledPermutation):
            if flips == []:
                if reduction is None or reduction is False:
                    from copy import copy
                    return copy(args)
                else:
                    return args.reduced()
            else: # conversion not yet implemented
                reduced = reduction in (None, False)
                return PermutationIET(
                    args.list(), 
                    reduced=reduced,
                    flips=flips,
                    alphabet=alphabet)

        if isinstance(args, ReducedPermutation):
            if flips == []:
                if reduction is None or reduction is True:
                    from copy import copy
                    return copy(args)
                else:  # conversion not yet implemented
                    return PermutationIET(
                        args.list(),
                        reduced=True)
            else: # conversion not yet implemented
                reduced = reduction in (None, True)
                return PermutationIET(
                    args.list(),
                    reduced=reduced,
                    flips=flips,
                    alphabet=alphabet)

    a = _two_lists(args)
   
    l = a[0] + a[1]
    letters = set(l)

    for letter in flips :
        if letter not in letters :
            raise ValueError, "flips contains not valid letters"
    
    for letter in letters :
        if a[0].count(letter) != 1 or a[1].count(letter) != 1:
            raise ValueError, "letters must appear once in each interval"
    
    if reduction == True :
        if flips == [] :
            return ReducedPermutationIET(a, alphabet=alphabet)
        else :
            return FlippedReducedPermutationIET(a, alphabet=alphabet, flips=flips)
    else :
        if flips == [] :
            return LabelledPermutationIET(a, alphabet=alphabet)
        else :
            return FlippedLabelledPermutationIET(a, alphabet=alphabet, flips=flips)
Beispiel #3
0
    def __mul__(self, other):
        r"""
        Composition of iet.

        The domain (i.e. the length) of the two iets must be the same). The
        alphabet choosen depends on the permutation.

        TESTS:

        ::

            sage: p = iet.Permutation("a b", "a b")
            sage: t = iet.IET(p, [1,1])
            sage: r = t*t
            sage: r.permutation()
            aa bb
            aa bb
            sage: r.lengths()
            [1, 1]

        ::

            sage: p = iet.Permutation("a b","b a")
            sage: t = iet.IET(p, [1,1])
            sage: r = t*t
            sage: r.permutation()
            ab ba
            ab ba
            sage: r.lengths()
            [1, 1]

        ::

            sage: p = iet.Permutation("1 2 3 4 5","5 4 3 2 1")
            sage: q = iet.Permutation("a b","b a")
            sage: s = iet.IET(p, [1]*5)
            sage: t = iet.IET(q, [1/2, 9/2])
            sage: r = s*t
            sage: r.permutation()
            a5 b1 b2 b3 b4 b5
            b5 a5 b4 b3 b2 b1
            sage: r.lengths()
            [1/2, 1, 1, 1, 1, 1/2]
            sage: r = t*s
            sage: r.permutation()
            1b 2b 3b 4b 5a 5b
            5b 4b 3b 2b 1b 5a
            sage: r.lengths()
            [1, 1, 1, 1, 1/2, 1/2]
            sage: t = iet.IET(q, [3/2, 7/2])
            sage: r = s*t
            sage: r.permutation()
            a4 a5 b1 b2 b3 b4
            a5 b4 a4 b3 b2 b1
            sage: r.lengths()
            [1/2, 1, 1, 1, 1, 1/2]
            sage: t = iet.IET(q, [5/2,5/2])
            sage: r = s*t
            sage: r.permutation()
            a3 a4 a5 b1 b2 b3
            a5 a4 b3 a3 b2 b1
            sage: r = t*s
            sage: r.permutation()
            1b 2b 3a 3b 4a 5a
            3b 2b 1b 5a 4a 3a

        ::

            sage: p = iet.Permutation("a b","b a")
            sage: s = iet.IET(p, [4,2])
            sage: q = iet.Permutation("c d","d c")
            sage: t = iet.IET(q, [3, 3])
            sage: r1 = t * s
            sage: r1.permutation()
            ac ad bc
            ad bc ac
            sage: r1.lengths()
            [1, 3, 2]
            sage: r2 = s * t
            sage: r2.permutation()
            ca cb da
            cb da ca
            sage: r2.lengths()
            [1, 2, 3]
        """
        assert (isinstance(other, IntervalExchangeTransformation)
                and self.length() == other.length())

        from labelled import LabelledPermutationIET
        from sage.combinat.words.words import Words

        other_sg = other.range_singularities()[1:]
        self_sg = self.domain_singularities()[1:]

        n_other = len(other._permutation)
        n_self = len(self._permutation)

        interval_other = other._permutation._intervals[1]
        interval_self = self._permutation._intervals[0]

        d_other = dict([(i, []) for i in interval_other])
        d_self = dict([(i, []) for i in interval_self])

        i_other = 0
        i_self = 0

        x = 0
        l_lengths = []
        while i_other < n_other and i_self < n_self:
            j_other = interval_other[i_other]
            j_self = interval_self[i_self]

            d_other[j_other].append(j_self)
            d_self[j_self].append(j_other)

            if other_sg[i_other] < self_sg[i_self]:
                l = other_sg[i_other] - x
                x = other_sg[i_other]
                i_other += 1
            elif other_sg[i_other] > self_sg[i_self]:
                l = self_sg[i_self] - x
                x = self_sg[i_self]
                i_self += 1
            else:
                l = self_sg[i_self] - x
                x = self_sg[i_self]
                i_other += 1
                i_self += 1

            l_lengths.append(((j_other, j_self), l))

        alphabet_other = other._permutation.alphabet()
        alphabet_self = self._permutation.alphabet()

        d_lengths = dict(l_lengths)

        l_lengths = []
        top_interval = []
        for i in other._permutation._intervals[0]:
            for j in d_other[i]:
                a = alphabet_other.unrank(i)
                b = alphabet_self.unrank(j)
                top_interval.append(str(a) + str(b))
                l_lengths.append(d_lengths[(i, j)])

        bottom_interval = []
        for i in self._permutation._intervals[1]:
            for j in d_self[i]:
                a = alphabet_other.unrank(j)
                b = alphabet_self.unrank(i)
                bottom_interval.append(str(a) + str(b))

        p = LabelledPermutationIET((top_interval, bottom_interval))
        return IntervalExchangeTransformation(p, l_lengths)
Beispiel #4
0
    def recoding(self, n):
        r"""
        Recode this interval exchange transformation on the words of length
        ``n``.

        EXAMPLES::

            sage: from surface_dynamics.all import *
            sage: p = iet.Permutation('a d c b', 'b c a d', alphabet='abcd')
            sage: T = iet.IntervalExchangeTransformation(p, [119,213,82,33])
            sage: T.recoding(2)
            Interval exchange transformation of [0, 447[ with permutation
            ab db cc cb ba bd bc
            ba bd bc cc cb ab db
            sage: T.recoding(3)
            Interval exchange transformation of [0, 447[ with permutation
            aba abd abc dbc ccb cba bab bdb bcc bcb
            cba aba abd abc dbc bcc bcb ccb bab bdb
        """
        length = len(self._permutation)
        lengths = self._lengths
        A = self.permutation().alphabet()
        unrank = A.unrank

        top = self._permutation._labels[0]
        bot = self._permutation._labels[1]
        bot_twin = self._permutation._twin[1]

        sg_top = self.domain_singularities()[
            1:-1]  # iterates of the top singularities
        cuts = [[[i], lengths[i]] for i in bot]  # the refined bottom interval

        translations = self.translations()

        for step in range(n - 1):
            i = 0
            y = self.base_ring().zero()
            new_sg_top = []
            limits = [0]
            for j, x in enumerate(sg_top):
                while y < x:
                    cuts[i][0].append(top[j])
                    y += cuts[i][1]
                    i += 1

                limits.append(i)
                if y != x:
                    cuts.insert(i, [cuts[i - 1][0][:-1], cuts[i - 1][1]])
                    cuts[i - 1][1] -= y - x
                    cuts[i][0].append(top[j + 1])
                    cuts[i][1] = y - x
                    i += 1
            while i < len(cuts):
                cuts[i][0].append(top[j + 1])
                i += 1
            limits.append(len(cuts))

            # now we reorder cuts with respect to T according to the cut at
            # limits
            if step != n - 2:
                new_cuts = []
                for j in bot_twin:
                    new_cuts.extend(cuts[limits[j]:limits[j + 1]])
                cuts = new_cuts

        # build the new interval exchange transformations
        itop = [None] * (max(top) + 1)
        for i, j in enumerate(top):
            itop[j] = i
        key = lambda x: [itop[i] for i in x[0]]
        top = sorted(cuts, key=key)
        lengths = [y for x, y in top]
        top = [''.join(str(unrank(i)) for i in x) for x, y in top]
        bot = cuts
        bot = [''.join(str(unrank(i)) for i in x) for x, y in bot]

        from labelled import LabelledPermutationIET
        p = LabelledPermutationIET((top, bot))
        return IntervalExchangeTransformation(p, lengths)