[R] problem with generalized singular value decomposition using LAPACK

Altuna Akalin altuna.akalin at bccs.uib.no
Thu Sep 20 10:19:07 CEST 2007


Hi All,
I'm trying to run  generalized singular value decomposition (GSVD)   function
from LAPACK library. Basically my problem is that I can not run it for large
matrices, I get a memory error.
I'm using R 2.5.1.  I tried this on  intel centos5 machines with 2 GB memory 
and 8 GB memory. I have unlimited max memory,cpu time and virtual memory.

LAPACK is already compiled for R (libRlapack.so ) and using dyn.load and
.Fortran functions it's possible to call LAPACK functions(I don't if it's the
best way to do it)
. I pasted the function below.
As I said,  it's not possible to run GSVD on large matrices. Here is couple of
examples:

>  res=GSVD( matrix(1:35000,5000,6), matrix(1:35000,5000,6)  ) #runs without
problems
>  res=GSVD( matrix(1:36000,6000,6), matrix(1:36000,6000,6)  )
Error: cannot allocate vector of size 274.7 Mb

when tried with 8gig machine:
res=GSVD(matrix(1:36000,6000,6), matrix(1:36000,6000,6)  ) #runs without problems
>  res=GSVD(matrix(1:42000,7000,6), matrix(1:36000,6000,6)  )
Error: cannot allocate vector of size 373.8 Mb

when I tried this with equivalent built-in matlab GSVD function, I get a similar
memory error as well. matlab also uses LAPACK for this.

Is there a workaround for this problem without increasing the memory? Does using
.Fortran makes it worse (memory wise)?
I need to work with matrices 4 times larger than the ones I tried.

I would be grateful if anyone can help on these issues
Best,
Altuna

# function
GSVD<-function(A,B)
{   
    # A=U*E1*Q'
    # B=V*E2*Q'
    dyn.load("/usr/local/lib/R/lib/libRlapack.so")
        #is.loaded("dggsvd") # returns TRUE
 
    z <- .Fortran("dggsvd",
        as.character('N'),
        as.character('N'),
        as.character('Q'),
        as.integer(nrow(A)),
        as.integer(ncol(A)),
        as.integer(nrow(B)),
        integer(1),
        integer(1),
        as.double(A),
        as.integer(nrow(A)),
        as.double(B),
        as.integer(nrow(B)),
         double(ncol(A)),
        double(ncol(A)),
        double(nrow(A)*nrow(A)),
        as.integer(nrow(A)),
        double(nrow(B)*nrow(B)),
        as.integer(nrow(B)),
        double(ncol(A)*ncol(A)),
        as.integer(ncol(A)),
        double(max(c(3*ncol(A),nrow(A),nrow(B)))+ncol(A)),
        integer(ncol(A)),
        integer(1),dup=FALSE)
    K=z[7][[1]]
    L=z[8][[1]]
    U=z[15][[1]]
    V=z[17][[1]]
    Q=z[19][[1]]
    ALPHA=z[13][[1]]
        BETA=z[14][[1]]
    R=matrix(z[9][[1]],ncol(A),nrow=nrow(A),byrow=FALSE)
    U=matrix(U,ncol=nrow(A),nrow=nrow(A),byrow=FALSE)
    V=matrix(V,ncol=nrow(B),nrow=nrow(B),byrow=FALSE)
      Q=matrix(Q,ncol=ncol(A),nrow=ncol(A),byrow=FALSE)
    D1=mat.or.vec(nrow(A),K+L)
    D2=mat.or.vec(nrow(B),K+L)

    oR=mat.or.vec((K+L),ncol(A))
    if(K > 0)
    {
        if(K==1)
    { D1[1:K,1:K] =rep(1,K)
    }
    else
    {
      diag(D1[1:K,1:K])=rep(1,K)
    }
         diag(D1[(K+1):(K+L),(K+1):(K+L)])=ALPHA[(K+1):(K+L)]
        diag(D2[1:L,(K+1):(K+L)])=BETA[(K+1):(K+L)]
               
    }

    if(K ==0)
    {
        diag(D1[(K+1):(K+L),(K+1):(K+L)])=ALPHA[(K+1):(K+L)]
        diag(D2[1:L,(K+1):(K+L)])=BETA[(K+1):(K+L)]

    }
   
    Ci=ALPHA[(K+1):(K+L)]
    S=BETA[(K+1):(K+L)]
    oR[(1):(K+L),(ncol(A)-K-L+1):(ncol(A))]=R[(1):(K+L),(ncol(A)-K-L+1):(ncol(A))]
   
    return(list(U=U,V=V,Q=Q,D1=D1,D2=D2,oR=oR,C=Ci,S=S,K=K,L=L))
   
}



More information about the R-help mailing list