J'ai deux tableaux de matrices complexes de 2 par 2, et je me demandais quelle serait la méthode la plus rapide de les multiplier. (Je veux faire une multiplication de matrice sur les éléments des matrices de matrice.) À l'heure actuelle, j'ai
numpy.array(map(lambda i: numpy.dot(m1[i], m2[i]), range(l)))
5 Réponses :
si m1 code> et
m2 code> sont des matrices em> des matrices complexes 2x2, ils ont essentiellement une forme
(L, 2 , 2) code>. Donc, la multiplication de matrice sur les deux derniers axes est équivalente à la somme du produit du dernier axe de
M1 code> avec le deuxième axe de l'axe de
M2 code>. C'est exactement ce que np.dot fait :
[np.dot(m1[i],m2[i]) for i in range(l)]
Si M1 et M2 sont des matrices 1 dimensions de matrices complexes 2x2, ils ont essentiellement une forme (L, 2,2). Donc, la multiplication de matrice sur les deux derniers axes équivaut à la résumée du produit du dernier axe de M1 avec le deuxième axe de m2 de M2. C'est exactement ce que np.dot fait: p>
Mais ce n'est pas ce que NP.dot fait. P>
[np.dot(m1[i],m2[i]) for i in range(l)]
Je pense que la réponse que vous recherchez est Ici . Malheureusement, il s'agit d'une solution assez désordonnée impliquant un remodelage. P>
Numpy.Einsum est la solution optimale de ce problème et elle est mentionnée vers le bas vers le bas de la référence de DaveP. Le code est propre, très facile à comprendre et un ordre de grandeur plus rapide que de boucler dans le tableau et de faire la multiplication un par un. Voici quelques échantillons de code:
import numpy l = 100 m1 = rand(l,2,2) m2 = rand(l,2,2) m3 = numpy.array(map(lambda i: numpy.dot(m1[i], m2[i]), range(l))) m3e = numpy.einsum('lij,ljk->lik', m1, m2) %timeit numpy.array(map(lambda i: numpy.dot(m1[i], m2[i]), range(l))) %timeit numpy.einsum('lij,ljk->lik', m1, m2) print np.all(m3==m3e)
Pourquoi est-ce plus rapide que la main-écrivant les boucles?
Ah, je pense avoir trouvé la réponse: Numpy utilise l'Atlas / Blas.
See stackoverflow.com/questions / 8385602 / ... pour plus de spéculation à ce sujet.
Peut-être que c'est une question trop ancienne mais je cherchais toujours une réponse.
J'ai essayé ce code p> Les résultats sont les suivants: pour "dot" < / p> pour 'einsum' p> J'ai vérifié que c et d sont identiques p> Toujours 'DOT' est le gagnant, je cherche toujours une meilleure méthode mais pas de succès p> p>