29. Norma o módulo de un vector

La norma asigna a cada vector un número no negativo que mide su tamaño. En geometría representa longitud; en programación permite calcular distancias, velocidades y errores.

29.1 Introducción

Un vector contiene dirección y tamaño. Para extraer únicamente su tamaño utilizamos una función llamada norma, también conocida como módulo o magnitud.

La norma más frecuente es la euclídea, que coincide con la longitud geométrica obtenida mediante el teorema de Pitágoras.

La norma de v se escribe ||v|| y su resultado siempre es un escalar no negativo.

29.2 Norma euclídea

Para v = (v1, ..., vn) en ℝn, la norma euclídea se define como:

||v||2 = √(v12 + v22 + ... + vn2)

El subíndice 2 identifica la norma euclídea dentro de una familia de posibles normas. Cuando no hay ambigüedad se escribe simplemente ||v||.

29.3 Norma en el plano

Para v = (x, y), sus componentes forman los catetos de un triángulo rectángulo y el vector actúa como hipotenusa:

||v|| = √(x2 + y2)

Si v = (3, 4), entonces ||v|| = √(9 + 16) = 5.

const v = [3, 4];
const modulo = Math.sqrt(v[0] ** 2 + v[1] ** 2);

console.log(modulo); // 5

29.4 Norma en el espacio

En ℝ3 se incorpora el cuadrado de la tercera componente:

||(x, y, z)|| = √(x2 + y2 + z2)

Para v = (2, −3, 6), la norma es √(4 + 9 + 36) = 7.

const [x, y, z] = [2, -3, 6];
const norma = Math.sqrt(x ** 2 + y ** 2 + z ** 2);

console.log(norma); // 7

29.5 Norma en ℝn

La misma definición funciona para cualquier cantidad finita de componentes. Se suman sus cuadrados y se calcula la raíz cuadrada.

function normaEuclidea(vector) {
  return Math.sqrt(
    vector.reduce((suma, valor) => suma + valor ** 2, 0)
  );
}

console.log(normaEuclidea([1, 2, 2, 4])); // 5

Este cálculo trata todas las componentes de manera simétrica.

29.6 Cálculo con Math.hypot()

JavaScript ofrece Math.hypot(), que calcula la raíz de la suma de cuadrados y admite cualquier cantidad de argumentos.

function norma(vector) {
  return Math.hypot(...vector);
}

console.log(norma([3, 4]));       // 5
console.log(norma([2, -3, 6]));   // 7
console.log(norma([1, 2, 2, 4])); // 5

Además de ser legible, su implementación evita ciertos desbordamientos y pérdidas de precisión del cálculo ingenuo.

29.7 Propiedades de una norma

PropiedadExpresiónInterpretación
No negatividad||v|| ≥ 0Una longitud no es negativa
Definida positiva||v|| = 0 ⇔ v = 0Solo el vector cero tiene longitud cero
Homogeneidad||kv|| = |k| ||v||Escalar el vector escala su longitud
Desigualdad triangular||u + v|| ≤ ||u|| + ||v||El camino directo no es más largo

29.8 Norma de un múltiplo escalar

Multiplicar un vector por k multiplica su norma por |k|. El valor absoluto aparece porque la norma nunca es negativa.

const norma = v => Math.hypot(...v);
const escalar = (k, v) => v.map(valor => k * valor);
const v = [3, 4];

console.log(norma(escalar(-2, v))); // 10
console.log(Math.abs(-2) * norma(v)); // 10

Un escalar negativo invierte el sentido del vector, pero no convierte su longitud en negativa.

29.9 Norma del vector cero

El vector cero posee todas sus componentes iguales a cero y su norma es cero. Recíprocamente, si la norma euclídea es cero, cada componente debe ser cero.

const cero2D = [0, 0];
const cero5D = Array(5).fill(0);

console.log(Math.hypot(...cero2D)); // 0
console.log(Math.hypot(...cero5D)); // 0

Este caso requiere atención al normalizar, porque no es posible dividir un vector por una norma igual a cero.

29.10 Distancia entre dos puntos

La distancia euclídea entre los puntos A y B es la norma del vector B − A:

d(A, B) = ||B − A||2
function distancia(A, B) {
  if (A.length !== B.length) throw new Error("Dimensiones diferentes");
  return Math.hypot(...B.map((valor, i) => valor - A[i]));
}

console.log(distancia([1, 2], [4, 6]));       // 5
console.log(distancia([0, 0, 0], [2, 3, 6])); // 7

29.11 Norma al cuadrado

Si solo necesitamos comparar longitudes, podemos evitar la raíz cuadrada. Como la raíz es creciente, comparar ||u|| y ||v|| equivale a comparar sus cuadrados.

