12

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 ...).

Lance Roberts
  • 22,383
  • 32
  • 112
  • 130
hamsternik
  • 1,376
  • 3
  • 18
  • 26
  • 2
    Have you tried looking at the determinant (with the `det` function)? You could make a function that returns a boolean with this (e.g., `ifelse(det(M) == 0, FALSE, TRUE)`). – tkmckenzie Jul 25 '14 at 18:13
  • @josilber Good call. Additionally, it looks like the `Matrix` package might have some more efficient methods if you have additional information about the matrix in question. – tkmckenzie Jul 25 '14 at 18:19
  • Thanks a lot, i really forgot about this property of matrix and its iverse :) – hamsternik Jul 25 '14 at 18:35

4 Answers4

13

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().

MAB
  • 545
  • 2
  • 8
  • +1. This seems like the best currently posted approach -- with `M <- 1e-5 * diag(100)` (clearly invertible), `det(M)` returns 0 (implying it's not invertible) but `determinant(M)$modulus` returns -1151.293, implying it's invertible. – josliber Jul 25 '14 at 18:56
  • One problem I can see if with e.g. `determinant(crossprod(matrix(rnorm(300), 10, 30)))`, which is finite (although the matrix has only rank 10 out of 30). – F. Privé Nov 24 '21 at 07:04
8

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.

Misa Lazovic
  • 2,805
  • 10
  • 32
  • 38
Akki
  • 134
  • 1
  • 4
7

@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
jlhoward
  • 58,004
  • 7
  • 97
  • 140
  • 2
    This no longer works in R 4.0.0. From R News:` matrix objects now also inherit from class "array", so e.g., class(diag(1)) is c("matrix", "array"). This invalidates code incorrectly assuming that class(matrix_obj)) has length one. ` Changing the first line to `f <- function(m) "matrix" %in% class(try(solve(m),silent=TRUE))` seems to work. – Matt Tyers Jun 10 '20 at 21:11
  • So, `is.matrix(try(solve(m), silent = TRUE))`. – F. Privé Nov 24 '21 at 07:08
  • 1
    `is_invertible <- function(X) !inherits(try(solve(X), silent = TRUE), "try-error")` should work across R versions and will also support `Matrix` objects, as well as other arbitrary matrix classes that implement `solve()` methods. – alexpghayes Jun 29 '22 at 15:20
2

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")

Hack-R
  • 22,422
  • 14
  • 75
  • 131