3

こんにちは私はパフォーマンスのために最適化しようとしているRの関数を持っています。forループをベクトル化する必要があります。私の問題は、少し複雑なデータ構造と、「which」コマンドを使用してルックアップを実行する必要がある方法です。

5つの要素(1,2,3,4,5)を扱っているとしましょう。10x2のマトリックスのペアは、5つの要素(つまり、(1,2)、(1,3)、(1)のすべての一意のペアの組み合わせです。 、4)....(4,5))。all_prodsは10x1の行列であり、5つの要素すべてを反復処理しながらペアを使用して検索する必要があります。

したがって、1の場合、all_prodsから行1、2、3、4(ペア1、2、1、3、1、4、および1、5)にインデックスを付ける必要があり、1、2、3、4、5のようになります。

私は最近matlabからRに切り替えたばかりなので、助けていただければ幸いです。

foo <- function(AA , BB , CC ){
    pa <- AA*CC;
    pairs <-  t(combn(seq_len(length(AA)),2));

    all_prods <- pa[pairs[,1]] * pa[pairs[,2]];

    result <- matrix(0,1,length(AA));

    # WANT TO VECTORIZE THIS BLOCK
    for(st in seq(from=1,to=length(AA))){
       result[st] <- sum(all_prods[c(which(pairs[,1]==st), which(pairs[,2]==st))])*BB[st];
    }
   return(result);
}
AA <- seq(from=1,to=5); BB<-seq(from=11,to=15); CC<-seq(from=21,to=25);
results <- foo(AA,BB,CC);

#final results is [7715 164208 256542 348096 431250]

forループをベクトル化されたバージョンに変換したいと思います。すべての要素stをループするのではなく、(要素ごとに構築するのではなく)結果ベクトルを取得する1つのコマンドで実行したいと思います。

4

1 に答える 1

8

次のように関数を書くことができます。

foo <- function(AA, BB, CC) {
  pa <- AA*CC
  x <- outer(pa, pa)
  diag(x) <- 0
  res <- colSums(x)*BB
  return(res)
}

重要なアイデアは、対称性を破らないことです。順序付けの使用はpairs、私の行列の右上の三角形に対応しxます。これは計算する値の半分のように見えますが、構文と計算のオーバーヘッドは非常に大きくなります。stペアの最初の要素が2番目の要素である状況を区別しています。後でこれはその区別を取り除くためにかなりの問題につながります。完全な対称行列を使用すると、順序を気にする必要がなく、物事はスムーズにベクトル化されます。

于 2012-06-26T10:35:20.240 に答える