Ticket #2737: 2737.patch

File 2737.patch, 5.1 KB (added by mhansen, 2 years ago)
  • sage/misc/all.py

    # HG changeset patch
    # User Mike Hansen <mhansen@gmail.com>
    # Date 1206963896 25200
    # Node ID 05d044a79146ec63c45153a0e9bc1e60a466634f
    # Parent  258da00fdef8602f670a0a7065b7256f44628be8
    [mq]: fast_sum
    
    diff -r 258da00fdef8 -r 05d044a79146 sage/misc/all.py
    a b  
    33                  get_verbose_files, unset_verbose_files, get_verbose,  
    44                  version, banner, add, union, uniq, powerset, subsets, 
    55                  exists, forall,  
    6                   random_sublist, mul, prod, walltime, generic_cmp, 
     6                  random_sublist, mul, prod, balanced_sum, walltime, generic_cmp, 
    77                  repr_lincomb, tmp_dir, tmp_filename, 
    88                  pad_zeros, 
    99                  DOT_SAGE, SAGE_ROOT, SAGE_URL, SAGE_DB, SAGE_TMP, 
  • sage/misc/misc.py

    diff -r 258da00fdef8 -r 05d044a79146 sage/misc/misc.py
    a b  
    361361        if c: return c 
    362362    return 0 
    363363 
    364 from sage.misc.misc_c import prod, running_total 
     364from sage.misc.misc_c import prod, running_total, balanced_sum 
    365365 
    366366# alternative name for prod 
    367367mul = prod 
  • sage/misc/misc_c.pyx

    diff -r 258da00fdef8 -r 05d044a79146 sage/misc/misc_c.pyx
    a b  
    117117        prod = z*prod 
    118118         
    119119    return prod 
    120      
     120 
     121 
    121122 
    122123cdef balanced_list_prod(L, Py_ssize_t offset, Py_ssize_t count, Py_ssize_t cutoff): 
    123124    """ 
     
    149150        k = (1+count) >> 1 
    150151        return balanced_list_prod(L, offset, k, cutoff) * balanced_list_prod(L, offset+k, count-k, cutoff) 
    151152 
     153 
     154def balanced_sum(x, z=None, Py_ssize_t recursion_cutoff = 5): 
     155    """ 
     156    Return the sum of the elements in the list x.  If optional 
     157    argument z is not given, start the sum with the first element 
     158    of the list, otherwise use z.  The empty product is the int 0 if z 
     159    is not specified, and is z if given. 
     160 
     161    This assumes that your multiplication is associative; we don't promise  
     162    which end of the list we start at. 
     163 
     164    EXAMPLES: 
     165        sage: balanced_sum([1,2,34]) 
     166        37 
     167        sage: balanced_sum([2,3], 5) 
     168        10 
     169        sage: balanced_sum((1,2,3), 5) 
     170        11 
     171 
     172    AUTHORS: 
     173        Joel B. Mohler (2007-10-03 -- Reimplemented in Cython and optimized) 
     174        Robert Bradshaw (2007-10-26) -- Balanced product tree, other optimizations, (lazy) generator support 
     175    """ 
     176    if not PyList_CheckExact(x) and not PyTuple_CheckExact(x): 
     177     
     178        if PyGen_Check(x): 
     179            # lazy list, do lazy product 
     180            try: 
     181                sum = x.next() if z is None else z * x.next() 
     182                for a in x: 
     183                    sum += a 
     184                return sum 
     185            except StopIteration: 
     186                x = [] 
     187                 
     188        else: 
     189     
     190            try: 
     191                return x.sum() 
     192            except AttributeError: 
     193                pass 
     194 
     195            x = list(x) 
     196 
     197    cdef Py_ssize_t n = len(x) 
     198 
     199    if n == 0: 
     200        if z is None: 
     201            import sage.rings.integer 
     202            return sage.rings.integer.Integer(0) 
     203        else: 
     204            return z 
     205     
     206    sum = balanced_list_sum(x, 0, n, recursion_cutoff) 
     207     
     208    if z is not None: 
     209        sum = z+sum 
     210         
     211    return sum 
     212 
     213cdef balanced_list_sum(L, Py_ssize_t offset, Py_ssize_t count, Py_ssize_t cutoff): 
     214    """ 
     215    INPUT:  
     216        L      -- the terms (MUST be a tuple or list) 
     217        off    -- offset in the list from which to start 
     218        count  -- how many terms in the product 
     219        cutoff -- the minimum count to recurse on 
     220         
     221    OUTPUT:  
     222        L[offset] + L[offset+1] + ... + L[offset+count-1] 
     223     
     224    NOTE: The parameter cutoff must be at least 1, and there is no reason to 
     225          ever make it less than 3. However, there are at least two advantages 
     226          to setting it higher (and consequently not recursing all the way  
     227          down the tree). First, one avoids the overhead of the function  
     228          calls at the base of the tree (which is the majority of them) and  
     229          second, it allows one to save on object creation if inplace 
     230          operations are used. The asymptotic gains should usually be at the  
     231          top of the tree anyway. 
     232    """ 
     233    cdef Py_ssize_t k 
     234    if count <= cutoff: 
     235        sum = <object>PySequence_Fast_GET_ITEM(L, offset) 
     236        for k from offset < k < offset+count: 
     237            sum += <object>PySequence_Fast_GET_ITEM(L, k) 
     238        return sum 
     239    else: 
     240        k = (1+count) >> 1 
     241        return balanced_list_sum(L, offset, k, cutoff) + balanced_list_sum(L, offset+k, count-k, cutoff) 
    152242 
    153243class NonAssociative: 
    154244    """ 
     
    205295            (a*(b*c)) 
    206296        """ 
    207297        return NonAssociative(self, other) 
    208          
    209  No newline at end of file 
     298