我正在尝试使用特征值方法检查我的矩阵是否是奇异的(即,如果特征值之一为零,则矩阵是奇异的)。这是代码:
z <- matrix(c(-3,2,1,4,-9,6,3,12,5,5,9,4),nrow=4,ncol=3)
eigen(t(z)%*%z)$values
我知道特征值是按降序排列的。有人可以告诉我是否有办法找出与矩阵中的哪一列相关联的特征值?我需要删除共线列。
在上面的示例中可能很明显,但这只是一个示例,旨在节省您创建新矩阵的时间。
例子:
z <- matrix(c(-3,2,1,4,-9,6,3,12,5,5,9,4),nrow=4,ncol=3)
m <- crossprod(z) ## slightly more efficient than t(z) %*% z
这告诉您第三个特征向量对应于共线组合:
ee <- eigen(m)
(evals <- zapsmall(ee$values))
## [1] 322.7585 124.2415 0.0000
现在检查相应的特征向量,它们被列为对应于它们各自特征值的列:
(evecs <- zapsmall(ee$vectors))
## [1,] -0.2975496 -0.1070713 0.9486833
## [2,] -0.8926487 -0.3212138 -0.3162278
## [3,] -0.3385891 0.9409343 0.0000000
第三个特征值为零;第三个特征向量 ( evecs[,3]
) 的前两个元素不为零,这表明第 1 列和第 2 列是共线的。
这是自动化此测试的一种方法:
testcols <- function(ee) {
## split eigenvector matrix into a list, by columns
evecs <- split(zapsmall(ee$vectors),col(ee$vectors))
## for non-zero eigenvalues, list non-zero evec components
mapply(function(val,vec) {
if (val!=0) NULL else which(vec!=0)
},zapsmall(ee$values),evecs)
}
testcols(ee)
## [[1]]
## NULL
## [[2]]
## NULL
## [[3]]
## [1] 1 2
你可以tmp <- svd(z)
用来做一个svd。然后将特征值保存tmp$d
为特征值的对角矩阵。这也适用于非方阵。
> diag(tmp$d)
[,1] [,2] [,3]
[1,] 17.96548 0.00000 0.000000e+00
[2,] 0.00000 11.14637 0.000000e+00
[3,] 0.00000 0.00000 8.787239e-16