のために、私は、次のループベクトル化するために願っています:ベクタライズ分()行列
for (i in 1:n) {
for (j in 1:m) {
temp_mat[i,j]=min(temp_mat[i,j],1);
}
}
を私はtemp_mat=min(temp_mat,1)
を行うことができると思ったが、これは私の望ましい結果を与えていません。はるかに高速にするために、このループをベクトル化する方法はありますか?
のために、私は、次のループベクトル化するために願っています:ベクタライズ分()行列
for (i in 1:n) {
for (j in 1:m) {
temp_mat[i,j]=min(temp_mat[i,j],1);
}
}
を私はtemp_mat=min(temp_mat,1)
を行うことができると思ったが、これは私の望ましい結果を与えていません。はるかに高速にするために、このループをベクトル化する方法はありますか?
temp_mat <- pmin(temp_mat, 1)
を使用してください。パラレルミニマムの詳細については、?pmin
を参照してください。
例:あなたは計算科学のバックグラウンドを持っているので
set.seed(0); A <- matrix(sample(1:3, 25, replace = T), 5)
#> A
# [,1] [,2] [,3] [,4] [,5]
#[1,] 3 1 1 3 3
#[2,] 1 3 1 2 3
#[3,] 2 3 1 3 1
#[4,] 2 2 3 3 2
#[5,] 3 2 2 2 1
B <- pmin(A, 2)
#> B
# [,1] [,2] [,3] [,4] [,5]
#[1,] 2 1 1 2 2
#[2,] 1 2 1 2 2
#[3,] 2 2 1 2 1
#[4,] 2 2 2 2 2
#[5,] 2 2 2 2 1
、私はより多くの情報を提供したいと思います。
pmin
は高速ですが、高性能ではありません。接頭辞「parallel」はelement-wise
を示唆しています。 Rの「ベクトル化」の意味は、HPCの「SIMDベクトル化」と同じではありません。 Rは解釈言語なので、Rの「ベクトル化」は、RレベルループではなくCレベルループを選択することを意味します。したがって、pmin
はちょっとしたCループでコーディングされています。
実際の高性能コンピューティングでは、SIMDのベクトル化が役立ちます。私はあなたがSSE/AVX組み込み関数を知っていると信じています。だから、のコードを書いてからSSE2
を入力すると、pmin
から2倍のスピードアップが得られます。 AVXの_mm256_min_pd
が表示されている場合、pmin
から〜4倍のスピードアップが得られます。
残念ながら、R自体はSIMDを実行できません。この問題に関しては、Does R leverage SIMD when doing vectorized calculations?の投稿への回答があります。ご質問の場合、HPC BLASにRをリンクしてもpmin
にはBLAS操作が含まれていないため、pmin
はSIMDの恩恵を受けません。コンパイルされたコードを自分で書く方が良いでしょう。
min()
はがベクトル化されているため、少し混乱します。この特定の場合に望ましい結果を得るためには、この関数を使う必要はありません。 論理サブセットは、おそらくより効率的な(そしてもっとコンパクトな)代替手段を提供します。
私が正しくあなたの所望の出力を理解している場合、あなたのコード内でネストされたループを実行した場合と同様に、マトリックスの変更は、単一のコマンドで実現することができるに:
temp_mat[temp_mat > 1] <- 1
は、この情報がお役に立てば幸いです。
set.seed(123)
temp_mat <- matrix(2*runif(50),10)
#> temp_mat
# [,1] [,2] [,3] [,4] [,5]
# [1,] 0.5751550 1.91366669 1.7790786 1.92604847 0.2856000
# [2,] 1.5766103 0.90666831 1.3856068 1.80459809 0.8290927
# [3,] 0.8179538 1.35514127 1.2810136 1.38141056 0.8274487
# [4,] 1.7660348 1.14526680 1.9885396 1.59093484 0.7376909
# [5,] 1.8809346 0.20584937 1.3114116 0.04922737 0.3048895
# [6,] 0.0911130 1.79964994 1.4170609 0.95559194 0.2776121
# [7,] 1.0562110 0.49217547 1.0881320 1.51691908 0.4660682
# [8,] 1.7848381 0.08411907 1.1882840 0.43281587 0.9319249
# [9,] 1.1028700 0.65584144 0.5783195 0.63636202 0.5319453
#[10,] 0.9132295 1.90900730 0.2942273 0.46325157 1.7156554
temp_mat[temp_mat > 1] <- 1
#> temp_mat
# [,1] [,2] [,3] [,4] [,5]
# [1,] 0.5751550 1.00000000 1.0000000 1.00000000 0.2856000
# [2,] 1.0000000 0.90666831 1.0000000 1.00000000 0.8290927
# [3,] 0.8179538 1.00000000 1.0000000 1.00000000 0.8274487
# [4,] 1.0000000 1.00000000 1.0000000 1.00000000 0.7376909
# [5,] 1.0000000 0.20584937 1.0000000 0.04922737 0.3048895
# [6,] 0.0911130 1.00000000 1.0000000 0.95559194 0.2776121
# [7,] 1.0000000 0.49217547 1.0000000 1.00000000 0.4660682
# [8,] 1.0000000 0.08411907 1.0000000 0.43281587 0.9319249
# [9,] 1.0000000 0.65584144 0.5783195 0.63636202 0.5319453
#[10,] 0.9132295 1.00000000 0.2942273 0.46325157 1.0000000
私はそれはRが列優先であることとは何かを持っているとは思いません。 'pmin'は渡された項目間の要素的な最小値を返します。そのため、1は同じ次元のオブジェクトに強制的に変換されます。たとえば、異なるサイズベクトルが渡された場合、リサイクルされる要素についての警告が表示されます。 – Gabe
OPが要求したものではありませんでしたが、Rで大規模並列計算を実現するにはいくつかの方法があります。例としては、 'snow'、' multicore'、 'foreach'、' Rmpi'、 'Rth'、' gputools'パッケージと、これまでに別々のパッケージのいくつかを統合した 'parallel'のパッケージがあります。このトピックの最新技術については、[参考文献](https://books.google.com/books/about/Parallel_Computing_for_Data_Science.html?id=SsbECQAAQBAJ)をご覧ください。 – RHertel
"たとえば、OPの問題はこのフォームの恩恵を受けることはできません。メモリにバインドされているため、複数のスレッドを設定すると速度が低下します。どうして?並列プログラミングでは、マトリックスを別々のチャンクに分割し、それぞれを別々のスレッドで処理させるのが標準タスクではないでしょうか?この場合、スレッド間で通信する必要はありません。これは私には恥ずかしいほど平行な状況の標準的な例のようで、Rで簡単に扱うことができます。 – RHertel