#for-loop #parallel-processing #matlab
#для цикла #параллельная обработка #matlab
Вопрос:
У меня есть фрагмент кода, который делит матрицу изображений img
на небольшие фрагменты и работает над ними параллельно. Но Matlab говорит, что parfor
цикл не может быть использован, потому что способ outC{i,j}
индексируется. Как мне это исправить?
Подматрицы имеют разный размер. Если img=[4x7]
, то
C=[3x3 3x3 3x1;
1x3 1x3 1x1]
Кстати, я не уверен, что использование массива ячеек здесь хорошая идея. Если нет, не стесняйтесь давать предложения о том, как также разделить img
.
C=mat2cell(img, rowSplit, colSplit);
[rowc,colc]=size(C);
outC=cell(rowc,colc);
parfor i=1:rowc
for j=1:colc
outC{i,j}=doWork(C{i,j});
end
end
Ответ №1:
Вы можете использовать линейную индексацию как для ввода, так и для вывода.
Сначала я делаю вид, что вводил вашу форму, и простую doWork
функцию:
>> C= {rand(3) rand(3) rand(3,1); rand(1,3) rand(1,3) rand(1)};
>> C
C =
[3x3 double] [3x3 double] [3x1 double]
[1x3 double] [1x3 double] [ 0.3922]
>> doWork = @(x)2*x;
Затем используйте линейную индексацию:
>> outC=cell(size(C));
>> parfor ci=1:numel(C)
outC{ci} = doWork(C{ci});
end
Быстрая проверка, что это сработало:
>> outC{2,1}./C{2,1}
ans =
2 2 2
Ответ №2:
Хотя здесь есть много ответов, которые помогут использовать parfor
блок для выполнения того, что вам нужно, я бы подумал, что еще лучшим решением может быть использование вместо него блока spmd.
Вместо того, чтобы разбивать ваше изображение на более мелкие части в массиве ячеек, рассмотрите вместо этого возможность преобразования его в распределенный массив, возможно, распределяя теми же частями, что вы делаете в данный момент. Внутри spmd
блока вы можете выполнить свою doWork
функцию, и она будет применена к любой части (совместно) распределенного массива, присутствующей на этом рабочем элементе. Наконец, вы можете собрать результаты и собрать их обратно клиенту.
Я нахожу spmd
более сложным для понимания, чем parfor
, но это очень мощно, как только вы получите представление об этом; и я бы подумал, что этот пример может быть очень удобно выражен в такой форме.
Комментарии:
1. Не могли бы вы привести пример кода? У меня есть изображение, к которому я хочу применить фильтр. Например, фильтр радиуса 5. Каков был бы наилучший способ его обработки? Спасибо.
Ответ №3:
Просто создайте вектор выходных данных и используйте reshape
впоследствии, чтобы превратить его в матрицу.
Комментарии:
1. Не могли бы вы показать, как это можно сделать? Подматрицы имеют разный размер, например, img = [4×7] становится C = [3×3 3×3 3×1;1×3 1×3 1×1].
2. @Usavich: Я имел в виду массив ячеек. Работает ли это, если вы написали,
outC{i j*colc} = ...
а затем вызвалиreshape
?