knitr::opts_chunk$set( warning = FALSE, message = FALSE ) options(digits=4) par(mar=c(5,4,1,1)+.1)
library(rgl) library(knitr) knit_hooks$set(webgl = hook_webgl)
This vignette illustrates the ideas behind solving systems of linear equations of the form $\mathbf{A x = b}$ where
The general conditions for solutions are:
We use c( R(A), R(cbind(A,b)) )
to show the ranks, and all.equal( R(A), R(cbind(A,b)) )
to test
for consistency.
library(matlib) # use the package
Each equation in two unknowns corresponds to a line in 2D space. The equations have a unique solution if all lines intersect in a point.
A <- matrix(c(1, 2, -1, 2), 2, 2) b <- c(2,1) showEqn(A, b) c( R(A), R(cbind(A,b)) ) # show ranks all.equal( R(A), R(cbind(A,b)) ) # consistent?
Plot the equations:
par(mar=c(4,4,0,0)+.1) plotEqn(A,b)
Solve()
is a convenience function that shows the solution in a more comprehensible form:
Solve(A, b, fractions = TRUE)
For three (or more) equations in two unknowns, $r(\mathbf{A}) \le 2$, because $r(\mathbf{A}) \le \min(m,n)$. The equations will be consistent if $r(\mathbf{A}) = r(\mathbf{A | b})$. This means that whatever linear relations exist among the rows of $\mathbf{A}$ are the same as those among the elements of $\mathbf{b}$.
Geometrically, this means that all three lines intersect in a point.
A <- matrix(c(1,2,3, -1, 2, 1), 3, 2) b <- c(2,1,3) showEqn(A, b) c( R(A), R(cbind(A,b)) ) # show ranks all.equal( R(A), R(cbind(A,b)) ) # consistent? Solve(A, b, fractions=TRUE) # show solution
Plot the equations:
par(mar=c(4,4,0,0)+.1) plotEqn(A,b)
Three equations in two unknowns are inconsistent when $r(\mathbf{A}) < r(\mathbf{A | b})$.
A <- matrix(c(1,2,3, -1, 2, 1), 3, 2) b <- c(2,1,6) showEqn(A, b) c( R(A), R(cbind(A,b)) ) # show ranks all.equal( R(A), R(cbind(A,b)) ) # consistent?
You can see this in the result of reducing $\mathbf{A} | \mathbf{b}$ to echelon form, where the last row indicates the inconsistency.
echelon(A, b)
Solve()
shows this more explicitly:
Solve(A, b, fractions=TRUE)
An approximate solution is sometimes available using a generalized inverse.
x <- MASS::ginv(A) %*% b x
Plot the equations. You can see that each pair of equations has a solution, but all three do not have a common, consistent solution.
par(mar=c(4,4,0,0)+.1) plotEqn(A,b, xlim=c(-2, 4)) points(x[1], x[2], pch=15)
Each equation in three unknowns corresponds to a plane in 3D space. The equations have a unique solution if all planes intersect in a point.
A <- matrix(c(2, 1, -1, -3, -1, 2, -2, 1, 2), 3, 3, byrow=TRUE) colnames(A) <- paste0('x', 1:3) b <- c(8, -11, -3) showEqn(A, b)
Are the equations consistent?
c( R(A), R(cbind(A,b)) ) # show ranks all.equal( R(A), R(cbind(A,b)) ) # consistent?
Solve for $\mathbf{x}$.
solve(A, b) solve(A) %*% b inv(A) %*% b
Another way to see the solution is to reduce $\mathbf{A | b}$ to echelon form. The result is $\mathbf{I | A^{-1}b}$, with the solution in the last column.
echelon(A, b) echelon(A, b, verbose=TRUE, fractions=TRUE)
Plot them. plotEqn3d
uses rgl
for 3D graphics. If you rotate the figure, you'll see an orientation
where all three planes intersect at the solution point, $\mathbf{x} = (2, 3, -1)$
plotEqn3d(A,b, xlim=c(0,4), ylim=c(0,4))
A <- matrix(c(1, 3, 1, 1, -2, -2, 2, 1, -1), 3, 3, byrow=TRUE) colnames(A) <- paste0('x', 1:3) b <- c(2, 3, 6) showEqn(A, b)
Are the equations consistent? No.
c( R(A), R(cbind(A,b)) ) # show ranks all.equal( R(A), R(cbind(A,b)) ) # consistent?
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.