Resolución de sistemas lineales con solve()
Encuentre soluciones para sistemas Ax = b y calcule inversas de matrices.
Resolución de sistemas lineales con solve() es una lección gratuita de R Academy en CoddyKit. Esta es la lección 2 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de R Academy, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de R Academy incluye 4 lecciones en total.
Sistemas lineales: Ax = b
Un sistema de ecuaciones lineales puede escribirse como Ax = b, donde A es una matriz de coeficientes, x es el vector de incógnitas y b es el término independiente. Resolver x analíticamente significa calcular x = A⁻¹b.
# System of equations:
# 2x + y = 5
# x + 3y = 7
# Matrix form: A %*% x = b
A <- matrix(c(2, 1,
1, 3), nrow = 2, byrow = TRUE)
b <- c(5, 7)
# What are A and b?
print(A)
print(b)
cat('We want to find x such that A %*% x = b')solve(A, b): la solución directa
solve(A, b) resuelve Ax = b para obtener x. Internamente utiliza la descomposición LU, que es más estable y eficiente numéricamente que calcular explícitamente A⁻¹ y multiplicarla después por b.
A <- matrix(c(2, 1,
1, 3), nrow = 2, byrow = TRUE)
b <- c(5, 7)
# Solve Ax = b
x <- solve(A, b)
print(x) # x[1] = ?, x[2] = ?
# Verify: A %*% x should equal b
residual <- A %*% x - b
print(residual) # Should be near zero
# Manual check:
# 2*(8/5) + (9/5) = 16/5 + 9/5 = 25/5 = 5 ✓
# 1*(8/5) + 3*(9/5) = 8/5 + 27/5 = 35/5 = 7 ✓solve(A): la matriz inversa
Llamar a solve(A) con un solo argumento devuelve la inversa de A: A⁻¹, tal que A %*% A⁻¹ = I. Evite usarlo para resolver Ax=b; use directamente solve(A,b) (es más rápido y estable).
A <- matrix(c(4, 3,
3, 2), nrow = 2, byrow = TRUE)
# Compute inverse
A_inv <- solve(A)
print(A_inv)
# Verify: A %*% A_inv = I
A %*% A_inv # Should be identity matrix
round(A %*% A_inv, 10)
# Also A_inv %*% A = I
round(A_inv %*% A, 10)
# det(A) != 0 required for invertibility
det(A) # -1 (nonzero, so invertible)Comprobación de la solución
Verifique siempre la solución calculando A %*% x - b. Debido a la aritmética de coma flotante, el residuo no será exactamente cero, pero debería estar cerca del épsilon de máquina (~1e-15). Use norm() para obtener una única magnitud del residuo.
A <- matrix(c(3, -1, 2,
1, 4, 0,
-2, 1, 5), nrow = 3, byrow = TRUE)
b <- c(1, 2, 3)
# Solve
x <- solve(A, b)
cat('Solution x:\n'); print(x)
# Residual check
residual <- A %*% x - b
cat('Residual vector:\n'); print(residual)
# Residual norm (should be near 0)
resid_norm <- sqrt(sum(residual^2))
cat('Residual norm:', resid_norm, '\n')
# Expected: something like 2e-16Número de condición: kappa()
El número de condición de A mide la sensibilidad de la solución a las perturbaciones en b. Un número de condición grande significa que pequeños errores en b provocan grandes errores en x: el sistema está mal condicionado.
# Well-conditioned matrix
A_good <- matrix(c(2, 1, 1, 3), nrow = 2, byrow = TRUE)
kappa(A_good) # Small -> good
# Ill-conditioned (nearly singular) matrix
A_bad <- matrix(c(1.000, 1.001,
1.001, 1.002), nrow = 2, byrow = TRUE)
kappa(A_bad) # Very large -> bad!
# Rule of thumb: kappa > 1/machine_epsilon is trouble
.Machine$double.eps # ~2.2e-16
# For A_bad: you lose about log10(kappa) digits of precision
cat('Digits lost:', log10(kappa(A_bad)), '\n')backsolve() para matrices triangulares superiores
backsolve(R, b) resuelve Rx = b cuando R es triangular superior, mediante sustitución hacia atrás. Es mucho más rápido que solve() para sistemas triangulares: O(n²) frente a O(n³).
# Upper triangular system: Rx = b
# 2x + 3y + z = 14
# 5y + 2z = 13
# 4z = 8
R <- matrix(c(2, 3, 1,
0, 5, 2,
0, 0, 4), nrow = 3, byrow = TRUE)
b <- c(14, 13, 8)
# Solve using back-substitution
x <- backsolve(R, b)
print(x) # z=2, y=(13-4)/5=9/5, x=(14-3*9/5-2)/2
# Verify
all.equal(as.vector(R %*% x), b) # TRUE
# Compare with general solve
x_general <- solve(R, b)
all.equal(x, x_general) # TRUE (same result)forwardsolve() para matrices triangulares inferiores
forwardsolve(L, b) resuelve Lx = b cuando L es triangular inferior, mediante sustitución hacia delante. Complementa a backsolve() y, juntas, estas funciones constituyen la base de los solucionadores basados en la descomposición LU.
# Lower triangular system: Lx = b
# 3x = 6
# 2x + 4y = 10
# x + 2y + 5z = 16
L <- matrix(c(3, 0, 0,
2, 4, 0,
1, 2, 5), nrow = 3, byrow = TRUE)
b <- c(6, 10, 16)
# Solve using forward-substitution
x <- forwardsolve(L, b)
print(x) # x=2, y=(10-4)/4=1.5, z=(16-2-3)/5=2.2
# Verify
all.equal(as.vector(L %*% x), b) # TRUE
# Use case: solving L*U*x = b
# forwardsolve(L, b) -> y, then backsolve(U, y) -> xMúltiples términos independientes
solve(A, B), donde B es una matriz, resuelve simultáneamente AX = B para todas las columnas de B. Es más eficiente que llamar a solve(A, b) por separado para cada columna.
A <- matrix(c(2, 1,
1, 3), nrow = 2, byrow = TRUE)
# Solve for two right-hand sides simultaneously
B <- matrix(c(5, 7, # first system
3, 1), # second system
nrow = 2, byrow = TRUE)
# X[:,1] solves Ax = B[:,1]
# X[:,2] solves Ax = B[:,2]
X <- solve(A, B)
print(X)
# Verify both solutions
A %*% X # Should equal B
all.equal(A %*% X, B) # TRUEDetección de matrices singulares
Llamar a solve(A) con una matriz singular produce un error. Compruebe det(A) o rcond(A) (el inverso del número de condición) antes de resolver. Use tryCatch() para escribir código robusto.
# Singular matrix (rows are linearly dependent)
S <- matrix(c(1, 2,
2, 4), nrow = 2, byrow = TRUE)
det(S) # 0 -> singular
kappa(S) # Inf
# Safe solve with tryCatch
safe_solve <- function(A, b) {
tryCatch(
solve(A, b),
error = function(e) {
cat('Matrix is singular or nearly so:\n')
cat(e$message, '\n')
return(NULL)
}
)
}
result <- safe_solve(S, c(1, 2))
print(result) # NULLMínimos cuadrados con solve()
En los sistemas sobredeterminados (con más ecuaciones que incógnitas), no existe una solución exacta. La solución de mínimos cuadrados minimiza ||Ax - b||². Resuelve las ecuaciones normales: A'Ax = A'b.
# Overdetermined: 4 equations, 2 unknowns (y = a + b*x)
set.seed(1)
x_vals <- c(1, 2, 3, 4)
y_vals <- c(2.1, 4.0, 5.9, 8.2) # approx y = 0 + 2x
A <- cbind(1, x_vals) # Design matrix (4x2)
b <- y_vals
# Normal equations: (A'A) beta = A'b
AtA <- crossprod(A)
Atb <- crossprod(A, b)
beta_ols <- solve(AtA, Atb)
print(beta_ols) # Intercept ~0.1, slope ~2.0
# Residual sum of squares
y_hat <- A %*% beta_ols
rss <- sum((b - y_hat)^2)
cat('RSS:', rss)Uso de qr.solve() para mayor estabilidad
qr.solve(A, b) es numéricamente más estable que solve() para sistemas mal condicionados o sobredeterminados. Utiliza la descomposición QR en lugar de LU. lm() la utiliza internamente.
# For overdetermined system, qr.solve is preferred
x_vals <- c(1, 2, 3, 4, 5)
y_vals <- c(1.9, 4.1, 6.0, 7.8, 10.1)
A <- cbind(1, x_vals)
b <- y_vals
# qr.solve handles overdetermined systems directly
beta_qr <- qr.solve(A, b)
print(beta_qr) # intercept, slope
# Equivalent to:
beta_lm <- coef(lm(y_vals ~ x_vals))
all.equal(beta_qr, beta_lm, check.names = FALSE) # TRUE
# For well-determined square systems, solve() is fine
# For overdetermined or ill-conditioned: use qr.solve()Comprobación rápida
Compruebe su comprensión de la resolución de sistemas lineales en R.
Resumen: resolución de sistemas lineales
Ideas clave: solve(A, b) resuelve Ax=b directamente (es la opción preferida). solve(A) calcula A⁻¹ (evítelo para resolver sistemas). backsolve(R,b) y forwardsolve(L,b) son rápidos para sistemas triangulares. kappa(A) mide el condicionamiento: los valores grandes indican soluciones inestables. Para sistemas sobredeterminados, use qr.solve(). Verifique siempre con A %*% x - b.
# Summary of solve() functions:
A <- matrix(c(3, 1, 1, 2), nrow = 2)
b <- c(9, 8)
# Solve Ax = b
x <- solve(A, b)
print(x) # c(2, 3)
# Check conditioning
kappa(A) # Small -> well-conditioned
# Verify
max(abs(A %*% x - b)) # Near zero
# For triangular systems:
R <- matrix(c(2, 3, 0, 4), nrow = 2, byrow = TRUE)
backsolve(R, c(8, 4)) # x=c(1, 1)
# For least squares (overdetermined):
# qr.solve(design_matrix, y)Preguntas frecuentes
¿La lección «Resolución de sistemas lineales con solve()» es gratis?
Sí — el texto completo de «Resolución de sistemas lineales con solve()» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de R Academy, actualiza a CoddyKit PRO. El curso de R Academy incluye 4 lecciones en total.
¿Qué aprenderé en «Resolución de sistemas lineales con solve()»?
Encuentre soluciones para sistemas Ax = b y calcule inversas de matrices. Practicas R Academy con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.
¿Necesito experiencia previa para empezar R Academy?
No se requiere experiencia previa. R Academy en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 2 de 4.
¿Cuánto tiempo toma la lección «Resolución de sistemas lineales con solve()»?
La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.
¿Puedo escribir y ejecutar código en esta lección de R Academy?
Sí. Cada lección de R Academy incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.
Todas las lecciones de este curso
- Multiplicación de matrices y determinantes
- Resolución de sistemas lineales con solve()
- Valores propios y vectores propios
- Descomposiciones SVD, QR y de Cholesky