我对 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
提前致谢。
答案 0 :(得分:5)
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