This example shows two classical ways to find the determinant, \(\det(A)\) of a square matrix. They each work by reducing the problem to a series of smaller ones which can be more easily calculated.
library(matlib)
det()
by cofactor expansionSet up a \(3 \times 3\) matrix, and find its determinant (so we know what the answer should be).
<- matrix(c(4, 2, 1,
A 5, 6, 7,
1, 0, 3), nrow=3, byrow=TRUE)
det(A)
## [1] 50
The cofactor \(A_{i,j}\) of element \(a_{i,j}\) is the signed determinant of what is left when row i, column j of the matrix \(A\) are deleted. NB: In R, negative subscripts delete rows or columns.
cat(cofactor(A, 1, 1), " == ", 1 * det( (A[-1, -1]), "\n" ))
## 18 == 18
cat(cofactor(A, 1, 2), " == ", -1 * det( (A[-1, -2]), "\n" ))
## -8 == -8
cat(cofactor(A, 1, 3), " == ", 1 * det( (A[-1, -3]), "\n" ))
## -6 == -6
In symbols: \(\det(A) = a_{1,1} * A_{1,1} + a_{1,2} * A_{1,2} + a_{1,3} * A_{1,3}\)
rowCofactors()
is a convenience function, that calculates these all together
rowCofactors(A, 1)
## [1] 18 -8 -6
Voila: Multiply row 1 times the cofactors of its elements. NB: In R, this multiplication gives a \(1 \times 1\) matrix.
1,] %*% rowCofactors(A, 1) A[
## [,1]
## [1,] 50
all.equal( det(A), c(A[1,] %*% rowCofactors(A, 1)) )
## [1] TRUE
det()
by Gaussian elimination (pivoting)This example follows Green and Carroll, Table 2.2. Start with a 4 x 4 matrix, \(M\), and save det(M)
.
<- matrix(c(2, 3, 1, 2,
M 4, 2, 3, 4,
1, 4, 2, 2,
3, 1, 0, 1), nrow=4, ncol=4, byrow=TRUE)
<- det(M)) (dsave
## [1] 15
# ### 'pivot' on the leading diagonal element, M[1,1]:
det()
will be the product of the ‘pivots’, the leading diagonal elements. This step reduces row 1 and column 1 to 0, so it may be discarded. NB: In R, dropping a row/column can change a matrix to a vector, so we use drop = FALSE
inside the subscript.
<- M[1,1]) (d
## [1] 2
#-- Reduce row 1, col 1 to 0
1,] <- M[1,, drop=FALSE] / M[1, 1]) (M[
## [,1] [,2] [,3] [,4]
## [1,] 1 1.5 0.5 1
<- M - M[,1] %*% M[1,, drop=FALSE]) (M
## [,1] [,2] [,3] [,4]
## [1,] 0 0.0 0.0 0
## [2,] 0 -4.0 1.0 0
## [3,] 0 2.5 1.5 1
## [4,] 0 -3.5 -1.5 -2
#-- Drop first row and column
<- M[-1, -1]
M
#-- Accumulate the product of pivots
<- d * M[1, 1] d
1,] <- M[1,, drop=FALSE] / M[1,1]) (M[
## [,1] [,2] [,3]
## [1,] 1 -0.25 0
<- M - M[,1] %*% M[1,, drop=FALSE]) (M
## [,1] [,2] [,3]
## [1,] 0 0.000 0
## [2,] 0 2.125 1
## [3,] 0 -2.375 -2
<- M[-1, -1]
M = d * M[1, 1] d
1,] <- M[1,, drop=FALSE] / M[1,1]) (M[
## [,1] [,2]
## [1,] 1 0.4706
<- M - M[,1] %*% M[1,, drop=FALSE]) (M
## [,1] [,2]
## [1,] 0 0.0000
## [2,] 0 -0.8824
<- M[-1, -1, drop=FALSE]
M <- d * M[1, 1]
d
# did we get it right?
all.equal(d, dsave)
## [1] TRUE