ó
~9­\c           @  s
  d  d l  m Z m Z d  d l m Z m Z m Z d  d l m Z m	 Z	 m
 Z
 d  d l m Z d  d l m Z d  d l m Z d  d l m Z m Z m Z d  d l m Z d	 e f d
 „  ƒ  YZ d e f d „  ƒ  YZ e d „ Z d „  Z d „  Z d „  Z d „  Z d S(   iÿÿÿÿ(   t   print_functiont   division(   t   Basict   Dictt   sympify(   t   as_intt   default_sort_keyt   range(   t   bell(   t   zeros(   t	   FiniteSet(   t   has_dupst   flattent   group(   t   defaultdictt	   Partitionc           B  s   e  Z d  Z d Z d Z d „  Z d d „ Z e d „  ƒ Z	 d „  Z
 d „  Z d „  Z d „  Z e d „  ƒ Z e d	 „  ƒ Z e d
 „  ƒ Z RS(   sù   
    This class represents an abstract partition.

    A partition is a set of disjoint sets whose union equals a given set.

    See Also
    ========

    sympy.utilities.iterables.partitions,
    sympy.utilities.iterables.multiset_partitions
    c         G  s®   | } t  d „  | Dƒ ƒ s+ t d ƒ ‚ n  t t | g  ƒ d t ƒ} t | ƒ ra t d ƒ ‚ n  t j |  g  | D] } t | Œ  ^ qq Œ } t | ƒ | _	 t
 | ƒ | _ | S(   sÍ  
        Generates a new partition object.

        This method also verifies if the arguments passed are
        valid and raises a ValueError if they are not.

        Examples
        ========

        >>> from sympy.combinatorics.partitions import Partition
        >>> a = Partition([1, 2], [3])
        >>> a
        {{3}, {1, 2}}
        >>> a.partition
        [[1, 2], [3]]
        >>> len(a)
        2
        >>> a.members
        (1, 2, 3)

        c         s  s$   |  ] } t  | t t f ƒ Vq d  S(   N(   t
   isinstancet   listR
   (   t   .0t   part(    (    s=   lib/python2.7/site-packages/sympy/combinatorics/partitions.pys	   <genexpr>4   s    s:   Each argument to Partition should be a list or a FiniteSett   keys(   Partition contained duplicated elements.(   t   allt
   ValueErrort   sortedt   sumR   R   R
   t   __new__t   tuplet   memberst   lent   size(   t   clst	   partitiont   argst   xt   obj(    (    s=   lib/python2.7/site-packages/sympy/combinatorics/partitions.pyR      s    +c           s^   ˆ  d k r |  j } n$ t t |  j d ‡  f d †  ƒƒ } t t t |  j | |  j f ƒ ƒ S(   s£  Return a canonical key that can be used for sorting.

        Ordering is based on the size and sorted elements of the partition
        and ties are broken with the rank.

        Examples
        ========

        >>> from sympy.utilities.iterables import default_sort_key
        >>> from sympy.combinatorics.partitions import Partition
        >>> from sympy.abc import x
        >>> a = Partition([1, 2])
        >>> b = Partition([3, 4])
        >>> c = Partition([1, x])
        >>> d = Partition(list(range(4)))
        >>> l = [d, b, a + 1, a, c]
        >>> l.sort(key=default_sort_key); l
        [{{1, 2}}, {{1}, {2}}, {{1, x}}, {{3, 4}}, {{0, 1, 2, 3}}]
        R   c           s   t  |  ˆ  ƒ S(   N(   R   (   t   w(   t   order(    s=   lib/python2.7/site-packages/sympy/combinatorics/partitions.pyt   <lambda>Z   t    N(	   t   NoneR   R   R   R   t   mapR   R   t   rank(   t   selfR$   R   (    (   R$   s=   lib/python2.7/site-packages/sympy/combinatorics/partitions.pyt   sort_keyB   s
    c         C  sJ   |  j  d k rC t g  |  j D] } t | d t ƒ^ q ƒ |  _  n  |  j  S(   sÜ   Return partition as a sorted list of lists.

        Examples
        ========

        >>> from sympy.combinatorics.partitions import Partition
        >>> Partition([1], [2, 3]).partition
        [[1], [2, 3]]
        R   N(   t
   _partitionR'   R   R    R   (   R*   t   p(    (    s=   lib/python2.7/site-packages/sympy/combinatorics/partitions.pyR   ]   s    .c         C  sK   t  | ƒ } |  j | } t | t |  j ƒ |  j ƒ } t j | |  j ƒ S(   st  
        Return permutation whose rank is ``other`` greater than current rank,
        (mod the maximum rank for the set).

        Examples
        ========

        >>> from sympy.combinatorics.partitions import Partition
        >>> a = Partition([1, 2], [3])
        >>> a.rank
        1
        >>> (a + 1).rank
        2
        >>> (a + 100).rank
        1
        (   R   R)   t
   RGS_unrankt   RGS_enumR   R   t   from_rgsR   (   R*   t   othert   offsett   result(    (    s=   lib/python2.7/site-packages/sympy/combinatorics/partitions.pyt   __add__m   s    c         C  s   |  j  | ƒ S(   sq  
        Return permutation whose rank is ``other`` less than current rank,
        (mod the maximum rank for the set).

        Examples
        ========

        >>> from sympy.combinatorics.partitions import Partition
        >>> a = Partition([1, 2], [3])
        >>> a.rank
        1
        >>> (a - 1).rank
        0
        >>> (a - 100).rank
        1
        (   R4   (   R*   R1   (    (    s=   lib/python2.7/site-packages/sympy/combinatorics/partitions.pyt   __sub__…   s    c         C  s   |  j  ƒ  t | ƒ j  ƒ  k S(   s  
        Checks if a partition is less than or equal to
        the other based on rank.

        Examples
        ========

        >>> from sympy.combinatorics.partitions import Partition
        >>> a = Partition([1, 2], [3, 4, 5])
        >>> b = Partition([1], [2, 3], [4], [5])
        >>> a.rank, b.rank
        (9, 34)
        >>> a <= a
        True
        >>> a <= b
        True
        (   R+   R   (   R*   R1   (    (    s=   lib/python2.7/site-packages/sympy/combinatorics/partitions.pyt   __le__˜   s    c         C  s   |  j  ƒ  t | ƒ j  ƒ  k  S(   sL  
        Checks if a partition is less than the other.

        Examples
        ========

        >>> from sympy.combinatorics.partitions import Partition
        >>> a = Partition([1, 2], [3, 4, 5])
        >>> b = Partition([1], [2, 3], [4], [5])
        >>> a.rank, b.rank
        (9, 34)
        >>> a < b
        True
        (   R+   R   (   R*   R1   (    (    s=   lib/python2.7/site-packages/sympy/combinatorics/partitions.pyt   __lt__¬   s    c         C  s/   |  j  d k	 r |  j  St |  j ƒ |  _  |  j  S(   sá   
        Gets the rank of a partition.

        Examples
        ========

        >>> from sympy.combinatorics.partitions import Partition
        >>> a = Partition([1, 2], [3], [4, 5])
        >>> a.rank
        13
        N(   t   _rankR'   t   RGS_rankt   RGS(   R*   (    (    s=   lib/python2.7/site-packages/sympy/combinatorics/partitions.pyR)   ½   s    c         C  s”   i  } |  j  } x5 t | ƒ D]' \ } } x | D] } | | | <q/ Wq Wt g  t g  | D] } | D] } | ^ qa qW d t ƒD] } | | ^ q} ƒ S(   s½  
        Returns the "restricted growth string" of the partition.

        The RGS is returned as a list of indices, L, where L[i] indicates
        the block in which element i appears. For example, in a partition
        of 3 elements (a, b, c) into 2 blocks ([c], [a, b]) the RGS is
        [1, 1, 0]: "a" is in block 1, "b" is in block 1 and "c" is in block 0.

        Examples
        ========

        >>> from sympy.combinatorics.partitions import Partition
        >>> a = Partition([1, 2], [3], [4, 5])
        >>> a.members
        (1, 2, 3, 4, 5)
        >>> a.RGS
        (0, 0, 1, 2, 2)
        >>> a + 1
        {{3}, {4}, {5}, {1, 2}}
        >>> _.RGS
        (0, 0, 1, 2, 3)
        R   (   R   t	   enumerateR   R   R   (   R*   t   rgsR   t   iR   t   jR-   (    (    s=   lib/python2.7/site-packages/sympy/combinatorics/partitions.pyR:   Ï   s    		c         C  s»   t  | ƒ t  | ƒ k r' t d ƒ ‚ n  t | ƒ d } g  t | ƒ D] } g  ^ qD } d } x- | D]% } | | j | | ƒ | d 7} qc Wt d „  | Dƒ ƒ s± t d ƒ ‚ n  t | Œ  S(   s	  
        Creates a set partition from a restricted growth string.

        The indices given in rgs are assumed to be the index
        of the element as given in elements *as provided* (the
        elements are not sorted by this routine). Block numbering
        starts from 0. If any block was not referenced in ``rgs``
        an error will be raised.

        Examples
        ========

        >>> from sympy.combinatorics.partitions import Partition
        >>> Partition.from_rgs([0, 1, 2, 0, 1], list('abcde'))
        {{c}, {a, d}, {b, e}}
        >>> Partition.from_rgs([0, 1, 2, 0, 1], list('cbead'))
        {{e}, {a, c}, {b, d}}
        >>> a = Partition([1, 4], [2], [3, 5])
        >>> Partition.from_rgs(a.RGS, a.members)
        {{2}, {1, 4}, {3, 5}}
        s#   mismatch in rgs and element lengthsi   i    c         s  s   |  ] } | Vq d  S(   N(    (   R   R-   (    (    s=   lib/python2.7/site-packages/sympy/combinatorics/partitions.pys	   <genexpr>  s    s(   some blocks of the partition were empty.(   R   R   t   maxR   t   appendR   R   (   R*   R<   t   elementst   max_elemR=   R   R>   (    (    s=   lib/python2.7/site-packages/sympy/combinatorics/partitions.pyR0   ï   s    N(   t   __name__t
   __module__t   __doc__R'   R8   R,   R   R+   t   propertyR   R4   R5   R6   R7   R)   R:   t   classmethodR0   (    (    (    s=   lib/python2.7/site-packages/sympy/combinatorics/partitions.pyR      s   	%				 t   IntegerPartitionc           B  sw   e  Z d  Z d Z d Z d d „ Z d „  Z d „  Z d „  Z	 e
 d „  ƒ Z d „  Z d „  Z d d	 „ Z d
 „  Z RS(   s  
    This class represents an integer partition.

    In number theory and combinatorics, a partition of a positive integer,
    ``n``, also called an integer partition, is a way of writing ``n`` as a
    list of positive integers that sum to n. Two partitions that differ only
    in the order of summands are considered to be the same partition; if order
    matters then the partitions are referred to as compositions. For example,
    4 has five partitions: [4], [3, 1], [2, 2], [2, 1, 1], and [1, 1, 1, 1];
    the compositions [1, 2, 1] and [1, 1, 2] are the same as partition
    [2, 1, 1].

    See Also
    ========

    sympy.utilities.iterables.partitions,
    sympy.utilities.iterables.multiset_partitions

    Reference: https://en.wikipedia.org/wiki/Partition_%28number_theory%29
    c         C  s„  | d k	 r | | } } n  t | t t f ƒ r® g  } xe t t | j ƒ  ƒ d t ƒD]E \ } } | sn qV n  t | ƒ t | ƒ } } | j	 | g | ƒ qV Wt
 | ƒ } n! t
 t t t | ƒ d t ƒƒ } t } | d k rö t | ƒ } t } n t | ƒ } | r.t | ƒ | k r.t d | ƒ ‚ n  t d „  | Dƒ ƒ rSt d ƒ ‚ n  t j |  | | ƒ } t | ƒ | _ | | _ | S(   sç  
        Generates a new IntegerPartition object from a list or dictionary.

        The partition can be given as a list of positive integers or a
        dictionary of (integer, multiplicity) items. If the partition is
        preceded by an integer an error will be raised if the partition
        does not sum to that given integer.

        Examples
        ========

        >>> from sympy.combinatorics.partitions import IntegerPartition
        >>> a = IntegerPartition([5, 4, 3, 1, 1])
        >>> a
        IntegerPartition(14, (5, 4, 3, 1, 1))
        >>> print(a)
        [5, 4, 3, 1, 1]
        >>> IntegerPartition({1:3, 2:1})
        IntegerPartition(5, (2, 1, 1, 1))

        If the value that the partition should sum to is given first, a check
        will be made to see n error will be raised if there is a discrepancy:

        >>> IntegerPartition(10, [5, 4, 3, 1])
        Traceback (most recent call last):
        ...
        ValueError: The partition is not valid

        t   reverses   Partition did not add to %sc         s  s   |  ] } | d  k  Vq d S(   i   N(    (   R   R=   (    (    s=   lib/python2.7/site-packages/sympy/combinatorics/partitions.pys	   <genexpr>_  s    s"   The summands must all be positive.N(   R'   R   t   dictR   R   R   t   itemst   TrueR   t   extendR   R(   t   FalseR   R   t   anyR   R   R   t   integer(   R   R   RP   t   _t   kt   vt   sum_okR"   (    (    s=   lib/python2.7/site-packages/sympy/combinatorics/partitions.pyR   ,  s0    +!		c         C  sC  t  t ƒ } | j |  j ƒ  ƒ |  j } | d g k rK t i d |  j 6ƒ S| d d k r© | | d c d 8<| d d k rŒ d | d <q3d | | d d <| d <nŠ | | d c d 8<| d | d } | d } d | d <xM | r2| d 8} | | d k ræ | | c | | 7<| | | | 8} qæ qæ Wt |  j | ƒ S(   sŠ  Return the previous partition of the integer, n, in lexical order,
        wrapping around to [1, ..., 1] if the partition is [n].

        Examples
        ========

        >>> from sympy.combinatorics.partitions import IntegerPartition
        >>> p = IntegerPartition([4])
        >>> print(p.prev_lex())
        [3, 1]
        >>> p.partition > p.prev_lex().partition
        True
        i   iÿÿÿÿi   iþÿÿÿi    (   R   t   intt   updatet   as_dictt   _keysRH   RP   (   R*   t   dt   keyst   leftt   new(    (    s=   lib/python2.7/site-packages/sympy/combinatorics/partitions.pyt   prev_lexg  s(    	

	
c         C  sÜ  t  t ƒ } | j |  j ƒ  ƒ |  j } | d } | |  j k r[ | j ƒ  |  j | d <nq| d k rß | | d k rž | | d c d 7<| | c d 8<qÌ| d } | | d c d 7<| | d | | d <d | | <ní | | d k rnt | ƒ d k r1| j ƒ  d | | d <|  j | d | d <qÌ| d } | | c d 7<| | | | | d <d | | <n^ | d } | d } | | c d 7<| | | | | | | } d | | <| | <| | d <t |  j | ƒ S(   s†  Return the next partition of the integer, n, in lexical order,
        wrapping around to [n] if the partition is [1, ..., 1].

        Examples
        ========

        >>> from sympy.combinatorics.partitions import IntegerPartition
        >>> p = IntegerPartition([3, 1])
        >>> print(p.next_lex())
        [4]
        >>> p.partition < p.next_lex().partition
        True
        iÿÿÿÿi   i   iþÿÿÿi    (	   R   RU   RV   RW   RX   RP   t   clearR   RH   (   R*   RY   R   t   at   bt   a1t   b1t   need(    (    s=   lib/python2.7/site-packages/sympy/combinatorics/partitions.pyt   next_lexŒ  s>    	







c         C  s]   |  j  d k rV t |  j d t ƒ} g  | D] } | d ^ q+ |  _ t | ƒ |  _  n  |  j  S(   s[  Return the partition as a dictionary whose keys are the
        partition integers and the values are the multiplicity of that
        integer.

        Examples
        ========

        >>> from sympy.combinatorics.partitions import IntegerPartition
        >>> IntegerPartition([1]*3 + [2] + [3]*4).as_dict()
        {1: 3, 2: 1, 3: 4}
        t   multiplei    N(   t   _dictR'   R   R   RN   RX   RJ   (   R*   t   groupst   g(    (    s=   lib/python2.7/site-packages/sympy/combinatorics/partitions.pyRW   ¾  s
     c         C  sƒ   d } t  |  j ƒ d g } | d } d g | } xI | d k r~ x, | | | k rp | | | d <| d 8} qE W| d 7} q6 W| S(   s  
        Computes the conjugate partition of itself.

        Examples
        ========

        >>> from sympy.combinatorics.partitions import IntegerPartition
        >>> a = IntegerPartition([6, 3, 3, 2, 1])
        >>> a.conjugate
        [5, 4, 3, 1, 1, 1]
        i   i    (   R   R   (   R*   R>   t   temp_arrRR   R`   (    (    s=   lib/python2.7/site-packages/sympy/combinatorics/partitions.pyt	   conjugateÐ  s    
c         C  s(   t  t |  j ƒ ƒ t  t | j ƒ ƒ k  S(   s€  Return True if self is less than other when the partition
        is listed from smallest to biggest.

        Examples
        ========

        >>> from sympy.combinatorics.partitions import IntegerPartition
        >>> a = IntegerPartition([3, 1])
        >>> a < a
        False
        >>> b = a.next_lex()
        >>> a < b
        True
        >>> a == b
        False
        (   R   t   reversedR   (   R*   R1   (    (    s=   lib/python2.7/site-packages/sympy/combinatorics/partitions.pyR7   è  s    c         C  s(   t  t |  j ƒ ƒ t  t | j ƒ ƒ k S(   s   Return True if self is less than other when the partition
        is listed from smallest to biggest.

        Examples
        ========

        >>> from sympy.combinatorics.partitions import IntegerPartition
        >>> a = IntegerPartition([4])
        >>> a <= a
        True
        (   R   Rk   R   (   R*   R1   (    (    s=   lib/python2.7/site-packages/sympy/combinatorics/partitions.pyR6   û  s    t   #c         C  s'   d j  g  |  j D] } | | ^ q ƒ S(   s  
        Prints the ferrer diagram of a partition.

        Examples
        ========

        >>> from sympy.combinatorics.partitions import IntegerPartition
        >>> print(IntegerPartition([1, 1, 5]).as_ferrers())
        #####
        #
        #
        s   
(   t   joinR   (   R*   t   charR=   (    (    s=   lib/python2.7/site-packages/sympy/combinatorics/partitions.pyt
   as_ferrers	  s    c         C  s   t  t |  j ƒ ƒ S(   N(   t   strR   R   (   R*   (    (    s=   lib/python2.7/site-packages/sympy/combinatorics/partitions.pyt   __str__  s    N(   RC   RD   RE   R'   Rf   RX   R   R]   Rd   RW   RF   Rj   R7   R6   Ro   Rq   (    (    (    s=   lib/python2.7/site-packages/sympy/combinatorics/partitions.pyRH     s   ;	%	2			c         C  sß   d d l  m } t |  ƒ }  |  d k  r7 t d ƒ ‚ n  | | ƒ } g  } xS |  d k rž | d |  ƒ } | d |  | ƒ } | j | | f ƒ |  | | 8}  qL W| j d t ƒ t g  | D] \ } } | g | ^ q¹ ƒ } | S(   s  
    Generates a random integer partition summing to ``n`` as a list
    of reverse-sorted integers.

    Examples
    ========

    >>> from sympy.combinatorics.partitions import random_integer_partition

    For the following, a seed is given so a known value can be shown; in
    practice, the seed would not be given.

    >>> random_integer_partition(100, seed=[1, 1, 12, 1, 2, 1, 85, 1])
    [85, 12, 2, 1]
    >>> random_integer_partition(10, seed=[1, 2, 3, 1, 5, 1])
    [5, 3, 1, 1]
    >>> random_integer_partition(1)
    [1]
    iÿÿÿÿ(   t   _randinti   s   n must be a positive integeri    RI   (   t   sympy.utilities.randtestRr   R   R   R@   t   sortRL   R   (   t   nt   seedRr   t   randintR   RR   t   multt   m(    (    s=   lib/python2.7/site-packages/sympy/combinatorics/partitions.pyt   random_integer_partition  s    ,c         C  sÒ   t  |  d ƒ } x+ t d |  d ƒ D] } d | d | f <q$ Wx t d |  d ƒ D]x } xo t |  ƒ D]a } | |  | k r¶ | | | d | f | | d | d f | | | f <qe d | | | f <qe WqR W| S(   sé  
    Computes the m + 1 generalized unrestricted growth strings
    and returns them as rows in matrix.

    Examples
    ========

    >>> from sympy.combinatorics.partitions import RGS_generalized
    >>> RGS_generalized(6)
    Matrix([
    [  1,   1,   1,  1,  1, 1, 1],
    [  1,   2,   3,  4,  5, 6, 0],
    [  2,   5,  10, 17, 26, 0, 0],
    [  5,  15,  37, 77,  0, 0, 0],
    [ 15,  52, 151,  0,  0, 0, 0],
    [ 52, 203,   0,  0,  0, 0, 0],
    [203,   0,   0,  0,  0, 0, 0]])
    i   i    (   R	   R   (   Ry   RY   R=   R>   (    (    s=   lib/python2.7/site-packages/sympy/combinatorics/partitions.pyt   RGS_generalizedC  s    ;c         C  s.   |  d k  r d S|  d k r  d St  |  ƒ Sd S(   sˆ  
    RGS_enum computes the total number of restricted growth strings
    possible for a superset of size m.

    Examples
    ========

    >>> from sympy.combinatorics.partitions import RGS_enum
    >>> from sympy.combinatorics.partitions import Partition
    >>> RGS_enum(4)
    15
    >>> RGS_enum(5)
    52
    >>> RGS_enum(6)
    203

    We can check that the enumeration is correct by actually generating
    the partitions. Here, the 15 partitions of 4 items are generated:

    >>> a = Partition(list(range(4)))
    >>> s = set()
    >>> for i in range(20):
    ...     s.add(a)
    ...     a += 1
    ...
    >>> assert len(s) == 15

    i   i    N(   R   (   Ry   (    (    s=   lib/python2.7/site-packages/sympy/combinatorics/partitions.pyR/   c  s
    c   	      C  s  | d k  r t  d ƒ ‚ n  |  d k  s9 t | ƒ |  k rH t  d ƒ ‚ n  d g | d } d } t | ƒ } xŒ t d | d ƒ D]w } | | | | f } | | } | |  k rÔ | d | | <|  | 8}  | d 7} q t |  | d ƒ | | <|  | ;}  q Wg  | d D] } | d ^ qS(   s  
    Gives the unranked restricted growth string for a given
    superset size.

    Examples
    ========

    >>> from sympy.combinatorics.partitions import RGS_unrank
    >>> RGS_unrank(14, 4)
    [0, 1, 2, 3]
    >>> RGS_unrank(0, 4)
    [0, 0, 0, 0]
    i   s   The superset size must be >= 1i    s   Invalid argumentsi   (   R   R/   R{   R   RU   (	   R)   Ry   t   LR>   t   DR=   RS   t   crR!   (    (    s=   lib/python2.7/site-packages/sympy/combinatorics/partitions.pyR.   ˆ  s"    

c         C  sƒ   t  |  ƒ } d } t | ƒ } x^ t d | ƒ D]M } t  |  | d ƒ } t |  d | !ƒ } | | | | d f |  | 7} q. W| S(   sð   
    Computes the rank of a restricted growth string.

    Examples
    ========

    >>> from sympy.combinatorics.partitions import RGS_rank, RGS_unrank
    >>> RGS_rank([0, 1, 2, 1, 3])
    42
    >>> RGS_rank(RGS_unrank(4, 7))
    4
    i    i   (   R   R{   R   R?   (   R<   t   rgs_sizeR)   R}   R=   Ru   Ry   (    (    s=   lib/python2.7/site-packages/sympy/combinatorics/partitions.pyR9   «  s    $N(   t
   __future__R    R   t
   sympy.coreR   R   R   t   sympy.core.compatibilityR   R   R   t%   sympy.functions.combinatorial.numbersR   t   sympy.matricesR	   t   sympy.sets.setsR
   t   sympy.utilities.iterablesR   R   R   t   collectionsR   R   RH   R'   Rz   R{   R/   R.   R9   (    (    (    s=   lib/python2.7/site-packages/sympy/combinatorics/partitions.pyt   <module>   s    ÿ ÿ 
'	 	%	#