2012-08-07 18 views
22

Supongamos que tiene n matrices cuadradas A1, ..., An. ¿Hay alguna forma de multiplicar estas matrices de una manera ordenada? Por lo que sé, dot in numpy solo acepta dos argumentos. Una forma obvia es definir una función para llamarse a sí misma y obtener el resultado. ¿Hay alguna forma mejor de hacerlo?Multiplica varias matrices en numpy

Respuesta

38

Esta podría ser una característica relativamente reciente, pero me gusta:

A.dot(B).dot(C) 

o si ha tenido una larga cadena que podía hacer:

reduce(numpy.dot, [A1, A2, ..., An]) 

Actualización:

Hay más información acerca de reducir here. Aquí hay un ejemplo que podría ayudar.

>>> A = [np.random.random((5, 5)) for i in xrange(4)] 
>>> product1 = A[0].dot(A[1]).dot(A[2]).dot(A[3]) 
>>> product2 = reduce(numpy.dot, A) 
>>> numpy.all(product1 == product2) 
True 

Actualización 2016: A partir de Python 3.5, existe un nuevo símbolo matrix_multiply, @:

R = A @ B @ C 
+0

Gracias por la respuesta. La primera opción funciona bien; pero el segundo no; o al menos no pude hacer que funcione. ¿Puedes por favor elaborarlo un poco más o quizás dar un ejemplo? Muchas gracias – NNsr

+4

Me encuentro con esto todo el tiempo y terminé escribiendo una función de ayuda. Desearía que esto fuera parte de NumPy: 'def xdot (* args): return reduce (np.dot, args)' – rd11

+0

Simplemente añadiendo un comentario que esto funciona cuando A, B y C son de tipo numpy.ndarray. Esto puede funcionar para otros tipos, pero no lo he comprobado. – OfLettersAndNumbers

3

Si calcula todas las matrices a priori, entonces debe usar un esquema de optimización para la multiplicación de la cadena de matrices. Ver this Wikipedia article.

+2

Gracias por su comentario; pero no creo que para matrices cuadradas sea importante. ¿Derecha? – NNsr

+0

@Nikandish: Correcto. Me perdí esa parte en tu respuesta original. –

2
A_list = [np.random.randn(100, 100) for i in xrange(10)] 
B = np.eye(A_list[0].shape[0]) 
for A in A_list: 
    B = np.dot(B, A) 

C = reduce(np.dot, A_list) 

assert(B == C) 
16

Resurrecting una vieja pregunta con una actualización:

A partir de November 13, 2014 ahora existe una función np.linalg.multi_dot que hace exactamente lo que usted desea. También tiene la ventaja de optimizar el orden de las llamadas, aunque eso no es necesario en su caso.

Tenga en cuenta que esto está disponible comenzando con la versión numpy 1.10.

0

Otra forma de lograr esto sería usando einsum, que implementa el Einstein summation convention para NumPy.

Para explicar muy brevemente esta convención con respecto a este problema: Al escribir su producto de matriz múltiple como una gran cantidad de productos, se obtiene algo así como:

P_im = sum_j sum_k sum_l A1_ij A2_jk A3_kl A4_lm 

donde P es el resultado de su producto y A1, A2, A3 y A4 son las matrices de entrada. Tenga en cuenta que suma exactamente los índices que aparecen dos veces en el summand, es decir, j, k y l. Como una suma con esta propiedad aparece a menudo en física, cálculo vectorial y probablemente en otros campos, existe una herramienta NumPy para él, es decir, einsum.

En el ejemplo anterior, se puede usar para calcular su producto matricial de la siguiente manera:

P = np.einsum("ij,jk,kl,lm", A1, A2, A3, A4) 

Aquí, el primer argumento indica a la función que los índices de aplicar a las matrices de argumentos y luego todos los índices doblemente aparecen se suman, produciendo el resultado deseado.

Tenga en cuenta que la eficiencia computacional depende de varios factores (por lo que es probablemente el mejor fuera con sólo probarlo):

Cuestiones relacionadas