#matlab #performance #for-loop #nested-loops
#matlab #Производительность #цикл for #вложенные циклы
Вопрос:
У меня есть небольшой логический массив ( A
) размером 256x256x256 с неизвестной формой единиц где-то в массиве. Также существует двойной массив меньшего размера ( se
) размером 13x13x13. В se в середине массива находится определенный куб логических циклов ( se
).
Мне нужно пробежаться по каждому логическому элементу в A
и для каждого логического элемента в A
меньшем массиве se
необходимо добавить его в A
. Имеется в виду расширение формы A
на se
.
Вот что у меня получилось на данный момент. Это работает, но имеет очень низкую производительность в отношении скорости.
У кого-нибудь есть предложения о том, как ускорить эту задачу кодирования?
[p, q, r] = size(se);
[m, n, o] = size(A);
temp = zeros(m, n, o);
for i = 1:m
for j = 1:n
for k = 1:o
if img_g(i, j, k) == 1
for s = 1:p
for t = 1:q
for u = 1:r
if se(s, t, u) == 1
c = i s;
d = j t;
e = k u;
temp(c, d, e) = 1;
end
end
end
end
end
end
end
end
B = temp;
Я очень благодарен за любую помощь и предложения, которые улучшают мои навыки программирования.
Комментарии:
1. Если это действительно простое трехмерное расширение, и у вас есть доступ к инструменту обработки изображений MATLAB , тогда взгляните на то, как расширять точки в 3D-пространстве, используя сферические структурирующие элементы для примера. Помимо этого, трехмерная свертка (см.
convn
) также должна работать (с некоторыми последующими шагами).2. Определенно есть один, путем применения операций над матрицами вместо этого. Теперь, какую операцию выполнить? зависит от того, что вы хотите сделать. К сожалению, я не смог понять, чего вы хотите достичь. Не могли бы вы объяснить это другими словами, пожалуйста?
3. Нет способа ускорить вложенные циклы без изменения реализации вашего кода. Я бы также посоветовал вам проверить imdilate() из документации Matlab, если это то, что вы пытаетесь сделать.
4. Я пытался избежать использования инструментария обработки изображений. Вот почему я делаю набор сам.
5. Можете ли вы привести пример
A
иse
? Достаточно ли этого для выполненияA = rand(255, 255, 255); A(20:40, 20:40, 20:40) = 1;
?
Ответ №1:
в зависимости от используемого вами процессора, вы можете, по крайней мере, использовать «parfor» для внешнего цикла (первый цикл). это позволяет выполнять параллельные вычисления и ускоряет вашу производительность за счет количества физических ядер, полученных вашим процессором.
Комментарии:
1. В общем, можно было бы рассмотреть предложение, но оно не будет работать с моей структурой кода и моими изменениями
temp
.
Ответ №2:
Я не уверен на 100%, что это делает то, о чем вы просите (поскольку я не совсем понимаю, что делает ваш код), но, возможно, методология даст некоторое вдохновение.
Я сгенерировал не «логический» A
, а случайный, и я установил куб внутри равным 1. Аналогично для se
. Я использую meshgrid
для получения массивов, соответствующих индексам, и использую mask
логическую индексацию. (возможно, мой mask
— это то, для A
чего у вас есть в первую очередь?)
A = rand(255,255,255);
A(40:50, 23:33, 80:100) = 1;
mask = (A==1);
[I,J,K] = meshgrid(1:255);
se = rand(13,13,13);
se(4:6, 3:7, 2:8) = 1;
se_mask = (se==1);
[se_I, se_J, se_K] = meshgrid(1:13);
Здесь я предполагаю, что куб в A
находится достаточно далеко от любого ребра (скажем, 13 пробелов), поэтому мы не получим c
, d
или e
больше 255.
Я сгладил mask
в вектор строк, чтобы find
получить единый индекс ii
, который мы можем использовать для ссылки на любую точку в A
, тогда исходные i
, j
и k
индексы находятся в I(ii)
, J(ii)
и K(ii)
соответственно. Аналогично для se_I
и т.д.
temp = zeros(255, 255, 255);
for ii=find(mask(:).')
for jj=find(se_mask(:).')
c = I(ii) se_I(jj);
d = J(ii) se_J(jj);
e = K(ii) se_K(jj);
temp(c,d,e) = 1;
end % for
end % for
Матрицы I
, J
, K
se_I
se_J
и se_K
являются обычными, поэтому, если их создание / хранение становится узким местом, вы можете написать функции для их замены. Матрица temp
может быть очень разреженной в зависимости от размера ваших кубов единиц, поэтому вы могли бы рассмотреть возможность использования sparse
.
Я не сравнивал тайминги с вашим решением.