473,388 Members | 1,526 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,388 software developers and data experts.

Generalized range

I need to create ranges that can start and end with real numbers.
Searching this newsgroup brought me to a function that I then modified
as follows:

def myRange(iMin, iMax=None, iStep=1):
"""Extends range to real numbers. Wherever possible, use Python's
range .
In other cases, make the behavior follow the spirit of Python's
range """
epsilon = 1.e-8

if iMax == None and iStep == 1:
return range(int(iMin))

elif type(iMin).__name__.lower() in ('int', 'long') and \
type(iMax).__name__.lower() in ('int', 'long') and \
type(iStep).__name__.lower() in ('int', 'long') and iStep !=
0:
return range( iMin, iMax, iStep)

elif iMin <= iMax and iStep 0:
return [ iMin+i*iStep for i in range( int(math.ceil((iMax -
iMin - epsilon)/iStep)) )]

elif iMin >= iMax and iStep < 0:
return [ iMin+i*iStep for i in range(-int(math.ceil((iMin -
iMax + epsilon)/iStep)) )]

else:
raise ValueError, 'Cannot construct a range with steps of size
' + str(iStep) + ' between ' + str(iMin) + ' and ' + str(iMax)
The one part of my implementation that has me a bit queasy (i.e.
works in my current application, but I can see it misbehaving
elsewhere) is the addition/subtraction of a fixed epsilon to ensure
that my rounding goes the right way. A clean implementation would
modify epsilon based on the achievable level of precision given the
particular values of iMax, iMin and iStep. I suspect this requires a
detailed understanding of the implementation of floating point
arithmetic, and would appreciate hearing any thoughts you might have
on gilding this lily.

Sincerely

Thomas Philips

Apr 26 '07 #1
8 1874
tk****@hotmail.com schrieb:
I need to create ranges that can start and end with real numbers.
Searching this newsgroup brought me to a function that I then modified
as follows:

def myRange(iMin, iMax=None, iStep=1):
Just as a sidenote: it is not common to prefix your names with its type.
It could change at any time and min, max, step would be clear, too. IMO.
"""Extends range to real numbers. Wherever possible, use Python's
range .
In other cases, make the behavior follow the spirit of Python's
range """
If you want to stick to the "normal" range-implementation, myRange
should consider an one-argument-call as transmission of iMax.
epsilon = 1.e-8
I can't really say if your attempt using an epsilon-environment is good.
I think just increasing a "counter" from iMin to iMax should be fine,
achieving more precision by making computations fuzzy -- i don't know,
perhaps it's very good. I wouldn't do it.
If you like to care about precision, you should have a look at the
`decimal module <http://docs.python.org/lib/module-decimal.html>`_.
>
if iMax == None and iStep == 1:
return range(int(iMin))

elif type(iMin).__name__.lower() in ('int', 'long') and \
type(iMax).__name__.lower() in ('int', 'long') and \
type(iStep).__name__.lower() in ('int', 'long') and iStep !=
0:
return range( iMin, iMax, iStep)
Ouchie! *That* is a bad one. Checking for a name of an object is neither
safe nor good nor common. A better way would be directly comparing
type(yourobject) with int/long/float/anytype. See
http://docs.python.org/lib/comparisons.html for details on comparisons.
Another way of type-checking in python is doing something like ``if
isinstance(iMin, (int, long))``. Would work for subclasses, too.
>
elif iMin <= iMax and iStep 0:
return [ iMin+i*iStep for i in range( int(math.ceil((iMax -
iMin - epsilon)/iStep)) )]

elif iMin >= iMax and iStep < 0:
return [ iMin+i*iStep for i in range(-int(math.ceil((iMin -
iMax + epsilon)/iStep)) )]
Will eat your memory. See below.
else:
raise ValueError, 'Cannot construct a range with steps of size
' + str(iStep) + ' between ' + str(iMin) + ' and ' + str(iMax)
In Python, it is common to use string interpolation instead. Like::
print 'Hello from %d to %d' % (iMin, iMax)
Read `String Formatting Operations
<http://docs.python.org/lib/typesseq-strings.html>`_ in the manual for
details.
>

