Artículos

1.4 Multiplicación de matrices


La siguiente operación matricial importante que exploraremos es la multiplicación de matrices. A lo largo de esta sección, también demostraremos cómo se relaciona la multiplicación de matrices con los sistemas lineales de ecuaciones.

Primero, proporcionamos una definición formal de vectores de fila y columna.

Definición ( PageIndex {1} ): vectores de fila y columna

Las matrices de tamaño (n times 1 ) o (1 times n ) se llaman vectores. Si (X ) es tal matriz, entonces escribimos (x_ {i} ) para denotar la entrada de (X ) en la fila (i ^ {th} ) de una matriz de columna, o la columna (i ^ {th} ) de una matriz de filas.

La matriz (n times 1 ) [X = left [ begin {array} {c} x_ {1} vdots x_ {n} end {array} right] ] es llamado a vector de columna. La matriz (1 times n ) [X = left [ begin {array} {ccc} x_ {1} & cdots & x_ {n} end {array} right] ] se llama vector fila.

Podemos simplemente usar el término vector a lo largo de este texto para hacer referencia a un vector de columna o de fila. Si lo hacemos, el contexto dejará claro a qué nos referimos.

En este capítulo, usaremos nuevamente la noción de combinación lineal de vectores como en Definición [def: combinación lineal]. En este contexto, una combinación lineal es una suma que consta de vectores multiplicados por escalares. Por ejemplo, [ left [ begin {array} {r} 50 122 end {array} right] = 7 left [ begin {array} {r} 1 4 end {array} right] +8 left [ begin {array} {r} 2 5 end {array} right] +9 left [ begin {array} {r} 3 6 end {array} right] ] es una combinación lineal de tres vectores.

Resulta que podemos expresar cualquier sistema de ecuaciones lineales como una combinación lineal de vectores. De hecho, los vectores que usaremos son solo las columnas de la matriz aumentada correspondiente.

Definición ( PageIndex {2} ): la forma vectorial de un sistema de ecuaciones lineales

Supongamos que tenemos un sistema de ecuaciones dado por [ begin {array} {c} a_ {11} x_ {1} + cdots + a_ {1n} x_ {n} = b_ {1} vdots a_ {m1} x_ {1} + cdots + a_ {mn} x_ {n} = b_ {m} end {array} ] Podemos expresar este sistema en forma vectorial que es la siguiente: [x_1 left [ begin {array} {c} a_ {11} a_ {21} vdots a_ {m1} end {array} right] + x_2 izquierda [ begin {array} {c} a_ {12} a_ {22} vdots a_ {m2} end {array} right] + cdots + x_n left [ begin {array } {c} a_ {1n} a_ {2n} vdots a_ {mn} end {array} right] = left [ begin {array} {c} b_1 b_2 vdots b_m end {matriz} derecha] ]

Observe que cada vector utilizado aquí es una columna de la matriz aumentada correspondiente. Hay un vector para cada variable en el sistema, junto con el vector constante.

La primera forma importante de multiplicación de matrices es multiplicar una matriz por un vector. Considere el producto dado por [ left [ begin {array} {rrr} 1 & 2 & 3 4 & 5 & 6 end {array} right] left [ begin {array} {r} 7 8 9 end {array} right] ] Pronto veremos que esto es igual a [7 left [ begin {array} {c} 1 4 end {array} right] + 8 left [ begin {array} {c} 2 5 end {array} right] +9 left [ begin {array} {c} 3 6 end {array} right] = left [ begin {array} {c} 50 122 end {array} right] ]

En términos generales, [ begin {alineado} left [ begin {array} {ccc} a_ {11} & a_ {12} & a_ {13} a_ {21} & a_ {22} & a_ { 23} end {matriz} right] left [ begin {matriz} {c} x_ {1} x_ {2} x_ {3} end {matriz} right] & = & x_ {1} left [ begin {array} {c} a_ {11} a_ {21} end {array} right] + x_ {2} left [ begin {array} {c} a_ { 12} a_ {22} end {matriz} right] + x_ {3} left [ begin {array} {c} a_ {13} a_ {23} end {array} right] & = & left [ begin {array} {c} a_ {11} x_ {1} + a_ {12} x_ {2} + a_ {13} x_ {3} a_ {21} x_ { 1} + a_ {22} x_ {2} + a_ {23} x_ {3} end {array} right] end {alineado} ] Por lo tanto, toma (x_ {1} ) multiplicado por la primera columna , suma a (x_ {2} ) multiplicado por la segunda columna, y finalmente (x_ {3} ) multiplicado por la tercera columna. La suma anterior es una combinación lineal de las columnas de la matriz. Cuando multiplica una matriz a la izquierda por un vector a la derecha, los números que componen el vector son solo los escalares que se usarán en la combinación lineal de las columnas como se ilustra arriba.

Aquí está la definición formal de cómo multiplicar una matriz (m times n ) por un vector columna (n times 1 ).

Definición ( PageIndex {3} ): Multiplicación de vector por matriz

Sea (A = left [a_ {ij} right] ) una matriz (m times n ) y sea (X ) una matriz (n times 1 ) dada por [ A = left [A_ {1} cdots A_ {n} right], X = left [ begin {array} {r} x_ {1} vdots x_ {n} end {array } derecho]]

Entonces el producto (AX ) es el vector de columna (m times 1 ) que es igual a la siguiente combinación lineal de las columnas de (A ): [x_ {1} A_ {1} + x_ {2 } A_ {2} + cdots + x_ {n} A_ {n} = sum_ {j = 1} ^ {n} x_ {j} A_ {j} ]

Si escribimos las columnas de (A ) en términos de sus entradas, tienen la forma [A_ {j} = left [ begin {array} {c} a_ {1j} a_ {2j} vdots a_ {mj} end {array} right] ] Entonces, podemos escribir el producto (AX ) como [AX = x_ {1} left [ begin {array} { c} a_ {11} a_ {21} vdots a_ {m1} end {matriz} right] + x_ {2} left [ begin {array} {c} a_ {12} a_ {22} vdots a_ {m2} end {array} right] + cdots + x_ {n} left [ begin {array} {c} a_ {1n} a_ {2n} vdots a_ {mn} end {array} right] ]

Tenga en cuenta que la multiplicación de una matriz (m times n ) y un vector (n times 1 ) produce un vector (m times 1 ).

Aquí hay un ejemplo.

Ejemplo ( PageIndex {1} ): un vector multiplicado por una matriz

