在R中计算稀疏矩阵的特征向量

4

我试图在R中计算一个大稀疏矩阵的前m个特征向量。使用eigen()是不切实际的,因为这里大约N > 106

到目前为止,我已经确定应该使用igraph包中的ARPACK处理稀疏矩阵。然而,我无法在一个非常简单的(3x3)矩阵上使其正常工作:

library(Matrix)
library(igraph)

TestDiag <- Diagonal(3, 3:1)
TestMatrix <- t(sparseMatrix(i = c(1, 1, 2, 2, 3), j = c(1, 2, 1, 2, 3), x = c(3/5, 4/5, -4/5, 3/5, 1)))
TestMultipliedMatrix <- t(TestMatrix) %*% TestDiag %*% TestMatrix

然后使用帮助文档中arpack()函数示例中给出的代码提取前两个特征向量:

func <- function(x, extra=NULL) { as.vector(TestMultipliedMatrix %*% x) } 
arpack(func, options=list(n = 3, nev = 2, ncv = 3, sym=TRUE, which="LM", maxiter=200), complex = FALSE)

我收到了一个错误信息:
Error in arpack(func, options = list(n = 3, nev = 2, ncv = 3, sym = TRUE,  :
  At arpack.c:1156 : ARPACK error, NCV must be greater than NEV and less than or equal to N

我不理解这个错误,因为在这里ncv(3)大于nev(2),并且等于N(3)。

我是犯了一些愚蠢的错误还是有更好的方法来计算R中稀疏矩阵的特征向量?


更新

这个错误显然是由于arpack()函数中NCV和NEV的大小写问题导致的。

欢迎提出任何解决此错误(我尝试查看软件包代码,但它对我来说过于复杂)或以其他方式计算特征向量的建议。


这可能是arpack()函数中的一个错误。 - Gabor Csardi
如果函数本身没有错误,那么至少应该更新文档以反映这一事实,因为nev和ncv始终是小写。 - Calimo
1
不幸的是,这并不是真的,我的意思是大小写问题。如果您以大写形式提供它们,则会被简单地忽略,并且nev设置为1,ncv设置为3。 - Gabor Csardi
这就解释了我的下一个问题 - Calimo
2个回答

4

实际上这里没有bug,但是你在ARPACK选项列表中错误地加入了sym=TRUE,然而symarpack()函数的一个参数。也就是说,正确的调用方式应该是:

ev <- arpack(func, options=list(n=3, nev=2, ncv=3, which="LM", maxiter=200), 
             sym=TRUE, complex = FALSE)
ev$values
# [1] 3 2
ev$vectors
#               [,1]          [,2]
# [1,] -6.000000e-01 -8.000000e-01
# [2,]  8.000000e-01 -6.000000e-01
# [3,]  2.220446e-16 -9.714451e-17

如果您对细节感兴趣,那么发生的情况是,不是使用对称的特征值求解器,而是使用通用的非对称特征值求解器,并且需要满足 NCV-NEV >= 2。引用自 ARPACK 源代码(dnaupd.f):
...
c          NOTE: 2 <= NCV-NEV in order that complex conjugate pairs of Ritz 
c          values are kept together. (See remark 4 below)
...

以下是与您的问题略微相关的一些评论。 arpack() 可能会非常缓慢。它的问题在于您需要在每次迭代中从 C 代码回调到 R。请参见此线程:http://lists.gnu.org/archive/html/igraph-help/2012-02/msg00029.html 底线是,arpack() 只有在您的矩阵向量积回调快速且不需要多次迭代时才有帮助,后者与矩阵的特征结构有关。

我在 igraph 问题跟踪器中创建了一个问题,以查看是否可以选择使用 Rcpp 的 C 回调,而不是 R 回调:https://github.com/igraph/igraph/issues/491 如果您感兴趣,可以关注此问题。


1
刚刚注意到在arpack()手册页的示例中出现了相同的错误,对此感到抱歉..... - Gabor Csardi
实际上,我是通过复制粘贴手册中的示例开始的。将sym作为arpack函数的参数传递,它非常好用。谢谢!我还需要看看它在更大的矩阵上的运行情况。 - Calimo

1

可能有点烦人,但当你把nev=2, ncv=3改成NEV=3, NCV=2时,它就可以工作了。R是区分大小写的,这可能导致了问题。


确实,NEV和NCV必须大写,n必须小写。谢谢! - Calimo
1
嗯,显然将其转换为大写会产生其他问题。请参见上面Gabor的评论。 - Calimo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接