PRODUCTOS
Productos matriciales y vectoriales
Operaciones fundamentales entre vectores y matrices. Backbone del algebra lineal numerica.
11 metodos · numpy 2.4
Productos punto y vectoriales
np.dot
Producto punto
Producto escalar de dos arrays. Comportamiento depende de dimensiones del input.
Sintaxis y aplicacion
import numpy as np

# Vectores: escalar (producto punto clasico)
v1 = np.array([1, 2, 3])
v2 = np.array([4, 5, 6])
np.dot(v1, v2)         # 32  = 1*4 + 2*5 + 3*6

# Matrices: multiplicacion matricial
A = np.array([[1,2],[3,4]])
B = np.array([[5,6],[7,8]])
np.dot(A, B)           # [[19,22],[43,50]]

# Escalar: multiplica todo el array
np.dot(3, v1)          # [3, 6, 9]
Variantes
A @ B np.matmul(A, B) np.vdot(v1,v2) np.inner(v1,v2)
Para matrices 2D usa @ — es mas legible y el estandar desde NumPy 1.10. np.dot reserva para productos escalares o broadcasting explicito.
np.dot con arrays 3D+ no es conmutativo y tiene broadcasting no-obvio. Usa matmul o einsum para N-dims.
@ / matmul
Multiplicacion matricial
Producto matricial estricto. No acepta escalares. Operador @ es el preferido en produccion.
Sintaxis y aplicacion
A = np.array([[1,2,3],[4,5,6]])   # (2,3)
B = np.array([[7,8],[9,10],[11,12]])  # (3,2)

C = A @ B               # (2,2) — forma preferida
C = np.matmul(A, B)     # equivalente

# Broadcasting en batches (stacked matrices)
batch = np.random.rand(10, 3, 3)
result = batch @ batch.transpose(0,2,1)
# aplica @ a cada par de matrices: (10,3,3)

# Matrix-vector con @
x = np.array([1,2,3])
A @ x                   # (2,) vector resultado
Variantes
np.linalg.matmul(A,B) np.matvec(A,x) np.vecmat(x,A)
@ es el operador estandar: legible, eficiente y compatible con todos los backends (PyTorch, JAX, TensorFlow).
linalg.multi_dot
Producto encadenado optimizado
Multiplica 2+ matrices eligiendo automaticamente el orden optimo de asociatividad.
Sintaxis y aplicacion
A = np.random.rand(10000, 100)
B = np.random.rand(100,   1000)
C = np.random.rand(1000,  5)

# Ineficiente: evalua izquierda a derecha
# 10000*100*1000 + 10000*1000*5 operaciones
R1 = A @ B @ C

# Optimizado: elige orden de menor costo
# internamente usa programacion dinamica
R2 = np.linalg.multi_dot([A, B, C])  # 100x mas rapido

# Verificar el orden optimo
path, info = np.einsum_path('ij,jk,kl->il', A, B, C)
print(info)  # muestra el orden y costo
Imprescindible cuando hay 3+ matrices con dimensiones muy dispares. La ganancia puede ser de ordenes de magnitud.
inner / outer
Producto interior y exterior
inner: suma productos element-wise. outer: matriz (n,m) de todos los pares posibles.
Sintaxis y aplicacion
v = np.array([1, 2, 3])
w = np.array([4, 5, 6])

# inner: igual que dot para 1D
np.inner(v, w)     # 32 (escalar)

# outer: matriz (n,m) todos los v[i]*w[j]
np.outer(v, w)
# [[ 4,  5,  6],
#  [ 8, 10, 12],
#  [12, 15, 18]]

# Uso tipico: matrices de covarianza rank-1
v_centered = v - v.mean()
cov_rank1 = np.outer(v_centered, v_centered)
outer es la base de multiplicacion de matrices: A @ B = sum(outer(A[:,i], B[i,:])). Util para matrices rank-1 en optimizacion.
np.einsum
Suma de Einstein — operacion universal
Expresa cualquier operacion tensorial con notacion de indices. El metodo mas expresivo.
Patrones esenciales
A = np.random.rand(3, 4)
B = np.random.rand(4, 5)
v = np.random.rand(3)
w = np.random.rand(3)