Calcule el producto (AX ) para [A = left [ begin {array} {rrrr} 1 & 2 & 1 & 3 0 & 2 & 1 & -2 2 & 1 & 4 & 1 end {matriz} derecha], X = left [ begin {matriz} {r} 1 2 0 1 end {matriz} derecha] ]

Solución

Usaremos Definición [def: multiplicationvectormatrix] para calcular el producto. Por lo tanto, calculamos el producto (AX ) de la siguiente manera. [ begin {alineado} & 1 left [ begin {array} {r} 1 0 2 end {array} right] + 2 left [ begin {array} {r} 2 2 1 end {matriz} right] + 0 left [ begin {matriz} {r} 1 1 4 end {matriz} right] + 1 left [ begin {matriz } {r} 3 -2 1 end {array} right] & = left [ begin {array} {r} 1 0 2 end {array} right] + left [ begin {array} {r} 4 4 2 end {array} right] + left [ begin {array} {r} 0 0 0 end {array } right] + left [ begin {array} {r} 3 -2 1 end {array} right] & = left [ begin {array} {r} 8 2 5 end {matriz} right] end {alineado} ]

Usando la operación anterior, también podemos escribir un sistema de ecuaciones lineales en forma de matriz. De esta forma, expresamos el sistema como una matriz multiplicada por un vector. Considere la siguiente definición.

Definición ( PageIndex {4} ): la forma matricial de un sistema de ecuaciones lineales

Supongamos que tenemos un sistema de ecuaciones dado por [ begin {array} {c} a_ {11} x_ {1} + cdots + a_ {1n} x_ {n} = b_ {1} a_ {21} x_ {1} + cdots + a_ {2n} x_ {n} = b_ {2} vdots a_ {m1} x_ {1} + cdots + a_ {mn} x_ {n} = b_ { m} end {array} ] Entonces podemos expresar este sistema en forma de matriz como sigue. [ left [ begin {array} {cccc} a_ {11} & a_ {12} & cdots & a_ {1n} a_ {21} & a_ {22} & cdots & a_ {2n} vdots & vdots & ddots & vdots a_ {m1} & a_ {m2} & cdots & a_ {mn} end {array} right] left [ begin {array} {c} x_ {1} x_ {2} vdots x_ {n} end {matriz} right] = left [ begin {array} {c} b_ {1} b_ {2} vdots b_ {m} end {array} right] ]

La expresión (AX = B ) también se conoce como Forma de matriz del correspondiente sistema de ecuaciones lineales. La matriz (A ) es simplemente la matriz de coeficientes del sistema, el vector (X ) es el vector columna construido a partir de las variables del sistema, y ​​finalmente el vector (B ) es el vector columna construido a partir de las constantes del sistema. Es importante tener en cuenta que cualquier sistema de ecuaciones lineales se puede escribir de esta forma.

Observe que si escribimos un sistema homogéneo de ecuaciones en forma de matriz, tendría la forma (AX = 0 ), para el vector cero (0 ).

Puede ver en esta definición que un vector [X = left [ begin {array} {c} x_ {1} x_ {2} vdots x_ {n} end {array} right] ] satisfará la ecuación (AX = B ) solo cuando las entradas (x_ {1}, x_ {2}, cdots, x_ {n} ) del vector (X ) sean soluciones al sistema original.

Ahora que hemos examinado cómo multiplicar una matriz por un vector, deseamos considerar el caso en el que multiplicamos dos matrices de tamaños más generales, aunque estos tamaños todavía deben ser apropiados, como veremos. Por ejemplo, en el Ejemplo [exa: vectormultbymatrix], multiplicamos una matriz (3 times 4 ) por un vector (4 times 1 ). Queremos investigar cómo multiplicar otros tamaños de matrices.

¡Todavía no hemos dado ninguna condición sobre cuándo es posible la multiplicación de matrices! Para las matrices (A ) y (B ), para formar el producto (AB ), el número de columnas de (A ) debe ser igual al número de filas de (B. ) Considere un producto (AB ) donde (A ) tiene un tamaño (m veces n ) y (B ) tiene un tamaño (n veces p ). Entonces, el producto en términos de tamaño de matrices viene dado por [(m times overset { text {¡estos deben coincidir!}} { Widehat {n) ; (n} times p}) = m veces p ]

Tenga en cuenta que los dos números exteriores dan el tamaño del producto. Una de las reglas más importantes con respecto a la multiplicación de matrices es la siguiente. Si los dos números del medio no coinciden, ¡no puedes multiplicar las matrices!

Cuando el número de columnas de (A ) es igual al número de filas de (B ), se dice que las dos matrices son conforme y el producto (AB ) se obtiene como sigue.

Definición ( PageIndex {4} ): Multiplicación de dos matrices

Sea (A ) una matriz (m times n ) y sea (B ) una matriz (n times p ) de la forma [B = left [B_ {1} cdots B_ {p} right] ] donde (B_ {1}, ..., B_ {p} ) son las (n times 1 ) columnas de (B ). Entonces la matriz (m times p ) (AB ) se define de la siguiente manera: [AB = A left [B_ {1} cdots B_ {p} right] = left [(AB) _ {1} cdots (AB) _ {p} right] ] donde ((AB) _ {k} ) es una matriz (m times 1 ) o un vector de columna que da el (k ^ {th} ) columna de (AB ).

Considere el siguiente ejemplo.

Ejemplo ( PageIndex {2} ): multiplicar dos matrices

Encuentra (AB ) si es posible. [A = left [ begin {array} {rrr} 1 & 2 & 1 0 & 2 & 1 end {array} right], B = left [ begin {array} {rrr} 1 & 2 & 0 0 & 3 & 1 -2 & 1 & 1 end {array} right] ]

Solución

Lo primero que debe verificar al calcular un producto es si la multiplicación es posible. La primera matriz tiene un tamaño (2 times 3 ) y la segunda matriz tiene un tamaño (3 times 3 ). Los números internos son iguales, por lo que (A ) y (B ) son matrices conformes. De acuerdo con la discusión anterior, (AB ) será una matriz (2 times 3 ). La definición [def: multiplicación de dos matrices] nos da una forma de calcular cada columna de (AB ), como sigue.

