2016-04-15 18 views
1

これは、新しいコードを要求することではなく、Rがそのような計算を行う方法についての詳細です。もちろん、効率を上げるためのあらゆる提案をします。ループの高速化R

のは、私はそうのようなスクリプトがあるとしましょう:

x=matrix(complex(1:10,1:10,imaginary = 1:10),ncol=2) 
y=x+300 
raw=list(x,y) 
raw_complex = list(raw,raw,raw,raw) 

それは複雑な行列のリストです。私は、それのうちの位相角を取得しようとしている:phase = atan(Im(x)/Re(x))

私の現在のコードは次のとおりです。

for (m in 1:length(raw_complex)){ 
    for (n in 1:length(raw_complex[[m]])){ 
    for (i in 1:dim(raw_complex[[m]][[n]])[1]){ 
     for (j in 1:dim(raw_complex[[m]][[n]])[2]){ 
raw_complex[[m]][[n]][i,j]=(atan(Im(raw_complex[[m]][[n]][i,j])/Re(raw_complex[[m]][[n]][i,j]))) 
     }}}} 

私は、私が知っている、Rのforループを回避知っているが、概念的には、これはそれが容易になります私には何が起きているのか、礼儀正しいかサプリーかを見ることができます。

私の質問は、ループの繰り返しごとに、リストまたは行列全体を一度に1つずつ取り出すのではなく、メモリ内にコピーすることです。明らかに、私はRがすべての繰り返しをコピーするようにはしたくないでしょう。

私の実際のデータセットは、リストの各要素に95個のマトリックスを持つ4のリストを持っています。各マトリックスは145x901なので、私はこれをできるだけ速くしたいと思っています。

ああ、出力が複素数ではなく実数であればいいでしょう。私はatan()の前にas.numeric()を追加しようとしましたが、それは役に立たないようです。

ありがとうございます!

+1

出力が複雑です。科学的ではありませんが、虚数部分は0 –

答えて

5

Rがベクター化されているという事実を利用する。具体的には、ベクトルや行列に直接多くの計算を適用することができます。例えば

、相用の関数を定義:

phase <- function(x)atan(Im(x)/Re(x)) 
phase(x) 

この単一の、シンプルな機能では、あなたがあなたのマトリックス内の各セルの位相を計算する:

  [,1]  [,2] 
[1,] 0.7853982 0.7853982 
[2,] 0.7853982 0.7853982 
[3,] 0.7853982 0.7853982 
[4,] 0.7853982 0.7853982 
[5,] 0.7853982 0.7853982 

今あなたが1ですこのphase機能をあなたのリストに適用することから一歩離れてください。

lapply(raw, phase) 
[[1]] 
      [,1]  [,2] 
[1,] 0.7853982 0.7853982 
[2,] 0.7853982 0.7853982 
[3,] 0.7853982 0.7853982 
[4,] 0.7853982 0.7853982 
[5,] 0.7853982 0.7853982 

[[2]] 
      [,1]  [,2] 
[1,] 0.003322247 0.01960533 
[2,] 0.006622420 0.02279735 
[3,] 0.009900667 0.02596819 
[4,] 0.013157135 0.02911798 
[5,] 0.016391974 0.03224688 

をしかし、あなたが本当に後にしているものを、リストのリストに再帰的にこの機能を適用することである。このためには、lapply()を使用することができます。このため、機能rapply()が存在する - 再帰のための場所rスタンド: - あなたはループを避けるためではない -

z <- rapply(raw_complex, phase, how = "list") 
str(z) 
List of 4 
$ :List of 2 
    ..$ : num [1:5, 1:2] 0.785 0.785 0.785 0.785 0.785 ... 
    ..$ : num [1:5, 1:2] 0.00332 0.00662 0.0099 0.01316 0.01639 ... 
$ :List of 2 
    ..$ : num [1:5, 1:2] 0.785 0.785 0.785 0.785 0.785 ... 
    ..$ : num [1:5, 1:2] 0.00332 0.00662 0.0099 0.01316 0.01639 ... 
$ :List of 2 
    ..$ : num [1:5, 1:2] 0.785 0.785 0.785 0.785 0.785 ... 
    ..$ : num [1:5, 1:2] 0.00332 0.00662 0.0099 0.01316 0.01639 ... 
$ :List of 2 
    ..$ : num [1:5, 1:2] 0.785 0.785 0.785 0.785 0.785 ... 
    ..$ : num [1:5, 1:2] 0.00332 0.00662 0.0099 0.01316 0.01639 ... 

をこれが高速になりますが、あなたは、マトリックスではなく、すべてのセルに計算しているため。

さらに重要なことは、簡潔で読みやすいことです。

+0

うわーです。それは最高です。ありがとう! –

+1

もちろん、これらの行列の次元がすべて同じ場合、配列はネストされたリストよりも優れたデータ構造になります。 – Roland

+0

'R'に' 'Arg'関数があります。これは' 'phase''を実行します。 – nicola