# Multiplicacion matricial
np.einsum('ij,jk->ik', A, B)      # A @ B

# Producto punto vectorial
np.einsum('i,i->', v, w)           # np.dot(v,w)

# Traza
np.einsum('ii->', A[:3,:3])       # np.trace(A)

# Transpuesta
np.einsum('ij->ji', A)            # A.T

# Producto exterior
np.einsum('i,j->ij', v, w)        # np.outer(v,w)

# Suma de filas
np.einsum('ij->i', A)             # A.sum(axis=1)

# Contraccion triple optimizada
np.einsum('ij,jk,kl->il', A, B, B.T, optimize='optimal')
Usa optimize='optimal' para cadenas de 3+ tensores. einsum_path calcula el mejor orden de contraccion antes de ejecutar.
einsum reemplaza dot, trace, outer, inner, transpose y sumas. Un solo metodo para toda operacion tensorial.
kron / cross / matrix_power
Kronecker, producto vectorial y potencias
Operaciones especializadas con matrices y vectores en 3D.
Producto de Kronecker
A = np.array([[1,2],[3,4]])
I = np.eye(2)
np.kron(I, A)   # bloque diagonal con A en cada bloque
# Uso: sistemas multipartícula, Hamiltonians
Producto vectorial y potencia
# Cross product 3D
v = np.array([1, 0, 0])
w = np.array([0, 1, 0])
np.linalg.cross(v, w)   # [0, 0, 1] (eje Z)
# Anticonmutativo: cross(v,w) = -cross(w,v)
# cross(v,v) = [0,0,0] siempre

# Potencia de matriz
A = np.array([[1,1],[1,0]])   # Fibonacci matrix
np.linalg.matrix_power(A, 10)  # A^10
np.linalg.matrix_power(A, -1)  # inv(A)
np.linalg.matrix_power(A, 0)   # identidad I
matrix_power(A,-n) usa internamente linalg.inv. Para potencias reales o fraccionarias usa scipy.linalg.fractional_matrix_power.
DESCOMP
Descomposiciones matriciales
Factorizan matrices en formas estructuradas. Base de resolucion numerica, compresion y analisis de datos.
4 metodos principales
linalg.svd
Descomposicion en Valores Singulares
A = U · Sigma · Vt. La descomposicion mas importante del algebra lineal numerica.
Sintaxis y aplicacion
A = np.random.rand(5, 3)   # (m,n)

# SVD completa
U, s, Vh = np.linalg.svd(A, full_matrices=True)
# U:  (m,m) ortogonal
# s:  (k,) valores singulares k=min(m,n), orden desc
# Vh: (n,n) conjugado transpuesto de V

# SVD reducida (economica) — mas eficiente
U, s, Vh = np.linalg.svd(A, full_matrices=False)
# U:(m,k), s:(k,), Vh:(k,n)

# Reconstruir A exactamente
A_rec = U @ np.diag(s) @ Vh

# Aproximacion de rango r (compresion)
r = 2
A_r = U[:, :r] @ np.diag(s[:r]) @ Vh[:r, :]

# Solo valores singulares (mas rapido)
s_only = np.linalg.svdvals(A)
Variantes
svd(full_matrices=False) linalg.svdvals(A) scipy.sparse.linalg.svds(A, k=r)
Para matrices grandes, usa full_matrices=False. Para SVD truncada en matrices enormes, usa scipy.sparse.linalg.svds(A, k=r).
Aplicaciones: PCA, compresion de imagenes, pseudoinversa, rango numerico, least-squares, recomendacion.
linalg.qr
Descomposicion QR
A = Q · R. Q ortogonal, R triangular superior. Base de minimos cuadrados y algoritmos de eigenvalores.
Sintaxis y aplicacion
A = np.random.rand(5, 3)

# QR reducida (default) — la mas usada
Q, R = np.linalg.qr(A, mode='reduced')
# Q: (m,k), R: (k,n) donde k=min(m,n)

# QR completa
Q, R = np.linalg.qr(A, mode='complete')
# Q: (m,m) ortogonal, R: (m,n) triang. sup.

# Verificar ortogonalidad
np.allclose(Q.T @ Q, np.eye(Q.shape[1]))  # True

