[Numpy-discussion] arange(start, stop, step) and floating point (Ticket #8)

Tim Hochberg tim.hochberg at cox.net
Thu Feb 9 09:47:14 EST 2006


Travis Oliphant wrote:

> Tim Hochberg wrote:
>
>>>
>>
>>
>> I see that Travis has vetoed this in any event, but perhaps we should 
>> fix up the fill functions to be more accurate and maybe most of the 
>> problem would just magically go away.
>
>
>
> To do something different than arange has always done we need a new 
> function, not change what arange does and thus potentially break lots 
> of code.
>
> How do you propose to make the fill funtions more accurate?   I'm 
> certainly willing to see improvements there.

OK, I experimented with. I replaced the code for @NAME at _fill in 
arraytypes.inc.src with:

    /**begin repeat
    #NAME=BYTE,UBYTE,SHORT,USHORT,INT,UINT,LONG,ULONG,LONGLONG,ULONGLONG,FLOAT,DOUBLE,LONGDOUBLE#
    #typ=byte,ubyte,short,ushort,int,uint,long,ulong,longlong,ulonglong,float,double,longdouble#
    */
    static void
    @NAME at _fill(@typ@ *buffer, intp length, void *ignored)
    {
        intp i;   
        @typ@ start = buffer[0];
        @typ@ delta = buffer[1];
        delta -= start;
        buffer += 2;
        for (i=2; i<length; i++, buffer++) {
                    *buffer = start + i*delta;
        }
    }
    /**end repeat**/


I characterized the change with the little attached benchmark. Before 
the change the output was:

    arange(0, 100.65000000000001, 0.14999999999999999) failed 100.65 >=
    100.65
    arange(0, 100.68000000000001, 0.12) failed 100.68 >= 100.68
    arange(0, 100.65000000000001, 0.074999999999999997) failed 100.65 >=
    100.65
    arange(0, 100.26000000000001, 0.059999999999999998) failed 100.26 >=
    100.26
    arange(0, 100.62, 0.059999999999999998) failed 100.62 >= 100.62
    arange(0, 100.68000000000001, 0.059999999999999998) failed 100.68 >=
    100.68
    arange(0, 100.98, 0.059999999999999998) failed 100.98 >= 100.98
    arange(0, 100.5, 0.031914893617021274) failed 100.5 >= 100.5

    arange(10000) took 2.25123220968 seconds for 100000 reps
    arange(10000.0) took 4.31864636427 seconds for 100000 reps


After the change:

    arange(10000) took 1.82795662577 seconds for 100000 reps
    arange(10000.0) took 3.93278363591 seconds for 100000 reps



That is, not only did all of the incorrect end cases go away, it 
actually got marginally faster. Why it got faster I can't say, there's 
not much to be gained in second guessing an optimizing compiler. It's 
quite possible that this may be compiler dependant, so I'd be interested 
in the results with other compilers. Also, I only sampled a small chunk 
of the input space of arange, so if you have some other failing input 
values, please send them to me and I can test them and see if this 
change fixes them also.

I didn't mess with the complex version of fill yet. Is that just there 
to support arange(0, 100, 2, dtype=complex), or is there some other use 
for _fill besides arange?

Regards,

-tim




-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: testarange.py
URL: <http://mail.python.org/pipermail/numpy-discussion/attachments/20060209/8ddf07e3/attachment.ksh>


More information about the NumPy-Discussion mailing list