2016-08-24 4 views
0

RcppC++R)の行列をメモリ内の列の順番で格納しています。すなわち、それは次のようになります。ベクトルのインデックスを使用してムーア近傍を取得する方法

 [,1] [,2] [,3] [,4] [,5] 
[1,] 1 6 11 16 21 
[2,] 2 7 12 17 22 
[3,] 3 8 13 18 23 
[4,] 4 9 14 19 24 
[5,] 5 10 15 20 25 

、私はi = 1から25に走る単一forループを持っている(心の中でクマを、それがベースのすべてゼロであるが、ここで私は、便宜上1を言っています)。

マトリックスのすべての要素について、私はそのムーア近隣を望みます。これは、エッジにない要素では簡単です。私たちの選択したインデックスがidxで、正方行列のサイズがnrowであれば、我々は

leftmid = idx - nrow 
lefttop = (idx - nrow) - 1 
leftbot = (idx - nrow) + 1 

rightmid = idx + nrow 
righttop = (idx + nrow) - 1 
rightbot = (idx + nrow) + 1 

midtop = idx - 1 
midbot = idx + 1 

を持っているが、私はエッジケースに対処する方法を見つけ出す傾けます。例えば、idx = 3場合、それから私は隣人をしたい:

leftmid = 23 
lefttop = 22 
leftbot = 24 

rightmid = 8 
righttop = 7 
rightbot = 9 

midtop = 2 
midbot = 4 

それは同様にもう少し複雑なコーナーケースのです。ここの目標は時間を短縮することです。現在私のプログラムはdouble forループで動作していますが、それは妥当なものより遅いです。私はパフォーマンスを改善するためにそれを単一のforループに変更したいと思います。

編集:leftrightの境界がモジュラスによって得られることを実現しました。従って3 - 5 %% 25 = 23。しかし、私はまだ上端と下端のケースを持っています。

答えて

0

「周期的」境界条件に興味があるようです。行列がトロイダルトポロジを持つ、つまり上が下を囲み、右が左に折り返されます。

4つのループ(行と列のそれぞれに1つずつ)、それから近隣の行と列にそれぞれ1つのループを反復するほうが簡単かもしれません。このような何か作業をする必要があります:

int mooreNeighbors[3][3]; 
int nRows = 5; 
int nCols = 5; 

// Loop over the rows and columns of the matrix 
for (int i = 0; i < nRows; ++i) { 
    for (int j = 0; j < nCols; ++j) { 

     // Loop over the cyclic Moore neighborhood 
     for (int mnI = 0; mnI < 3; ++mnI) { 
      for (int mnJ = 0; mnJ < 3; ++mnJ) { 

       // Sub-matrix indices 
       int subI = (i - mnI - 1) % nRows; 
       int subJ = (j - mnJ - 1) % nCols; 

       // Index into column-dominant matrix 
       int idx = subI + subJ*nRows; 

       mooreNeighbors[mnI][mnJ] = matrix[idx]; 
      } 
     } 
    } 
} 

私はこれをコンパイルしようとしていないが、修正するために近く、どんな間違いを修正するために十分明確にする必要があります。疑似コードと考えることができます。

また、私は、最適性をはっきりとわかります。たとえば、最も内側のループですべてを行う必要はありません。

関連する問題