# Resolver Ax=b con QR (mas estable que inv)
b = np.random.rand(5)
Q, R = np.linalg.qr(A)
x = np.linalg.solve(R, Q.T @ b)
Modos disponibles
modeQ shapeR shapeUso
reduced(m,k)(k,n)Default. Eficiente.
complete(m,m)(m,n)Base ortogonal completa.
r(k,n)Solo R, mas rapido.
QR es numericamente mas estable que calcular inv(A). Usalo cuando A es tall (m > n) para minimos cuadrados.
linalg.cholesky
Descomposicion de Cholesky
A = L · Lt para matrices simetricas definidas positivas (SPD). La factorizacion mas eficiente cuando aplica.
Sintaxis y aplicacion
# Crear matriz SPD garantizada
M = np.random.rand(4, 4)
A = M.T @ M + np.eye(4)   # siempre SPD

# Cholesky lower (default)
L = np.linalg.cholesky(A)        # A = L @ L.T

# Cholesky upper triangular
U = np.linalg.cholesky(A, upper=True)  # A = U.T @ U

# Verificar
np.allclose(L @ L.T, A)  # True

# Resolver Ax=b (2x mas rapido que LU para SPD)
b = np.random.rand(4)
y = np.linalg.solve(L, b)      # forward substitution
x = np.linalg.solve(L.T, y)   # back substitution
Lanza LinAlgError si la matriz no es definida positiva. Verifica con np.linalg.eigvalsh(A).min() > 0 antes de llamar.
2x mas eficiente que LU. Ideal para covarianzas, matrices de Gram y sistemas SPD en Machine Learning.
EIGEN
Eigenvalores y eigenvectores
Analisis espectral de matrices. Clave en PCA, sistemas dinamicos, vibraciones y optimizacion.
4 metodos
linalg.eig
Eigenvalores y eigenvectores (general)
Av = lambda*v. Para matrices cuadradas generales. Valores/vectores pueden ser complejos.
Sintaxis y aplicacion
A = np.array([[3,1],[0,2]])

vals, vecs = np.linalg.eig(A)
# vals: (n,) eigenvalores (pueden ser complejos)
# vecs: (n,n) columnas son eigenvectores normalizados
# vecs[:,i] es el eigenvector de vals[i]

# Verificar Av = lambda*v
i = 0
np.allclose(A @ vecs[:,i], vals[i] * vecs[:,i])  # True

# Diagonalizacion: A = V @ diag(lambda) @ V_inv
V = vecs
V_inv = np.linalg.inv(V)
np.allclose(V @ np.diag(vals) @ V_inv, A)  # True

# Ordenar por eigenvalor descendente
idx = np.argsort(np.abs(vals))[::-1]
vals_sorted = vals[idx]
vecs_sorted = vecs[:, idx]
Variantes
linalg.eigvals(A) linalg.eigh(A) linalg.eigvalsh(A) scipy.linalg.eig(A,B)
Para matrices simetricas/hermitianas, usa eigh. Es mas rapido, mas estable y garantiza valores reales.
linalg.eigh
Eigenvalores de matriz simetrica/hermitiana
Version optimizada para A = At (o A = Ah complejas). Valores siempre reales, vectores ortonormales.
Sintaxis y aplicacion
# Crear matriz simetrica
M = np.random.rand(4, 4)
A = (M + M.T) / 2

vals, vecs = np.linalg.eigh(A)
# vals: reales, ORDEN ASCENDENTE (diferente a eig)
# vecs: ortonormales: vecs.T @ vecs = I

# PCA manual con eigh:
X = np.random.rand(100, 5)
C = np.cov(X.T)                        # covarianza simetrica
vals, vecs = np.linalg.eigh(C)
# Reordenar descendente (eigh da ascendente)
idx = np.argsort(vals)[::-1]
components = vecs[:, idx]
variance_ratio = vals[idx] / vals.sum()

# Proyectar en k componentes principales
k = 2
X_pca = X @ components[:, :k]
Parametro UPLO
UPLODescripcion
'L'Default. Lee triangulo inferior.
'U'Lee triangulo superior.
2x mas rapido que eig. Eigenvectores ortogonales garantizados. Preferir siempre sobre eig cuando A es simetrica.
eigvals / eigvalsh
Solo eigenvalores (sin vectores)
Mas eficiente cuando solo necesitas los valores, no los vectores propios.
Sintaxis y aplicacion
A = np.array([[4,2],[1,3]])

