0

Why do the elements in the numpy arrays not equal each other?

This is my env:

jupyter QtConsole 4.3.1
Python 2.7.13 |Anaconda custom (x86_64)| (default, Dec 20 2016, 23:05:08) 
Type "copyright", "credits" or "license" for more information.

IPython 5.3.0 -- An enhanced Interactive Python.
?         -> Introduction and overview of IPython's features.
%quickref -> Quick reference.
help      -> Python's own help system.
object?   -> Details about 'object', use 'object??' for extra details.

import sys
print(sys.version)
print np.__version__
2.7.13 |Anaconda custom (x86_64)| (default, Dec 20 2016, 23:05:08) 
[GCC 4.2.1 Compatible Apple LLVM 6.0 (clang-600.0.57)]
1.12.1

This is how I get both arrays:

A = np.array([[2., 3.],
              [10., 1.]])
rprime = np.array([[8.], [13.]])
A_inv = np.linalg.inv(A)
r = np.dot(A_inv, rprime)

As you can see they look the same:

np.dot(A, r)
Out[72]: 
array([[  8.],
       [ 13.]])

rprime
Out[73]: 
array([[  8.],
       [ 13.]])

But when I compare them, they are not:

np.dot(A, r) == rprime
Out[74]: 
array([[False],
       [False]], dtype=bool)

The shapes and types are all the same:

print type(np.dot(A, r))
print type(rprime)
print type(np.dot(A, r)[0, 0])
print type(rprime[0, 0])
print type(np.dot(A, r)[1, 0])
print type(rprime[1, 0])
print np.dot(A, r).shape
print rprime.shape


<type 'numpy.ndarray'>
<type 'numpy.ndarray'>
<type 'numpy.float64'>
<type 'numpy.float64'>
<type 'numpy.float64'>
<type 'numpy.float64'>
(2, 1)
(2, 1)

When I use allclose I get true:

np.allclose(np.dot(A, r), rprime)
Out[76]: True

What I am trying to understand is why they are not considered identical?

Addition: It must have to do with the exact floats stored in the matrices:

np.round(np.dot(A, r),0) == np.round(rprime,0)
Out[81]: 
array([[ True],
       [ True]], dtype=bool)

Still, trying to understand what exactly is going on.

Jean-François Corbett
  • 37,420
  • 30
  • 139
  • 188
  • Answer is basically, [Floating-point arithmetic](https://en.wikipedia.org/wiki/Floating-point_arithmetic). The values aren't exactly equal, e.g. 7.999999999999999 and 8.000000000001 because off by one or two bits. – Jean-François Corbett Jun 28 '18 at 07:20
  • How can I know what exactly is in each of the matrices? When I do a normal print, it does not show the 7.999999999999999 and 8.000000000001. –  Jun 28 '18 at 07:22
  • `np.allclose` is the best way to compare float arrays. – hpaulj Jun 28 '18 at 07:51
  • numpy rounds off numbers for matrix display purposes. But the underlying values aren't rounded. To reveal them, just extract one of the matrix elements, e.g. `np.dot(A, r)[0][0]` returns `7.999999999999999`. The second element returns `13.000000000000002`. – Jean-François Corbett Jun 28 '18 at 08:14
  • Thanks! I got it now. What is confusing to me is that I am specifically insisting on working with floats and I assumed in that case numpy would display the matrix showing the 'full' float and not round as you mentioned. –  Jun 29 '18 at 07:47

2 Answers2

0

They are not identical due to the way floating point numbers work. See e.g. The Floating-Point Guide on comparing floating point numbers. This is the reason numpy provides the allclose method.

If you change the type of the array to integer (e.g. dtype=np.int32), the arrays will be equal.

IonicSolutions
  • 2,559
  • 1
  • 18
  • 31
-2

When you apply == to a numpy array, it compares each element in the array to the element you are comparing to. So in this case you are checking each element in the array to an array.