||v||2 = v12 + ... + vn2
const normaCuadrada = vector =>
  vector.reduce((suma, valor) => suma + valor ** 2, 0);

const u = [3, 4];
const v = [1, 6];
console.log(normaCuadrada(u)); // 25
console.log(normaCuadrada(v)); // 37: v es más largo

Esta optimización es frecuente en detección de cercanía y colisiones simples.

29.12 Aplicación: detectar cercanía

Para saber si dos posiciones están dentro de un radio r, se compara la distancia al cuadrado con r2.

function estanCerca(A, B, radio) {
  const distanciaCuadrada = A.reduce(
    (suma, valor, i) => suma + (B[i] - valor) ** 2,
    0
  );
  return distanciaCuadrada <= radio ** 2;
}

console.log(estanCerca([1, 1], [4, 5], 5)); // true
console.log(estanCerca([1, 1], [4, 5], 4)); // false

29.13 Norma 1 o Manhattan

La norma 1 suma los valores absolutos de las componentes:

||v||1 = |v1| + ... + |vn|

Su nombre “Manhattan” evoca recorridos por calles ortogonales, donde no puede avanzarse en diagonal.

function norma1(vector) {
  return vector.reduce((suma, valor) => suma + Math.abs(valor), 0);
}

console.log(norma1([3, -4]));       // 7
console.log(norma1([2, -1, 5]));   // 8

29.14 Norma infinito

La norma infinito toma la mayor magnitud entre todas las componentes:

||v|| = max(|v1|, ..., |vn|)
function normaInfinito(vector) {
  return vector.length ? Math.max(...vector.map(Math.abs)) : 0;
}

console.log(normaInfinito([3, -7, 2])); // 7

Es útil cuando importa controlar la mayor desviación individual.

29.15 Norma p

Las normas anteriores pertenecen a una familia. Para p ≥ 1:

||v||p = (|v1|p + ... + |vn|p)1/p
function normaP(vector, p) {
  if (!Number.isFinite(p) || p < 1) throw new Error("p debe ser al menos 1");
  const suma = vector.reduce(
    (total, valor) => total + Math.abs(valor) ** p,
    0
  );
  return suma ** (1 / p);
}

console.log(normaP([3, 4], 1)); // 7
console.log(normaP([3, 4], 2)); // 5

29.16 Elegir una norma

NormaQué mideAplicación típica
Euclídea, ||v||2Distancia rectaGeometría, física y gráficos
Manhattan, ||v||1Suma de desplazamientos por ejeCuadrículas y regularización
Infinito, ||v||Mayor componente absolutaControl del peor error

No existe una norma universalmente mejor. La elección depende de la geometría y del significado del problema.

29.17 Aplicación: rapidez de un objeto

La velocidad es un vector; la rapidez es el escalar obtenido mediante su norma. La dirección desaparece, pero se conserva cuánto se mueve el objeto por unidad de tiempo.

function rapidez(velocidad) {
  return Math.hypot(...velocidad);
}

const velocidad = [6, 8]; // unidades por segundo
console.log(rapidez(velocidad)); // 10

29.18 Precisión y errores frecuentes

Elevar valores extremadamente grandes al cuadrado puede producir infinito aunque la norma final sea representable. Math.hypot() aplica un escalado interno más seguro.

const valores = [1e200, 1e200];
const calculoIngenuo = Math.sqrt(valores.reduce((s, x) => s + x ** 2, 0));
const calculoEstable = Math.hypot(...valores);

console.log(calculoIngenuo); // Infinity
console.log(calculoEstable); // aproximadamente 1.414e+200

Otros errores habituales son olvidar la raíz, sumar componentes antes de elevarlas, omitir valores absolutos en la norma 1, intentar normalizar el vector cero y mezclar normas al comparar resultados.

29.19 Qué debes recordar de este tema

  • La norma mide el tamaño de un vector y produce un escalar no negativo.
  • La norma euclídea es la raíz de la suma de cuadrados.
  • Math.hypot(...vector) ofrece un cálculo claro y estable.
  • Solo el vector cero tiene norma cero.
  • ||kv|| = |k| ||v||.
  • La distancia entre A y B es ||B − A||.
  • Para comparar longitudes puede utilizarse la norma al cuadrado.
  • Las normas 1, 2 e infinito describen geometrías diferentes.

29.20 Conclusión

La norma transforma un vector en una medida de tamaño. Esta operación conecta el álgebra con conceptos prácticos como longitud, distancia, rapidez y error.

En el próximo tema utilizaremos la norma para construir vectores unitarios, que conservan una dirección con longitud igual a uno.