# General (puede ser complejo)
np.linalg.eigvals(A)     # [5., 2.]

# Simetrica (siempre real, orden ascendente)
S = A + A.T
np.linalg.eigvalsh(S)

# Casos de uso comunes:

# Verificar definida positiva
es_spd = np.all(np.linalg.eigvalsh(S) > 0)

# Radio espectral (convergencia iterativa)
rho = np.max(np.abs(np.linalg.eigvals(A)))

# Numero de condicion espectral
eigs = np.linalg.eigvalsh(S)
cond = eigs.max() / eigs.min()

# Comprobar convergencia de metodo iterativo
converge = rho < 1.0
Si no necesitas los vectores, eigvals/eigvalsh es ~30% mas rapido que eig/eigh. Preferirlo para chequeos de propiedades.
NORMAS
Normas, determinantes y metricas
Medidas de magnitud, condicionamiento y propiedades escalares de matrices y vectores.
8 metodos
linalg.norm
Norma de vector o matriz
Mide la magnitud de un vector o matriz segun el orden p especificado.
Normas de vectores
v = np.array([3.0, 4.0])

np.linalg.norm(v)              # L2 Euclidiana    = 5.0
np.linalg.norm(v, ord=1)      # L1 Manhattan     = 7.0
np.linalg.norm(v, ord=2)      # L2 (= default)   = 5.0
np.linalg.norm(v, ord=np.inf) # L-inf max(|v|)   = 4.0
np.linalg.norm(v, ord=0)      # L0 no-ceros      = 2.0
np.linalg.norm(v, ord=-np.inf)# min(|v|)         = 3.0
Normas de matrices
A = np.array([[1,2],[3,4]])

np.linalg.norm(A)              # Frobenius (default)
np.linalg.norm(A, ord='fro')  # Frobenius: sqrt(sum|aij|^2)
np.linalg.norm(A, ord=1)      # max suma columnas
np.linalg.norm(A, ord=np.inf) # max suma filas
np.linalg.norm(A, ord=2)      # valor singular maximo
np.linalg.norm(A, ord='nuc')  # norma nuclear: suma sigma_i

# Versiones modernas broadcast-aware
np.linalg.vector_norm(A, axis=1)    # norma L2 de cada fila
np.linalg.matrix_norm(A, ord='fro') # norma matricial

# Normalizar un vector
v_unit = v / np.linalg.norm(v)

# Normalizar filas de una matriz
A_norm = A / np.linalg.norm(A, axis=1, keepdims=True)
Para normalizar vectores: v / np.linalg.norm(v). Para normalizar filas: A / norm(A, axis=1, keepdims=True).
linalg.det / slogdet
Determinante
det = producto de eigenvalores. Mide cambio de volumen bajo la transformacion lineal A.
Sintaxis y aplicacion
A = np.array([[1,2],[3,4]])

np.linalg.det(A)   # -2.0  (1*4 - 2*3)

# Para matrices grandes, det puede overflow/underflow
# slogdet: retorna (signo, log|det|) — siempre estable
sign, logdet = np.linalg.slogdet(A)
det = sign * np.exp(logdet)

# Batch: stacked matrices
batch = np.random.rand(100, 3, 3)
dets = np.linalg.det(batch)   # (100,)

# Digitos de precision perdidos por condicionamiento
import math
perdidos = math.log10(np.linalg.cond(A))
Nunca uses det para verificar invertibilidad en produccion. Usa matrix_rank o cond. det puede ser ~0 por error numerico aunque la matriz sea invertible.
linalg.cond
Numero de condicion
kappa(A) = norm(A) * norm(A_inv). Mide sensibilidad de la solucion a perturbaciones en los datos.
Sintaxis y aplicacion
A = np.array([[1,2],[1.001,2]])   # casi singular

np.linalg.cond(A)            # norma 2 (default)
np.linalg.cond(A, p=1)       # norma 1
np.linalg.cond(A, p=np.inf)  # norma infinito
np.linalg.cond(A, p='fro')   # norma Frobenius

