【问题标题】:Computing eigenvectors of a sparse matrix in R在 R 中计算稀疏矩阵的特征向量
【发布时间】:2013-06-06 15:56:44
【问题描述】:

我正在尝试计算 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()函数的帮助示例中给出的代码提取前2个特征向量:

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()函数的一个bug。
  • 如果不是函数本身的错误,至少应该更新文档以反映这一事实,因为 nev 和 ncv 总是小写的。
  • 不幸的是,这不是真的,我的意思是小写/大写的东西。如果您以大写形式给出它们,那么它们将被简单地忽略,并且将 nev 设置为 1,将 ncv 设置为 3。
  • 这解释了我的following question

标签: r sparse-matrix igraph eigenvector arpack


【解决方案1】:

这里实际上没有错误,但是您将sym=TRUE 放入ARPACK 选项列表时出错了,但是symarpack() 函数的参数。 IE。正确的调用是:

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)
...

还有一些 cmets,仅与您的问题松散相关。 arpack() 可能会很慢。它的问题是您需要在每次迭代中从 C 代码回调到 R。看到这个线程:http://lists.gnu.org/archive/html/igraph-help/2012-02/msg00029.html 底线是arpack() 仅在您的矩阵向量乘积回调很快并且您不需要多次迭代时才有帮助,后者与矩阵的特征结构有关。

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

【讨论】:

  • 刚刚注意到示例中的arpack()手册页中出现了相同的错误,对此感到抱歉.....
  • 确实,我从复制粘贴手动示例开始。使用 sym 作为 arpack 函数的参数,它就像一个魅力。谢谢!我仍然需要看看它在更大的矩阵上是如何工作的。
【解决方案2】:

这可能有点烦人,但是当您将 nev=2, ncv=3 更改为 NEV=3, NCV=2 时它会起作用。 R 区分大小写,这可能是导致问题的原因。

【讨论】:

  • 确实,NEV和NCV必须大写,n小写。谢谢!
  • 好吧,显然将其设为大写会产生其他问题。请参阅 Gabor 对上述问题的 cmets。
最近更新 更多