计算R中非方矩阵的倒数

时间:2014-01-26 13:35:21

标签: r matrix matrix-inverse

我对 R 语言很陌生,并试图找出如何计算非正方形矩阵的逆矩阵。 (非正方形?不规则?我不确定正确的术语)。

从我的书和快速谷歌搜索(请参阅source),我发现您可以使用solve(a)查找矩阵的逆矩阵如果 {{ 1}}是正方形。

我创建的矩阵是,据我所知,不是正方形:

a

是否有解决这种尺寸矩阵的函数或者我必须对每个元素做些什么?因为 > matX<-matrix(c(rep(1, 8),2,3,4,0,6,4,3,7,-2,-4,3,5,7,8,9,11), nrow=8, ncol=3); > matX [,1] [,2] [,3] [1,] 1 2 -2 [2,] 1 3 -4 [3,] 1 4 3 [4,] 1 0 5 [5,] 1 6 7 [6,] 1 4 8 [7,] 1 3 9 [8,] 1 7 11 > 函数会出现此错误:

solve()

我想从上面的矩阵中实现的计算是: Error in solve.default(matX) : 'a' (8 x 3) must be square

提前致谢。

2 个答案:

答案 0 :(得分:5)

MASS包中的

ginv ginv将给出矩阵的广义逆。通过它预乘原始矩阵将给出身份:

> library(MASS)
> inv <- ginv(matX)
>
> # test it out
> inv %*% matX
              [,1]         [,2]          [,3]
[1,]  1.000000e+00 6.661338e-16  4.440892e-15
[2,] -8.326673e-17 1.000000e+00 -1.110223e-15
[3,]  6.938894e-17 8.326673e-17  1.000000e+00

根据评论中的建议,可以使用zapsmall

以更好的方式显示
> zapsmall(inv %*% matX)
     [,1] [,2] [,3]
[1,]    1    0    0
[2,]    0    1    0
[3,]    0    0    1

matX'matX的倒数现在是:

> tcrossprod(inv)
             [,1]         [,2]         [,3]
[1,]  0.513763935 -0.104219636 -0.002371406
[2,] -0.104219636  0.038700372 -0.007798748
[3,] -0.002371406 -0.007798748  0.006625269

解决但是,如果您的目标是计算matX'matX的倒数,那么您首先不需要它。这不涉及MASS:

> solve(crossprod(matX))
             [,1]         [,2]         [,3]
[1,]  0.513763935 -0.104219636 -0.002371406
[2,] -0.104219636  0.038700372 -0.007798748
[3,] -0.002371406 -0.007798748  0.006625269

svd svd也可以使用,同样不需要MASS:

> with(svd(matX), v %*% diag(1/d^2) %*% t(v))
             [,1]         [,2]         [,3]
[1,]  0.513763935 -0.104219636 -0.002371406
[2,] -0.104219636  0.038700372 -0.007798748
[3,] -0.002371406 -0.007798748  0.006625269

添加了一些其他信息。

答案 1 :(得分:2)

您可以执行名为&#34; Moore–Penrose pseudoinverse&#34;的操作。这是一个函数exp.mat,它将为您执行此操作。还有一个示例概述了它的使用here

exp.mat()

#The exp.mat function performs can calculate the pseudoinverse of a matrix (EXP=-1)
#and other exponents of matrices, such as square roots (EXP=0.5) or square root of 
#its inverse (EXP=-0.5). 
#The function arguments are a matrix (MAT), an exponent (EXP), and a tolerance
#level for non-zero singular values.
exp.mat<-function(MAT, EXP, tol=NULL){
    MAT <- as.matrix(MAT)
    matdim <- dim(MAT)
    if(is.null(tol)){
        tol=min(1e-7, .Machine$double.eps*max(matdim)*max(MAT))
    }
    if(matdim[1]>=matdim[2]){ 
        svd1 <- svd(MAT)
        keep <- which(svd1$d > tol)
        res <- t(svd1$u[,keep]%*%diag(svd1$d[keep]^EXP, nrow=length(keep))%*%t(svd1$v[,keep]))
    }
    if(matdim[1]<matdim[2]){ 
        svd1 <- svd(t(MAT))
        keep <- which(svd1$d > tol)
        res <- svd1$u[,keep]%*%diag(svd1$d[keep]^EXP, nrow=length(keep))%*%t(svd1$v[,keep])
    }
    return(res)
}

使用示例:

source("exp.mat.R")
X <- matrix(c(rep(1, 8),2,3,4,0,6,4,3,7,-2,-4,3,5,7,8,9,11), nrow=8, ncol=3)
iX <- exp.mat(X, -1)
zapsmall(iX %*% X) # results in identity matrix
[,1] [,2] [,3]
[1,]    1    0    0
[2,]    0    1    0
[3,]    0    0    1