9. Igualdad de matrices

Dos matrices son iguales cuando tienen el mismo orden y todos sus elementos correspondientes son iguales. En programación también debemos distinguir entre comparar referencias, contenidos exactos y resultados aproximados.

9.1 Introducción

Comparar matrices es necesario para comprobar resultados, validar datos, resolver ecuaciones y escribir pruebas automatizadas. La igualdad matricial posee una definición precisa: no basta con que las matrices tengan algunos valores en común o la misma cantidad total de elementos.

Debemos comprobar dos condiciones:

  1. Las matrices tienen el mismo orden.
  2. Los elementos ubicados en posiciones correspondientes son iguales.
A = B si tienen el mismo orden y aij = bij para toda posición (i, j).

9.2 Definición formal

Sean A y B dos matrices. Si A tiene orden m × n y B tiene orden p × q, entonces A = B solamente si:

m = p
n = q
aij = bij para todo i y j

La igualdad se escribe A = B. Cuando no se cumplen las condiciones, escribimos A ≠ B.

9.3 Primera condición: mismo orden

Dos matrices de dimensiones diferentes nunca son iguales, aunque contengan los mismos números o la misma cantidad total de elementos.

A = [1   2   3   4] tiene orden 1 × 4.

B = [1   2] tiene orden 2 × 2.
    [3   4]

