Ho una funzione C per normalizzare le righe di un array nello spazio log (ciò impedisce l'underflow numerico).Come rendere conto di un array di colonne contigui durante l'estensione di numpy con C
Il prototipo della mia C-funzione è la seguente:
void normalize_logspace_matrix(size_t nrow, size_t ncol, double* mat);
Si può vedere che ci vuole un puntatore ad un array e lo modifica in posizione. Il codice C ovviamente presuppone che i dati vengano salvati come un array contiguo C, cioè contiguo alla riga.
I avvolgere la funzione come segue utilizzando Cython (importazioni e cdef extern from
omesso):
def normalize_logspace(np.ndarray[np.double_t, ndim=2] mat):
cdef Py_ssize_t n, d
n = mat.shape[0]
d = mat.shape[1]
normalize_logspace_matrix(n, d, <double*> mat.data)
return mat
maggior parte del tempo NumPy-array sono riga contigua e la funzione funziona bene. Tuttavia, se un array numpy è stato precedentemente trasposto, i dati non vengono copiati ma viene restituita solo una nuova vista nei dati. In questo caso la mia funzione fallisce perché l'array non è più contiguo alla riga.
posso aggirare questo definendo la matrice per avere ordine Fortran contigue, in modo tale che dopo la trasposizione sarà C contigue:
A = np.array([some_func(d) for d in range(D)], order='F').T
A = normalize_logspace(A)
Ovviamente questo è molto soggetto ad errori e l'utente deve prendere cura che l'array sia nell'ordine corretto, cosa che l'utente non dovrebbe aver bisogno di preoccuparsi di Python.
Qual è il modo migliore in cui è possibile farlo funzionare con array sia in righe che in colonna? Presumo che una sorta di controllo degli array in Cython sia la strada da percorrere. Certo, preferirei una soluzione che non richieda di copiare i dati in un nuovo array, ma presumo quasi che sia necessario.
Questa risposta del 2010 è ancora attuale oppure esiste un modo migliore per ottenere questo risultato ora? –
@larsmans: non so esattamente cosa intendi con "questo".Scrivere una funzione C in grado di gestire sia gli array bidimensionali Fortran-contigui che C-contigui funziona ancora in questo modo, se questo è ciò che si desidera. Se è ok che i tuoi array vengano copiati, ci sono (e sono stati nel 2010) altre soluzioni. –