Ticket #13215: trac_13640_qjordan.patch

File trac_13640_qjordan.patch, 5.1 KB (added by caruso, 9 years ago)
  • sage/combinat/q_analogues.py

    # HG changeset patch
    # User Xavier Caruso <xavier.caruso@normalesup.org>
    # Date 1343377665 -7200
    # Node ID 3200ac91ff9f0efa532024e19a32fd2cb196d7f2
    # Parent  bfb3aa49bd8a5394d2d7bdd8f0d495437b17f5fe
    imported patch skewpolynomials
    
    diff --git a/sage/combinat/q_analogues.py b/sage/combinat/q_analogues.py
    a b  
    4949            p = ZZ['q'].gens()[0]
    5050        return sum([p**i for i in range(n)])
    5151    else:
    52         raise ValueError, "Argument (%s) must be a nonnegative integer." %n
     52        raise ValueError("Argument (%s) must be a nonnegative integer." %n)
    5353
    5454def q_factorial(n, p=None):
    5555    """
     
    7878    if n in ZZ and n >= 0:
    7979        return prod([q_int(i, p) for i in range(1, n+1)])
    8080    else:
    81         raise ValueError, "Argument (%s) must be a nonnegative integer." %n
     81        raise ValueError("Argument (%s) must be a nonnegative integer." %n)
    8282
    8383def q_binomial(n,k,p=None):
    8484    """
     
    113113        0
    114114    """
    115115    if not (n in ZZ and k in ZZ):
    116         raise ValueError, "Argument (%s, %s) must be integers."%(n, k)
     116        raise ValueError("Argument (%s, %s) must be integers."%(n, k))
    117117    if n < 0:
    118118        raise NotImplementedError
    119119    if 0 <= k and k <= n:
     
    156156    if n in ZZ and n >= 0:
    157157        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))
    158158    else:
    159         raise ValueError, "Argument (%s) must be a nonnegative integer." %n
     159        raise ValueError("Argument (%s) must be a nonnegative integer." %n)
    160160
    161161def qt_catalan_number(n):
    162162    """
     
    190190            d[tup] = d.get(tup,0)+1
    191191        return ZZqt(d)
    192192    else:
    193         raise ValueError, "Argument (%s) must be a nonnegative integer." %n
     193        raise ValueError("Argument (%s) must be a nonnegative integer." %n)
    194194
     195dict_jordan = { }
     196def q_jordan(t,q):
     197    """
     198    INPUT:
     199
     200    -  ``t`` -- a list of nonnegative integers sorted in
     201       decreasing order
     202
     203    -  ``q`` -- an integer greater than `1`
     204
     205    OUTPUT:
     206
     207    The number of complete flags in `F_q^N` (where `N` is the
     208    sum of the entries in `t`) stable under a linear nilpotent
     209    endomorphism `f` whose Jordan type is `t`, i.e. such that
     210    for all `i`::
     211
     212    .. MATH::
     213
     214        \dim (\ker f^i) = t[0] + \cdots + t[i-1]
     215
     216    The result is cached.
     217
     218    .. NOTE::
     219
     220        This works even if `q` is not a power a prime number.
     221        (There is a formula for the number we are computing
     222        from which we get a nice interpolation working for all
     223        integer `q > 1`).
     224
     225    EXAMPLES::
     226
     227        sage: from sage.combinat.q_analogues import q_jordan
     228        sage: q_jordan([7,5,3,1],2)
     229        779380858243664667
     230
     231    If `t` is a singleton, we get the `q`-factorial (in this case,
     232    the nilpotent endomorphism is `0`)::
     233
     234        sage: from sage.combinat.q_analogues import q_factorial
     235        sage: q_jordan([5],3) == q_factorial(5,3)
     236        True
     237        sage: q_jordan([11],5) == q_factorial(11,5)
     238        True
     239
     240    TESTS::
     241
     242        sage: q_jordan(2,3)
     243        Traceback (most recent call last):
     244        ...
     245        ValueError: t must be a list
     246
     247        sage: q_jordan([1,2],3)
     248        Traceback (most recent call last):
     249        ...
     250        ValueError: t must be a list of nonnegative integers sorted in decreasing order
     251
     252        sage: q_jordan([1,-1],3)
     253        Traceback (most recent call last):
     254        ...
     255        ValueError: t must be a list of nonnegative integers sorted in decreasing order
     256
     257        sage: q_jordan([4,3,1],3.2)
     258        Traceback (most recent call last):
     259        ...
     260        ValueError: q must be an integer > 1
     261
     262    AUTHOR:
     263
     264    - Xavier Caruso (2012-06-29)
     265    """
     266    if not isinstance(t,list):
     267        raise ValueError("t must be a list")
     268    l = list(t)
     269    l.reverse()
     270    prevn = 0
     271    for n in l:
     272        if not (n in ZZ and n >= 0 and n >= prevn):
     273            raise ValueError("t must be a list of nonnegative integers sorted in decreasing order")
     274        prevn = n
     275    if not (q in ZZ and q > 1):
     276        raise ValueError("q must be an integer > 1")
     277    while len(l) > 0:
     278        if l[0] <= 0:
     279            del l[0]
     280        else:
     281            break
     282    try:
     283        dict = dict_jordan[q]
     284    except KeyError:
     285        dict = dict_jordan[q] = { (): 1 }
     286        return _q_jordan(dict,l,q)
     287    try:
     288        return dict[tuple(l)]
     289    except:
     290        return _q_jordan(dict,l,q)
     291
     292def _q_jordan(dict,t,q):
     293    tj = 0
     294    res = 0
     295    for i in range(len(t)):
     296        ti = t[i]
     297        if ti > tj:
     298            if ti == 1:
     299                tp = t[1:]
     300                try:
     301                    res += dict[tuple(tp)]
     302                except KeyError:
     303                    res += _q_jordan(dict,tp,q)
     304            else:
     305                tp = list(t)
     306                tp[i] -= 1
     307                c = (q**ti - q**tj) / (q-1)
     308                try:
     309                    res += dict[tuple(tp)] * c
     310                except KeyError:
     311                    res += _q_jordan(dict,tp,q) * c
     312            tj = ti
     313    dict[tuple(t)] = res
     314    return res