代码之家  ›  专栏  ›  技术社区  ›  Wok

如何加速这种双for循环?

  •  3
  • Wok  · 技术社区  · 14 年前

    我正在编程 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 回复  |  直到 7 年前
        1
  •  4
  •   Wine    14 年前

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

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

    对于第二个问题,我认为因为你将它作为列表来做,所以更难向量化。也许你可以用三维数组来代替矩阵列表?所以mydf.array[i,j,k]的维度是n,d,d(或d,d,n)。

        2
  •  3
  •   Gregg Lind    14 年前

    我甚至不想过早地提出这样的建议,但这是在R中构建C扩展可能是有意义的。对于已定义(已知)大小的矩阵(这里有!),C扩展不是 太难了 建造,我保证!这里最糟糕的一点可能是“我的朋友”

    我的R-knowledge已经过时了,但是对于循环(特别是像这样的循环!)以前很残忍。

    也许时间和找出哪个部分比较慢会有帮助?是我的朋友吗?如果你把它改成一个身份呢?

        3
  •  2
  •   duffymo    14 年前

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