# Moore-Penrose generalized determinant

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)

-
# The generalized determinant of 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.) - 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
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