Ticket #11411: trac_11411-correction_q_analogues_fc.patch

File trac_11411-correction_q_analogues_fc.patch, 6.7 KB (added by chapoton, 9 years ago)

folded review patch and minor change in qt-catalan

  • sage/combinat/q_analogues.py

    # HG changeset patch
    # User Frederic Chapoton <chapoton at math.univ-lyon1.fr>
    # Date 1307044885 -7200
    # Node ID b1724e72c36076c0c22e20cc62b8eb42d5979b9a
    # Parent  42904573cc300e7d25bd5cc5f5db75c45de82e14
    #11411 changes in q-analogues
    
    * restricts the q-factorial to nonnegative integers
    
    * restricts the q-binomial to nonnegative top argument
    
    * little speed-up of q-binomial
    
    * new function q_catalan
    * * *
    #11411: Review patch for q-analogue fix.
    
    diff --git a/sage/combinat/q_analogues.py b/sage/combinat/q_analogues.py
    a b from dyck_word import DyckWords 
    2222
    2323def q_int(n, p=None):
    2424    """
    25     Returns the q-analogue of the integer n.
    26    
    27     If p is unspecified, then it defaults to using the generator q for
     25    Returns the ``q``-analogue of the integer ``n``.
     26
     27    If ``p`` is unspecified, then it defaults to using the generator ``q`` for
    2828    a univariate polynomial ring over the integers.
    29    
     29
    3030    EXAMPLES::
    31    
     31
    3232        sage: import sage.combinat.q_analogues as q_analogues
    3333        sage: q_analogues.q_int(3)
    3434        q^2 + q + 1
    3535        sage: p = ZZ['p'].0
    3636        sage: q_analogues.q_int(3,p)
    3737        p^2 + p + 1
     38
     39    The ``q``-analogue of ``n`` is only defined for ``n`` a nonnegative
     40    integer (trac #11411)::
     41
     42        sage: q_analogues.q_int(-2)
     43        Traceback (most recent call last):
     44        ...
     45        ValueError: Argument (-2) must be a nonnegative integer.
    3846    """
    39     if p == None:
    40         p = ZZ['q'].gens()[0]
    41         #pass
    42     return sum([p**i for i in range(n)])
     47    if n in ZZ and n >= 0:
     48        if p == None:
     49            p = ZZ['q'].gens()[0]
     50        return sum([p**i for i in range(n)])
     51    else:
     52        raise ValueError, "Argument (%s) must be a nonnegative integer." %n
    4353
    4454def q_factorial(n, p=None):
    4555    """
    46     Returns the q-analogue of the n!.
    47    
    48     If p is unspecified, then it defaults to using the generator q for
     56    Returns the ``q``-analogue of the factorial ``n!``.
     57
     58    If ``p`` is unspecified, then it defaults to using the generator ``q`` for
    4959    a univariate polynomial ring over the integers.
    50    
     60
    5161    EXAMPLES::
    52    
     62
    5363        sage: import sage.combinat.q_analogues as q_analogues
    5464        sage: q_analogues.q_factorial(3)
    5565        q^3 + 2*q^2 + 2*q + 1
    5666        sage: p = ZZ['p'].0
    5767        sage: q_analogues.q_factorial(3, p)
    5868        p^3 + 2*p^2 + 2*p + 1
     69
     70    The ``q``-analogue of ``n!`` is only defined for ``n`` a nonnegative
     71    integer (trac #11411)::
     72
     73        sage: q_analogues.q_factorial(-2)
     74        Traceback (most recent call last):
     75        ...
     76        ValueError: Argument (-2) must be a nonnegative integer.
    5977    """
    60     return prod([q_int(i,p) for i in range(1, n+1)])
     78    if n in ZZ and n >= 0:
     79        return prod([q_int(i, p) for i in range(1, n+1)])
     80    else:
     81        raise ValueError, "Argument (%s) must be a nonnegative integer." %n
    6182
    6283def q_binomial(n,k,p=None):
    6384    """
    64     Returns the q-binomial coefficient.
    65    
    66     If p is unspecified, then it defaults to using the generator q for
     85    Returns the ``q``-binomial coefficient.
     86
     87    If ``p`` is unspecified, then it defaults to using the generator ``q`` for
    6788    a univariate polynomial ring over the integers.
    68    
     89
    6990    EXAMPLES::
    70    
     91
    7192        sage: import sage.combinat.q_analogues as q_analogues
    7293        sage: q_analogues.q_binomial(4,2)
    7394        q^4 + q^3 + 2*q^2 + q + 1
    7495        sage: p = ZZ['p'].0
    7596        sage: q_analogues.q_binomial(4,2,p)
    7697        p^4 + p^3 + 2*p^2 + p + 1
     98
     99    The ``q``-analogue of ``binomial(n,k)`` is currently only defined for
     100    ``n`` a nonnegative integer, it is zero for negative k  (trac #11411)::
     101
     102        sage: q_analogues.q_binomial(5, -1)
     103        0
    77104    """
     105    if not (n in ZZ and k in ZZ):
     106        raise ValueError, "Argument (%s, %s) must be integers."%(n, k)
     107    if n < 0:
     108        raise NotImplementedError
     109    if 0 <= k and k <= n:
     110        k=min(k, n-k)
     111        return (prod(q_int(j, p) for j in range(n-k+1, n+1)) /
     112                prod(q_int(j, p) for j in range(1, k+1)))
     113    else:
     114        return 0
    78115
    79     return q_factorial(n,p)/(q_factorial(k,p)*q_factorial(n-k,p))
     116def q_catalan_number(n,p=None):
     117    """
     118    Returns the ``q``-Catalan number of index ``n``.
    80119
     120    If ``p`` is unspecified, then it defaults to using the generator ``q`` for
     121    a univariate polynomial ring over the integers.
     122
     123    There are several ``q``-Catalan numbers. This procedure
     124    returns the one which can be written using the ``q``-binomial coefficients.
     125
     126    EXAMPLES::
     127
     128        sage: import sage.combinat.q_analogues as q_analogues
     129        sage: q_analogues.q_catalan_number(4)
     130        q^12 + q^10 + q^9 + 2*q^8 + q^7 + 2*q^6 + q^5 + 2*q^4 + q^3 + q^2 + 1
     131        sage: p = ZZ['p'].0
     132        sage: q_analogues.q_catalan_number(4,p)
     133        p^12 + p^10 + p^9 + 2*p^8 + p^7 + 2*p^6 + p^5 + 2*p^4 + p^3 + p^2 + 1
     134
     135    The ``q``-Catalan number of index ``n`` is only defined for ``n`` a
     136    nonnegative integer (trac #11411)::
     137
     138        sage: q_analogues.q_catalan_number(-2)
     139        Traceback (most recent call last):
     140        ...
     141        ValueError: Argument (-2) must be a nonnegative integer.
     142    """
     143    if n in ZZ and n >= 0:
     144        return prod(q_int(j, p) for j in range(n+2, 2*n+1)) / prod(q_int(j, p) for j in range(2,n+1))
     145    else:
     146        raise ValueError, "Argument (%s) must be a nonnegative integer." %n
    81147
    82148def qt_catalan_number(n):
    83149    """
    84     Returns the q,t-Catalan number.
    85    
     150    Returns the ``q,t``-Catalan number of index ``n``.
     151
    86152    EXAMPLES::
    87    
     153
    88154        sage: import sage.combinat.q_analogues as q_analogues
    89155        sage: q_analogues.qt_catalan_number(1)
    90156        1
    def qt_catalan_number(n): 
    94160        q^3 + q^2*t + q*t^2 + t^3 + q*t
    95161        sage: q_analogues.qt_catalan_number(4)
    96162        q^6 + q^5*t + q^4*t^2 + q^3*t^3 + q^2*t^4 + q*t^5 + t^6 + q^4*t + q^3*t^2 + q^2*t^3 + q*t^4 + q^3*t + q^2*t^2 + q*t^3
     163
     164    The ``q,t``-Catalan number of index ``n`` is only defined for ``n`` a
     165    nonnegative integer (trac #11411)::
     166
     167        sage: q_analogues.qt_catalan_number(-2)
     168        Traceback (most recent call last):
     169        ...
     170        ValueError: Argument (-2) must be a nonnegative integer.
    97171    """
    98     ZZqt = ZZ['q','t']
     172    if n in ZZ and n >= 0:
     173        ZZqt = ZZ['q','t']
     174        d = {}
     175        for dw in DyckWords(n):
     176            tup = (dw.a_statistic(),dw.b_statistic())
     177            d[tup] = d.get(tup,0)+1
     178        return ZZqt(d)
     179    else:
     180        raise ValueError, "Argument (%s) must be a nonnegative integer." %n
    99181
    100     d = {}
    101     for dw in DyckWords(n):
    102         tup = (dw.a_statistic(),dw.b_statistic())
    103         d[tup] = d.get(tup,0)+1
    104     return ZZqt(d)