# Interpretacion:
# cond = 1        bien condicionada
# cond = 1e6      pierde ~6 digitos de precision
# cond > 1/eps    numericamente singular
# eps machine float64 = 1e-16

# Clasificacion practica
c = np.linalg.cond(A)
estado = "bien" if c < 1e4 else ("mal" if c < 1e12 else "singular")
Si cond(A) > 1e12 en float64, el sistema es numericamente singular. Considera regularizacion Tikhonov o usar pinv.
linalg.matrix_rank / trace
Rango y traza
Rango: numero de valores singulares significativos. Traza: suma diagonal = suma eigenvalores.
Rango de matriz
A = np.array([[1,2,3],[4,5,6],[7,8,9]])
# fila3 = fila1 + fila2 -> rango 2

np.linalg.matrix_rank(A)              # 2
np.linalg.matrix_rank(A, tol=1e-10)   # tolerancia custom
np.linalg.matrix_rank(A, hermitian=True)  # mas rapido si simetrica

m, n = A.shape
rango_completo = np.linalg.matrix_rank(A) == min(m, n)
nulidad = n - np.linalg.matrix_rank(A)
Traza
np.trace(A)              # suma diagonal: 15
np.trace(A, offset=1)    # super-diagonal: 8
np.trace(A, offset=-1)   # sub-diagonal: 12
np.einsum('ii', A)       # equivalente con einsum

# Identidad: trace(A) = sum(eigvals(A))
# Norma Frobenius via traza:
frob = np.sqrt(np.trace(A.T @ A))
matrix_rank usa SVD internamente — mas robusto que contar eigenvalores > 0 o usar det para determinar rango.
SISTEMAS
Resolucion de sistemas e inversas
Ax = b, minimos cuadrados, inversas exactas y pseudoinversas. Nucleo del computo numerico.
5 metodos
linalg.solve
Resolver sistema Ax = b
Solucion exacta de sistema cuadrado no-singular. Mas estable y rapido que inv(A) @ b.
Sintaxis y aplicacion
A = np.array([[2,1,-1],[-3,-1,2],[-2,1,2]], dtype=float)
b = np.array([8, -11, -3], dtype=float)

x = np.linalg.solve(A, b)    # [2., 3., -1.]
np.allclose(A @ x, b)         # True

# Multiples vectores b simultaneamente
B = np.random.rand(3, 5)     # 5 sistemas a la vez
X = np.linalg.solve(A, B)    # (3,5)

# Batch: stacked matrices
A_batch = np.random.rand(100, 4, 4)
b_batch = np.random.rand(100, 4)
x_batch = np.linalg.solve(A_batch, b_batch)  # (100,4)
Patron: nunca usar inv(A) @ b
# Lento e inestable
x = np.linalg.inv(A) @ b

# Correcto: 3x mas rapido y mas estable
x = np.linalg.solve(A, b)

# Multiples b con misma A: usar scipy LU
from scipy.linalg import lu_factor, lu_solve
lu, piv = lu_factor(A)
for b_i in many_bs:
    x_i = lu_solve((lu, piv), b_i)  # reutiliza LU
Lanza LinAlgError si A es singular. Verifica con matrix_rank o cond(A) antes de llamar en produccion.
Internamente usa factorizacion LU con pivoteo parcial — numericamente estable para matrices bien condicionadas.
linalg.lstsq
Minimos cuadrados
Minimiza ||Ax - b||^2. Para sistemas sobredeterminados (m > n) o singulares. Via SVD.
Sintaxis y aplicacion
# Sistema sobredeterminado: mas ecuaciones que incognitas
A = np.array([[1,1],[1,2],[1,3],[1,4]])  # (4,2)
b = np.array([2, 3, 5, 4])              # (4,)

x, residuals, rank, sv = np.linalg.lstsq(A, b, rcond=None)
# x:         solucion LS
# residuals: ||Ax - b||^2 (vacio si rank < n)
# rank:      rango numerico de A
# sv:        valores singulares de A