The one part of my implementation that has me a bit queasy (i.e.
works in my current application, but I can see it misbehaving
elsewhere) is the addition/subtraction of a fixed epsilon to ensure
that my rounding goes the right way. A clean implementation would
modify epsilon based on the achievable level of precision given the
particular values of iMax, iMin and iStep. I suspect this requires a
detailed understanding of the implementation of floating point
arithmetic,
I think so, too. That's why it is a bad idea, IMO.
and would appreciate hearing any thoughts you might have
on gilding this lily.

Sincerely

Thomas Philips
I'd recommend you to have a look into `generators
<http://docs.python.org/ref/yield.html>`_, it is what `xrange
<http://docs.python.org/lib/built-in-funcs.html#l2h-80>`_ uses. You
don't put all numbers into your memory ("precompute them") but behave a
little bit lazy and compute them whenever the user needs the next one. I
expect Google to have lots of example implementations of range as a
generator in python for you. :-)

HTH,
Stargaming
Apr 26 '07 #2
tk****@hotmail.com wrote:
I need to create ranges that can start and end with real numbers.
Searching this newsgroup brought me to a function that I then modified
as follows:

def myRange(iMin, iMax=None, iStep=1):
"""Extends range to real numbers. Wherever possible, use Python's
range .
In other cases, make the behavior follow the spirit of Python's
range """
epsilon = 1.e-8

if iMax == None and iStep == 1:
return range(int(iMin))

elif type(iMin).__name__.lower() in ('int', 'long') and \
type(iMax).__name__.lower() in ('int', 'long') and \
type(iStep).__name__.lower() in ('int', 'long') and iStep !=
0:
return range( iMin, iMax, iStep)

elif iMin <= iMax and iStep 0:
return [ iMin+i*iStep for i in range( int(math.ceil((iMax -
iMin - epsilon)/iStep)) )]

elif iMin >= iMax and iStep < 0:
return [ iMin+i*iStep for i in range(-int(math.ceil((iMin -
iMax + epsilon)/iStep)) )]

else:
raise ValueError, 'Cannot construct a range with steps of size
' + str(iStep) + ' between ' + str(iMin) + ' and ' + str(iMax)
The one part of my implementation that has me a bit queasy (i.e.
works in my current application, but I can see it misbehaving
elsewhere) is the addition/subtraction of a fixed epsilon to ensure
that my rounding goes the right way. A clean implementation would
modify epsilon based on the achievable level of precision given the
particular values of iMax, iMin and iStep. I suspect this requires a
detailed understanding of the implementation of floating point
arithmetic, and would appreciate hearing any thoughts you might have
on gilding this lily.
In addition to the comments of Stargaming, most of which I agree with, I
think you would be far better dropping the epsilon business and doing
something like:

# requires that minimum <= maximum; swap values if necessary
res = minimum
while res < maximum:
yield res
res += step
--
Michael Hoffman
Apr 26 '07 #3
Thanks - you have covered a fair bit of gorund here - I will modify
myRange taking your suggestions into account. The one suggestion that
I'm going to have to think through is repeatedly incrementing res.

I deliberately did not use this as repeated addition can cause
rounding errors to accumulate, making the loop run a little longer or
shorter than necessary. I thought I would be far less likely to run
into rounding issues with a multiplicative construct - hence my use of
epsilon, and my question about an appropriate value for it

Apr 26 '07 #4
tk****@hotmail.com wrote:
Thanks - you have covered a fair bit of gorund here - I will modify
myRange taking your suggestions into account. The one suggestion that
I'm going to have to think through is repeatedly incrementing res.

