如何加速这种双循环?

时间:2010-11-22 18:20:58

标签: r performance for-loop vectorization expectation-maximization

我正在使用R编写expectation-maximization algorithm。为了加快计算速度,我想将这个瓶颈进行矢量化。我知道N大约是k的一百倍。

MyLoglik = 0
for (i in c(1:N))
{
 for (j in c(1:k))
 {
  MyLoglik = MyLoglik + MyTau[i,j]*log(MyP[j]*MyF(MyD[i,], MyMu[j,], MyS[[j]]))
 }
}

还有这个矩阵列表:

MyDf.list <- vector("list", k)
for(i in 1:k)
{
 MyDf.list[[i]] <- matrix(0,d,d)
 for (j in c(1:N))
 {
  MyDf.list[[i]] = MyDf.list[[i]] + MyTau[j,i]*as.numeric((MyD[j,]-MyMu[i,])) %*% t(as.numeric(MyD[j,]-MyMu[i,]))  
 }
 MyDf.list[[i]] = MyDf.list[[i]] / MyM[i]
}

我使用了一些事情:

MyLoglik = 0
for (j in c(1:k))
{
 MyR= apply(MyD, 1, function(x) log(MyP[j]*MyF(x, MyMu[j,], MyS[[j]])))
 MyLoglik = MyLoglik + sum(MyTau[,j]*MyR)
}

d = dim(MyD)[2]
MyDf.list <- vector("list", k)
for(i in 1:k)
{
 MyDf.list[[i]] <- matrix(0,d,d)
 MyR= apply(MyD, 1, function(x) as.numeric((x-MyMu[i,])) %*% t(as.numeric(x-MyMu[i,])))
 MyDf.list[[i]] = matrix(rowSums(t(MyTau[,i]*t(MyR))) / MyM[i],d,d)
}

3 个答案:

答案 0 :(得分:4)

对于第一个,我假设MyF是你做的一个功能?如果您可以确保将矩阵和列表作为输入并输出矩阵,则可以执行以下操作:

MyLoglik = sum(MyTau%*%log(MyP)) + sum(MyTau*log(MyF(MyD, MyMu, MyS)))

对于第二个,我认为因为你在列表中这样做会更难以矢量化。也许你可以有一个三维数组而不是矩阵列表?因此MyDf.array [i,j,k]的维度为N,d,d(或d,d,N)。

答案 1 :(得分:3)

我讨厌甚至过早提出这个建议,但这就是在R中构建C-extension可能有意义的事情。对于具有已定义(已知)大小的矩阵(您在这里!),我承诺,C扩展不是那么难以构建的!这里最糟糕的一点可能是传递'myF'

我的R知识已经过时了,但对于循环(特别是像这一个!)曾经是残酷的。

也许计时并找出哪个部分很慢会有所帮助?是myF吗?如果您将其更改为身份怎么办?

答案 2 :(得分:2)

如果事物是​​对称的,你可以减少在内循环中完成的工作:A[i,j] = A[j,i]