[ left [ overset { text {Primera columna}} { overbrace { left [ begin {array} {rrr} 1 & 2 & 1 0 & 2 & 1 end {array} right] " left [ begin {array} {r} 1 0 -2 end {array} right]}}, overset { text {Segunda columna}} { overbrace { left [ begin { array} {rrr} 1 & 2 & 1 0 & 2 & 1 end {array} right] left [ begin {array} {r} 2 3 1 end {array} right ]}}, overset { text {Tercera columna}} { overbrace { left [ begin {array} {rrr} 1 & 2 & 1 0 & 2 & 1 end {array} right] left [ begin {array} {r} 0 1 1 end {array} right]}} right] ] Sabes cómo multiplicar una matriz por un vector, usando la Definición [def: multiplicationvectormatrix] para cada una de las tres columnas. Por lo tanto, [ left [ begin {array} {rrr} 1 & 2 & 1 0 & 2 & 1 end {array} right] left [ begin {array} {rrr} 1 & 2 & 0 0 & 3 & 1 -2 & 1 & 1 end {array} right] = left [ begin {array} {rrr} -1 & 9 & 3 -2 & 7 & 3 end {matriz} right] ]

Dado que los vectores son simplemente matrices (n times 1 ) o (1 times m ), también podemos multiplicar un vector por otro vector.

Ejemplo ( PageIndex {3} ): multiplicación vectorial multiplicada por vectores

Multiplica si es posible ( left [ begin {array} {r} 1 2 1 end {array} right] left [ begin {array} {rrrr} 1 & 2 & 1 & 0 fin {matriz} derecha]. )

Solución

En este caso, estamos multiplicando una matriz de tamaño (3 times 1 ) por una matriz de tamaño (1 times 4. ) Los números internos coinciden, por lo que el producto está definido. Tenga en cuenta que el producto será una matriz de tamaño (3 por 4 ). Usando la Definición [def: multiplicación de dos matrices], podemos calcular este producto de la siguiente manera (: ) [ left [ begin {array} {r} 1 2 1 end {array} right] left [ begin {array} {rrrr} 1 & 2 & 1 & 0 end {array} right] = left [ overset { text {First column}} { overbrace { left [ begin {array " } {r} 1 2 1 end {matriz} right] left [ begin {matriz} {r} 1 end {matriz} right]}}, overset { text {Segunda columna }} { overbrace { left [ begin {array} {r} 1 2 1 end {array} right] left [ begin {array} {r} 2 end {array} right]}}, overset { text {Tercera columna}} { overbrace { left [ begin {array} {r} 1 2 1 end {array} right] left [ begin {array} {r} 1 end {array} right]}}, overset { text {Cuarta columna}} { overbrace { left [ begin {array} {r} 1 2 1 end {matriz} derecha] izquierda [ begin {matriz} {r} 0 end {matriz} derecha]}} derecha] ]

Puede usar la Definición [def: multiplicationvectormatrix] para verificar que este producto sea [ left [ begin {array} {cccc} 1 & 2 & 1 & 0 2 & 4 & 2 & 0 1 & 2 & 1 & 0 end {array} right] ]

Ejemplo ( PageIndex {4} ): una multiplicación que no está definida

Encuentra (BA ) si es posible. [B = left [ begin {array} {ccc} 1 & 2 & 0 0 & 3 & 1 -2 & 1 & 1 end {array} right], A = left [ begin {array} {ccc} 1 & 2 & 1 0 & 2 & 1 end {array} right] ]

Solución

Primero compruebe si es posible. Este producto tiene la forma ( left (3 times 3 right) left (2 times 3 right). ) Los números interiores no coinciden, por lo que no puedes hacer esta multiplicación.

En este caso, decimos que la multiplicación no está definida. Observe que estas son las mismas matrices que usamos en el Ejemplo [exa: multiplicación de dos matrices]. En este ejemplo, intentamos calcular (BA ) en lugar de (AB ). Esto demuestra otra propiedad de la multiplicación de matrices. Si bien el producto (AB ) puede definirse, no podemos asumir que el producto (BA ) será posible. Por tanto, es importante comprobar siempre que el producto esté definido antes de realizar cualquier cálculo.

Anteriormente, definimos la matriz cero (0 ) como la matriz (de tamaño apropiado) que contiene ceros en todas las entradas. Considere el siguiente ejemplo de multiplicación por la matriz cero.

Ejemplo ( PageIndex {5} ): multiplicación por la matriz cero

Calcule el producto (A0 ) para la matriz [A = left [ begin {array} {rr} 1 & 2 3 & 4 end {array} right] ] y el (2 multiplicado por 2 ) matriz cero dada por [0 = left [ begin {array} {rr} 0 & 0 0 & 0 end {array} right] ]

Solución

En este producto, calculamos [ left [ begin {array} {rr} 1 & 2 3 & 4 end {array} right] left [ begin {array} {rr} 0 & 0 0 & 0 end {array} right] = left [ begin {array} {rr} 0 & 0 0 & 0 end {array} right] ]

Por tanto, (A0 = 0 ).

Observe que también podríamos multiplicar (A ) por (2 times 1 ) vector cero dado por ( left [ begin {array} {r} 0 0 end {array} right] ). El resultado sería el vector (2 times 1 ) cero. Por lo tanto, siempre es el caso de que (A0 = 0 ), para una matriz cero o vector de tamaño apropiado.


Multiplicación de matrices MA265F11 Walther - Rhea

Una multiplicación de matrices es la producción de una nueva matriz a partir de un par de matrices.

Las matrices solo se pueden multiplicar si el número de columnas de la primera matriz es igual al número de filas de la segunda matriz.

Una matriz --- & gt 3x2 (3 es el número de filas y 2 es el número de columnas)

B --- & gt 2x3 matriz (2 es el número de filas y 3 es el número de columnas)


La nueva matriz tendrá las filas de la primera matriz y las columnas de la segunda matriz.

Para hacer una multiplicación de matrices, debe existir la operación de producto escalar entre las filas de la primera matriz y las columnas de la segunda matriz. Para encontrar la entrada (a, b) en la nueva matriz, la suma de los productos de la b-ésima columna de la segunda matriz y de la th fila de la primera matriz.

Tomas a11 * b11 + a12 * b21 y ese es tu c11.

Entonces a11 * b12 + a12 * b22 = c12
(1)*(6) + (2)*(8) = 22

Después de no tener más columnas, pasa a la siguiente fila. Tome a21 * b11 + a22 * b21 = c21

Y el último en este caso sería a21 * b12 + a22 * b22 = c22

Entonces, la nueva matriz sería $ left ( begin19 & amp22 43 & amp50 end right) $


1.3 Multiplicación de matrices en el mundo real

La multiplicación de matrices se utiliza en muchas situaciones de la vida. De hecho este semestre tuve dos clases donde se aplicaron matrices.

Resolver variables y obtener probabilidades son algunas de las funciones principales en el mundo real.

Cuando tiene ecuaciones y necesita resolver las variables desconocidas, una multiplicación de matrices y Rref le permiten hacer esto.

Puede ponerlos en una multiplicación de matrices como esta: & # 160

Puede verificar que las ecuaciones y la matriz son iguales haciendo el producto escalar.

Obtienes que la variable x = 2 y y = 6 .


1.4 Multiplicación de matrices relacionada con otras clases.

Conozco matrices desde hace 1 año y ya las he usado en cuatro clases. Las matrices como se dijeron antes funcionan por muchas razones y áreas. Álgebra lineal, ecuación diferencial, modelos estocásticos e investigación operativa I. En muchas empresas, utilizan la multiplicación de matrices para calcular cuántos productos producir o cuántos empleados tener. En los modelos estocásticos la razón principal de las matrices donde las probabilidades, donde con una cadena de Markov, se obtiene la probabilidad de pasar de un paso a otro.

En una cadena de Markov discreta de 3 pasos, tiene una probabilidad del 40% de permanecer del paso 1 al paso 1, del 20% de pasar del paso 1 al paso 2 y del 40% de pasar del paso 3. & # 160

Luego, del paso 2 al paso 1, tiene un 20%. Desde el paso 2 hasta permanecer en el paso 2, tiene un 30%. Para ir del paso 2 al paso 3 tiene un 50%.

Finalmente, del paso 3 al paso 1, 60%, del paso 3 al paso 2 solo el 20%, y del paso 3 para permanecer en el paso 3, 20%.

Si le preguntan, inicialmente (k) es en el paso 1, ¿cuántas veces en promedio el paso 3 sería visita en (k + 3)?

Por lo tanto, debe agregar la entrada p13 + (p13) ^ 2 + (p13) ^ 3. En otras palabras, el número medio de visitas en k + 1 sería p13, entonces MULTIPLICAR& # 160la matriz multiplicada por la misma matriz y agregue la misma entrada. Nuevamente el mismo paso pero para k + 3, donde se lleva la matriz al tercero.

P13 + (P13) ^ 2 + (P13) ^ 3 = (.4) + & # 160 (.34) + (.354) = 1.094 visitas en promedio al estado 3.


La siguiente operación es igual a la cantidad de campeonatos de Alemania y Uruguay. Alemania será la variable "x" y Uruguay será la variable "y".

Haces el producto escalar y obtienes eso:

Este es un ejemplo fácil, pero es solo uno de los muchos problemas que se pueden resolver con las multiplicaciones de matrices.

Veo la multiplicación de matrices como algo nuevo en mi vida, pero tiene un uso muy positivo. No es material que sepa un estudiante de secundaria, es algo extra. Pero, al mismo tiempo, no es tan difícil. El proceso de resolver estas multiplicaciones es con las mismas herramientas que has trabajado desde los nueve años: multiplicación, suma, resta, etc. No te asustes porque es una operación matricial, solo paso a paso, ve con el problema y no deberías tener ningún problema. El único problema es saber qué hacer a continuación y qué evitar. Porque hay algunas propiedades a seguir en la multiplicación de matrices, donde en 1.7 se mencionaría.


a) & # 160La primera propiedad es que es asociativa:

B) La segunda propiedad de que es distributiva sobre la suma de matrices:

C) El tercero es que es compatible con la multiplicación escalar:


Matrix Multiplication en NumPy es una biblioteca de Python utilizada para la computación científica. Con esta biblioteca, podemos realizar operaciones matriciales complejas como multiplicación, producto escalar, inverso multiplicativo, etc. en un solo paso. En esta publicación, aprenderemos sobre diferentes tipos de multiplicación de matrices en la biblioteca numpy.

Diferentes tipos de multiplicación de matrices

Existen principalmente tres tipos diferentes de multiplicación de matrices:

Desarrollo web, lenguajes de programación, pruebas de software y otros

Función Descripción
np.matmul (matriz a, matriz b) Devuelve el producto matricial de dos matrices dadas.
np.multiply (matriz a, matriz b) Devuelve la multiplicación por elementos de dos matrices dadas.
np.dot (matriz a, matriz b) Devuelve el producto escalar o escalar de dos matrices dadas

1. Producto matricial de dos matrices dadas

Para encontrar el producto matricial de dos matrices dadas, podemos usar la siguiente función:

La entrada para esta función no puede ser un valor escalar

A = todas a12 a13
a21 a22 a23
B = b11 b12 b13
b21 b22 b23
b31 b32 b33

a11 * b11 + a12 * b21 + a13 * b31 a11 * b12 + a12 * b22 + a13 * b32 a11 * b13 + a12 * b23 + a13 * b33
a21 * b11 + a22 * b21 + a23 * b31 a21 * b12 + a22 * b22 + a23 * b32 a21 * b13 + a22 * b23 + a23 * b33

Ejemplo 1

Programa para ilustrar el producto matricial de dos matrices n-d dadas.

importar numpy como np
A = np.array ([[1,2,3], [4,5,6]])
B = np.array ([[1,1,1], [0,1,0], [1,1,1]])
print ("La matriz A es: n", A)
print ("La matriz A es: n", B)
C = np.matmul (A, B)
print ("La multiplicación de matrices A y B es: n", C)

El producto de la matriz de las matrices dadas se calcula de las siguientes formas:

1*1 + 2*0 + 3*1 = 4 1*1 + 2*1 + 3*1 = 6 1*1 + 2*0 + 3*1 = 4
4*1 + 5*0 + 6*1 = 10 4*1 + 5*1 + 6*1 = 15 4*1 + 5*0 + 6*1 = 10

2. Multiplicación por elementos de dos matrices dadas

Para encontrar el producto por elementos de dos matrices dadas, podemos usar la siguiente función.

np.multiply (matriz a, matriz b)

A = todas a12 a13
a21 a22 a23
B = a21 a22 a23
a21 a22 a23

a11 * b11 a12 * b12 a13 * b13
a21 * b21 a22 * b22 a23 * b23

Ejemplo # 2

Programa para ilustrar la multiplicación por elementos de dos matrices dadas

importar numpy como np
A = np.array ([[1,2,3], [4,5,6]])
B = np.array ([[1,2,3], [4,5,6]])
print ("La matriz A es: n", A)
print ("La matriz A es: n", B)
C = np. Multiplicar (A, B)
print ("La multiplicación de matrices A y B es: n", C)

La multiplicación de matrices por elementos de las matrices dadas se calcula de las siguientes formas:

A = 1 2 3
4 5 6
B = 1 1 1
0 1 0
1 1 1

1*1 = 1 2*2 = 4 3*3 = 9
4*4 = 16 5*5 = 25 6*6 = 36

3. Producto escalar o escalar de dos matrices dadas

El producto escalar de dos matrices dadas es básicamente su producto matricial. La única diferencia es que en el producto escalar también podemos tener valores escalares.

A = a11 a12 a13
B = b11
b12
b13

A.B = a11 * b11 + a12 * b12 + a13 * b13

Ejemplo # 3

Un programa para ilustrar el producto escalar de dos matrices 1-D dadas

importar numpy como np
A = np.array ([1,2,3])
B = np.array ([4,5,6])
print ("La matriz A es: n", A)
print ("La matriz A es: n", B)
C = np.dot (A, B)
print ("La multiplicación de matrices A y B es: n", C)

El producto escalar de dos matrices 1-D dadas se calcula de las siguientes formas:

Ejemplo # 4

Un programa para ilustrar el producto escalar de dos matrices bidimensionales dadas

importar numpy como np
A = np.array ([[1,2], [2,1]])
B = np.array ([[4,5], [4,5]])
print ("La matriz A es: n", A)
print ("La matriz A es: n", B)
C = np.dot (A, B)
print ("La multiplicación de matrices A y B es: n", C)

El producto escalar de matrices 2D o n-D dadas se calcula de las siguientes formas:

A = l 2
2 1
B = 4 5
4 5

1*4 + 2*4 = 12 1*5+2*5 = 15
2*4+ 1*4 = 12 2*5+ 1*5 = 15

Ejemplo # 5

Un programa para ilustrar el producto escalar de un valor escalar y una matriz 2-D

A = np.array ([[1,1], [1,1]])
print ("La matriz A es: n", A)
C = np.dot (2, A)
print ("La multiplicación de matrices A y B es: n", C)

Conclusión

Numpy ofrece una amplia gama de funciones para realizar la multiplicación de matrices. Si desea realizar una multiplicación de matrices por elementos, utilice la función np.multiply (). Las dimensiones de las matrices de entrada deben ser las mismas. Y si tiene que calcular el producto matricial de dos matrices / matrices dadas, utilice la función np.matmul (). Las dimensiones de las matrices de entrada deben tener el formato mxn y nxp. Finalmente, si tiene que multiplicar un valor escalar y una matriz n-dimensional, use np.dot (). np.dot () es una especialización de las funciones np.matmul () y np.multiply ().

Artículos recomendados

Esta es una guía para la multiplicación de matrices en NumPy. Aquí discutimos los diferentes tipos de multiplicación de matrices junto con los ejemplos y resultados. También puede consultar nuestros otros artículos relacionados para obtener más información.


Algoritmos para matemáticas aplicadas

Si bien multiplicar dos matrices juntas no es mucho más complicado que la suma o la multiplicación escalar, debemos tener mucho cuidado. También presentaremos otro comando incorporado, sum.

Definición 4.3.1

Suponga que (A ) es una matriz (m times n ) y que (B ) es una matriz (p times q ). Entonces se define si y solo si (n = p text <.> ) En este caso, (AB ) es una matriz (m times q ) dada por

Es decir, el elemento en la fila (i ^ text ) y la columna (j ^ text ) de la matriz del producto (AB ) es la suma del elemento por productos de elementos de la fila (i ^ text ) de (A ) y la columna (j ^ text ) de (B text <.> )

Ejemplo 4.3.2 Ejemplo de multiplicación de matrices

Supongamos que tenemos las siguientes matrices:

Entonces (A ) es una matriz (2 times 3 ), (B ) es una matriz (3 times 3 ) y (C ) es una (3 times 2 ) matriz. Estos son los posibles productos y, si existen, las dimensiones de la matriz de productos:

Producto ¿Existe? Dimensiones
(AB ) ((2 times 3) cdot (3 times 3) = 2 times 3 )
(LICENCIADO EN LETRAS) No ((3 times 3) cdot (2 times 3) )
(C.A) ((2 times 3) cdot (3 times 2) = 2 times 2 )
(CALIFORNIA) ((3 times 2) cdot (2 times 3) = 3 times 3 )
(ANTES DE CRISTO) ((3 times 3) cdot (3 times 2) = 3 times 2 )
(CB ) No ((3 times 2) cdot (3 times 3) )
Tabla 4.3.3 Clasificación de existencia y dimensiones de matrices de productos

Dado que las dimensiones de (AC ) y (CA ) son diferentes, vemos que incluso si existen (AC ) y (CA ), no es necesario que sean iguales! Ésta es una demostración simple del hecho de que la multiplicación de matrices es no conmutativo. Entonces podemos ver el proceso de multiplicar en acción,

Para pensar en esto algorítmicamente, digamos que (A ) es una matriz (m times n ) y (B ) es una matriz (n times q ). Entonces (C = AB ) es una (m times q ) matriz si (C = [c_]_ text <,> ) luego

Por lo tanto, debemos calcular la suma de una lista de números en cada entrada de nuestra nueva cuadrícula, este es precisamente el propósito del comando sum.

Convención 4.3.4 Uso del comando suma
Algoritmo 4.3.5 Multiplicación de matrices

Suponga que self y other son objetos aam_Matrix que representan respectivamente una matriz (m times n ) y una matriz (p times q ).

  1. Si (n neq p text <,> ) genera un ValueError con respecto a la discrepancia de dimensión.
  2. Cree una nueva lista de listas, con el (j ^ text) elemento de su (i ^ text) lista es la suma de la lista que consta de self [i, k] + otro [k, j], donde (k in <1,2, ldots, n > text <.> )
  3. Construya una nueva aam_Matrix a partir de esta nueva lista de listas.

Con el uso cuidadoso de listas por comprensión y el comando de suma, la nueva lista de listas creadas en el algoritmo se puede construir en un solo comando.

Punto de verificación 4.3.6 Implementación de la multiplicación de matrices

Complete el siguiente código para la multiplicación de matrices.

Listado 4.3.7 Un código parcial para el método __mul__ en la clase aam_Matrix.


Multiplicación de matriz de ruta más corta de todos los pares

Se le presenta un gráfico y su objetivo es encontrar todos los pares de rutas más cortas mediante la programación dinámica.

El primer paso es crear una matriz donde el número de filas y columnas sea igual al número de vértices y luego completarla con los datos iniciales. Por cada vértice al que se pueda llegar con un salto, lo completará con el peso del borde. Si un vértice no se puede alcanzar con un salto, lo poblará con infinito y si un vértice está tratando de alcanzarse a sí mismo, lo poblará con cero. Repasemos el algoritmo para completar la matriz inicial.

Empezaremos rellenando todos los ceros. Los ceros estarán en la diagonal. ¿Por qué? Mirando la primera entrada en A1(1,1), estás intentando pasar del vértice 1 al vértice 1. ¿Cuál es el peso de eso? Cero. Lo mismo ocurre con (2,2), (3,3) y (4,4).

Examinemos A1(1,2) siguiente. Puede ir del vértice 1 al 2 en un salto. El peso del borde es 10.

A continuación, veremos A1(1,3). Como no puede llegar al vértice 3 desde el vértice 1 en un salto, ingresa infinito.

Completemos el resto de los campos.

  • De 1 a 4, A0(1,4) = 5
  • De 2 a 1, A0(2,1) = ∞
  • De 2 a 3, A0(2,3) = ∞
  • De 2 a 4, A0(2,4) = 9
  • De 3 a 1, A0(3,1) = -2
  • De 3 a 2, A0(3,2) = 4
  • De 3 a 4, A0(3,4) = ∞
  • De 4 a 1, A0(4,1) = ∞
  • De 4 a 2, A0(4,2) = -3
  • De 4 a 3, A0(4,3) = 1

A continuación, veamos el algoritmo de manera programática y visual.

Empezamos intentando obtener el valor de A0(1,1). Si seguimos el ciclo for, k será igual a 1, luego a 2, luego a 3 y finalmente a 4, mientras que los valores de i y j no cambian.

Luego, ingrese los valores para esas entradas.

El valor mínimo es 0. Entonces, tomamos el valor de cero y lo conectamos a A1(1,1)

A continuación, examinaremos A1 (1,2), pero esta vez lo haremos visualmente. Lo que hicimos en el ejemplo anterior es pasar por la fila y la columna correspondientes a la entrada. Como miramos la entrada (1,1), agregamos los valores de la primera fila y la primera columna y luego obtuvimos el mínimo de esas entradas. Comencemos resaltando la primera fila y la segunda columna, ya que estamos trabajando en la entrada (1,2).

Si analizamos el algoritmo, sumamos (1,1) a (1,2), (1,2) a (2,2), (1,3) a (3,2) y (1,4) a (4,2).


Multiplicamos los elementos de las filas de la primera matriz por los elementos de las columnas de la segunda matriz.

  1. Multiplicamos los elementos de la primera fila por los elementos de la primera columna.
    • Multiplicamos el primer elemento de la primera fila por el primer elemento de la primera columna.
    • Multiplicamos el segundo elemento de la primera fila por el segundo elemento de la primera columna.
    • Hacemos esto para cada elemento hasta llegar al final tanto de la primera fila de la primera matriz como de la primera columna de la segunda matriz.
    • Sumamos cada uno de los resultados.
    • El resultado final será el primer elemento de la primera fila de la matriz resultante.
  2. Multiplicamos los elementos de la primera fila de la primera matriz por los elementos de la segunda columna de la segunda matriz.
    • Multiplicamos el primer elemento de la primera fila por el primer elemento de la segunda columna.
    • Multiplicamos el segundo elemento de la primera fila por el segundo elemento de la segunda columna.
    • Hacemos esto para cada elemento hasta llegar al final tanto de la primera fila de la primera matriz como de la segunda columna de la segunda matriz.
    • Sumamos cada uno de los resultados.
    • El resultado final será el segundo elemento de la primera fila de la matriz resultante.
  3. Usando el mismo algoritmo, multiplicamos los elementos de la primera fila de la primera matriz por los elementos de las columnas restantes de la segunda matriz. Los resultados completarán la primera fila de la matriz resultante.
  4. La segunda línea de la matriz resultante se completará de la misma manera, multiplicando los elementos de la segunda línea de la primera matriz por los elementos de cada columna de la segunda matriz y completando los resultados de cada suma.
  5. Hacemos esto para cada línea de la primera matriz hasta que se completa la matriz resultante.

Ejemplo 7
$ A = begin 1 y 2 y 2 3 y 1 y 1 end$
$ B = begin 4 y 2 3 y 1 1 y 5 end$

Observamos que la matriz A tiene 3 columnas y la matriz B tiene 3 líneas, lo que significa que podemos multiplicarlas.

$ B cdot A = begin color4 & color2 color3 & color1 color1 & color5 end empezar color1 & color2 & color2 color3 & color1 & color1 fin=$

Observamos que $ A cdot B neq B cdot A $

Ejemplo 8
$ A = begin 5 y 2 3 y 1 end B = begin 4 y 6 5 y 2 end$

Una vez más $ A cdot B neq B cdot A $.

Ejemplo 9
$ A = begin 1 y 4 y 3 2 y 1 y 5 3 y 2 y 1 end B = begin 5 y 2 y 1 4 y 3 y 2 2 y 1 y 5 end$

Una vez más $ A cdot B neq B cdot A $.

Observamos que $ A cdot I_ <2> = I_ <2> cdot A = A $.

Ejemplo 11
$ A = begin 1 y 4 y 3 2 y 1 y 5 3 y 2 y 1 end I_ <3> = begin 1 & 0 & 0 0 & 1 & 0 0 & 0 & 1 end$


Los algoritmos de transformada rápida de Fourier utilizan las simetrías de la matriz para reducir el tiempo de multiplicar un vector por esta matriz, desde el O (N 2) < displaystyle O (N ^ <2>)> habitual. Se pueden aplicar técnicas similares para multiplicaciones por matrices como la matriz de Hadamard y la matriz de Walsh.

Edición de dos puntos

La DFT de dos puntos es un caso simple, en el que la primera entrada es la CC (suma) y la segunda entrada es la CA (diferencia).

La primera fila realiza la suma y la segunda fila realiza la diferencia.

Edición de cuatro puntos

La matriz DFT de cuatro puntos en el sentido de las agujas del reloj es la siguiente:

Edición de ocho puntos

La primera potencia entera no trivial de dos casos es de ocho puntos:

The following image depicts the DFT as a matrix multiplication, with elements of the matrix depicted by samples of complex exponentials:

The real part (cosine wave) is denoted by a solid line, and the imaginary part (sine wave) by a dashed line.

The top row is all ones (scaled by 1 / 8 >> for unitarity), so it "measures" the DC component in the input signal. The next row is eight samples of negative one cycle of a complex exponential, i.e., a signal with a fractional frequency of −1/8, so it "measures" how much "strength" there is at fractional frequency +1/8 in the signal. Recall that a matched filter compares the signal with a time reversed version of whatever we're looking for, so when we're looking for fracfreq. 1/8 we compare with fracfreq. −1/8 so that is why this row is a negative frequency. The next row is negative two cycles of a complex exponential, sampled in eight places, so it has a fractional frequency of −1/4, and thus "measures" the extent to which the signal has a fractional frequency of +1/4.

The following summarizes how the 8-point DFT works, row by row, in terms of fractional frequency:

  • 0 measures how much DC is in the signal
  • −1/8 measures how much of the signal has a fractional frequency of +1/8
  • −1/4 measures how much of the signal has a fractional frequency of +1/4
  • −3/8 measures how much of the signal has a fractional frequency of +3/8
  • −1/2 measures how much of the signal has a fractional frequency of +1/2
  • −5/8 measures how much of the signal has a fractional frequency of +5/8
  • −3/4 measures how much of the signal has a fractional frequency of +3/4
  • −7/8 measures how much of the signal has a fractional frequency of +7/8

Equivalently the last row can be said to have a fractional frequency of +1/8 and thus measure how much of the signal has a fractional frequency of −1/8. In this way, it could be said that the top rows of the matrix "measure" positive frequency content in the signal and the bottom rows measure negative frequency component in the signal.

The DFT is (or can be, through appropriate selection of scaling) a unitary transform, i.e., one that preserves energy. The appropriate choice of scaling to achieve unitarity is 1 / N >> , so that the energy in the physical domain will be the same as the energy in the Fourier domain, i.e., to satisfy Parseval's theorem. (Other, non-unitary, scalings, are also commonly used for computational convenience e.g., the convolution theorem takes on a slightly simpler form with the scaling shown in the discrete Fourier transform article.)

For other properties of the DFT matrix, including its eigenvalues, connection to convolutions, applications, and so on, see the discrete Fourier transform article.


2. Using matmul() Function

The matmul() function in the NumPy library is used to return the matrix product of two given arrays.

then, A*B using matmul() function will be calculated like this:

Syntax for matmul() :

The syntax required to use this function is as follows:

It is important to note that while it returns a normal product for 2-D arrays, if dimensions of either of the given array is >2 then it is treated as a stack of matrices residing in the last two indexes and is broadcast accordingly. And on the other hand, if either argument is a 1-D array then it is promoted to a matrix by appending a 1 to its dimension, which is removed after multiplication.

Ejemplo 1:

In the example below, we have used the matmul() function for matrix multiplication:

The output of the above code will be:

Ejemplo 2:

Let's take another example in which the two arrays(matrix) being multiplied are of different dimensions:


A is [[1, 4], [2, 1]]
B is [1, 2]
AxB is
[9 4]
BxA is
[5 6]


Multiplication of Matrices

Matrix multiplication is an operation performed upon two (or sometimes more) matrices, with the result being another matrix.

This explanation will assume the student is familiar with the basics of matrices, such as matrix notation and vector dot products.

There are certain rules which must be followed in the multiplication process. First, when multiplying any two matrices #A_(rs)# and #B_(tu)# , where #r# and #t# are the number of rows in matrices #A & B# respectively and #s# and #u# the number of columns in matrices #A & B# respectively, if #s!=t# (that is, the number of rows in #A# does not equal the number of columns in #B# ), the matrix multiplication cannot be carried out.

When multiplying two matrices such as this, the resultant matrix #AB# will possess #r# rows and #u# columns in other words, the same number of rows as the #A# matrix and the same number of columns as the #B# matrix.

Each entry in the #AB# matrix will be calculated via the dot product of a row from the #A# matrix and a column from the #B# matrix. Renaming the #AB# matrix as #C# for ease of use, the value of any individual element #c_ij# can be found by taking the dot product of row #i# from #A# and column #j# from #B# .

There is currently some difficulty in utilizing Socratic's math code to construct a matrix, so different notation must be used temporarily. Consider the 2x3 matrix #A# , such that #a_11 = 1, a_12 = 0, a_13 = 3, a_21 = 0, a_22 = 5, a_23 = -1# , as well as the 3x2 matrix #B# such that #b_11 = 4, b_12 = 5, b_21 = 0, b_22 = -3, b_31 = -4, b_32 = 1# . Then the resultant matrix #AB = C# is a 2x2 matrix, with
#c_11 = (a_11*b_11) + (a_12*b_21) + (a_13*b_31)# ,
#c_12 = (a_11*b_12)+(a_12*b_22)+(a_13*b_32),#
#c_21 = (a_21*b_11) + (a_22*b_21)+(a_23*b_31), #
#c_22 = (a_21*b_12)+(a_22+b_22)+(a_23+b_32)#

Plugging in the respective values, we get #c_11 = -8, c_12 = 8, c_21 = 4, c_22 = -16#

There is some information on Multiplication of Matrices here on Socratic.

I think of it as a process that is easier to explain in person, but I'll do my best here.

Let's go through an example:

Find the first row of the product

Take the first row of #((1, 2),(3, 4))# , and make it vertical in front of #((3, 5),(7, 11))# . (We'll do the same for the second row in a minute.)

Now multiply times the first column and add to get the first number in the first row of the answer:
#<:(1 xx 3),(2 xx 7) :>=<:(3),(14) :># now add to get # 17#

Next multiply times the second column and add to get the second number in the first row of the answer:
#<:(1 xx 5),(2 xx 11) :>=<:(5),(22) :># now add to get # 27#

The first row of the product is: #((17,27))#

A this point we know that the product looks like:

Find the second row of the product
Find the second row of the product by the same process using the second row of #((1, 2),(3, 4))#

# <: (3),(4) :>((3, 5),(7, 11)) # to get: #9+28 = 37# and #15+44 = 59#

The second row of the product is: #((37,59))#

Write the answer


Matrix multiplication using SIMD instructions

In my previous post, I tried various things to improve the performance of a matrix multiplication using compiler features.

However, -O4 -fopenmp using transposed matrices turned out faster (0.882 seconds) than -O4 -fopenmp and auto-vectorization using untransposed matrices. I couldn’t get auto-vectorization to work with the transposed matrices.

In this post, we’ll use simple SIMD instructions to optimize this further. It builds up on my post from two days ago, where I explain how to use SIMD instructions for a very simple and synthetic example.

Note that much more can be done to optimized matrix multiplication than is described in this post. This post just explains the very basics. If you need more advanced algorithms, maybe look through these three links:

Using transposed matrices makes vectorizing matrix multiplication quite easy. ¿Por qué? Well, remember that in our simple example, there were three steps. The first step requires that the data to be loaded is laid out sequentially in memory.

  1. Loading data into SIMD registers
  2. Performing operations on corresponding operands in two SIMD registers
  3. Storing the result

Step 1: Loading data

Remember that the data load wanted a memory address where the four (or eight) float values were stored sequentially. Well, if we just transpose the matrix before we start doing stuff, we can just load the matrix B floats sequentially. So the code looks almost the same as in the baby steps post. To make things a bit easier, we will be using SSE for now.

Step 2: Doing the calculations

Está bien. We have our floats loaded into two registers. In SSE, we have four floats per register:

Register 1 (va) 0.1 0.1 0.1 0.1
Register 2 (vb) 0.2 0.2 0.2 0.2

The first step is to multiply. In the baby steps post, we used _mm_add_ps to perform addition. Well, multiplication uses an intrinsic with a similar name: _mm_mul_ps. (The AVX version is _mm256_mul_ps.) So if we do:

¡Estupendo! Now we just need to add the contents of vresult together! Unfortunately, there is no SIMD instruction that would add every component together to give us 0.08 as the output, given the above vresult as its only input.

From SSE3, there exists _mm_hadd_ps however, the “horizontal add” instruction (https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_hadd_ps&expand=2777), which takes two registers as input (you can use the same registers), and computes:

va 0.1 0.2 0.3 0.4
vb 0.5 0.6 0.7 0.8
vresult 0.3 0.7 1.1 1.5

Sorry for the weird color scheme. Maybe you can already see that this is a bit odd – why does it want two registers as input, for starters? We wanted 0.1+0.2+0.3+0.4, which should be 1. Well, let’s see what happens when we use the same register for both inputs, and perform this operation twice!

va 0.1 0.2 0.3 0.4
va 0.1 0.2 0.3 0.4
vresult 0.3 0.7 0.3 0.7
vresult 0.3 0.7 0.3 0.7
vresult 0.3 0.7 0.3 0.7
vresult (new) 1 1 1 1

Yay, we did it! We got 1, which is the result of 0.1+0.2+0.3+0.4. (This works for SSE. We will talk about AVX later.) Here’s the code:

Step 3: Storing the result

Step 3 involves storing the result. We can of course just store the four bytes into an array as before, but as they’re all the same, we’re really only interested in one of them. We could use _mm_extract_ps, which is capable of extracting any of the four floats. But we can do slightly better, we can just cast, which will get us the lowest float in the 128-bit register. There is an intrinsic for this type of cast, _mm_cvtss_f32, so we can just write:

And that’s (assuming SSE3) four sub-operations of the matrix multiplication done in one go! Because we’re doing four ks at once, we have to change the inner loop to reflect that:

So let’s see the code. In this example I’ve also decided to use malloc instead of stack arrays (except for result), so matrix_a[i][k] turns into matrix_a+(i*1024)+k.

And the run time is about 1.054 seconds using a single thread. Note that we have to pass -msse3 to gcc, as vanilla SSE does not support the horizontal add instruction.

As mentioned earlier, the double-hadd method does not work for the AVX _mm256_hadd_ps intrinsic (https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm256_hadd_ps&expand=2778), which works like this:

Here’s a va-vb-table that shows what happens with AVX:

va 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8
vb 0.9 1 1.1 1.2 1.3 1.4 1.5 1.6
vresult 0.3 0.7 1.9 1.3 1.1 1.5 2.7 3.1

Here’s the first va-va table of the double-hadd method:

va 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8
va 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8
vresult 0.3 0.7 0.3 0.7 1.1 1.5 1.1 1.5

And the second vresult-vresult table:

vresult 0.3 0.7 0.3 0.7 1.1 1.5 1.1 1.5
vresult 0.3 0.7 0.3 0.7 1.1 1.5 1.1 1.5
vresult (new) 1 1 1 1 2.6 2.6 2.6 2.6

As you can see, we do not reach our expected result of 3.6 (0.1+0.2+…+0.8). (It’s just like it’s doing two SSE hadds completely independent from each other.) There are various ways to get out of this problem, e.g. extract the two 128-bit halves from the 256-bit register, and then use SSE instructions. This is how you extract:

The second argument indicates with half you want.

As an aside: instead of extracting the lower 128 bits and putting them in a register, we can also use a cast, _mm256_castps256_ps128 (https://software.intel.com/en-us/node/524181).

The lower 128-bits of the source vector are passed unchanged to the result. This intrinsic does not introduce extra moves to the generated code.

Anyway, let’s go with the extracted values first. So we have the following situation:

vlow 0.1 0.2 0.3 0.4
vhigh 0.5 0.6 0.7 0.8

And we want to add all these eight values together. So why don’t we just simply use our trusty _mm_add_ps(vlow, vhigh) first? This way we can do four of eight required additions, leaving us with the following 128-bit register:

And now we want to add up horizontally, so we use the double-_mm_hadd_ps method described above:

vresult 0.6 0.8 1 1.2
vresult 0.6 0.8 1 1.2
vresult 1.4 2.2 1.4 2.2
vresult 1.4 2.2 1.4 2.2
vresult 1.4 2.2 1.4 2.2
vresult 3.6 3.6 3.6 3.6

That is… a tiny bit faster. (Note that I’m running everything multiple times to make sure the difference isn’t just due to change.) However, with AVX we are supposed to get twice the FLOPs, right? We’ll look at other optimizations of the vectorization in a later post. Before that, let’s add OpenMP into the mix.

OpenMP

Unfortunately, OpenMP’s #pragma omp parallel for sometimes doesn’t appear to do what you need it to do. Sticking this in front of the outer (i) loop reduces performance by half! However, we can be sure that this isn’t the processor “oversubscribing” the SIMD units, because if we run two instances of our program at the same time, both finish with almost the same run time we see with just a single instance:

So we’ll use the same chunking trick that we used last time, and our result gets a little better: 0.753 seconds:

To be honest, with a 2 core/4 thread system, I would have expected better. Running multiple instances doesn’t increase the run time, and the previous version took only 1.27 times as long as this.

Re-evaluating our performance measurements

Array initialization will always take the same small amount of time, but printf(“%f”, …) takes a non-constant amount of time and depends on the values. Let’s see what kind of timing we get when we change this to an %x format string.

That sounds much better, both in absolute terms and in OpenMP terms. By the way, if we remove the matrix multiplication and only leave initialization and output, we still get an execution time of about 0.111 seconds. So it’s reasonably safe to say that our matrix multiplication takes about 0.377 seconds on a single thread. (I feel like I shot myself in the foot for measuring this using shell’s time, rather than embedding the measurement in the code itself…)

Aligned accesses

To allow the use of the aligned _mm256_load_ps, allocate your memory like this:

Unfortunately, I didn’t notice a significant difference. (You may be able to shave off a few percent.)


Ver el vídeo: Sec Prep Matrix Multiplication (Octubre 2021).