在R中的维度上累积应用函数

时间:2017-01-28 00:01:49

标签: r performance multidimensional-array

我想将下面伪代码中显示的内容加速到R中最快的代码(矢量化,或任何比简单for循环更快的方法)。

成像我有一个4维数组A(任意填充1只作为例子):

A = array(runif(nx*ny*nz*nt), c(nx,ny,nz,nt))

并且我希望以更快的速度循环(填充output数组,该数组具有比其先前值更累积的第二维度...更像是第二维的累积乘积输入A数组:

output = array(1, c(nx, ny+1, nz, nt))
for (x in 1:nx)
{
  for (z in 1:nz)
  {
    for (t in 1:nt)
    {
      for (y in 2:(ny+1))
      {
        output[x,y,z,t] = output[x,y-1,z,t] * (1 - A[x,y-1,z,t])
      }
    }
  }
}

我怎样才能更快地完成这项工作?使用apply()?或者一些最后有abind()的智能累积产品?

1 个答案:

答案 0 :(得分:2)

您当然可以使用data_papply来获得相同的结果(cumprod是必要的,因为apply调用的函数的结果在第一维中结束):

aperm

将结果与output1 <- aperm(apply(A,c(1,3,4),function(v) cumprod(1-v)),c(2,1,3,4)) 进行比较,差异非常接近output

.Machine$double.eps

请注意,> max(abs(output[,2:11,,]-output1)) [1] 1.110223e-16 > .Machine$double.eps [1] 2.220446e-16 不包含output1,但此矩阵只包含以下内容:

output[,1,,]

因此,如果需要,可以轻松扩展> all(output[,1,,]==1) [1] TRUE

对于output1,这种方法显然更好:

nx = ny = nz = nt = 10

然后nx = ny = nz = nt = 10 A = array(runif(nx*ny*nz*nt), c(nx,ny,nz,nt)) f.old <- function(){ output = array(1, c(nx, ny+1, nz, nt)) for (x in 1:nx) { for (z in 1:nz) { for (t in 1:nt) { for (y in 2:(ny+1)) { output[x,y,z,t] = output[x,y-1,z,t] * (1 - A[x,y-1,z,t]) } } } } } f.new <- function() aperm(apply(A,c(1,3,4),function(v) cumprod(1-v)),c(2,1,3,4)) 产生(在我的机器上):

microbenchmark