【问题标题】:how to parallelize a nested for loop with if statements in R?如何使用 R 中的 if 语句并行化嵌套 for 循环?
【发布时间】:2016-06-27 22:53:05
【问题描述】:

这是一个说明我的问题的示例代码:

for(i  in 1:100) {
    for(j in 1:100)
    { 
       if (A[i] < A[j]) {
            tempMatrix[i, j]  <- foo(val_1[i], val_2[j])
        } else {
            tempMatrix[i, j]  <- foo(val_2[j], val_1[i])
        }
    }
}

上面这段代码计算时间太长,有没有办法并行化上面的代码?

val_1、val_2 和 A 是大约 50k 个元素的向量

【问题讨论】:

  • 查看plyr 包,语法比使用标准apply 系列函数要容易一些。
  • 如果在并行 for 循环上死机,请查看 foreach 包。您也可以用并行应用函数替换外部循环,有关这些的详细信息,请参阅parallel 包。
  • 请考虑向我们提供一些示例数据,以使您的问题可重现。例如,为 Aval_1val_2 中的每一个提供 10 个值。另外,代替foominmaxmean 合适吗?
  • 这是一个复杂的函数。让我们说一下 O(N^2)。

标签: r parallel-processing vectorization parallel-foreach


【解决方案1】:

使用ifelse 的基本矢量化本身似乎获得了 40% 的加速:

n <- 300
A <- rnorm(n)
val_1 <- rpois(n, 10)
val_2 <- rpois(n, 20)
tempMatrix <- matrix(NA, n, n)
tempMatrix2 <- matrix(NA, n, n)


foo <- function(i, j) if( i %% j == 0) 5 else i


microbenchmark(times=30, orig=
for(i  in 1:n) {
    for(j in 1:n)
    { 
       if (A[i] < A[j]) {
            tempMatrix[i, j]  <- foo(val_1[i], val_2[j])
        } else {
            tempMatrix[i, j]  <- foo(val_2[j], val_1[i])
        }
    }
}
,mapp=
for(j in 1:n) {
  w <- A < A[j]
  x <- ifelse(w, val_1, val_2[j])
  y <- ifelse(w, val_2[j], val_1)
  tempMatrix2[,j] = mapply(foo, x, y)
}
)
all.equal(tempMatrix, tempMatrix2)

产量:

Unit: milliseconds
 expr        min         lq        mean     median         uq        max neval
 orig 187.449344 191.274325 195.7138641 192.635209 196.705712 220.292461    30
 mapp 116.479130 117.531128 121.5658793 118.779243 123.359916 147.540282    30

将 n 提高到 400 收益率:

Unit: milliseconds
 expr        min         lq        mean      median         uq        max neval
 orig 338.356754 341.815807 351.2388823 345.4547705 357.107122 382.312691    30
 mapp 203.892420 206.377714 209.9775747 208.6823080 210.757181 239.354271    30

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-08-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-25
    • 1970-01-01
    相关资源
    最近更新 更多