I am trying to compute the m
first eigenvectors of a large sparse matrix in R. Using eigen()
is not realistic because large means N > 106 here.
So far I figured out that I should use ARPACK from the igraph
package, which can deal with sparse matrices. However I can't get it to work on a very simple (3x3) matrix:
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
And then using the code given in example of the help of the arpack()
function to extract the 2 first eigenvectors :
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)
I get an error message:
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
I don't understand this error, as ncv (3) is greater than nev (2) here, and equal to N (3).
Am I making some stupid mistake or is there a better way to compute eigenvectors of a sparse matrix in R?
Update
This error is apparently due to a bug in the arpack()
function with uppercase / lowercase NCV and NEV.
Any suggestions to solve the bug (I tried to have a look at the package code but it is far too complex for me to understand) or compute the eigenvectors in an other way are welcome.
Well it might be kinda irritating, but it works when you change
nev=2, ncv=3
toNEV=3, NCV=2
. R is case sensitive, that might have caused the problem.There are actually no bugs here, but you made a mistake putting
sym=TRUE
into the ARPACK option list, butsym
is an argument of thearpack()
function. I.e. the correct call is:If you are interested in the details, what happens is that instead of the symmetric, the general non-symmetric eigensolver is called and for that NCV-NEV >= 2 is also required. From the ARPACK source (dnaupd.f):
Some more comments, only loosely related to your question.
arpack()
can be quite slow. The problem with it is that you need to call back to R from the C code in each iteration. See this thread: http://lists.gnu.org/archive/html/igraph-help/2012-02/msg00029.html The bottom line is thatarpack()
only helps if your matrix-vector product callback is fast and you don't need many iterations, the latter being related to the eigenstructure of the matrix.I created an issue in the igraph issue tracker, to see if it would be possible to optionally use C callback, using Rcpp, instead of the R callback: https://github.com/igraph/igraph/issues/491 You can follow this issue if you are interested.