A ≠ B
function tienenMismoOrden(A, B) {
  if (!A.length || !B.length) return false;

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

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

9.4 Segunda condición: elementos correspondientes

Una vez comprobado el orden, comparamos cada elemento con el que ocupa la misma fila y columna en la otra matriz.

A = [ 2   5 ]    B = [ 2   5 ]
    [ 1   7 ]       [ 1   7 ]

a11 = b11, a12 = b12,
a21 = b21, a22 = b22.

Por lo tanto, A = B.

La comparación siempre relaciona posiciones iguales. No podemos cambiar el orden de filas o columnas para intentar obtener igualdad.

9.5 Ejemplos de matrices iguales

Matriz A Matriz B Motivo
[[3, 5]] [[3, 5]] Mismo orden y mismos elementos
[[2], [7]] [[1 + 1], [10 - 3]] Las expresiones producen los mismos valores
[[0, 0], [0, 0]] O2×2 Ambas son la matriz nula 2 × 2
[[1, 0], [0, 1]] I2 Ambas representan la identidad de orden 2

Los nombres y las expresiones utilizadas para obtener los elementos pueden ser diferentes. Lo que importa es el valor final de cada posición.

9.6 Ejemplos de matrices diferentes

Las siguientes situaciones producen matrices distintas:

  • Tienen diferente cantidad de filas.
  • Tienen diferente cantidad de columnas.
  • Al menos un par de elementos correspondientes es diferente.
  • Contienen los mismos valores, pero ubicados en posiciones diferentes.
A = [1   2]    B = [1   3]
    [3   4]       [2   4]

A ≠ B porque a12 ≠ b12 y a21 ≠ b21.

9.7 La igualdad produce ecuaciones

Cuando una matriz contiene incógnitas, la igualdad con otra matriz permite formar una ecuación por cada par de elementos correspondientes.

A = [ x + 1     2 ]    B = [5   2]
    [   3       y - 2 ]       [3   6]

x + 1 = 5 → x = 4
y - 2 = 6 → y = 8
const x = 5 - 1;
const y = 6 + 2;

const A = [[x + 1, 2], [3, y - 2]];
const B = [[5, 2], [3, 6]];

console.log("x =", x);
console.log("y =", y);
console.log(A, B);

9.8 Propiedades de la igualdad

La igualdad de matrices es una relación de equivalencia y cumple tres propiedades.

  • Reflexiva: A = A.
  • Simétrica: si A = B, entonces B = A.
  • Transitiva: si A = B y B = C, entonces A = C.

Estas propiedades permiten sustituir una matriz por otra igual dentro de cualquier expresión compatible.

9.9 Referencias y contenidos en JavaScript

El operador === aplicado a arreglos no compara sus elementos. Comprueba si ambas variables apuntan al mismo objeto en memoria.

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

console.log(A === B);
console.log(A === C);

A y B tienen contenidos matemáticamente iguales, pero son objetos distintos. C contiene la misma referencia que A, por eso A === C es verdadero.

9.10 Comparación exacta en JavaScript

Para comparar contenidos debemos recorrer las matrices y revisar dimensiones y valores.

function matricesIguales(A, B) {
  if (A.length !== B.length) return false;

  return A.every((fila, i) =>
    fila.length === B[i].length &&
    fila.every((valor, j) => valor === B[i][j])
  );
}

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

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

9.11 Validar antes de comparar

Una comparación robusta debe rechazar valores que no sean matrices rectangulares válidas.

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

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

console.log(esMatrizValida([[1, 2], [3, 4]]));
console.log(esMatrizValida([[1, 2], [3]]));
console.log(esMatrizValida([[1, 2], [3, NaN]]));

Esta función exige filas de igual longitud y elementos numéricos finitos.

9.12 El problema de los números decimales

Las computadoras representan muchos números decimales mediante aproximaciones binarias. Por eso, dos cálculos matemáticamente equivalentes pueden no producir exactamente el mismo valor almacenado.

const A = [[0.1 + 0.2]];
const B = [[0.3]];

console.log(A[0][0]);
console.log(B[0][0]);
console.log(A[0][0] === B[0][0]);

En matemática esperamos igualdad, pero la comparación exacta de JavaScript devuelve falso debido al redondeo de punto flotante.

9.13 Igualdad aproximada con tolerancia absoluta

Para resultados numéricos podemos considerar iguales dos valores si su diferencia absoluta es menor o igual que una tolerancia.

|aij - bij| ≤ tolerancia
function matricesCasiIguales(A, B, tolerancia = 1e-9) {
  if (A.length !== B.length) return false;

  return A.every((fila, i) =>
    fila.length === B[i].length &&
    fila.every((valor, j) =>
      Math.abs(valor - B[i][j]) <= tolerancia
    )
  );
}

console.log(matricesCasiIguales([[0.1 + 0.2]], [[0.3]]));

La tolerancia adecuada depende de la precisión necesaria y de la escala de los datos.

9.14 Tolerancia relativa

Una tolerancia absoluta puede ser inadecuada cuando los valores son muy grandes o muy pequeños. Podemos ajustar el límite según la magnitud de los números comparados.

function casiIguales(a, b, tolerancia = 1e-9) {
  const escala = Math.max(1, Math.abs(a), Math.abs(b));
  return Math.abs(a - b) <= tolerancia * escala;
}

function matricesCasiIguales(A, B, tolerancia = 1e-9) {
  return A.length === B.length && A.every((fila, i) =>
    fila.length === B[i].length &&
    fila.every((valor, j) => casiIguales(valor, B[i][j], tolerancia))
  );
}

console.log(matricesCasiIguales(
  [[1000000000, 0.000001]],
  [[1000000000.1, 0.0000010000001]]
));

Esta estrategia combina un piso absoluto con una comparación proporcional a la escala.

9.15 Medir la diferencia máxima

Además de obtener verdadero o falso, puede ser útil conocer el mayor error entre elementos correspondientes.

function diferenciaMaxima(A, B) {
  if (A.length !== B.length ||
      A.some((fila, i) => fila.length !== B[i].length)) {
    return Infinity;
  }

  let maxima = 0;
  A.forEach((fila, i) =>
    fila.forEach((valor, j) => {
      maxima = Math.max(maxima, Math.abs(valor - B[i][j]));
    })
  );

  return maxima;
}

const A = [[1, 2], [3, 4]];
const B = [[1.001, 2], [2.998, 4.0005]];

console.log(diferenciaMaxima(A, B));

Este valor permite informar cuánto se alejan los resultados en lugar de limitarse a una decisión binaria.

9.16 Igualdad y copias de matrices

Una copia puede comenzar siendo igual a la matriz original y dejar de serlo después de una modificación. Conviene copiar también cada fila para evitar compartir arreglos internos.

const A = [[1, 2], [3, 4]];
const copia = A.map(fila => [...fila]);

console.log("Antes:", JSON.stringify(A) === JSON.stringify(copia));

copia[0][0] = 99;

console.log("Después:", JSON.stringify(A) === JSON.stringify(copia));
console.log("Original:", A);
console.log("Copia:", copia);

JSON.stringify resulta útil en este ejemplo simple, pero una función elemento a elemento permite controlar mejor validaciones y tolerancias.

9.17 Uso en pruebas de programas

La comparación de matrices permite verificar que una operación produzca el resultado esperado.

function transponer(matriz) {
  return matriz[0].map((_, j) =>
    matriz.map(fila => fila[j])
  );
}

function matricesIguales(A, B) {
  return A.length === B.length && A.every((fila, i) =>
    fila.length === B[i].length &&
    fila.every((valor, j) => valor === B[i][j])
  );
}

const resultado = transponer([[1, 2, 3], [4, 5, 6]]);
const esperado = [[1, 4], [2, 5], [3, 6]];

console.log("Prueba aprobada:", matricesIguales(resultado, esperado));

En aplicaciones científicas suele utilizarse una comparación aproximada para verificar algoritmos que realizan numerosos cálculos decimales.

9.18 Errores frecuentes

  • Comparar solamente la cantidad total de elementos.
  • Ignorar la posición de los valores.
  • Comparar solo una fila o la diagonal.
  • Usar === esperando que JavaScript compare el contenido de dos arreglos distintos.
  • No validar que todas las filas tengan igual longitud.
  • Exigir igualdad exacta después de operaciones con punto flotante.
  • Usar una tolerancia tan grande que oculte errores significativos.
  • Modificar una copia superficial que todavía comparte filas con la matriz original.

9.19 Qué debes recordar de este tema

  • Dos matrices son iguales si tienen el mismo orden y elementos correspondientes iguales.
  • Los mismos valores en posiciones diferentes no producen matrices iguales.
  • La igualdad de matrices con incógnitas genera ecuaciones entre elementos correspondientes.
  • En JavaScript, === compara referencias de arreglos, no sus contenidos.
  • La comparación exacta es apropiada para enteros y resultados controlados.
  • Los cálculos decimales suelen requerir tolerancia absoluta o relativa.
  • Medir la diferencia máxima ayuda a evaluar la calidad de un resultado.

9.20 Conclusión

La igualdad matricial exige coincidencia de forma y contenido. En programación debemos traducir esta definición a un recorrido completo y elegir entre comparación exacta o aproximada según el origen de los valores.

En el próximo tema aprenderemos a sumar y restar matrices del mismo orden, aplicando operaciones elemento a elemento.