Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NumPy linspace rounding error

Could someone explain this rounding issue with numpy.linspace?

import numpy as np

np.linspace(0, 1, 6) == np.around( np.linspace(0, 1, 6), 10 )
# array([ True,  True,  True, False,  True,  True], dtype=bool)

Here's how I arrived here...

import numpy as np

## Two ways of defining the same thing
A = np.array([ 0., 0.2, 0.4, 0.6, 0.8, 1. ])
B = np.linspace(0, 1, 6)

## A and B appear to be the same
A # array([ 0., 0.2, 0.4, 0.6, 0.8, 1. ])
B # array([ 0., 0.2, 0.4, 0.6, 0.8, 1. ])


## They're not
A == B # array([ True, True, True, False, True, True], dtype=bool)
A - B  # array([ 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, -1.11022302e-16, 0.00000000e+00, 0.00000000e+00])


## Gotta round to get my expected result
C = np.round( np.linspace( 0, 1, 6 ), 10 )
C      # array([ 0., 0.2, 0.4, 0.6, 0.8, 1. ])
A == C # array([ True, True, True, True, True, True], dtype=bool)

The way I defined B seems innocent enough . . . is this rounding issue something that can bite us all over the place?

like image 828
ajwood Avatar asked Feb 05 '13 21:02

ajwood


People also ask

What does the NumPy Linspace () function do?

The NumPy linspace function creates sequences of evenly spaced values within a defined interval. Essentally, you specify a starting point and an ending point of an interval, and then specify the total number of breakpoints you want within that interval (including the start and end points).

What is a correct method to round decimals in NumPy?

The ceil() function rounds off decimal to nearest upper integer. E.g. ceil of 3.166 is 4.

How do you round values in NumPy?

To round elements of the array to the nearest integer, use the numpy. rint() method in Python Numpy. For values exactly halfway between rounded decimal values, NumPy rounds to the nearest even value.

When should we use Linspace vs arange?

When it comes to creating a sequence of values, linspace and arange are two commonly used NumPy functions. Here is the subtle difference between the two functions: linspace allows you to specify the number of steps. arange allows you to specify the size of the steps.


1 Answers

It's not pretty, but its the way floating point is, you are going to have to learn to live with it. This is where your weird result comes from:

>>> a = np.float(1)
>>> a /= 5
>>> a
0.2
>>> a*3
0.6000000000000001

You have np.allclose to help you deal with this kind of stuff, but if you are not disciplined about floating point comparisons then yes, it will bite you over and over again.

like image 73
Jaime Avatar answered Oct 04 '22 20:10

Jaime