21. Rango de una matriz

El rango mide cuántas filas o columnas aportan información linealmente independiente. Permite reconocer transformaciones que pierden dimensiones y anticipar el comportamiento de los sistemas lineales.

21.1 Introducción

Una matriz puede contener filas o columnas repetidas, proporcionales o formadas a partir de otras. Esos datos no agregan nuevas direcciones de información.

El rango resume cuántas direcciones independientes conserva la matriz. Se escribe rango(A), rg(A) o rank(A).

El rango de A es el número máximo de filas linealmente independientes, que coincide con el número máximo de columnas linealmente independientes.

21.2 Interpretación intuitiva

Considere A = [[1, 2], [2, 4]]. La segunda fila es el doble de la primera, por lo que no aporta una dirección nueva. Aunque la matriz tiene dos filas, su rango es 1.

const A = [[1, 2], [2, 4]];
const primera = A[0];
const segundaEsperada = primera.map(valor => 2 * valor);

console.log(A[1]);             // [2, 4]
console.log(segundaEsperada); // [2, 4]

En cambio, [[1, 2], [2, 5]] tiene dos filas independientes: ninguna es múltiplo de la otra. Su rango es 2.

21.3 Límites del rango

Si A tiene m filas y n columnas, su rango siempre satisface:

0 ≤ rango(A) ≤ min(m, n)
MatrizRango máximoMotivo
2 × 52Solo dispone de 2 filas
4 × 33Solo dispone de 3 columnas
3 × 33Puede tener 3 pivotes
Matriz nula0No contiene ninguna dirección no nula

21.4 Rango por filas y por columnas

El rango por filas es la dimensión del espacio generado por las filas. El rango por columnas se define de forma análoga con las columnas.

Un resultado fundamental establece que ambos números siempre coinciden. Por eso hablamos simplemente del rango de la matriz.

const matriz = [[1, 0, 1], [0, 1, 1]];
const filas = matriz.length;
const columnas = matriz[0].length;

console.log({ filas, columnas, rangoMaximo: Math.min(filas, columnas) });

21.5 Forma escalonada y pivotes

Una matriz está en forma escalonada cuando cada fila no nula comienza más a la derecha que la anterior y las filas nulas quedan al final.

[[1, 2, 0], [0, 3, 4], [0, 0, 0]]

El primer elemento no nulo de cada fila se denomina pivote. La matriz del ejemplo tiene dos pivotes y, por tanto, rango 2.

const escalonada = [[1, 2, 0], [0, 3, 4], [0, 0, 0]];
const tolerancia = 1e-12;
const filasNoNulas = escalonada.filter(fila =>
  fila.some(valor => Math.abs(valor) > tolerancia)
);

console.log(filasNoNulas.length); // 2

21.6 Operaciones que conservan el rango

Las operaciones elementales por fila no cambian el rango:

  • Intercambiar dos filas.
  • Multiplicar una fila por un número distinto de cero.
  • Sumar a una fila un múltiplo de otra.

Estas operaciones permiten simplificar la matriz hasta una forma escalonada sin perder la información necesaria para medir su rango.

const A = [[1, 2], [2, 4]];

// F2 recibe F2 - 2F1.
const reducida = [A[0], A[1].map((valor, j) => valor - 2 * A[0][j])];

console.log(reducida); // [[1, 2], [0, 0]]

21.7 Cálculo mediante eliminación de Gauss

El procedimiento más práctico consiste en escalonar la matriz y contar sus filas no nulas:

  1. Seleccionar un pivote no nulo.
  2. Intercambiar filas si es necesario.
  3. Anular los valores situados debajo del pivote.
  4. Avanzar a la siguiente fila y columna.
  5. Contar los pivotes obtenidos.
Número de pivotes = número de filas no nulas = rango de la matriz.

21.8 Ejemplo de reducción por filas

Sea A = [[1, 2, 3], [2, 4, 6], [1, 1, 1]]. Aplicamos F2 − 2F1 y F3 − F1:

[[1, 2, 3], [0, 0, 0], [0, −1, −2]]

