Ho convertito in cython una funzione python aggiungendo solo alcuni tipi e compilandolo. Stavo ottenendo piccole differenze numeriche tra i risultati delle funzioni python e cython. Dopo un po 'di lavoro ho scoperto che le differenze derivavano dall'accedere ad una matrice numpy usando int unsigned invece di int.Cython: gli indici int unsigned per gli array numpy danno un risultato diverso
ero utilizzando indici int senza segno per accelerare l'accesso secondo: http://docs.cython.org/src/userguide/numpy_tutorial.html#tuning-indexing-further
comunque ho pensato che fosse innocuo per utilizzare unsigned int.
Vedi questo codice:
cpdef function(np.ndarray[np.float32_t, ndim=2] response, max_loc):
cdef unsigned int x, y
x, y = int(max_loc[0]), int(max_loc[1])
x2, y2 = int(max_loc[0]), int(max_loc[1])
print response[y,x], type(response[y,x]), response.dtype
print response[y2,x2], type(response[y2,x2]), response.dtype
print 2*(response[y,x] - min(response[y,x-1], response[y,x+1]))
print 2*(response[y2,x2] - min(response[y2,x2-1], response[y2,x2+1]))
stampe:?
0.959878861904 <type 'float'> float32
0.959879 <type 'numpy.float32'> float32
1.04306024313
1.04306030273
perché questo accade !!! E 'un errore?
Ok, come richiesto: ecco uno SSCCE con gli stessi tipi e valori che ho usato nella mia funzione originaria
cpdef function():
cdef unsigned int x, y
max_loc2 = np.asarray([ 15., 25.], dtype=float)
cdef np.ndarray[np.float32_t, ndim=2] response2 = np.zeros((49,49), dtype=np.float32)
x, y = int(max_loc2[0]), int(max_loc2[1])
x2, y2 = int(max_loc2[0]), int(max_loc2[1])
response2[y,x] = 0.959878861904
response2[y,x-1] = 0.438348740339
response2[y,x+1] = 0.753262758255
print response2[y,x], type(response2[y,x]), response2.dtype
print response2[y2,x2], type(response2[y2,x2]), response2.dtype
print 2*(response2[y,x] - min(response2[y,x-1], response2[y,x+1]))
print 2*(response2[y2,x2] - min(response2[y2,x2-1], response2[y2,x2+1]))
stampe
0.959878861904 <type 'float'> float32
0.959879 <type 'numpy.float32'> float32
1.04306024313
1.04306030273
io uso Python 2.7.3 Cython 0,18 e msvc9 express
Se davvero si vuole confrontare 'int' unsigned vs.' int' firmato, invece di 'int' unsigned vs.' PyObject'-o-qualunque-cosa-Cython-sceglie, è necessario 'CDEF int x2, y2'. – abarnert
Ancora più importante: puoi darci un [SSCCE] (http://sscce.org) che mostri il problema e le versioni esatte che stai utilizzando. Poiché ogni versione a cui ho accesso, utilizzando i valori di esempio di JoshAdel, ottengo sempre gli stessi risultati per int, unsigned int e non specificato (ad eccezione delle differenze di precisione di stampa previste nei casi rilevanti). – abarnert
hai ragione con questo. Se dichiaro cdef int x2, y2 non ottengo questa differenza, quindi effettivamente cdef int o unsigned int vs PyObject-or-any-else-Cython-choos sceglie – martinako