Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Vectorization of nested for loop

I have the following function:

g.Bn = function(n) {
  Bn = 0
  for(k in 0:n) {
    res.of.loop = 0
    for(j in 0:k) {
      res.of.loop = res.of.loop + (-1)^j * (j + 1)^n * choose(k, j)
    }
    Bn = res.of.loop * 1/(k+1) + Bn
  }
  return(Bn)
}

Is here a way to vectorize it instead of using for loops?

like image 627
JWallmark Avatar asked Apr 29 '26 23:04

JWallmark


1 Answers

You could vectorise the inner loop (as per @DaveT), and use sapply:

g.Bn2 = function(n) {
  sum(sapply(0:n, function(k) {
    sum((-1)^(0:k) * (0:k + 1)^n * choose(k, 0:k)) * 1/(k+1)
  }))
}

Or another possibility to vectorise the outer loop:

g.Bn3 = function(n) {
  f <- function(k, n) sum((-1)^(0:k) * (0:k + 1)^n * choose(k, 0:k)) * 1/(k+1)
  sum(Vectorize(f, vectorize.args = "k")(0:n, n))
}
> microbenchmark(g.Bn(100), g.Bn2(100), g.Bn3(100))
       expr      min        lq      mean   median        uq      max neval
  g.Bn(100) 1493.086 1533.9280 1841.3455 1585.354 1675.3575 9023.316   100
 g.Bn2(100)  617.063  650.7850  905.6899  738.230  788.7305 9224.460   100
 g.Bn3(100)  685.094  772.3785 1015.9182  816.945  860.1775 8213.777   100
like image 178
waferthin Avatar answered May 02 '26 17:05

waferthin