1
votes

I compare two arrays interactively in iPython, the returns are correct:

In[143]: r=np.array([0.,0.04166667, 0.08333333, 0.125, 0.16666667 , 0.20833333 , 0.25, 0.29166667 , 0.33333333 , 0.375, 0.41666667,0.45833333 , 0.5, 0.54166667, 0.58333333 , 0.625, 0.66666667 , 0.70833333 , 0.75, 0.79166667, 0.83333333, 0.875, 0.91666667, 0.95833333])

In[144]: c=np.array([ 0., 0.04166667, 0., 0., 0., 0.20833333, 0., 0.29166667 , 0., 0.  , 0., 0.45833333, 0.,        0.54166667, 0. , 0. , 0.,0.70833333, 0. , 0.79166667 , 0., 0., 0., 0.95833333])

In [145]: c==r

Out[145]: 
array([ True,  True, False, False, False,  True, False,  True, False,
       False, False,  True, False,  True, False, False, False,  True,
       False,  True, False, False, False,  True], dtype=bool

)

But in a python program in the 'same' setting, the results are not correct:

turns=1

r = np.linspace(1/24, turns, 24*turns,endpoint=False)

rr=r%1 

c=np.array([0.,0.04166667,0,0,0,0.20833333,0,0.29166667,0,0,0,0.45833333,
0,0.54166667,0,0,0,0.70833333,0,0.79166667,0,0,0,0.95833333])

cc=np.tile(c,turns)

print([rr==cc])

The result is different:

[array([ True, False, False, False, False, False, False, False, False,
       False, False, False, False, False, False, False, False, False,
       False, False, False, False, False, False], dtype=bool)]

What mistake did I made? Your help is appreciated.

2

2 Answers

1
votes

This is an issue with floating point precision; your first and second case are really not the same. The Floating Point guide is a useful resource here.

In the first instance, you're populating two arrays from floating point literals and then comparing them directly. In the second, you're using the output of a numpy function and directly comparing that against the second array which is still created from literals.

Even though the displayed version of the function output looks the same, the actual numbers have more precision than that, and that's enough to throw off the == comparison; you should (almost) never be using equality comparison for floats in the first place.

A quick example:

>> print 0.1 + 0.2
0.3
>> 0.1 + 0.2
0.30000000000000004
1
votes

As answered this is a floating point issue. One solution is to use np.isclose:

In [11]: np.isclose(rr, cc)
Out[11]:
array([ True,  True, False, False, False,  True, False,  True, False,
       False, False,  True, False,  True, False, False, False,  True,
       False,  True, False, False, False,  True], dtype=bool)

This checks whether values are within atol of each other (by default 1e-8):

In [12]: cc[1]
Out[12]: 0.041666670000000003

In [13]: rr[1]
Out[13]: 0.041666666666666664

In [14]: cc[1] == rr[1]
Out[14]: False

In [15]: rr[1] + 1e-8 > cc[1]
Out[15]: True