3

R で期待値最大化アルゴリズムをプログラミングしています。計算を高速化するために、このボトルネックをベクトル化したいと考えています。N は k の約 100 倍であることを知っています。

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)
}
4

3 に答える 3

4

最初のものについては、MyFはあなたが作成した関数だと思いますか?行列とリストを入力として受け取り、行列を出力することを確認できる場合は、次のようにすることができます。

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

2つ目は、リストとして実行しているため、ベクトル化がより困難になると思います。たぶん、行列のリストの代わりに、3次元配列を持つことができますか?そのため、MyDf.array [i、j、k]の次元はN、d、d(またはd、d、N)になります。

于 2010-11-22T18:59:47.933 に答える
3

私はこれを時期尚早に提案することさえ嫌いですが、これはRでC拡張を構築することが理にかなっているようなものです。定義された(既知の)サイズ(ここにあります!)の行列の場合、C拡張機能を構築するのはそれほど難しくありません。ここで最も厄介なビットはおそらく「myF」を通過するでしょう

私のR知識はかなり時代遅れですが、forループ(特にこのようなものです!)は以前は残酷でした。

タイミングを合わせて、どの部分が遅いかを把握することが役立つかもしれません。myFですか?IDに変更するとどうなりますか?

于 2010-11-22T18:57:18.403 に答える
2

物事が対称的である場合、内側のループで行われる作業を削減できます。A[i,j] = A[j,i]

于 2010-11-22T18:27:38.697 に答える