hamsternik
hamsternik

Reputation: 1426

How to check if a matrix has an inverse in the R language

How do you determine if a matrix has an inverse in R?

So is there in R a function that with a matrix input, will return somethin like:

"TRUE" (this matrix has inverse)/"FALSE"(it hasn't ...).

Upvotes: 13

Views: 17752

Answers (5)

Vincent
Vincent

Reputation: 11

some cautions might be taken when using is.singular.matrix function from matrixcalc package (version 1.0.6) as mentioned in @Akki's answer.

library(gtools)
library(Matrix)

# define a compositional matrix consisting of 10 observations and 8 components
set.seed(2024)
x = rdirichlet(10, alpha = rep(1,8)) 
y = t(x) %*% x
> rankMatrix(y)
[1] 8
attr(,"method")
[1] "tolNorm2"
attr(,"useGrad")
[1] FALSE
attr(,"tol")
[1] 1.776357e-15
> nrow(y)
[1] 8
> is.singular.matrix(y)
[1] TRUE

The rank of y equals to the number of rows of y, suggesting y is a full rank matrix. Besides, solve(y) also gives answer. but is.singular.matrix(y) returns value TRUE suggests y is a singular matrix

Upvotes: 1

Akki
Akki

Reputation: 134

You can try using is.singular.matrix function from matrixcalc package.

To install package:

install.packages("matrixcalc")

To load it:

library(matrixcalc)

To create a matrix:

mymatrix<-matrix(rnorm(4),2,2)

To test it:

is.singular.matrix(mymatrix)

If matrix is invertible it returns FALSE, and if matrix is singlar/non-invertible it returns TRUE.

Upvotes: 8

MAB
MAB

Reputation: 565

Using abs(det(M)) > threshold as a way of determining if a matrix is invertible is a very bad idea. Here's an example: consider the class of matrices cI, where I is the identity matrix and c is a constant. If c = 0.01 and I is 10 x 10, then det(cI) = 10^-20, but (cI)^-1 most definitely exists and is simply 100I. If c is small enough, det() will underflow and return 0 even though the matrix is invertible. If you want to use determinants to check invertibility, check instead if the modulus of the log determinant is finite using determinant().

Upvotes: 14

jlhoward
jlhoward

Reputation: 59335

@MAB has a good point. This uses solve(...) to decide if the matrix is invertible.

f <- function(m) class(try(solve(m),silent=T))=="matrix"
x <- matrix(rep(1,25),nc=5)          # singular
y <- matrix(1+1e-10*rnorm(25),nc=5)  # very nearly singular matrix
z <- 0.001*diag(1,5)                 # non-singular, but very smalll determinant
f(x)
# [1] FALSE
f(y)
# [1] TRUE
f(z)
# [1] TRUE

Upvotes: 7

Hack-R
Hack-R

Reputation: 23217

In addition to the solution given by @josilber in the comments (i.e. abs(det(M)) > 1e-10) you can also use solve(M) %*% M for a square matrix or ginv in the MASS package will give the generalized inverse of a matrix.

To get TRUE or FALSE you can simply combine any of those methods with tryCatch and any like this:

out <- tryCatch(solve(X) %*% X, error = function(e) e)

any(class(out) == "error")

Upvotes: 2

Related Questions