Calculation of the eigenvectors of a sparse matrix in R

I am trying to calculate the first eigenvectors m large sparse matrix in R. Using eigen() is not realistic, because there is a large value of N> 10 6 .

So far I have figured out that I have to use ARPACK from the igraph package, which can deal with sparse matrices. However, I cannot get it to work with a very simple matrix (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 

And then using the code in the example using the arpack() function to extract the first 2 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) 

An error message appears:

 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 do not understand this error, since ncv (3) is greater than nev (2) and equal to N (3).

Am I making some kind of stupid mistake, or is there a better way to calculate the eigenvectors of a sparse matrix in R?


Update

This error seems to be due to an error in the arpack() function with upper or lower case NCV and NEV.

Any suggestions for fixing the error (I tried to look at the package code, but it’s too hard for me to understand) or calculate the eigenvectors in a different way.

+4
source share
2 answers

Actually there are no errors here, but you made a mistake by putting sym=TRUE in the list of ARPACK options, but sym is an argument to the arpack() function. That is the correct call:

 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 

If you are interested in the details, then what happens is that instead of symmetrical a common asymmetric eigensolver occurs and for this NCV-NEV> = 2 is also required. From source 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) ... 

A few more comments only related to your question. arpack() can be quite slow. The problem is that you need to call R back from C code at each iteration. See this topic: http://lists.gnu.org/archive/html/igraph-help/2012-02/msg00029.html The bottom line is that arpack() helps only if the matrix vector product callback is fast and you don’t need many iterations, the latter being related to the matrix’s own structure.

I created a problem in the igraph problem tester to find out if it is possible to use the C callback if necessary using Rcpp instead of the R callback: https://github.com/igraph/igraph/issues/491 You can follow this problem , if you are interested.

+4
source

Well, maybe this is annoying, but it works when you change nev=2, ncv=3 to NEV=3, NCV=2 . R is case sensitive, which might cause a problem.

+1
source

Source: https://habr.com/ru/post/1484865/


All Articles