Las matrices diagonales, triangulares y simétricas concentran información en posiciones específicas. Su estructura permite simplificar operaciones, resolver sistemas con menos cálculos y utilizar representaciones más eficientes.
Una matriz general puede contener valores distintos de cero en cualquier posición. Sin embargo, muchas matrices que aparecen en programación poseen patrones: ceros fuera de la diagonal, ceros a un lado de ella o valores reflejados respecto de la diagonal principal.
Reconocer estos patrones permite evitar operaciones innecesarias. También ayuda a elegir algoritmos y estructuras de almacenamiento especializados.
Una matriz diagonal es cuadrada y todos los elementos situados fuera de la diagonal principal son cero. Los valores de la diagonal pueden ser distintos entre sí y también pueden incluir ceros.
En notación de índices, una matriz diagonal cumple dij = 0 cuando i ≠ j.
Primero comprobamos que la matriz sea cuadrada. Después verificamos que toda posición ajena a la diagonal contenga cero.
function esDiagonal(matriz) {
const n = matriz.length;
if (!n || !matriz.every(fila => fila.length === n)) return false;
return matriz.every((fila, i) =>
fila.every((valor, j) => i === j || valor === 0)
);
}
console.log(esDiagonal([[5, 0, 0], [0, 2, 0], [0, 0, 8]]));
console.log(esDiagonal([[5, 1, 0], [0, 2, 0], [0, 0, 8]]));
Una matriz diagonal queda completamente determinada por los valores de su diagonal. Podemos recibir esos valores en un vector y colocar ceros en las demás posiciones.
function crearDiagonal(diagonal) {
return diagonal.map((valor, i) =>
diagonal.map((_, j) => i === j ? valor : 0)
);
}
const D = crearDiagonal([5, 2, 8]);
console.log(D);
La matriz identidad es un caso particular en el que todos los valores recibidos son iguales a uno.
Muchas operaciones se reducen a trabajar con los elementos de la diagonal.
Al multiplicar una matriz diagonal por un vector, cada componente se multiplica solamente por el valor diagonal correspondiente.
function diagonalPorVector(diagonal, vector) {
if (diagonal.length !== vector.length) {
throw new Error("Las dimensiones deben coincidir");
}
return diagonal.map((valor, i) => valor * vector[i]);
}
console.log(diagonalPorVector([2, 3, 4], [5, 6, 7]));
En lugar de realizar n² productos, la representación diagonal necesita solamente n productos.
Una matriz triangular superior es cuadrada y todos los elementos debajo de la diagonal principal son cero.
Se cumple uij = 0 cuando i > j. Los elementos de la diagonal y los situados encima de ella pueden tomar cualquier valor.
Una matriz triangular inferior es cuadrada y todos los elementos encima de la diagonal principal son cero.
Se cumple lij = 0 cuando i < j.
Una matriz diagonal es al mismo tiempo triangular superior e inferior. Por eso una función puede devolver más de una propiedad.
function analizarTriangular(matriz) {
const n = matriz.length;
if (!n || !matriz.every(fila => fila.length === n)) {
return { superior: false, inferior: false };
}
let superior = true;
let inferior = true;
for (let i = 0; i < n; i++) {
for (let j = 0; j < n; j++) {
if (i > j && matriz[i][j] !== 0) superior = false;
if (i < j && matriz[i][j] !== 0) inferior = false;
}
}
return { superior, inferior };
}
console.log(analizarTriangular([[2, 5, 7], [0, 3, 4], [0, 0, 6]]));
El determinante de una matriz triangular es el producto de los elementos de su diagonal principal. Esta propiedad evita aplicar métodos más costosos.
function determinanteTriangular(matriz) {
return matriz.reduce(
(producto, fila, i) => producto * fila[i],
1
);
}
const U = [[2, 5, 7], [0, 3, 4], [0, 0, 6]];
console.log(determinanteTriangular(U));
Antes de utilizar esta función debe comprobarse que la matriz sea triangular.
Un sistema con matriz triangular superior puede resolverse desde la última ecuación hacia la primera mediante sustitución hacia atrás.
function sustitucionHaciaAtras(U, b) {
const n = U.length;
const x = Array(n).fill(0);
for (let i = n - 1; i >= 0; i--) {
let suma = 0;
for (let j = i + 1; j < n; j++) {
suma += U[i][j] * x[j];
}
x[i] = (b[i] - suma) / U[i][i];
}
return x;
}
const U = [[2, 1, -1], [0, 3, 2], [0, 0, 4]];
const b = [5, 10, 8];
console.log(sustitucionHaciaAtras(U, b));
Para una matriz triangular inferior se utiliza sustitución hacia adelante, comenzando por la primera ecuación.
Una matriz simétrica es cuadrada y coincide con su transpuesta.
Los valores reflejados respecto de la diagonal principal son iguales: aij = aji.
Transponer una matriz intercambia sus filas por sus columnas. En una matriz simétrica, ese intercambio no modifica los valores.
function transponer(matriz) {
return matriz[0].map((_, j) =>
matriz.map(fila => fila[j])
);
}
const A = [[2, 5, 1], [5, 3, 7], [1, 7, 4]];
console.log(transponer(A));
La salida contiene las mismas filas que la matriz original.
Después de comprobar que la matriz sea cuadrada, comparamos cada elemento aij con su reflejo aji.
function esSimetrica(matriz) {
const n = matriz.length;
if (!n || !matriz.every(fila => fila.length === n)) return false;
for (let i = 0; i < n; i++) {
for (let j = i + 1; j < n; j++) {
if (matriz[i][j] !== matriz[j][i]) return false;
}
}
return true;
}
console.log(esSimetrica([[2, 5, 1], [5, 3, 7], [1, 7, 4]]));
Solo necesitamos revisar un lado de la diagonal, porque el otro contiene las posiciones reflejadas.
Podemos completar la mitad inferior copiando los valores reflejados de la mitad superior.
function completarSimetrica(parteSuperior) {
const n = parteSuperior.length;
return Array.from({ length: n }, (_, i) =>
Array.from({ length: n }, (_, j) =>
i <= j ? parteSuperior[i][j] : parteSuperior[j][i]
)
);
}
const superior = [[2, 5, 1], [0, 3, 7], [0, 0, 4]];
console.log(completarSimetrica(superior));
Las matrices simétricas aparecen cuando una relación entre i y j es igual a la relación entre j e i.
| Tipo | Valores necesarios | Propiedades adicionales |
|---|---|---|
| Diagonal n × n | n | Triangular superior, inferior y simétrica |
| Triangular n × n | n(n + 1) / 2 | Determinante igual al producto diagonal |
| Simétrica n × n | n(n + 1) / 2 | Coincide con su transpuesta |
| General n × n | n² | Sin patrón obligatorio |
Una matriz diagonal puede guardarse solamente como el vector de su diagonal.
const diagonalCompacta = [5, 2, 8, 4];
function obtenerElementoDiagonal(diagonal, i, j) {
return i === j ? diagonal[i] : 0;
}
console.log(obtenerElementoDiagonal(diagonalCompacta, 2, 2));
console.log(obtenerElementoDiagonal(diagonalCompacta, 1, 3));
Las matrices diagonales, triangulares y simétricas poseen patrones que simplifican operaciones y permiten algoritmos especializados. Identificar esos patrones evita recorrer o almacenar elementos cuyo valor ya conocemos por la estructura.
En el próximo tema estudiaremos la igualdad de matrices y las condiciones exactas que deben cumplir dos matrices para considerarse iguales.