2013-01-14 35 views
1

我正在使用我编写的R代码,它适用于我的目的。问题在于需要花费很多时间,我认为唯一的解决方案是将其平滑化。我从来没有做过,所以我需要一些建议如何做到这一点。 我的代码如下所示:并行化一个R代码

n<- nrow (aa) 
output <- matrix (0, n, n) 

akl<- function (dii){ 
     ddi<- as.matrix (dii) 
     m<- rowMeans(ddi) 
     M<- mean(ddi) 
     r<- sweep (ddi, 1, m) 
     b<- sweep (r, 2, m) 
     return (b + M) 
     } 
for (i in 1:n) 
{ 
A<- akl(dist(aa[i,])) 

dVarX <- sqrt(mean (A * A)) 

for (j in i:n) 
{ 
    B<- akl(dist(aa[j,])) 
     V <- sqrt (dVarX * (sqrt(mean(B * B)))) 

     output[i,j] <- (sqrt(mean(A * B)))/V   
} 
} 

我想并行在不同的CPU。我怎样才能做到这一点? 我看到了SNOW包,适合我的用途吗? 感谢您的建议, 加布

+0

你应该计算'dist(aa)'一次(外部循环)。 –

+0

输入是一个矩阵,我的代码在每一行(akl)上计算一些东西,然后每个行对计算不同的东西(实际上是一个相关性分数)。输出是另一个矩阵。 – Gabelins

+0

请提供工作示例 – ECII

回答

4

有些情况下,你的代码可以由运行得更快,我能想到的方法有两种:

First:作为@Dwin说的话(有一小搓),你可以(是的,不是必须的,但是整个akl)。

# a random square matrix 
aa <- matrix(runif(100), ncol=10) 
n <- nrow(aa) 
output <- matrix (0, n, n) 

akl <- function(dii) { 
    ddi <- as.matrix(dii) 
    m <- rowMeans(ddi) 
    M <- mean(m) # mean(ddi) == mean(m) 
    r <- sweep(ddi, 1, m) 
    b <- sweep(r, 2, m) 
    return(b + M) 
} 

# precompute akl here 
require(plyr) 
akl.list <- llply(1:nrow(aa), function(i) { 
    akl(dist(aa[i, ])) 
}) 

# Now, apply your function, but index the list instead of computing everytime 
for (i in 1:n) { 
    A  <- akl.list[[i]] 
    dVarX <- sqrt(mean(A * A)) 

    for (j in i:n) { 
     B <- akl.list[[j]] 
     V <- sqrt (dVarX * (sqrt(mean(B * B)))) 
     output[i,j] <- (sqrt(mean(A * B)))/V   
    } 
} 

这应该已经让你的代码运行速度比以前快(如你在计算在内循环AKL每次)在更大的矩阵。

Second:除此之外,您可以更快地通过parallelising如下得到它:

# now, the parallelisation you require can be achieved as follows 
# with the help of `plyr` and `doMC`. 

# First step of parallelisation is to compute akl in parallel 
require(plyr) 
require(doMC) 
registerDoMC(10) # 10 Cores/CPUs 
    akl.list <- llply(1:nrow(aa), function(i) { 
    akl(dist(aa[i, ])) 
}, .parallel = TRUE) 

# then, you could write your for-loop using plyr again as follows 
output <- laply(1:n, function(i) { 
    A  <- akl.list[[i]] 
    dVarX <- sqrt(mean(A * A)) 

    t <- laply(i:n, function(j) { 
     B <- akl.list[[j]] 
     V <- sqrt(dVarX * (sqrt(mean(B*B)))) 
     sqrt(mean(A * B))/V 
    }) 
    c(rep(0, n-length(t)), t) 
}, .parallel = TRUE) 

注意,我只在外环添加.parallel = TRUE。这是因为,您将10个处理器分配给外部循环。现在,如果将它添加到外部和内部循环中,那么处理器的总数将为10 * 10 = 100.请注意这一点。

+0

尝试过一个大矩阵......第一个解决方案非常好!非常感谢! – Gabelins

+0

在2500 x 700矩阵上使用第一个解决方案时,我遇到了内存大小问题。任何帮助解决? – Gabelins

+0

...还有一个问题:有了第一个解决方案,我该如何应用plyr函数来避免计算sqrt(平均值(A * B))中的循环? – Gabelins