0

大きな正方行列の要素を繰り返し計算する必要があることに取り組んでいます。このプロセスでは、別の行列に格納されているデータを読み取り、行列の要素を計算します。現在、これを行うために double forループを使用しています。

library(matrixcalc)

data <- matrix(nrow=3,ncol=1000)

for(x in 1:ncol(data)){
   for(y in 1:ncol(data)){
       matrix[x,y]=exp(-entrywise.norm(data[,x]-data[,y],2))
   }
}

問題は、私のマトリックスが非常に大きいため、これが非常に遅いことです。この手順の最速の代替手段は何ですか?

4

4 に答える 4

3

短くて非常に高速:

mat <- exp(-as.matrix(dist(t(data))))

また、ユークリッド距離の行列を計算fields::rdistするためのより高速な代替手段としてこの関数をお勧めします。したがって、パッケージのロードが問題にならない場合は、次のことを検討してください。dist

library(fields)
mat <- exp(-rdist(t(data)))

速度の向上のアイデアを提供するには:

data <- matrix(runif(3000), nrow=3, ncol=1000)

OP <- function(data) {
  require(matrixcalc)
  mat <- matrix(0, ncol(data), ncol(data))
  for(x in 1:ncol(data)){
    for(y in 1:ncol(data)){
      mat[x,y]=exp(-entrywise.norm(data[,x]-data[,y],2))
    }
  }
  mat
}

flodel1 <- function(data) exp(-as.matrix(dist(t(data))))
flodel2 <- function(data) {
  require(fields)
  exp(-rdist(t(data)))
}

system.time(res1 <- OP(data))
#   user  system elapsed 
# 22.708   2.080  24.602 
system.time(res2 <- flodel1(data))
#   user  system elapsed 
#  0.112   0.025   0.136 
system.time(res3 <- flodel2(data))
#   user  system elapsed 
#  0.048   0.000   0.049 

(OPおよびの場合flodel2、これらのランタイムにはパッケージのロードが含まれていないことに注意してください。パッケージはテスト前にロードされていたからです。)

于 2013-07-04T11:44:11.880 に答える
2

これはかなり高速になるはずです:

nc <- ncol(data)

mat <- diag(nc)

for(x in 2:nc){
   for(y in 1:x){
       mat[x, y] <- exp(-(sum((data[ , x] - data[ , y])^2) ^ .5))
   }
}

mat[upper.tri(mat)] <- t(mat)[upper.tri(mat)]
于 2013-07-04T11:03:15.087 に答える
1

R 言語では、列優先の配列が使用されます。for ループの順序を変更すると、パフォーマンスが向上します。このようにすると、より連続した形でメモリにアクセスできるため、CPU キャッシュの利点が得られます。

 for(y in 1:dim) //outer is y now
 {
    for(x in 1:dim) //now x is count inside
    {
        matrix[x,y]=exp(-entrywise.norm(data[,x]-data[,y],2))
    }
 }

あなたの「マトリックス」は2D配列ですよね?

さらに速度が必要な場合は、内部ループの一部をアンロールして、CPU の分岐負荷を減らし、キャッシング/プリフェッチを改善できます。

 for(y in 1:dim) 
 {
    for(x in 1:(dim/8)) //lets imagine dimension is a multiple of 8
    {
        matrix[x,y]=exp(-entrywise.norm(data[,x]-data[,y],2))
        matrix[x+1,y]=exp(-entrywise.norm(data[,x+1]-data[,y],2))
        matrix[x+2,y]=exp(-entrywise.norm(data[,x+2]-data[,y],2))
        matrix[x+3,y]=exp(-entrywise.norm(data[,x+3]-data[,y],2))
        matrix[x+4,y]=exp(-entrywise.norm(data[,x+4]-data[,y],2))
        matrix[x+5,y]=exp(-entrywise.norm(data[,x+5]-data[,y],2))
        matrix[x+6,y]=exp(-entrywise.norm(data[,x+6]-data[,y],2))
        matrix[x+7,y]=exp(-entrywise.norm(data[,x+7]-data[,y],2))
    }
 }
于 2013-07-04T11:00:07.270 に答える