Changeset 6448:1b6661884ccf


Ignore:
Timestamp:
09/20/07 16:01:22 (6 years ago)
Author:
Robert Bradshaw <robertwb@…>
Branch:
default
Message:

Fast range function for integers

Location:
sage
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • sage/misc/misc.py

    r6447 r6448  
    622622     
    623623################################################################# 
    624 # Used for [1,2,..,n] notation.  
     624# Ranges and [1,2,..,n] notation.  
    625625################################################################# 
    626626 
     
    635635        return range(start, end, step) 
    636636    elif universe is ZZ: 
    637         return srange(start, end, step) 
     637        return ZZ.range(start, end, step) 
    638638    else: 
    639639        L = [] 
     640        if (end-start)/step <= 0: 
     641            return L 
    640642        while start < end: 
    641643            L.append(start) 
     
    656658        return xsrange(start, end, step) 
    657659    else: 
    658         L = [] 
    659         while start < end: 
    660             L.append(start) 
    661             start += step 
    662         return L 
     660        return generic_xurange(start, end, step) 
    663661         
    664662def generic_xurange(start, end, step): 
     663    if (end-start)/step <= 0: 
     664        return 
    665665    while start < end: 
    666666        yield start 
  • sage/rings/integer_ring.pyx

    r6014 r6448  
     1 
    12r""" 
    23\protect{Ring $\Z$ of Integers} 
     
    6263include "../ext/random.pxi" 
    6364 
     65include "../ext/python_int.pxi" 
     66include "../ext/python_list.pxi" 
     67 
    6468import sage.rings.infinity 
    6569import sage.rings.rational 
     
    218222                pass 
    219223        raise TypeError, msg 
     224         
     225    def range(self, start, end=None, step=None): 
     226        """ 
     227        Optimized range function for SAGE integer.  
     228         
     229        AUTHOR:  
     230          -- Robert Bradshaw (2007-09-20) 
     231         
     232        EXAMPLES:  
     233            sage: ZZ.range(10) 
     234            [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 
     235            sage: ZZ.range(-5,5) 
     236            [-5, -4, -3, -2, -1, 0, 1, 2, 3, 4] 
     237            sage: ZZ.range(0,50,5) 
     238            [0, 5, 10, 15, 20, 25, 30, 35, 40, 45] 
     239            sage: ZZ.range(0,50,-5) 
     240            [] 
     241            sage: ZZ.range(50,0,-5) 
     242            [50, 45, 40, 35, 30, 25, 20, 15, 10, 5] 
     243            sage: ZZ.range(50,0,5) 
     244            [] 
     245            sage: ZZ.range(50,-1,-5) 
     246            [50, 45, 40, 35, 30, 25, 20, 15, 10, 5, 0] 
     247             
     248        It uses different code if the step doesn't fit in a long:  
     249            sage: ZZ.range(0,2^83,2^80) 
     250            [0, 1208925819614629174706176, 2417851639229258349412352, 3626777458843887524118528, 4835703278458516698824704, 6044629098073145873530880, 7253554917687775048237056, 8462480737302404222943232] 
     251        """ 
     252        if end is None: 
     253            end = start 
     254            start = PY_NEW(Integer) # 0 
     255        if step is None: 
     256            step = 1 
     257        if not PyInt_CheckExact(step): 
     258            if not PY_TYPE_CHECK(step, integer.Integer): 
     259                step = integer.Integer(step) 
     260            if mpz_fits_slong_p((<Integer>step).value): 
     261                step = int(step) 
     262        if not PY_TYPE_CHECK(start, integer.Integer): 
     263            start = integer.Integer(start) 
     264        if not PY_TYPE_CHECK(end, integer.Integer): 
     265            start = integer.Integer(end) 
     266        cdef integer.Integer a = <Integer>start 
     267        cdef integer.Integer b = <Integer>end 
     268         
     269        cdef int step_sign 
     270        cdef long istep 
     271        cdef integer.Integer zstep, last 
     272         
     273        L = [] 
     274        if PyInt_CheckExact(step): 
     275            istep = PyInt_AS_LONG(step) 
     276            step_sign = istep 
     277        else: 
     278            zstep = <Integer>step 
     279            step_sign = mpz_sgn(zstep.value) 
     280             
     281        _sig_on 
     282        while mpz_cmp(a.value, b.value)*step_sign < 0: 
     283            last = a 
     284            a = PY_NEW(Integer) 
     285            if PyInt_CheckExact(step): # count on branch prediction... 
     286                if istep > 0: 
     287                    mpz_add_ui(a.value, last.value, istep) 
     288                else: 
     289                    mpz_sub_ui(a.value, last.value, -istep) 
     290            else: 
     291                mpz_add(a.value, last.value, zstep.value) 
     292            PyList_Append(L, last) 
     293        _sig_off 
     294        return L 
    220295 
    221296    def __iter__(self): 
Note: See TracChangeset for help on using the changeset viewer.