我正在尝试计算R中大型稀疏矩阵的m
个第一特征向量。使用eigen()
是不现实的,因为大意味着N> 10 6 这里。
到目前为止,我发现我应该使用来自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的错误。
任何解决这个bug的建议(我试着查看一下包代码,但这对我来说太复杂了)或者以其他方式计算特征向量是值得欢迎的。
答案 0 :(得分:4)
这里实际上没有错误,但是你将sym=TRUE
放入ARPACK选项列表时出错,但sym
是arpack()
函数的参数。即正确的电话是:
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问题跟踪器中创建了一个问题,看看是否可以选择使用C回调,使用Rcpp而不是R回调:https://github.com/igraph/igraph/issues/491 如果您有兴趣,可以关注此问题。
答案 1 :(得分:1)
嗯,这可能有点刺激,但是当你将nev=2, ncv=3
更改为NEV=3, NCV=2
时,它会有效。 R区分大小写,可能导致问题。