I deliberately did not use this as repeated addition can cause
rounding errors to accumulate, making the loop run a little longer or
shorter than necessary. I thought I would be far less likely to run
into rounding issues with a multiplicative construct - hence my use of
epsilon, and my question about an appropriate value for it
You are right about rounding issues--with a sufficiently small step, the
way I have done it, it could become an infinite loop. But you can still
do it with multiplication, without using an epsilon constant. How about
something like this:

index = 0
while res < maximum:
yield minimum + (step * index)
index += 1
--
Michael Hoffman
Apr 26 '07 #5
Michael Hoffman wrote:
How about something like this:

index = 0
while res < maximum:
yield minimum + (step * index)
index += 1
Well it really would have to be something LIKE that since I never
defined res. Let's try that again:

index = 0
res = minimum
while res < maximum:
yield res
res = minimum + (step * index)
index += 1
--
Michael Hoffman
Apr 26 '07 #6
Michael Hoffman <ca*******@mh391.invalidwrote:
tk****@hotmail.com wrote:
Thanks - you have covered a fair bit of gorund here - I will modify
myRange taking your suggestions into account. The one suggestion that
I'm going to have to think through is repeatedly incrementing res.

I deliberately did not use this as repeated addition can cause
rounding errors to accumulate, making the loop run a little longer or
shorter than necessary. I thought I would be far less likely to run
into rounding issues with a multiplicative construct - hence my use of
epsilon, and my question about an appropriate value for it

You are right about rounding issues--with a sufficiently small step, the
way I have done it, it could become an infinite loop. But you can still
do it with multiplication, without using an epsilon constant. How about
something like this:

index = 0
while res < maximum:
yield minimum + (step * index)
index += 1
Absolutely (with your later correction of actually assigning res), MUCH
better than the misguided attempts based on repeatedly adding 'step'.

I've taught "numerical computing" in university, and I would have had to
fail anybody who'd misunderstood floating-point computations badly
enough to try that "+=step" idea (including, sigh, the coders of several
Fortran compilers who were popular at that time).

These days, I _heartily_ recommend "Real Computing Made Real" by Foreman
Acton -- the best programming book without one line of code in any
language (it's all formulas and graphs). Anybody who has trouble
following it must understand they should NOT use floating point numbers
until they've gotten the prereqs (which aren't all that deep:
engineering-undergrad-level algebra and calculus, plus
<http://docs.sun.com/source/806-3568/ncg_goldberg.htmland a couple
weeks' worth of refresher courses on fundamental algorithms such as
Newton's root-finding approach and the like -- I shudder to think how
many people with CS bachelor degrees and even post-grad degrees are just
never taught these fundamentals, yet end up having to program _some_
floating point computations, mistakenly thinking they can...).
Alex

Apr 27 '07 #7
On Apr 27, 1:32 am, a...@mac.com (Alex Martelli) wrote:
Michael Hoffman <cam.ac...@mh391.invalidwrote:
tkp...@hotmail.com wrote:
Thanks - you have covered a fair bit of gorund here - I will modify
myRange taking your suggestions into account. The one suggestion that
I'm going to have to think through is repeatedly incrementing res.
I deliberately did not use this as repeated addition can cause
rounding errors to accumulate, making the loop run a little longer or
shorter than necessary. I thought I would be far less likely to run
into rounding issues with a multiplicative construct - hence my use of
epsilon, and my question about an appropriate value for it
You are right about rounding issues--with a sufficiently small step, the
way I have done it, it could become an infinite loop. But you can still
do it with multiplication, without using an epsilon constant. How about
something like this:
index = 0
while res < maximum:
yield minimum + (step * index)
index += 1

Absolutely (with your later correction of actually assigning res), MUCH
better than the misguided attempts based on repeatedly adding 'step'.

I've taught "numerical computing" in university, and I would have had to
fail anybody who'd misunderstood floating-point computations badly
enough to try that "+=step" idea (including, sigh, the coders of several Fortran compilers who were popular at that time).
You may be referring to the Fortran DO loop with a REAL loop variable,
for example

do x=1.5,3.5,0.5
print*,x
end do

