2016-08-24 5 views
0

Ich habe eine Matrix in Rcpp (C++ für R), die in der Reihenfolge der Spalten im Speicher gespeichert ist. Das heißt, es sieht aus wie:Wie bekomme ich die Moore Nachbarschaft mit Index eines Vektors

 [,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 

Nun, ich einen einzigen for Schleife haben, die i = 1-25 läuft (bedenken, es ist alles null basiert, aber hier bin ich nur sagen, eine der Einfachheit halber).

Für jedes Element der Matrix möchte ich seine Moore Nachbarschaft. Dies ist einfach für die Elemente, die nicht am Rand sind. Also, wenn unsere gewählten Index idx und die Größe der quadratischen Matrix ist nrow dann haben wir

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 

Aber ich kann nicht herausfinden, wie man mit den Rand Fälle zu behandeln. Zum Beispiel, wenn idx = 3, dann möchte ich die Nachbarn:

leftmid = 23 
lefttop = 22 
leftbot = 24 

rightmid = 8 
righttop = 7 
rightbot = 9 

midtop = 2 
midbot = 4 

Es ist ein wenig komplizierter an den Eckt auch Fälle. Mein Ziel ist es, die Zeit zu reduzieren. Ich führe gerade mein Programm mit einer doppelten for-Schleife, die funktioniert, aber langsamer als vernünftig ist. Ich möchte es in eine einzige for Schleife ändern, um die Leistung zu verbessern.

Edit: Ich erkannte die left und right Grenzen können durch Modul erhalten werden. Also 3 - 5 %% 25 = 23. Aber ich habe immer noch die oberen und unteren Rand Fälle.

Antwort

0

Es scheint, dass Sie an "zyklischen" Randbedingungen interessiert sind, bei denen die Matrix eine toroidale Topologie aufweist, d. H. Der obere Bereich wird nach unten und der rechte Bereich nach links umgebrochen.

Es könnte einfacher sein, mit vier Schleifen zu iterieren, jeweils eine über die Zeile und die Spalte und dann jeweils eine über die Zeile und die Spalte der Umgebung. So etwas sollte funktionieren:

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]; 
      } 
     } 
    } 
} 

Ich habe nicht versucht, diese Zusammenstellung, aber es sollte in der Nähe zu korrigieren und klar genug sein, um Fehler zu korrigieren. Stellen Sie es sich als Pseudo-Code vor.

Auch bevorzuge ich Klarheit über Optimalität. Zum Beispiel müssen Sie nicht alles in der innersten Schleife tun.

Verwandte Themen