Tell me more ×
Cross Validated is a question and answer site for statisticians, data analysts, data miners and data visualization experts. It's 100% free, no registration required.

Is there a function in R to calculate the generalized determinant of a singular matrix? (similar to the ginv() used to compute the generalized inverse)

share|improve this question

1 Answer

up vote 5 down vote accepted

That determinant would be the product of all singular values that you consider to be nonzero, leading to this solution:

# The generalized determinant of x
det.mp <- function(x) {
     sigma <- zapsmall(svd(x)$d)   # The singular values of x
     prod(sigma[sigma != 0])       # Product of the nonzero singular values
}

Here is an application:

# Create test data
p <- 15                            # Number of columns
n <- 6                             # Number of rows
set.seed(17)
x <- matrix(rnorm(n * p), n, p)
x <- rbind(x, x[1,])               # Assure at least one singularity
det.mp(x)

The output is 3013.513. Note that x does not have to be a square matrix.

In larger problems, to avoid overflow you might need instead to obtain the logarithm of the determinant:

sum(log(sigma[sigma != 0]))

(This assumes all singular values are non-negative, because when log is applied to negative values it just returns NaN. Negative values can be handled by the related but slightly more complicated solution

tau <-sigma[sigma != 0]
list(modulus=sum(log(abs(tau))), sign=prod(sign(tau)))

which returns the logarithm of the magnitude of the determinant along with the sign of the determinant, exactly as in the built-in function determinant with the "logarithm" option.)

share|improve this answer
2  
The comparison to zero might require some testing. An alternative would be something like abs(sigma) >= .Machine$double.eps. The issue with zapsmall() is that it only sets very small numbers to 0 when there also is a big one. A hypothetical example: a <- c(.Machine$double.eps / 10, .Machine$double.eps / 10); b <- zapsmall(a); b[b != 0] gives both numbers that are numerically indistuingishable from zero. – caracal Mar 14 '12 at 22:02
1  
Thank you for amplifying that point, caracal. You are correct: zapsmall is there as a placeholder for your procedure to decide what numbers should be considered zeros. In this case, zapsmall is a reasonable default solution: it zeros out any singular value that is very small compared to the larger singular values, which is usually what one wants to do. – whuber Mar 14 '12 at 22:15
Many thanks, Whuber and Caracal! – Tim Mar 14 '12 at 23:38

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.