嵌套for循环的向量化

嵌套for循环的向量化,r,vectorization,R,Vectorization,我有以下功能: 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) } 这里有一种方法可以将其矢量化而不是使用for循环

我有以下功能:

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)
}

这里有一种方法可以将其矢量化而不是使用for循环吗?

您可以将for循环的
转换为
map
reduce

在下面的示例中,
purrr::map
迭代所有数据,
sum
将一个数值向量缩减为一个定标器(长度为1的数值向量)

似乎所有内环中的
j
s都可以替换为
0:k

g.Bn=函数(n){
总数(
映射dbl(0:n,函数(k){
求和(-1)^(0:k)*(0:k+1)^n*选择(k,0:k))*1/(k+1)
})
)
}

您可以矢量化内部循环(根据@DaveT),并使用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)
  }))
}
或将外环矢量化的另一种可能性:

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))
}

您可以尝试用
js替换内部循环。是否应该修改
g.Bn
作为向量化函数?意思是当提供输入向量时返回答案向量的函数?@slava kohut也许我的问题不清楚。我想使用向量运算,但返回的值仍然应该是实数。哦,等等。可以用c实现。这很可能会大大提高速度。两个
for
替换为两个
purr::
。两者都在使用迭代。是什么让它更强大?我不是在批评。我问得很认真。使用
purrr::
至少可以省去分配初始值设定项变量的麻烦。对我来说,通过使用嵌套匿名函数,每个级别上的逻辑都非常清晰。尝试了你的代码,在
n
通过某个阈值后,
g.Bn2
g.Bn3
)会产生不同的结果。试试
g.Bn(15)
g.Bn2(15)
。为什么呢?老实说,我不确定,但我认为精确性是有原因的。我不能说哪种方法在这方面更好。我猜这可能与浮点运算有关。。。试着在原木上做吗?@waferthin谢谢你的回答。我发现,仅使用DaveT的方法处理内循环并保持外循环不变,就比您的任何解决方案都能获得更好的微基准结果。你认为这是为什么?sapply只是以类似于循环的方式进行迭代吗
g.Bn=函数(n){Bn=0 for(k in 0:n){j=c(0:k)res.of.loop=sum(-1)^j*(j+1)^n*选择(k,j))Bn=Bn+res.of.loop*1/(k+1)}返回(Bn)
是的,通过内环的矢量化,可以实现此处的实际速度提高。所有其他更改实际上只是不同形式的循环(可以说语法更好,但没有真正的速度增益)。我认为加快速度的唯一办法是考虑是否可以以任何方式简化方程式。
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