12. Multiplicación de matrices

La multiplicación matricial combina las filas de la primera matriz con las columnas de la segunda. Las dimensiones internas deben coincidir y las dimensiones externas determinan el orden del resultado.

12.1 Introducción

La multiplicación de matrices es diferente de la suma, la resta y la multiplicación por un escalar. No consiste en multiplicar directamente los elementos que ocupan la misma posición.

Cada elemento del resultado se obtiene combinando una fila completa de la primera matriz con una columna completa de la segunda. Esta regla permite representar composiciones de transformaciones, sistemas lineales, recorridos en grafos y capas de modelos de aprendizaje automático.

Producto matricial = fila de A por columna de B

12.2 Compatibilidad de dimensiones

Sea A una matriz de orden m × n y B una matriz de orden r × p. El producto AB existe solamente si n = r.

Am×n · Bn×p = Cm×p

Las dimensiones internas n deben coincidir.
Las dimensiones externas m y p forman el resultado.
function sonMultiplicables(A, B) {
  if (!A.length || !B.length || !A[0].length || !B[0].length) {
    return false;
  }

  return A[0].length === B.length;
}

console.log(sonMultiplicables([[1, 2, 3]], [[1], [2], [3]]));
console.log(sonMultiplicables([[1, 2]], [[1, 2]]));

12.3 Dimensión del resultado

Orden de A Orden de B ¿Existe AB? Orden de AB
2 × 3 3 × 4 2 × 4
1 × 3 3 × 1 1 × 1
3 × 1 1 × 2 3 × 2
2 × 3 2 × 3 No No definido
3 × 3 3 × 3 3 × 3

Que dos matrices tengan el mismo orden no es la condición general. Lo importante es comparar las columnas de la primera con las filas de la segunda.

12.4 Producto de una fila por una columna

Multiplicamos componentes correspondientes y sumamos los productos.

[a1   a2   a3] · [b1] = a1b1 + a2b2 + a3b3
                                 [b2]
                                 [b3]
function filaPorColumna(fila, columna) {
  if (fila.length !== columna.length) {
    throw new Error("Las longitudes deben coincidir");
  }

  return fila.reduce(
    (suma, valor, k) => suma + valor * columna[k],
    0
  );
}

console.log(filaPorColumna([2, 3, 4], [5, 6, 7]));

El resultado es 56. Este cálculo se repite para cada posición de la matriz producto.

12.5 Ejemplo con matrices de orden 2 × 2

A = [1   2]    B = [5   6]
    [3   4]       [7   8]

c11 = 1·5 + 2·7 = 19
c12 = 1·6 + 2·8 = 22
c21 = 3·5 + 4·7 = 43
c22 = 3·6 + 4·8 = 50

AB = [19   22]
     [43   50]
const A = [[1, 2], [3, 4]];
const B = [[5, 6], [7, 8]];

const AB = [
  [A[0][0] * B[0][0] + A[0][1] * B[1][0],
   A[0][0] * B[0][1] + A[0][1] * B[1][1]],
  [A[1][0] * B[0][0] + A[1][1] * B[1][0],
   A[1][0] * B[0][1] + A[1][1] * B[1][1]]
];

console.log(AB);

12.6 Ejemplo con matrices rectangulares

Una matriz 2 × 3 puede multiplicarse por una matriz 3 × 2. El resultado será 2 × 2.

const A = [[1, 2, 3], [4, 5, 6]];
const B = [[7, 8], [9, 10], [11, 12]];

const C = A.map(fila =>
  B[0].map((_, j) =>
    fila.reduce((suma, valor, k) => suma + valor * B[k][j], 0)
  )
);

console.log(C);
console.log(`Orden: ${C.length} × ${C[0].length}`);

El resultado es [[58, 64], [139, 154]].

12.7 Fórmula general

Si C = AB, cada elemento cij se calcula sumando los productos entre la fila i de A y la columna j de B.

cij = Σ desde k = 1 hasta n de aikbkj

cij = ai1b1j + ai2b2j + ... + ainbnj

El índice k recorre la dimensión interna compartida por ambas matrices.

12.8 Algoritmo general en JavaScript

El algoritmo utiliza tres recorridos: filas de A, columnas de B y dimensión interna k.

function multiplicarMatrices(A, B) {
  if (A[0].length !== B.length) {
    throw new Error("Dimensiones incompatibles");
  }

  const filasResultado = A.length;
  const columnasResultado = B[0].length;
  const dimensionInterna = B.length;
  const C = Array.from({ length: filasResultado }, () =>
    Array(columnasResultado).fill(0)
  );

  for (let i = 0; i < filasResultado; i++) {
    for (let j = 0; j < columnasResultado; j++) {
      for (let k = 0; k < dimensionInterna; k++) {
        C[i][j] += A[i][k] * B[k][j];
      }
    }
  }

  return C;
}

