[newbie] problem making equally spaced value array with linspace

Dave Angel d at davea.name
Tue Dec 18 10:37:29 EST 2012


On 12/18/2012 07:37 AM, Jean Dubois wrote:
> I have trouble with the code beneath to make an array with equally
> spaced values
> When I enter 100e-6 as start value, 700e-6 as end value and 100e-6 I
> get the following result:
> [ 0.0001   0.00022  0.00034  0.00046  0.00058  0.0007 ]
> But I was hoping for:
> [ 0.0001   0.0002  0.0003  0.0004  0.0005  0.0006 0.0007]
> It works correctly for other values like 1,7,1 but not for 0.1,0.7,0.1
> then again for 0.01,0.07,0.01
I started this answer before there were any others visible, but had to
rush off to the dentist.  Now I'm finishing it and sending it, even
though there's some overlap with the other posts.

What Python has in common with nearly every other language is the use of
binary floating point.  Unlike integers, floating point values can have
both roundoff and quantization errors.  The former happen with many
operations, like you can see with pencil and paper trying to divide 1 by
3, and storing the result in 10 columns.

But quantization errors aren't as obvious.  They can occur whenever you
convert a number from one format to another.  In this case, you're
converting from the decimal string to a binary float.  To put it simply
binary floats can't store any decimal number exactly exact integers, and
mixed numbers where the fractional part happens to be an exact multiple
of a power of two.  So 0.5 is exact, but you get quantization error with
0.1, 0.2, ... 0.9

This is compounded by the fact that print will convert the number back
to a decimal string.  So sometimes the two quantization errors happen to
cancel, and sometimes they don't.

Now, your particular case is due to the convoluted way you calculate
nom.  And the easiest way to fix it would be to add 0.5 before
truncating with int().  Or better yet, have the user tell you how many
he wants in his list, and calculate the other way around.  If instead of
10 items, you have 100000 of them, you'll get a cumulative error with
your approach.  So you'd use a formula like
     start + (end-start)*i/nom

which would assure that each value was really close without cumulative
errors.  No idea how that'd fit with numpy.

Another approach is to use the Decimal package.  It's not inherently any
more accurate, but the errors are where you'd expect them, and you don't
get the quantization error converting back and forth to string.


-- 

DaveA




More information about the Python-list mailing list