Использовать логический массив «маска» для индексации массива - PullRequest
1 голос
/ 17 октября 2019

У меня очень большой массив с размерами (nr, nc) строк и столбцов. Я перебираю этот массив, чтобы вычислить функцию fun из постоянной записи этого массива (px, py). Расчет для этой функции важен только в постоянной области (расстояние d) вокруг этой точки. Поэтому моя цель - ускорить код и вычислять только в этом круге вокруг точки (px, py).

int i;
int j;
for(i=0; i<nr; i++){
    for(j=0; j<nc; j++){
        *(arr_stg+i*nc+j) = fun(i,j,px,py);
    }
}

У меня также есть функция для вычисления логической «маски» (я незнать, если это правильное слово для этого). Я рассчитываю это с евклидовым расстоянием вокруг точки выборки. Таким образом, для данного расстояния, т. Е. 4, я вычисляю этот тип массива-маски:

0 0 0 0 1 0 0 0 0
0 0 0 1 1 1 0 0 0
0 0 1 1 1 1 1 0 0
0 1 1 1 1 1 1 1 0
1 1 1 1 1 1 1 1 1
0 1 1 1 1 1 1 1 0
0 0 1 1 1 1 1 0 0
0 0 0 1 1 1 0 0 0
0 0 0 0 1 0 0 0 0

Точная форма (если это ноль или единица) здесь не имеет значения, должна работать для любого видаэто nxn- "маски".

Мой вопрос: как мне изменить два цикла for, чтобы перебирать только эту маску вокруг заданной точки таким образом, чтобы я получал более быстрый код, а затем просто вычислял егодля всех i, j большого массива и не используйте те, которые находятся на расстоянии больше указанного.

1 Ответ

1 голос
/ 17 октября 2019

Как правило, если у вас есть маска размером d с центром вокруг точки (xc, yc), вам нужно перебирать диапазоны:

(xc - d) <= x <= (xc + d)
(yc - d) <= y <= (yc + d)

Или, если у вас есть массив масок MASK[2*d+1, 2*d+1], тогда вы просто получите:

// iterate through MASK dimensions
for (var mi = 0; mi < 2 * d + 1; mi++)
   for (var mj = 0; mj < 2 * d + 1; mj++)
   {
        // move to the right location
        var x = xoffset + mi;
        var y = yoffset + mj;

        // do something with (x, y) and MASK[mi, mj]
   }

Однако вы должны убедиться, что xoffset + mi и yoffset + mj не выходят за пределы.

...