Verify using R that SVD and Eigenvalues are related
A <- matrix(c(1,2,3, -1, 0, 4), nrow = 2, ncol = 3, byrow = TRUE)
Compute the left-singular, singular values, and right-singular vectors of A using the svd command.
The vector d contains the singular values The matrix u contains the left singular vectors (rows). The matrix v contains the right singular vectors (columns).
A_svd <- svd(A, nu=nrow(A), nv=ncol(A))
singular_values <- as.matrix(diag(A_svd$d, nrow=nrow(A), ncol=ncol(A)))
left_singluar_vectors <- as.matrix(A_svd$u)
right_singluar_vectors <- as.matrix(A_svd$v)
Singular values from SVD
singular_values
## [,1] [,2] [,3]
## [1,] 5.157693 0.000000 0
## [2,] 0.000000 2.097188 0
The left singular vectors from SVD function
left_singluar_vectors
## [,1] [,2]
## [1,] -0.6576043 -0.7533635
## [2,] -0.7533635 0.6576043
The right singular vectors from SVD function
right_singluar_vectors
## [,1] [,2] [,3]
## [1,] 0.01856629 -0.6727903 -0.7396003
## [2,] -0.25499937 -0.7184510 0.6471502
## [3,] -0.96676296 0.1765824 -0.1849001
Compare left singular vector by computing AAT and taking its eigenvector:
X <- A %*% t(A)
X_eigen <- eigen(X) #AAT
X_left_singluar_vectors <- as.matrix(X_eigen$vectors)
X_eigenvalues <- X_eigen$values
let us compare the two
left_singluar_vectors
## [,1] [,2]
## [1,] -0.6576043 -0.7533635
## [2,] -0.7533635 0.6576043
X_left_singluar_vectors
## [,1] [,2]
## [1,] 0.6576043 -0.7533635
## [2,] 0.7533635 0.6576043
The numbers are the same but there are differences in signs.
The square root of the eigenvalues of X match the singular values of the SVD.
singular_values
## [,1] [,2] [,3]
## [1,] 5.157693 0.000000 0
## [2,] 0.000000 2.097188 0
diag(sqrt(X_eigenvalues), nrow=nrow(A), ncol=ncol(A))
## [,1] [,2] [,3]
## [1,] 5.157693 0.000000 0
## [2,] 0.000000 2.097188 0
Let us now compare right singular vector by computing ATA and taking its eigenvector
Y <- t(A)%*% A #ATA
Y_eigen <- eigen(Y)
Y_right_singluar_vectors <- as.matrix(Y_eigen$vectors)
Y_eigenvalues <- Y_eigen$values
The SVD right singular vectors and ATA eigenvectors match but there are sign differences
right_singluar_vectors
## [,1] [,2] [,3]
## [1,] 0.01856629 -0.6727903 -0.7396003
## [2,] -0.25499937 -0.7184510 0.6471502
## [3,] -0.96676296 0.1765824 -0.1849001
Y_right_singluar_vectors
## [,1] [,2] [,3]
## [1,] -0.01856629 -0.6727903 0.7396003
## [2,] 0.25499937 -0.7184510 -0.6471502
## [3,] 0.96676296 0.1765824 0.1849001
The eigenvalues of X and Y match for nonzero values
round(X_eigenvalues,3)
## [1] 26.602 4.398
round(Y_eigenvalues,3)
## [1] 26.602 4.398 0.000
#The function to get cofactors
getcofactors <- function(M) {
cofactors <- M
for(i in 1:nrow(M)){
for(j in 1:ncol(M)){
cofactors[i,j] <- (det(M[-i,-j])*(-1)^(i+j))
}
}
return(cofactors) # output of cofactors matrix
}
#The function to get the inverse of a square matrix that is invertible
myinverse <- function(M){
M_cofactors <- getcofactors(M)
M_cofactors_transpose <- t(M_cofactors)
M_det <- det(M)
return(M_cofactors_transpose/M_det)
}
Testing the function
mat<- matrix(c(4,3,7,8,6,2,2,1,6,1,2,1,2,3,6,7), nrow=4, ncol=4, byrow=TRUE)
mat
## [,1] [,2] [,3] [,4]
## [1,] 4 3 7 8
## [2,] 6 2 2 1
## [3,] 6 1 2 1
## [4,] 2 3 6 7
mat_inverse<-myinverse(mat)
mat_inverse
## [,1] [,2] [,3] [,4]
## [1,] 1 0.5 -0.625 -1.125
## [2,] 0 1.0 -1.000 0.000
## [3,] -5 -3.0 4.500 5.500
## [4,] 4 2.0 -3.250 -4.250
Check if mat*mat_inverse=Identity
print(mat%*%mat_inverse)
## [,1] [,2] [,3] [,4]
## [1,] 1.000000e+00 7.105427e-15 7.105427e-15 7.105427e-15
## [2,] -3.552714e-15 1.000000e+00 1.065814e-14 1.776357e-15
## [3,] -3.552714e-15 -4.440892e-16 1.000000e+00 1.776357e-15
## [4,] 0.000000e+00 1.776357e-15 1.421085e-14 1.000000e+00