console.log(multiplicarMatrices(
  [[1, 2, 3], [4, 5, 6]],
  [[7, 8], [9, 10], [11, 12]]
));

12.9 Validación segura

Antes de multiplicar debemos verificar que ambas entradas sean matrices rectangulares numéricas y que sus dimensiones internas coincidan.

function obtenerOrden(matriz) {
  if (!Array.isArray(matriz) || matriz.length === 0) return null;
  if (!matriz.every(fila => Array.isArray(fila))) return null;

  const columnas = matriz[0].length;
  const valida = columnas > 0 && matriz.every(fila =>
    fila.length === columnas && fila.every(Number.isFinite)
  );

  return valida ? [matriz.length, columnas] : null;
}

function validarProducto(A, B) {
  const ordenA = obtenerOrden(A);
  const ordenB = obtenerOrden(B);

  if (!ordenA || !ordenB) return { valido: false, motivo: "Matriz inválida" };
  if (ordenA[1] !== ordenB[0]) {
    return { valido: false, motivo: "Dimensiones internas diferentes" };
  }

  return { valido: true, ordenResultado: [ordenA[0], ordenB[1]] };
}

console.log(validarProducto([[1, 2, 3]], [[1], [2], [3]]));

12.10 Multiplicación de una matriz por un vector

Un vector columna de n componentes puede considerarse una matriz n × 1. Una matriz A de orden m × n lo transforma en un vector de m componentes.

Am×nvn×1 = wm×1
function matrizPorVector(A, vector) {
  if (A[0].length !== vector.length) {
    throw new Error("Dimensiones incompatibles");
  }

  return A.map(fila =>
    fila.reduce((suma, valor, k) => suma + valor * vector[k], 0)
  );
}

const A = [[2, 0, 1], [1, 3, 0]];
const v = [4, 5, 6];

console.log(matrizPorVector(A, v));

12.11 Producto con la matriz identidad

La identidad es el elemento neutro de la multiplicación. Para una matriz A de orden m × n:

ImA = A
AIn = A
function multiplicar(A, B) {
  return A.map(fila =>
    B[0].map((_, j) =>
      fila.reduce((suma, valor, k) => suma + valor * B[k][j], 0)
    )
  );
}

const A = [[2, 5, 1], [4, 3, 7]];
const I2 = [[1, 0], [0, 1]];
const I3 = [[1, 0, 0], [0, 1, 0], [0, 0, 1]];

console.log(multiplicar(I2, A));
console.log(multiplicar(A, I3));

12.12 Producto con una matriz nula

Cuando las dimensiones son compatibles, multiplicar por una matriz nula produce una matriz nula del orden correspondiente.

Am×nOn×p = Om×p
const A = [[1, 2, 3], [4, 5, 6]];
const O = [[0, 0], [0, 0], [0, 0]];

const resultado = A.map(fila =>
  O[0].map((_, j) =>
    fila.reduce((suma, valor, k) => suma + valor * O[k][j], 0)
  )
);

console.log(resultado);

Sin embargo, de AB = O no se puede concluir que A = O o B = O. Existen matrices no nulas cuyo producto es nulo.

12.13 El producto no es conmutativo

En general, cambiar el orden de las matrices cambia el resultado. Incluso puede ocurrir que AB exista y BA no exista.

AB ≠ BA, en general
function multiplicar(A, B) {
  return A.map(fila =>
    B[0].map((_, j) =>
      fila.reduce((suma, valor, k) => suma + valor * B[k][j], 0)
    )
  );
}

const A = [[1, 2], [0, 1]];
const B = [[2, 0], [3, 1]];

console.log("AB:", multiplicar(A, B));
console.log("BA:", multiplicar(B, A));

12.14 Propiedad asociativa

Si las dimensiones permiten ambos cálculos, podemos cambiar la agrupación sin cambiar el orden de las matrices.

(AB)C = A(BC)
const multiplicar = (A, B) => A.map(fila =>
  B[0].map((_, j) =>
    fila.reduce((suma, valor, k) => suma + valor * B[k][j], 0)
  )
);

const A = [[1, 2], [3, 4]];
const B = [[2, 0], [1, 2]];
const C = [[1, 1], [0, 1]];

console.log(multiplicar(multiplicar(A, B), C));
console.log(multiplicar(A, multiplicar(B, C)));

La propiedad permite elegir una agrupación más conveniente, pero no intercambiar A, B y C.

12.15 Propiedad distributiva

