Ho due matrici NxN che voglio moltiplicare insieme: A e B. In NumPy, ho usato:NumPy moltiplicazione di matrici di efficienza per matrice struttura nota
import numpy as np
C = np.dot(A, B)
Tuttavia, mi capita di sapere che per Matrix B solo la riga n e la colonna n sono diversi da zero (questo deriva direttamente dalla formula analitica che ha prodotto la matrice ed è senza dubbio sempre il caso).
speranza di trarre vantaggio da questo fatto e ridurre il numero di moltiplicazioni necessarie per produrre C, ho sostituito il precedente con:
import numpy as np
for row in range(0, N):
for col in range(0, N):
if col != n:
C[row, col] = A[row, n]*B[n, col] #Just one scalar multiplication
else:
C[row, col] = np.dot(A[row], B[:, n])
Analiticamente, questo dovrebbe ridurre la complessità totale come segue: Nel caso generale (non usando trucchi fantasiosi, solo moltiplicazione matrice di base) C = AB, dove A e B sono entrambi NxN, dovrebbe essere O (N^3). Cioè, ogni N righe devono moltiplicare tutte le colonne N, e ciascuno di questi prodotti dot contiene N moltiplicazioni => O (N N N) = O (N^3). #
sfruttando la struttura di B come Ho fatto sopra tuttavia dovrebbe andare come O (N^2 + N^2) = O (2N^2) = O (N^2). Ovvero, tutte le righe N devono moltiplicare tutte le colonne N, tuttavia, per tutte queste (eccetto quelle che riguardano 'B [:, n]') è richiesta una sola moltiplicazione scalare: solo un elemento di 'B [:, m]' è diverso da zero per m! = n. Quando n == m, che si verifica N volte (una volta per ogni riga di A che deve moltiplicare la colonna n di B), devono verificarsi N moltiplicazioni scalari. #
Tuttavia, il primo blocco di codice (utilizzando np.dot (A, B)) è sostanzialmente più veloce. Sono a conoscenza (tramite informazioni come: Why is matrix multiplication faster with numpy than with ctypes in Python?) che i dettagli di implementazione di basso livello di np.dot sono probabilmente da incolpare per questo. Quindi la mia domanda è questa: come posso sfruttare la struttura della matrice B per migliorare l'efficienza di moltiplicazione senza sacrificare l'efficienza di implementazione di NumPy, senza creare la mia propria moltiplicazione di matrice di basso livello in c?
Questo metodo fa parte di un'ottimizzazione numerica su molte variabili, quindi O (N^3) è intrattabile mentre O (N^2) probabilmente completerà il lavoro.
Grazie per qualsiasi aiuto. Inoltre, sono nuovo di SO, quindi per favore perdonare eventuali errori newbie.
Avete considerato 'cython' o qualche altro modo di compilare la vostra funzione di moltiplicazione direttamente in codice macchina? Nei giorni buoni, probabilmente avrei usato 'f2py' per questo, ma so che non tutti vogliono scrivere codice in fortran ;-) – mgilson
Non ne sono del tutto sicuro, ma Scipy potrebbe aver risolto alcuni problema simile usando matrici sparse. Qualche guru scipy sa? – mgilson
Dai un'occhiata a 'scipy.sparse', puoi rendere' B' una matrice sparsa 'B = scipy.sparse.csr_matrix (B)' e poi fai semplicemente 'A * B', se moltiplichi denso per sparso il risultato è denso Il mio istinto è che questo è più efficiente non l'ho provato. – Akavall