Complejidad de las multiplicaciones de matrices arbitrarias

Tengo una pregunta simple sobre la implementación de multiplicaciones de matrices. Sé que hay algoritmos para matrices de igual tamaño (nxn) que tienen una complejidad de O(n^2.xxx). Pero si tengo dos matrices A y B de diferentes tamaños (pxq, qxr), ¿cuál sería la complejidad mínima de la implementación a la fecha? Supongo que es O (pqr) ya que implementaría una multiplicación con 3 bucles anidados con iteraciones p, q y r. En particular, ¿alguien sabe cómo Propio biblioteca implementa una multiplicación?

preguntado el 09 de marzo de 12 a las 17:03

¿Has mirado el código fuente de Eigen? -

Sí, no lo entendí. No soy un gran matemático. :( -

3 Respuestas

Una técnica común es rellenar matrices con tamaño (p*q, q*r), de modo que sus tamaños se conviertan en (n*n). Luego, puedes aplicar el algoritmo de Strassen.

respondido 10 mar '12, 12:03

¿Hay publicaciones sobre esto o hay bibliotecas que usan esta técnica? - alfa

Mmm. El algoritmo de Strassen trata sobre la partición recursiva en tamaños iguales. También lo es la búsqueda binaria. La manera de hacer una búsqueda binaria rápida en una potencia de dos es hacer un primer paso que decida qué porción restante de tamaño de potencia de dos buscar, y luego realiza una búsqueda binaria eficiente que divide exactamente por dos. Espero que un concepto similar funcione para Strassen; donde no obtienes una partición ordenada, crea una fea, haz Strassen en el gran trozo binario y aplica strassen y correcciones a lo que queda. (Los árboles cuádruples hacen algo como esto con mucho éxito). - ira baxter

Tiene razón acerca de que es O (pqr) exactamente por las razones que indicó.

No estoy seguro de cómo lo implementa Eigen, pero hay muchas formas de optimizar los algoritmos de multiplicación de matrices, como optimizar el rendimiento de la memoria caché mediante embaldosado y ser consciente de si el idioma que está utilizando es fila mayor o columna mayor (Desea que los bucles internos accedan a la memoria en pasos lo más pequeños posible para evitar errores de caché). Se detallan algunas otras técnicas de optimización. aquí.

respondido 09 mar '12, 17:03

Como mencionó Yu-Had Lyu, puede rellenarlos con ceros, pero a menos que p, q y r estén cerca, la complejidad degenera (es hora de realizar el relleno).

Para responder a su otra pregunta sobre cómo Eigen lo implementa:

La forma en que los paquetes numéricos implementan la multiplicación de matrices es normalmente mediante el uso del algoritmo O(pqr) típico, pero muy optimizado en formas 'no matemáticas': bloqueo para una mejor localidad de caché, uso de instrucciones de procesador especiales (SIMD, etc.)

Algunos paquetes (MATLAB, Octave, ublas) usan dos bibliotecas llamadas BLAS y LAPACK que proporcionan primitivas de álgebra lineal (como la multiplicación de matrices) muy optimizadas de esta manera (a veces usando optimizaciones específicas de hardware).

AFAIK, Eigen simplemente usa instrucciones de bloqueo y SIMD.

Pocas bibliotecas numéricas comunes (incluido Eigen) utilizan Algoritmo de Strassen. La razón de esto es realmente muy interesante: mientras que la complejidad es mejor (O(n^(log2 7))) las constantes ocultas detrás del gran Oh son muy grandes debido a todas las adiciones realizadas; en otras palabras, el algoritmo solo es útil en la práctica para matrices grandes.

Nota: Hay un algoritmo aún más eficiente (en términos de complejidad asintótica) que el algoritmo de Strassen: el Algoritmo de calderero-Winograd con O(n^(2.3727)), pero para las cuales las constantes son tan grandes que es poco probable que alguna vez se use en la práctica. De hecho, se cree que existe un algoritmo que se ejecuta en O (n ^ 2) (que es el límite inferior trivial, ya que cualquier algoritmo necesita al menos leer los n ^ 2 elementos de las matrices).

contestado el 20 de mayo de 12 a las 21:05

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.