[R] Efficient way to compute power of a sparse matrix

Moshe Olshansky m_olshansky at yahoo.com
Tue Nov 20 05:53:54 CET 2007


Hello Stéphane,

Since 20 = 4 + 16 you need 5 matrix multiplications to
compute X^20 (2 for X^4, 2 more for X^16 and one more
for X^20).
If your matrix is NxN, one naive matrix multiplication
requires about N^3 operations. In your case N is 900.
If it were 1000, 1000^3 is one billion, so 5 matrix
multiplications should take several seconds.

To remedy the problem, one possibility is to use a
faster matrix multiplication which (if I remember
correctly - not sure) requires O(N^2.25) operations.

Even better possibility is to exploit sparsity.
I do not know what operations on sparse matrices the
Matrix package supports. If it does not contain what
you need you can do this yourself. It takes O(N^2)
operations to find all non-zero elements in the
matrix. Now if you want to multiply A by B and for
each row of A and each column of B you have the
indexes of non-zero elements, it will take only O(1)
operations to decide whether element (i,j) of the
product is non-zero (and to compute it), so matrix
multiplication will take just O(N^2) operations (I
believe that if N(A) is the number of non-zero
elements in A and N(B) is that number for B, you will
need O(N*(N(a)+N(B)) operations).
So hoping that the powers of you matrix X do not fill
in too fast you can compute the power much faster.

I believe that there exist packages which can do this
for you.

Regards,

Moshe.

--- Stéphane Dray <dray at biomserv.univ-lyon1.fr> wrote:

> Dear all,
> I would like to compute power of a square non
> symmetric matrix. This is 
> a part of a simulation study. Matrices are quite
> large (e.g., 900 by 
> 900), and contains many 0 (more than 99 %). I have
> try the function 
> mtx.exp of the Biodem package:
> 
> library(Biodem)
> m <- matrix(0, 900, 900)
> i <- sample(1:900, 3000, replace = T)
> j <- sample(1:900, 3000, replace = T)
> 
> for(x in 1:3000)
>     m[i[x],j[x]] <- runif(1)
> 
> system.time(mtx.exp(m, 20))
> 
> This returns (sorry, in french):
> 
> utilisateur     système      écoulé
>       3.646       0.018       3.665
> 
> Then, I have try to use the Matrix package and
> construct my own Mtx.exp 
> function:
> 
> library(Matrix)
> Mtx.exp <- function (X, n)
> {
>     if (n != round(n)) {
>         n <- round(n)
>         warning("rounding exponent `n' to", n)
>     }
>     phi <- Matrix(diag(nrow(X)))
>     pot <- X
>     while (n > 0) {
>         if (n%%2)
>             phi <- phi %*% pot
>         n <- n%/%2
>         pot <- pot %*% pot
>     }
>     return(phi)
> }
> M <- Matrix(m)
> system.time(Mtx.exp(M,20))
> 
> This approach is slower than the classical one:
> 
> utilisateur     système      écoulé
>       9.265       0.053       9.348
> 
> I am quite sure that the problem comes the diagonal
> matrix used in 
> Mtx.exp. it seems that different classes are used in
> the function which 
> induces this lack of speed. I am not sure of which
> classes of Matrix 
> must be used to improve the script. I wonder if
> someone could help me to 
> obtain an efficient (i.e. fastest) procedure to
> compute the power of a 
> matrix.
> 
> Please note that in this example, M^n could be a
> matrix of 0, but it is 
> not the case with my real data.
> 
> Thanks in advances,
> Cheers.
> 
> -- 
> Stéphane DRAY (dray at biomserv.univ-lyon1.fr )
> Laboratoire BBE-CNRS-UMR-5558, Univ. C. Bernard -
> Lyon I
> 43, Bd du 11 Novembre 1918, 69622 Villeurbanne
> Cedex, France
> Tel: 33 4 72 43 27 57       Fax: 33 4 72 43 13 88
> http://biomserv.univ-lyon1.fr/~dray/
> 
> ______________________________________________
> R-help at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-help
> PLEASE do read the posting guide
> http://www.R-project.org/posting-guide.html
> and provide commented, minimal, self-contained,
> reproducible code.
>



More information about the R-help mailing list