This was part of standard Fortran 77, so one should blame the
standards committee, not the compiler writers. Very few features of
F77 were deleted in Fortran 95, but this was one of them. In practice,
nothing gets deleted from commercial Fortran compilers.

At the SciPy site http://www.scipy.org/Cookbook/OptimizationAndFitDemo1
there is some code

1 from enthought.chaco.wx import plt
2 from scipy import arange, optimize, special
3
4 plt.figure()
5 plt.hold()
6 w = []
7 z = []
8 x = arange(0,10,.01)
9
10 for k in arange(1,5,.5):
11 y = special.jv(k,x)
12 plt.plot(x,y)
13 f = lambda x: -special.jv(k,x)
14 x_max = optimize.fminbound(f,0,6)
15 w.append(x_max)
16 z.append(special.jv(k,x_max))
17
18 plt.plot(w,z, 'ro')
19 from scipy import interpolate
20 t = interpolate.splrep(w, z, k=3)
21 s_fit3 = interpolate.splev(x,t)
22 plt.plot(x,s_fit3, 'g-')
23 t5 = interpolate.splrep(w, z, k=5)
24 s_fit5 = interpolate.splev(x,t5)
25 plt.plot(x,s_fit5, 'y-')

I think the use of arange with a non-integer increment is poor style,
for reasons discussed in this thread.

Apr 27 '07 #8
Beliavsky <be*******@aol.comwrote:
...
I've taught "numerical computing" in university, and I would have had to
fail anybody who'd misunderstood floating-point computations badly
enough to try that "+=step" idea (including, sigh, the coders of several
Fortran compilers who were popular at that time).

You may be referring to the Fortran DO loop with a REAL loop variable,
for example

do x=1.5,3.5,0.5
print*,x
end do

This was part of standard Fortran 77, so one should blame the
standards committee, not the compiler writers. Very few features of
I was thinking of "Fortran IV" aka Fortran '66, where as I recall per
the standard you were _supposed_ to only use integers in a DO, but
several compilers supplied real loop variables as an extension, and got
its implementation wrong.
Alex
Apr 27 '07 #9

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

3
by: venkat | last post by:
Hi, I want to solve linear least sqaure problem( min||c-Ax||2 subject to Bx=d ). How do I do it in python. lapack has a routine for doing this (DGGLSE). Can I access this from python? TIA,...
5
by: squidco | last post by:
I've been trying to wean myself off of tables. I've been reading about the float property, and have implemented a couple of sites using divs instead of tables, and generally I'm happy with the...
9
by: Bengt Richter | last post by:
;-) We have @deco def foo(): pass as sugar (unless there's an uncaught exception in the decorator) for def foo(): pass foo = deco(foo) The binding of a class name is similar, and class...
6
by: christopher diggins | last post by:
I wrote a dynamic matrix class similar to the one described in TCPL 3rd Edition. Rather than define two separate iterators for const and non-const scenarios I decided to be a lazy bastard and only...
5
by: Jean-Guillaume Pyraksos | last post by:
I want to work with "generalized lists" as in Lisp, say : ((23 () . 2) () ((10))) ; only pointers and integers So the basic element is a node, a struct with two fields car and cdr....
3
by: Spectre1337 | last post by:
Hello, I've encountered a rather puzzling problem with SqlDataAdapter. I've set up a number of elaborate tables in the Microsoft SQL Server Management Studio Express (including several table key...
3
by: | last post by:
I am enjoying making generalized methods to serve common needs, such as: ImageProcessing.MakeQuickResize(); ImageProcessing.Sharpen(); FileOps.CreateYearAndMonthAndDayDirectoryBasedOnDate()...
5
by: er | last post by:
hi, is anyone aware of a library that generalizes transform, for_each? e.g. transform( vec1.begin(), vec1.end(), vec2.begin(), vec3.begin(),
0
by: iain654 | last post by:
I have finally worked out how to automatically send a range of cells in the body of an email using Outlook but it is very clumsy and I have to build up the email using the limit of line...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.