Al ordenar las filas quedan dos filas no nulas. Por lo tanto, rango(A) = 2.

const A = [[1, 2, 3], [2, 4, 6], [1, 1, 1]];
const F1 = A[0];
const F2 = A[1].map((valor, j) => valor - 2 * F1[j]);
const F3 = A[2].map((valor, j) => valor - F1[j]);

console.log([F1, F3, F2]); // dos filas no nulas

21.9 Algoritmo general en JavaScript

El algoritmo siguiente emplea eliminación de Gauss con pivoteo parcial. Trabaja sobre una copia para conservar intacta la matriz recibida.

function rango(matriz, tolerancia = 1e-10) {
  if (matriz.length === 0) return 0;
  const columnas = matriz[0].length;
  if (matriz.some(fila => fila.length !== columnas)) {
    throw new Error("Todas las filas deben tener igual longitud");
  }

  const m = matriz.map(fila => fila.map(Number));
  let filaPivote = 0;

  for (let columna = 0; columna < columnas && filaPivote < m.length; columna++) {
    let mejorFila = filaPivote;
    for (let fila = filaPivote + 1; fila < m.length; fila++) {
      if (Math.abs(m[fila][columna]) > Math.abs(m[mejorFila][columna])) {
        mejorFila = fila;
      }
    }

    if (Math.abs(m[mejorFila][columna]) <= tolerancia) continue;
    [m[filaPivote], m[mejorFila]] = [m[mejorFila], m[filaPivote]];

    for (let fila = filaPivote + 1; fila < m.length; fila++) {
      const factor = m[fila][columna] / m[filaPivote][columna];
      for (let j = columna; j < columnas; j++) {
        m[fila][j] -= factor * m[filaPivote][j];
      }
    }
    filaPivote++;
  }

  return filaPivote;
}

console.log(rango([[1, 2, 3], [2, 4, 6], [1, 1, 1]])); // 2

21.10 Pivoteo y tolerancia numérica

El pivoteo parcial selecciona el valor de mayor magnitud disponible en una columna. Esto evita dividir por cero y reduce la amplificación de errores.

Con números decimales, un valor calculado como 0 puede quedar representado por una cantidad diminuta. La tolerancia permite tratarlo como cero.

const valores = [1, 1e-13, -4e-11, 0];
const tolerancia = 1e-10;

const normalizados = valores.map(valor =>
  Math.abs(valor) <= tolerancia ? 0 : valor
);
console.log(normalizados); // [1, 0, 0, 0]

Una tolerancia demasiado grande puede ocultar información válida; una demasiado pequeña puede contar ruido numérico como un pivote.

21.11 Cálculo del rango mediante menores

También puede buscarse el determinante no nulo de mayor orden contenido en A. Si existe un menor de orden r distinto de cero y todos los de orden superior son cero, entonces rango(A) = r.

Para matrices pequeñas este criterio es útil:

  • Si algún elemento es no nulo, el rango es al menos 1.
  • Si algún menor 2 × 2 tiene determinante no nulo, el rango es al menos 2.
  • En una matriz 3 × 3, si det(A) ≠ 0, el rango es 3.
function determinante2x2(a, b, c, d) {
  return a * d - b * c;
}

const menor = determinante2x2(1, 2, 1, 1);
console.log(menor); // -1: existe un menor de orden 2 no nulo

21.12 Rango de matrices especiales

MatrizRango
Nula de tamaño m × n0
Identidad Inn
DiagonalCantidad de elementos diagonales no nulos
Cuadrada invertible de orden nn
Una fila no nula1
const diagonal = [[5, 0, 0], [0, 0, 0], [0, 0, -2]];
const rangoDiagonal = diagonal.reduce(
  (cantidad, fila, i) => cantidad + Number(fila[i] !== 0),
  0
);
console.log(rangoDiagonal); // 2

21.13 Rango completo

Una matriz tiene rango completo cuando alcanza min(m, n).

  • Si m ≥ n y rango(A) = n, sus columnas son independientes.
  • Si m ≤ n y rango(A) = m, sus filas son independientes.
  • Si A es cuadrada de orden n y rango(A) = n, es invertible.
