[R] cumsum over a list or an array

Gabor Grothendieck ggrothendieck at myway.com
Sat Oct 2 06:55:30 CEST 2004


Stephane DRAY <stephane.dray <at> umontreal.ca> writes:

: 
: Hello list,
: 
: my question is related to svd of a matrix:
: 
: b=matrix(rnorm(50),10,5)
: mysvd=svd(b)
: 
: I would like to compute each xi where xi = di* ui %*% t(vi). I do it by :
: 
: xlist=sapply(1:ncol(b), function(x1,y) 
: y$d[x1]*y$u[,x1]%*%t(y$v[,x1]),y=mysvd,simplify=F) # result is a list
: 
: xarray=array(sapply(1:ncol(b), function(x1,y) 
: y$d[x1]*y$u[,x1]%*%t(y$v[,x1]),y=mysvd),c(nrow(b),ncol(b),ncol(b))) # 
: result is an array
: 
: Now i would like to compute cumulative sum:
: 
: y1=x1 # y[,,1]
: y2=x1+x2 # y[,,2]
: ...
: 
: I have try to do it with apply without succes:
: 
: y=apply(xarray,c(1,2),cumsum)
: 
: The results are good but not in the format that I want. I could modify the 
: results to modify the format but I am sure that it exists another faster way.
: 
: Is it possible to do the same on the list ?
: 
: Thanks in advance

I assume the format you want is a list in which the ith
element is the approximation to b formed from the first i
singular values and the associated spaces.

Its actually pretty straighforward and short to simply use a 
for loop:

   z1 <- xlist
   for(i in 2:length(mysvd$d)) z1[[i]] <- z1[[i-1]] + xlist[[i]]

or one can do it directly from the output of the svd
without using xlist or xarray by simply zeroing all but
the first i singular values in udv' in the ith iteration 
within lapply:

   z2 <- with(mysvd, {
      idx <- seq(along = d)
      lapply(idx, function(i) u %*% diag(d*(idx<=i)) %*% t(v))
   })

   all.equal(z1, z2) # TRUE




More information about the R-help mailing list