# Regresion lineal clasica
t = np.linspace(0, 10, 100)
y = 3*t + 1 + np.random.randn(100)
A_reg = np.column_stack([t, np.ones_like(t)])
(slope, intercept), *_ = np.linalg.lstsq(A_reg, y, rcond=None)
Siempre pasa rcond=None para silenciar el FutureWarning. rcond controla el umbral para considerar valores singulares como cero.
lstsq funciona aunque A sea singular, sobredeterminada o subdeterminada. Es el metodo mas general para Ax=b.
linalg.inv / pinv
Inversa y pseudoinversa
inv: inversa exacta (A cuadrada no-singular). pinv: Moore-Penrose (funciona con cualquier forma).
Sintaxis y aplicacion
A = np.array([[1,2],[3,4]])

# Inversa exacta (solo cuadradas no-singulares)
A_inv = np.linalg.inv(A)
np.allclose(A @ A_inv, np.eye(2))   # True

# Pseudoinversa Moore-Penrose (forma general)
B = np.random.rand(5, 3)     # (m,n) cualquier forma
B_pinv = np.linalg.pinv(B)   # (3,5)

# Propiedades de la pseudoinversa:
np.allclose(B @ B_pinv @ B, B)           # True
np.allclose(B_pinv @ B @ B_pinv, B_pinv) # True

# Solucion LS via pinv (equivalente a lstsq)
x = np.linalg.pinv(A) @ b

# Con tolerancia de singularidad personalizada
np.linalg.pinv(A, rcond=1e-10)
inv es peligrosa para matrices mal condicionadas. Usa solve(A,b) para resolver sistemas — nunca inv(A)@b.
pinv usa SVD internamente: A_plus = V @ diag(1/sigma_i) @ U.T descartando sigma_i < rcond.
LinAlgError — manejo robusto
Errores y patrones defensivos
Excepcion de numpy.linalg. Estrategias para codigo numerico robusto en produccion.
# Causas de LinAlgError:
# - inv(A) con A singular
# - solve(A,b) con A singular
# - cholesky(A) con A no definida positiva
# - eig/eigh sin convergencia

# Patron de manejo robusto
def safe_solve(A, b):
    try:
        cond = np.linalg.cond(A)
        if cond > 1e12:
            # Caer a minimos cuadrados con regularizacion
            return np.linalg.lstsq(A, b, rcond=None)[0]
        return np.linalg.solve(A, b)
    except np.linalg.LinAlgError:
        # Regularizacion Tikhonov como fallback
        n = A.shape[0]
        lam = 1e-6
        return np.linalg.solve(A.T @ A + lam*np.eye(n), A.T @ b)

# Verificar SPD antes de Cholesky
def safe_cholesky(A, jitter=1e-6):
    try:
        return np.linalg.cholesky(A)
    except np.linalg.LinAlgError:
        A_reg = A + jitter * np.eye(A.shape[0])
        return np.linalg.cholesky(A_reg)
Siempre usa try/except alrededor de inv, solve y cholesky en produccion. Las matrices numericas pueden ser singulares sin serlo exactamente.
OTRAS
Operaciones auxiliares, creacion y tabla completa
Transpuesta, diagonal, tensordot, matrices especiales y referencia rapida de todos los metodos.
10+ utilidades
Diagonal y transpuesta
diagonal / transpose
Diagonal y transposicion
Extraer/crear diagonales, transponer matrices simples o batches.
A = np.array([[1,2,3],[4,5,6],[7,8,9]])

# Extraer diagonal
np.diagonal(A)              # [1,5,9]
np.linalg.diagonal(A)       # version broadcast-aware
np.diagonal(A, offset=1)    # [2,6] superdiagonal
np.diagonal(A, offset=-1)   # [4,8] subdiagonal

# Crear matrices diagonales
np.diag([1,2,3])            # matriz 3x3 diagonal
np.diag([1,2], k=1)         # superdiagonal
np.diag([1,2], k=-1)        # subdiagonal

# Transpuesta
A.T                          # transpuesta
A.conj().T                   # Hermitiana (conjugada transpuesta)
np.linalg.matrix_transpose(A) # version broadcast-aware

