使用特征值来测试奇点:识别共线列

时间:2012-09-06 17:02:08

标签: r eigen

我试图使用特征值方法检查我的矩阵是否是奇异的(即,如果其中一个特征值为零,那么矩阵是奇异的)。这是代码:

z <- matrix(c(-3,2,1,4,-9,6,3,12,5,5,9,4),nrow=4,ncol=3) 
eigen(t(z)%*%z)$values

我知道特征值按降序排序。如果有办法找出特征值与矩阵中的哪个列相关联,有人可以告诉我吗?我需要删除共线列。

在上面的示例中可能很明显,但它只是一个示例,旨在为您节省创建新矩阵的时间。

2 个答案:

答案 0 :(得分:7)

示例:

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

答案 1 :(得分:2)

您可以使用tmp <- svd(z)来制作一张DVD。然后将特征值保存在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