Para una matriz cuadrada A de orden n:
rango(A) = n ⇔ det(A) ≠ 0 ⇔ A-1 existe.

21.14 Rango y transformaciones lineales

Si una matriz representa una transformación lineal, su rango es la dimensión de la imagen: la cantidad de dimensiones que pueden aparecer en la salida.

  • Rango 3 en el espacio: la salida puede ocupar un volumen.
  • Rango 2: el espacio puede comprimirse sobre un plano.
  • Rango 1: todas las salidas quedan sobre una recta.
  • Rango 0: todos los vectores se transforman en el vector cero.
const proyectarSobrePlanoXY = ([x, y, z]) => [x, y, 0];

console.log(proyectarSobrePlanoXY([3, 4, 5])); // [3, 4, 0]
// La transformación conserva dos direcciones: su rango es 2.

21.15 Rango y sistemas de ecuaciones

En el sistema Ax = b se comparan el rango de la matriz de coeficientes A y el de la matriz aumentada [A | b].

CondiciónResultado
rango(A) ≠ rango([A | b])No existe solución
rango(A) = rango([A | b]) = número de incógnitasSolución única
rango(A) = rango([A | b]) < número de incógnitasInfinitas soluciones

Estas condiciones se estudiarán con más detalle al trabajar con sistemas de ecuaciones lineales.

21.16 Construir una matriz aumentada

La matriz aumentada se obtiene agregando el vector de términos independientes como una columna adicional.

function aumentar(A, b) {
  if (A.length !== b.length) throw new Error("Dimensiones incompatibles");
  return A.map((fila, i) => [...fila, b[i]]);
}

const A = [[1, 1], [2, 2]];
const b = [3, 7];
console.log(aumentar(A, b)); // [[1, 1, 3], [2, 2, 7]]

En el ejemplo, rango(A) = 1 pero rango([A | b]) = 2. Las ecuaciones representan condiciones incompatibles y el sistema no tiene solución.

21.17 Aplicaciones en programación

El rango aparece en numerosos contextos computacionales:

  • Detectar variables o características redundantes en conjuntos de datos.
  • Determinar si una transformación gráfica aplasta una dimensión.
  • Comprobar si un sistema posee información suficiente para una solución única.
  • Analizar configuraciones degeneradas en geometría y visión por computadora.
  • Reducir datos mediante aproximaciones de rango bajo.
Un rango bajo puede indicar redundancia, pérdida de dimensiones o una estructura simplificable.

21.18 Errores frecuentes

  • Confundir el rango con el número de filas o columnas.
  • Contar filas no nulas antes de escalonar la matriz.
  • Suponer que solo las filas repetidas producen dependencia.
  • Contar como pivote un residuo decimal extremadamente pequeño.
  • Modificar accidentalmente la matriz original dentro de una función.
  • Aplicar la fórmula del determinante a una matriz rectangular.
const original = [[1, 2], [3, 4]];
const copia = original.map(fila => [...fila]);
copia[0][0] = 99;

console.log(original[0][0]); // 1: la original no fue modificada

21.19 Qué debes recordar de este tema

  • El rango cuenta direcciones linealmente independientes.
  • El rango por filas siempre coincide con el rango por columnas.
  • Para una matriz m × n, el rango no supera min(m, n).
  • Las operaciones elementales por fila conservan el rango.
  • Después de escalonar, el rango es la cantidad de pivotes o filas no nulas.
  • El pivoteo parcial y una tolerancia mejoran el cálculo numérico.
  • Una matriz cuadrada de rango completo es invertible.
  • Comparar rango(A) y rango([A | b]) permite clasificar un sistema lineal.

21.20 Conclusión

El rango revela cuánta información independiente contiene una matriz. La eliminación de Gauss proporciona una forma sistemática de calcularlo, mientras que los menores y determinantes explican su relación con la invertibilidad.

En el próximo tema introduciremos los sistemas de ecuaciones lineales y utilizaremos matrices para representar varias ecuaciones de manera compacta.