# Batch transpose: (N,m,n) -> (N,n,m)
batch = np.random.rand(10, 3, 4)
batch.transpose(0, 2, 1)     # (10,4,3)
Matrices especiales
Creacion de matrices estructuradas
Identidades, diagonales, SPD, ortogonales y otras formas de uso frecuente.
# Identidad
np.eye(3)                    # I 3x3
np.eye(3, 4)                 # rectangular 3x4
np.eye(4, k=1)               # super-diagonal

# Ceros, unos
np.zeros((3,4))
np.ones((2,2))

# Simetrica definida positiva (SPD)
M = np.random.rand(4, 4)
SPD = M.T @ M + 1e-6 * np.eye(4)

# Matriz ortogonal (via QR)
M = np.random.randn(4, 4)
Q, _ = np.linalg.qr(M)     # Q es ortogonal
np.allclose(Q.T @ Q, np.eye(4))  # True

# Triangular inferior/superior
np.tril(A)                   # triangular inferior
np.triu(A)                   # triangular superior
np.tril(A, k=-1)             # estrictamente inferior
Referencia rapida — tabla completa de metodos
MetodoCategoriaRetornaCuando usar
np.dot(a,b)Productoescalar/arrayProducto punto general. Usar @ para 2D.
a @ bProductoarrayMultiplicacion matricial estandar. Preferido.
linalg.multi_dot([...])Productoarray3+ matrices con dimensiones dispares.
np.einsum('ij,jk->ik', A, B)ProductoarrayCualquier operacion tensorial compleja.
np.outer(v, w)Producto(n,m)Matriz de todos los productos v[i]*w[j].
np.inner(a, b)Productoescalar/arrayProducto interior generalizado.
np.kron(A, B)ProductoarrayProducto de Kronecker. Sistemas tensoriales.
linalg.cross(v, w)Producto(3,)Producto vectorial 3D.
linalg.matrix_power(A, n)ProductoarrayA^n con n entero. n=-1 da inv(A).
linalg.svd(A)DescompU, s, VhPCA, rank, pseudoinversa, compresion.
linalg.svdvals(A)Descomp(k,)Solo valores singulares. Mas rapido que svd.
linalg.qr(A)DescompQ, RSistemas tall, ortogonalizacion, estabilidad.
linalg.cholesky(A)DescompLA SPD. Mas rapido que LU. Covarianzas.
linalg.eig(A)Eigenvals, vecsMatrices generales. Puede ser complejo.
linalg.eigh(A)Eigenvals, vecsA simetrica. Mas rapido, valores reales.
linalg.eigvals(A)EigenvalsSolo valores sin vectores. Mas rapido.
linalg.eigvalsh(A)EigenvalsSolo valores, A simetrica. Optimo.
linalg.norm(x)NormafloatMagnitud de vector o matriz.
linalg.vector_norm(x)NormafloatNorma vectorial broadcast-aware.
linalg.matrix_norm(A)NormafloatNorma matricial broadcast-aware.
linalg.det(A)MetricafloatDeterminante. slogdet para matrices grandes.
linalg.slogdet(A)Metricasign, logdetDeterminante estable para cualquier tamano.
linalg.cond(A)MetricafloatCondicionamiento del sistema lineal.
linalg.matrix_rank(A)MetricaintRango numerico via SVD. Robusto.
np.trace(A)MetricafloatSuma diagonal = suma eigenvalores.
linalg.solve(A, b)SistemaxAx=b cuadrado no-singular. Preferido.
linalg.lstsq(A, b)Sistemax, res, rank, svSobredeterminado, singular o general.
linalg.tensorsolve(A, b)Sistemax tensorSistema tensorial N-dimensional.
linalg.inv(A)InversaA_invCuando necesitas la inversa explicitamente.
linalg.pinv(A)InversaA_plusPseudoinversa. Cualquier forma de A.
linalg.tensorinv(A)InversaA_inv tensorInversa tensorial N-dimensional.
np.diagonal(A)EstructuraarrayExtraer diagonal principal o desplazada.
linalg.matrix_transpose(A)EstructuraarrayTranspuesta broadcast-aware para batches.
np.tensordot(A,B,axes)TensorarrayContraccion tensorial sobre ejes especificos.
linalg.LinAlgErrorErrorexceptionCapturar errores de operaciones singulares.