Das eigentliche Problem, das ich lösen wollen, einen Satz von N Einheitsvektoren gegeben wird, und einen weiteren Satz von M Vektoren für jede der Einheits berechnen Vektoren den Mittelwert von der absolute Wert des Skalarprodukts davon mit jedem der Vektoren M. Im Wesentlichen berechnet dies das äußere Produkt der zwei Matrizen und summiert und mittelt mit einem absoluten Wert dazwischen.Nicht-triviale Summen von äußeren Produkten ohne Provisorien in numpy
Für N und M nicht zu groß ist dies nicht schwer und es gibt viele Möglichkeiten (siehe unten), um fortzufahren. Das Problem ist, wenn die erstellten Provisorien groß sind und eine praktische Begrenzung für den vorgesehenen Ansatz bieten. Kann diese Berechnung ohne Erstellung von Provisorien durchgeführt werden? Die Hauptschwierigkeit, die ich habe, ist auf das Vorhandensein des absoluten Wertes zurückzuführen. Gibt es allgemeine Techniken zum "threading" solcher Berechnungen?
als Beispiel den folgenden Code betrachten
N = 7
M = 5
# Create the unit vectors, just so we have some examples,
# this is not meant to be elegant
phi = np.random.rand(N)*2*np.pi
ctheta = np.random.rand(N)*2 - 1
stheta = np.sqrt(1-ctheta**2)
nhat = np.array([stheta*np.cos(phi), stheta*np.sin(phi), ctheta]).T
# Create the other vectors
m = np.random.rand(M,3)
# Calculate the quantity we desire, here using broadcasting.
S = np.average(np.abs(np.sum(nhat*m[:,np.newaxis,:], axis=-1)), axis=0)
Dieser groß ist, ist S nun ein Array mit der Länge N und enthält die gewünschten Ergebnisse. Leider haben wir dabei einige potentiell riesige Arrays erstellt. Das Ergebnis der
np.sum(nhat*m[:,np.newaxis,:], axis=-1)
ist ein M X N Array. Das Endergebnis ist natürlich nur von der Größe N. Starten Sie die Größen von N und M zu erhöhen und wir schnell in einen Speicherfehler laufen.
Wie oben erwähnt, wenn der absolute Wert dann nicht erforderlich waren, gehen wir konnten wie folgt nun einsum()
T = np.einsum('ik,jk,j', nhat, m, np.ones(M))/M
mit Das funktioniert und arbeitet schnell sogar für recht große N und M. Für das spezifische Problem muss ich die abs()
einschließen, aber eine allgemeinere Lösung (möglicherweise eine allgemeinere ufunc) würde auch von Interesse sein.
Können Sie es mit [ 'dot'] (http://docs.scipy.org/doc/numpy/reference/generated/numpy.dot.html) und einige Achse Hantieren? – user2357112
[ 'tensordot'] (http://docs.scipy.org/doc/numpy/reference/generated/numpy.tensordot.html#numpy.tensordot) könnte nützlicher sein. – user2357112
Es ist nicht offensichtlich, wie dies wegen der Notwendigkeit der 'abs()' hilft. Wäre das nicht der Fall, wäre der Ausdruck "einsum()" in der Frage ideal! –