Question

I'm trying to use numpy with numba but I'm getting weird results while trying to access or set some values to a numpy array of float using a float index converted to an int. Check with this basic function.

@numba.jit("void(f8[:,::1],f8[:,::1])")
def test(table, index):
 x,y = int(index[0,0]), int(index[1,0)
 table[y,x] = 1.0
 print index[0,0], index[1,0], x,y
 print table
 print table[y,x]

table = np.zeros((5,5), dtype = np.float32)
index = np.random.ranf(((2,2)))*5
test(table, index)

results:

index[0,0] = 1.34129550525 index[1,0] = 0.0656177324359 x = 1 y = 0    
table[0,1] = 1.0 
table [[ 0.     0.     1.875  0.     0.   ]
       [ 0.     0.     0.     0.     0.   ]
       [ 0.     0.     0.     0.     0.   ]
       [ 0.     0.     0.     0.     0.   ]
       [ 0.     0.     0.     0.     0.   ]]

Why do I get a 1.875 in my table and not a 1.0? This a basic example but I'm working with big array and it gives me a lot of error. I know i can convert index to np.int32 and change @numba.jit("void(f8[:,::1],f8[:,::1])") to @numba.jit("void(f8[:,::1],i4[:,::1])") and that is working fine, but I would you like ton understand why this is not working. Is it a problem while parsing the type from python to c++?

Thanks for you help

Was it helpful?

Solution

In [198]: np.float64(1.0).view((np.float32,2))
Out[198]: array([ 0.   ,  1.875], dtype=float32)

So when

table[y,x] = 1.0

writes a np.float64(1.0) into table, table views the data as np.float32 and interprets it as a 0 and a 1.875.

Notice that the 0 shows up at index location [0,1], and 1.875 shows up at index location [0,2], whereas the assignment occurred at [y,x] = [0,1].

You could fix the dtype mismatch by changing

@numba.jit("void(f8[:,::1],f8[:,::1])")

to

@numba.jit("void(f4[:,::1],f8[:,::1])")

These are the 8 bytes in np.float64(1.0):

In [201]: np.float64(1.0).tostring()
Out[201]: '\x00\x00\x00\x00\x00\x00\xf0?'

And when the 4 bytes '\x00\x00\xf0?' are interpreted as a np.float32 you get 1.875:

In [205]: np.fromstring('\x00\x00\xf0?', dtype='float32')
Out[205]: array([ 1.875], dtype=float32)
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top