การแก้ระบบสมการเชิงเส้นด้วย solve()
หาคำตอบของระบบ Ax = b และคำนวณเมทริกซ์ผกผัน
การแก้ระบบสมการเชิงเส้นด้วย solve() เป็นบทเรียน R Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน R Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส R Academy มีบทเรียนทั้งหมด 4 บทเรียน
ระบบสมการเชิงเส้น: Ax = b
ระบบสมการเชิงเส้นสามารถเขียนเป็น Ax = b โดย A คือเมทริกซ์สัมประสิทธิ์ x คือเวกเตอร์ตัวไม่ทราบค่า และ b คือพจน์ด้านขวา การแก้หา x ในเชิงวิเคราะห์หมายถึงการคำนวณ 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): คำตอบโดยตรง
solve(A, b) แก้ Ax = b เพื่อหา x ภายในฟังก์ชันใช้การแยกเมทริกซ์แบบ LU ซึ่งมีเสถียรภาพเชิงตัวเลขและมีประสิทธิภาพมากกว่าการคำนวณ A⁻¹ โดยตรงแล้วจึงคูณด้วย 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): เมทริกซ์ผกผัน
การเรียก solve(A) โดยมีอาร์กิวเมนต์เพียงตัวเดียวจะคืนค่า เมทริกซ์ผกผันของ A: A⁻¹ ซึ่งทำให้ A %*% A⁻¹ = I หลีกเลี่ยงการใช้วิธีนี้เพื่อแก้ Ax=b — ให้ใช้ solve(A,b) โดยตรง (เร็วกว่าและมีเสถียรภาพมากกว่า)
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)การตรวจสอบคำตอบ
ตรวจสอบคำตอบเสมอโดยคำนวณ A %*% x - b เนื่องจากการคำนวณแบบจุดลอยตัว ค่าคลาดเหลือจะไม่เป็นศูนย์พอดี แต่ควรมีค่าใกล้เอปไซลอนของเครื่อง (~1e-15) ใช้ norm() เพื่อหาขนาดของค่าคลาดเหลือเพียงค่าเดียว
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-16จำนวนเงื่อนไข: kappa()
จำนวนเงื่อนไขของ A ใช้วัดว่าคำตอบไวต่อการเปลี่ยนแปลงเล็กน้อยใน b เพียงใด หากจำนวนเงื่อนไขมีค่าสูง ความคลาดเคลื่อนเพียงเล็กน้อยใน b จะทำให้เกิดความคลาดเคลื่อนขนาดใหญ่ใน x — ระบบจะมีสภาพ ไม่ดี
# 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() สำหรับเมทริกซ์สามเหลี่ยมบน
backsolve(R, b) แก้ Rx = b เมื่อ R เป็นเมทริกซ์สามเหลี่ยมบนโดยใช้การแทนค่าจากด้านหลัง เร็วกว่า solve() ทั่วไปมากสำหรับระบบสามเหลี่ยม — O(n²) เทียบกับ 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() สำหรับเมทริกซ์สามเหลี่ยมล่าง
forwardsolve(L, b) แก้ Lx = b เมื่อ L เป็นเมทริกซ์สามเหลี่ยมล่างโดยใช้การแทนค่าจากด้านหน้า วิธีนี้ทำงานเสริมกับ backsolve() และทั้งสองฟังก์ชันเป็นพื้นฐานของตัวแก้ระบบแบบแยกเมทริกซ์ 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) -> xพจน์ด้านขวาหลายชุด
solve(A, B) เมื่อ B เป็นเมทริกซ์ จะหาคำตอบ AX = B พร้อมกันสำหรับทุกคอลัมน์ของ B วิธีนี้มีประสิทธิภาพกว่าการเรียก solve(A, b) แยกกันสำหรับแต่ละคอลัมน์
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) # TRUEการตรวจจับเมทริกซ์เอกฐาน
การเรียก solve(A) กับเมทริกซ์เอกฐานจะทำให้เกิดข้อผิดพลาด ตรวจสอบ det(A) หรือ rcond(A) (ส่วนกลับของจำนวนเงื่อนไข) ก่อนแก้ระบบ ใช้ tryCatch() เพื่อเขียนโค้ดที่รับมือได้อย่างรัดกุม
# 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) # NULLกำลังสองน้อยที่สุดด้วย solve()
สำหรับระบบที่มีสมการมากกว่าตัวไม่ทราบค่า จะไม่มีคำตอบที่ตรงกันพอดี คำตอบแบบกำลังสองน้อยที่สุดจะลดค่า ||Ax - b||² ให้ต่ำสุด โดยแก้สมการปกติ: 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)การใช้ qr.solve() เพื่อเสถียรภาพ
qr.solve(A, b) มีเสถียรภาพเชิงตัวเลขมากกว่า solve() สำหรับระบบที่มีสภาพไม่ดีหรือมีสมการเกิน ใช้การแยกเมทริกซ์แบบ QR แทน LU ส่วน lm() ใช้วิธีนี้ภายใน
# 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()ตรวจสอบอย่างรวดเร็ว
ทดสอบความเข้าใจเกี่ยวกับการแก้ระบบสมการเชิงเส้นใน R
สรุป: การแก้ระบบสมการเชิงเส้น
ประเด็นสำคัญ: solve(A, b) แก้ Ax=b โดยตรง (เป็นวิธีที่แนะนำ) solve(A) คำนวณ A⁻¹ (หลีกเลี่ยงเมื่อใช้แก้ระบบ) backsolve(R,b) และ forwardsolve(L,b) ทำงานได้รวดเร็วกับระบบสามเหลี่ยม kappa(A) ใช้วัดสภาพของระบบ — ค่าสูงหมายถึงคำตอบไม่เสถียร สำหรับระบบที่มีสมการเกิน ให้ใช้ qr.solve() ตรวจสอบคำตอบด้วย 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)คำถามที่พบบ่อย
บทเรียน “การแก้ระบบสมการเชิงเส้นด้วย solve()” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “การแก้ระบบสมการเชิงเส้นด้วย solve()” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส R Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส R Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “การแก้ระบบสมการเชิงเส้นด้วย solve()”
หาคำตอบของระบบ Ax = b และคำนวณเมทริกซ์ผกผัน คุณปฏิบัติ R Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน R Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน R Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน
บทเรียน “การแก้ระบบสมการเชิงเส้นด้วย solve()” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน R Academy นี้ได้ไหม
ได้ บทเรียน R Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- การคูณเมทริกซ์และดีเทอร์มิแนนต์
- การแก้ระบบสมการเชิงเส้นด้วย solve()
- ค่าเอกลักษณ์และเวกเตอร์เอกลักษณ์
- การแยกเมทริกซ์ SVD, QR และ Cholesky