Ticket #14123: trac_14123-binary-trees-maps-rebase-cs.patch

File trac_14123-binary-trees-maps-rebase-cs.patch, 14.2 KB (added by stumpc5, 8 years ago)
  • sage/combinat/binary_tree.py

    # HG changeset patch
    # User Christian Stump <christian.stump at gmail.com>
    # Date 1360980852 18000
    # Node ID 57e8fccb829827a9eadce1f1dd6ae7eb259ee204
    # Parent  16768eaa774a10ee080f972ed1a80ab32baeaad9
    Trac #14123: Adding some maps for binary trees
    
    diff --git a/sage/combinat/binary_tree.py b/sage/combinat/binary_tree.py
    a b from sage.combinat.ordered_tree import L 
    2727from sage.rings.integer import Integer
    2828from sage.misc.classcall_metaclass import ClasscallMetaclass
    2929from sage.misc.lazy_attribute import lazy_attribute, lazy_class_attribute
     30from sage.combinat.combinatorial_map import combinatorial_map
    3031
    3132class BinaryTree(AbstractClonableTree, ClonableArray):
    3233    """
    class BinaryTree(AbstractClonableTree, C 
    341342        self._require_mutable()
    342343        self.__init__(self.parent(), None)
    343344
    344     def _to_dyck_word_rec(self):
     345    def _to_dyck_word_rec(self, usemap="1L0R"):
    345346        r"""
    346347        EXAMPLES::
    347348
    class BinaryTree(AbstractClonableTree, C 
    351352            [1, 0]
    352353            sage: BinaryTree([[[], [[], None]], [[], []]])._to_dyck_word_rec()
    353354            [1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0]
     355            sage: BinaryTree([[None,[]],None])._to_dyck_word_rec("L1R0")
     356            [1, 1, 0, 0, 1, 0]
     357            sage: BinaryTree([[[], [[], None]], [[], []]])._to_dyck_word_rec("L1R0")
     358            [1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0]
    354359        """
    355360        if self:
    356             return ([1]+self[0]._to_dyck_word_rec()+
    357                     [0]+self[1]._to_dyck_word_rec())
     361            w = []
     362            for l in usemap:
     363                if l == "L": w += self[0]._to_dyck_word_rec(usemap)
     364                elif l == "R": w+=self[1]._to_dyck_word_rec(usemap)
     365                elif l == "1": w+=[1]
     366                elif l == "0": w+=[0]
     367            return w
    358368        else:
    359369            return []
    360370
    361     def to_dyck_word(self):
     371    @combinatorial_map(name = "recursive map 'L 1 R 0' (Tamari)")
     372    def to_dyck_word_tamari(self):
    362373        r"""
    363         Return the Dyck word associated to ``self``
     374        Return the Dyck word associated with ``self`` in consistency with
     375        the Tamari order on dyck words and binary trees.
     376
     377        The bijection is defined recursively as follows:
     378
     379        - a leaf is associated with an empty Dyck word
     380
     381        - a tree with children `l,r` is associated with the Dyck word
     382          `T(l) 1 T(r) 0`
     383
     384        EXAMPLES::
     385
     386            sage: BinaryTree().to_dyck_word_tamari()
     387            []
     388            sage: BinaryTree([]).to_dyck_word_tamari()
     389            [1, 0]
     390            sage: BinaryTree([[None,[]],None]).to_dyck_word_tamari()
     391            [1, 1, 0, 0, 1, 0]
     392            sage: BinaryTree([[[], [[], None]], [[], []]]).to_dyck_word_tamari()
     393            [1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0]
     394        """
     395        from sage.combinat.dyck_word import DyckWord
     396        return self.to_dyck_word("L1R0")
     397
     398    @combinatorial_map(name="recursive map '1 L 0 R'")
     399    def to_dyck_word(self, usemap="1L0R"):
     400        r"""
     401        INPUT:
     402
     403        - ``usemap`` -- a string, either ``1L0R``, ``1R0L``, ``L1R0``, ``R1L0``
     404
     405        Return the Dyck word associated with ``self`` using the given map.
    364406
    365407        The bijection is defined recursively as follows:
    366408
    367409        - a leaf is associated to the empty Dyck Word
    368410
    369         - a tree with chidren `l,r` is associated to the Dyck word
    370           `1 T(l) 0 T(r)` where `T(l)` and `T(r)` are the Dyck words
    371           associated to `l` and `r`.
     411        - a tree with children `l,r` is associated with the Dyck word
     412          described by ``usemap`` where `L` and `R` are respectively the
     413          Dyck words associated with the `l` and `r`.
    372414
    373415        EXAMPLES::
    374416
    class BinaryTree(AbstractClonableTree, C 
    378420            [1, 0]
    379421            sage: BinaryTree([[[], [[], None]], [[], []]]).to_dyck_word()
    380422            [1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0]
     423            sage: BinaryTree([[None,[]],None]).to_dyck_word()
     424            [1, 1, 0, 1, 0, 0]
     425            sage: BinaryTree([[None,[]],None]).to_dyck_word("1R0L")
     426            [1, 0, 1, 1, 0, 0]
     427            sage: BinaryTree([[None,[]],None]).to_dyck_word("L1R0")
     428            [1, 1, 0, 0, 1, 0]
     429            sage: BinaryTree([[None,[]],None]).to_dyck_word("R1L0")
     430            [1, 1, 0, 1, 0, 0]
     431            sage: BinaryTree([[None,[]],None]).to_dyck_word("R10L")
     432            Traceback (most recent call last):
     433            ...
     434            ValueError: R10L is not a correct map
     435
     436        TESTS::
     437
     438            sage: bt = BinaryTree([[[], [[], None]], [[], []]])
     439            sage: bt == bt.to_dyck_word().to_binary_tree()
     440            True
     441            sage: bt == bt.to_dyck_word("1R0L").to_binary_tree("1R0L")
     442            True
     443            sage: bt == bt.to_dyck_word("L1R0").to_binary_tree("L1R0")
     444            True
     445            sage: bt == bt.to_dyck_word("R1L0").to_binary_tree("R1L0")
     446            True
    381447        """
    382448        from sage.combinat.dyck_word import DyckWord
    383         return DyckWord(self._to_dyck_word_rec())
     449        if usemap not in ["1L0R", "1R0L", "L1R0", "R1L0"]:
     450            raise ValueError, "%s is not a correct map"%(usemap)
     451        return DyckWord(self._to_dyck_word_rec(usemap))
     452
     453    @combinatorial_map(order = 2, name="Left-right symmetry")
     454    def left_right_symmetry(self):
     455        r"""
     456        Returns the left-right symmetrized tree of ``self``.
     457
     458        EXAMPLES::
     459
     460            sage: BinaryTree().left_right_symmetry()
     461            sage: BinaryTree([]).left_right_symmetry()
     462            [., .]
     463            sage: BinaryTree([[],None]).left_right_symmetry()
     464            [., [., .]]
     465            sage: BinaryTree([[None, []],None]).left_right_symmetry()
     466            [., [[., .], .]]
     467        """
     468        if not self:
     469            return None
     470        tree = [self[1].left_right_symmetry(),self[0].left_right_symmetry()]
     471        if(not self in LabelledBinaryTrees()):
     472            return BinaryTree(tree)
     473        return LabelledBinaryTree(tree, label = self.label())
     474
     475    @combinatorial_map(order=2, name="Left border symmetry")
     476    def left_border_symmetry(self):
     477        r"""
     478        Returns the tree where a symmetry has been applied recursively on
     479        all left borders. If a tree is made of three trees `[T_1, T_2,
     480        T_3]` on its left border, it becomes `[T_3', T_2', T_1']` where
     481        same symmetry has been applied to `T_1, T_2, T_3`.
     482
     483        EXAMPLES::
     484
     485            sage: BinaryTree().left_border_symmetry()
     486            sage: BinaryTree([]).left_border_symmetry()
     487            [., .]
     488            sage: BinaryTree([[None,[]],None]).left_border_symmetry()
     489            [[., .], [., .]]
     490            sage: BinaryTree([[None,[None,[]]],None]).left_border_symmetry()
     491            [[., .], [., [., .]]]
     492            sage: bt = BinaryTree([[None,[None,[]]],None]).canonical_labelling()
     493            sage: bt
     494            4[1[., 2[., 3[., .]]], .]
     495            sage: bt.left_border_symmetry()
     496            1[4[., .], 2[., 3[., .]]]
     497        """
     498        if not self:
     499            return None
     500        border = []
     501        labelled = self in LabelledBinaryTrees()
     502        labels = []
     503        t = self
     504        while(t):
     505            border.append(t[1].left_border_symmetry())
     506            if labelled: labels.append(t.label())
     507            t = t[0]
     508        tree = BinaryTree()
     509        for r in border:
     510            if labelled:
     511                tree = LabelledBinaryTree([tree,r],label=labels.pop(0))
     512            else:
     513                tree = BinaryTree([tree,r])
     514        return tree
    384515
    385516    def canopee(self):
    386517        """
  • sage/combinat/dyck_word.py

    diff --git a/sage/combinat/dyck_word.py b/sage/combinat/dyck_word.py
    a b class DyckWord_class(CombinatorialObject 
    13421342                close_positions.append(i+1)
    13431343        return Tableau(filter(lambda x: x != [],  [ open_positions, close_positions ]))
    13441344
     1345    @combinatorial_map(name="recursive map '1 L 0 R'")
     1346    def to_binary_tree(self, usemap="1L0R"):
     1347        r"""
     1348        INPUT:
     1349
     1350         - ``usemap`` -- a string, either ``1L0R``, ``1R0L``, ``L1R0``,
     1351           ``R1L0``.
     1352
     1353        Returns a binary tree recursively constructed from the Dyck path
     1354        by the sent ``usemap``. The default usemap is ``1L0R`` which means:
     1355
     1356        - an empty Dyck word is a leaf,
     1357
     1358        - a non empty Dyck word reads `1 L 0 R` where `L` and `R` correspond
     1359          to respectively its left and right subtrees.
     1360
     1361        Other valid usemaps are ``1R0L``, ``L1R0``, and ``R1L0`` all
     1362        correspondings to different recursive definitions of Dyck paths.
     1363
     1364        EXAMPLES::
     1365
     1366            sage: dw = DyckWord([1,0])
     1367            sage: dw.to_binary_tree()
     1368            [., .]
     1369            sage: dw = DyckWord([])
     1370            sage: dw.to_binary_tree()
     1371            .
     1372            sage: dw = DyckWord([1,0,1,1,0,0])
     1373            sage: dw.to_binary_tree()
     1374            [., [[., .], .]]
     1375            sage: dw.to_binary_tree("L1R0")
     1376            [[., .], [., .]]
     1377            sage: dw = DyckWord([1,0,1,1,0,0,1,1,1,0,1,0,0,0])
     1378            sage: dw.to_binary_tree() == dw.to_binary_tree("1R0L").left_right_symmetry()
     1379            True
     1380            sage: dw.to_binary_tree() == dw.to_binary_tree("L1R0").left_border_symmetry()
     1381            False
     1382            sage: dw.to_binary_tree("1R0L") == dw.to_binary_tree("L1R0").left_border_symmetry()
     1383            True
     1384            sage: dw.to_binary_tree("R1L0") == dw.to_binary_tree("L1R0").left_right_symmetry()
     1385            True
     1386            sage: dw.to_binary_tree("R10L")
     1387            Traceback (most recent call last):
     1388            ...
     1389            ValueError: R10L is not a correct map
     1390        """
     1391        if usemap not in ["1L0R", "1R0L", "L1R0", "R1L0"]:
     1392            raise ValueError("%s is not a correct map"%(usemap))
     1393        from sage.combinat.binary_tree import BinaryTree
     1394        if(len(self)==0):
     1395            return BinaryTree()
     1396        tp = [0]
     1397        tp.extend(self.touch_points())
     1398        l = len(self)
     1399        if(usemap[0]=='1'): # we check what kind of reduction we want
     1400            s0 = 1 #start point for first substree
     1401            e0 = tp[1] *2 -1 #end point for first subtree
     1402            s1 = e0 + 1 #start point for second subtree
     1403            e1 = l #end point for second subtree
     1404        else:
     1405            s0 = 0
     1406            e0 = tp[len(tp)-2] *2
     1407            s1 = e0 + 1
     1408            e1 = l - 1
     1409        trees = [DyckWord(self[s0:e0]).to_binary_tree(usemap), DyckWord(self[s1:e1]).to_binary_tree(usemap)]
     1410        if(usemap[0] == "R" or usemap[1]=="R"):
     1411            trees.reverse()
     1412        return BinaryTree(trees)
     1413
     1414    def to_binary_tree_tamari(self):
     1415        r"""
     1416        Returns the binary tree with consistency with the Tamari order.
     1417
     1418        EXAMPLES::
     1419
     1420            sage: DyckWord([1,0]).to_binary_tree_tamari()
     1421            [., .]
     1422            sage: DyckWord([1,0,1,1,0,0]).to_binary_tree_tamari()
     1423            [[., .], [., .]]
     1424            sage: DyckWord([1,0,1,0,1,0]).to_binary_tree_tamari()
     1425            [[[., .], .], .]
     1426        """
     1427        return self.to_binary_tree("L1R0")
     1428
    13451429    def to_area_sequence(self):
    13461430        r"""
    13471431        Return the sequence of numbers representing of full cells below the
  • sage/combinat/permutation.py

    diff --git a/sage/combinat/permutation.py b/sage/combinat/permutation.py
    a b class Permutation_class(CombinatorialObj 
    30313031            return LBT([rec(perm[:k]), rec(perm[k+1:])], label = mn)
    30323032        return rec(self)
    30333033
     3034    @combinatorial_map(name="Increasing tree")
     3035    def increasing_tree_shape(self, compare=min):
     3036        r"""
     3037        Returns the shape of the increasing tree associated with the
     3038        permutation.
     3039
     3040        EXAMPLES::
     3041
     3042            sage: Permutation([1,4,3,2]).increasing_tree_shape()
     3043            [., [[[., .], .], .]]
     3044            sage: Permutation([4,1,3,2]).increasing_tree_shape()
     3045            [[., .], [[., .], .]]
     3046
     3047        By passing the option ``compare=max`` one can have the decreasing
     3048        tree instead::
     3049
     3050            sage: Permutation([2,3,4,1]).increasing_tree_shape(max)
     3051            [[[., .], .], [., .]]
     3052            sage: Permutation([2,3,1,4]).increasing_tree_shape(max)
     3053            [[[., .], [., .]], .]
     3054        """
     3055        return self.increasing_tree(compare).shape()
     3056
    30343057    def binary_search_tree(self, left_to_right=True):
    30353058        """
    3036         Return the binary search tree associated to ``self``
     3059        Return the binary search tree associated to ``self``.
    30373060
    30383061        EXAMPLES::
    30393062
    class Permutation_class(CombinatorialObj 
    30423065            sage: Permutation([4,1,3,2]).binary_search_tree()
    30433066            4[1[., 3[2[., .], .]], .]
    30443067
    3045         By passing the option ``compare=max`` one can have the decreasing
    3046         tree instead::
     3068        By passing the option ``left_to_right=False`` one can have
     3069        the insertion going from right to left::
    30473070
    30483071            sage: Permutation([1,4,3,2]).binary_search_tree(False)
    30493072            2[1[., .], 3[., 4[., .]]]
    class Permutation_class(CombinatorialObj 
    31423165        S=PerfectMatchings(n)([(2*i+1,2*i+2) for i in range(n//2)])
    31433166        return S.loop_type(S.conjugate_by_permutation(self))
    31443167
     3168    @combinatorial_map(name = "Binary search tree (left to right)")
     3169    def binary_search_tree_shape(self, left_to_right=True):
     3170        r"""
     3171        Returns the shape of the binary search tree of the permutation
     3172        (a non labelled binary tree).
     3173
     3174        EXAMPLES::
     3175
     3176            sage: Permutation([1,4,3,2]).binary_search_tree_shape()
     3177            [., [[[., .], .], .]]
     3178            sage: Permutation([4,1,3,2]).binary_search_tree_shape()
     3179            [[., [[., .], .]], .]
     3180
     3181        By passing the option ``left_to_right=False`` one can have
     3182        the insertion going from right to left::
     3183
     3184            sage: Permutation([1,4,3,2]).binary_search_tree_shape(False)
     3185            [[., .], [., [., .]]]
     3186            sage: Permutation([4,1,3,2]).binary_search_tree_shape(False)
     3187            [[., .], [., [., .]]]
     3188        """
     3189        return self.binary_search_tree(left_to_right).shape()
     3190
    31453191################################################################
    31463192
    31473193def Arrangements(mset, k):