Ich habe zwei NxN-Matrizen, die ich zusammen multiplizieren will: A und B. In NumPy, habe ich:NumPy Matrixmultiplikation Effizienz für Matrix mit bekannter Struktur
import numpy as np
C = np.dot(A, B)
Allerdings habe ich vor, dass für die Matrix wissen B nur Zeile n und Spalte n sind ungleich Null (dies kommt direkt von der analytischen Formel, die die Matrix erzeugt hat und ist ohne Zweifel immer der Fall).
der Hoffnung, sich diese Tatsache zunutze zu machen und die Anzahl der Multiplikationen zu produzieren C erforderlich reduzieren, ersetzte ich das oben mit:
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])
Analytisch dies die Gesamtkomplexität verringern, sollten Sie wie folgt vor: Im allgemeinen Fall (nicht irgendwelche fancy Tricks, nur grundlegende Matrix-Multiplikation) C = AB, wo A und B beide NxN sind, sollte O (N^3) sein. Das heißt, alle N Zeilen müssen alle N Spalten multiplizieren, und jedes dieser Skalarprodukte enthält N Multiplikationen => 0 (N N N) = O (N^3) #
Ausnutzen der Struktur von B als Ich habe oben aber sollte gehen als O (N^2 + N^2) = O (2N^2) = O (N^2). Das heißt, alle N Zeilen müssen alle N Spalten multiplizieren, für alle (außer denen mit B [:, n]) ist jedoch nur eine Skalarmultiplikation erforderlich: nur ein Element von 'B [:, m]' ist nicht Null für m! = n. Wenn n == m, was N mal vorkommen wird (einmal für jede Zeile von A, die die Spalte n von B multiplizieren muss), müssen N skalare Multiplikationen auftreten. #
Der erste Code-Block (mit np.dot (A, B)) ist wesentlich schneller. Ich bin mir bewusst (über Informationen wie: Why is matrix multiplication faster with numpy than with ctypes in Python?), dass die Low-Level-Implementierungsdetails von np.dot wahrscheinlich dafür verantwortlich sind. Meine Frage lautet also: Wie kann ich die Struktur von Matrix B ausnutzen, um die Multiplikationseffizienz zu verbessern, ohne die Implementierungseffizienz von NumPy, , zu opfern, ohne meine eigene Low-Level-Matrixmultiplikation in c zu erstellen?
Diese Methode ist Teil einer numerischen Optimierung über viele Variablen, daher ist O (N^3) nicht praktikabel, während O (N^2) wahrscheinlich die Aufgabe erfüllt.
Vielen Dank für jede Hilfe. Außerdem bin ich neu in SO, also bitte entschuldigen Sie alle Anfängerfehler.
Haben Sie 'cython' oder eine andere Möglichkeit, Ihre Multiplikationsfunktion direkt in Maschinencode zu übersetzen, in Betracht gezogen? In den guten alten Tagen hätte ich wahrscheinlich 'f2py' dafür benutzt, aber ich weiß, dass nicht jeder in fortran Code schreiben will ;-) – mgilson
Ich bin mir da auch nicht ganz sicher, aber scipy hätte vielleicht einiges gelöst ähnliches Problem mit dünn besetzten Matrizen. Irgendwelche scipy Gurus wissen? – mgilson
Sieh dir 'scipy.sparse' an, Du kannst' B' eine dünne Matrix 'B = scipy.sparse.csr_matrix (B)' machen und dann einfach 'A * B', wenn du das Ergebnis verdichtet hast ist dicht. Mein Bauchgefühl ist, dass dies effizienter ist, weil ich es nicht getestet habe. – Akavall