El producto se distribuye respecto de la suma por ambos lados, siempre que las dimensiones sean compatibles.

A(B + C) = AB + AC
(A + B)C = AC + BC
const sumar = (A, B) => A.map((fila, i) =>
  fila.map((valor, j) => valor + B[i][j])
);

const multiplicar = (A, B) => A.map(fila =>
  B[0].map((_, j) =>
    fila.reduce((suma, valor, k) => suma + valor * B[k][j], 0)
  )
);

const A = [[1, 2], [3, 4]];
const B = [[2, 0], [1, 2]];
const C = [[0, 1], [2, 3]];

console.log(multiplicar(A, sumar(B, C)));
console.log(sumar(multiplicar(A, B), multiplicar(A, C)));

12.16 Composición de transformaciones

El producto de matrices permite combinar transformaciones. Con vectores columna, el producto ABv aplica primero B y después A.

const multiplicar = (A, B) => A.map(fila =>
  B[0].map((_, j) =>
    fila.reduce((suma, valor, k) => suma + valor * B[k][j], 0)
  )
);

const aplicar = (A, v) => A.map(fila =>
  fila.reduce((suma, valor, k) => suma + valor * v[k], 0)
);

const escalaX = [[2, 0], [0, 1]];
const rotacion90 = [[0, -1], [1, 0]];
const punto = [1, 1];

console.log("Rotar después de escalar:", aplicar(multiplicar(rotacion90, escalaX), punto));
console.log("Escalar después de rotar:", aplicar(multiplicar(escalaX, rotacion90), punto));

Los resultados son diferentes porque el orden de las transformaciones importa.

12.17 Aplicaciones en programación

La multiplicación matricial aparece en muchas áreas:

  • Composición de rotaciones, escalados y proyecciones gráficas.
  • Evaluación de sistemas de ecuaciones lineales.
  • Cálculo de capas lineales en redes neuronales.
  • Análisis de conexiones y caminos en grafos.
  • Conversión de colores y procesamiento de señales.
  • Transformación de conjuntos completos de datos.
function capaLineal(pesos, entrada, sesgo) {
  return pesos.map((fila, i) =>
    fila.reduce((suma, peso, j) => suma + peso * entrada[j], 0) + sesgo[i]
  );
}

const pesos = [[0.5, -0.2, 0.1], [0.3, 0.8, -0.4]];
const entrada = [10, 5, 2];
const sesgo = [1, -1];

console.log(capaLineal(pesos, entrada, sesgo));

El producto entre la matriz de pesos y el vector de entrada genera un nuevo vector; después se suma el sesgo.

12.18 Producto matricial y producto elemento a elemento

El producto elemento a elemento, también llamado producto de Hadamard, multiplica posiciones correspondientes y exige matrices del mismo orden. No es el producto matricial.

Característica Producto matricial AB Producto elemento a elemento
Condición Columnas de A = filas de B Mismo orden
Cálculo Filas por columnas y sumas Posiciones correspondientes
Orden del resultado Filas de A × columnas de B El mismo orden de A y B
Uso Composición y transformaciones Máscaras y ponderación individual
const A = [[1, 2], [3, 4]];
const B = [[5, 6], [7, 8]];

const hadamard = A.map((fila, i) =>
  fila.map((valor, j) => valor * B[i][j])
);

const matricial = A.map(fila =>
  B[0].map((_, j) =>
    fila.reduce((suma, valor, k) => suma + valor * B[k][j], 0)
  )
);

console.log("Elemento a elemento:", hadamard);
console.log("Matricial:", matricial);

Entre los errores frecuentes se encuentran confundir ambos productos, invertir las dimensiones internas, intercambiar el orden de los factores y olvidar validar filas irregulares.

12.19 Qué debes recordar de este tema

  • AB existe cuando las columnas de A coinciden con las filas de B.
  • Si A es m × n y B es n × p, entonces AB es m × p.
  • Cada elemento del resultado se obtiene multiplicando una fila por una columna.
  • La multiplicación matricial no es una operación elemento a elemento.
  • En general, AB ≠ BA.
  • El producto es asociativo y distributivo respecto de la suma.
  • La identidad es el elemento neutro y una matriz nula compatible produce un producto nulo.
  • Con vectores columna, ABv aplica primero B y después A.

12.20 Conclusión

La multiplicación matricial conecta filas con columnas y permite encadenar relaciones y transformaciones. Comprender las dimensiones antes de calcular es tan importante como aplicar correctamente la suma de productos.

En el próximo tema estudiaremos con mayor detalle las propiedades de las operaciones matriciales y cómo utilizarlas para reorganizar y simplificar expresiones.