MATLAB векторизация - PullRequest
0 голосов
/ 04 мая 2011

Мне было интересно, может ли кто-нибудь помочь мне векторизовать этот кусок кода.

fr_bw - это матрица.

 for i=1:height
   for j=1:width      
                [min_w, min_w_index] = min(w(i,j,:));  
                mean(i,j,min_w_index) = double(fr_bw(i,j));
                sd(i,j,min_w_index) = sd_init;
     end
end

Ответы [ 2 ]

1 голос
/ 04 мая 2011

Я не могу помочь вам с этим sif (match == 0) материалом - если он должен быть if (match == 0), вы не меняете match, поэтому его можно вынести за пределы цикла.

В противном случае, как насчет этого:

[min_w, min_w_index] = min(w, [], 3);
r = repmat((1:height)',1,width);
c = repmat(1:width,height,1);
ind = sub2ind(size(w),r(:),c(:),min_w_index(:));
w_mean(ind) = double(fr_bw);
w_sd(ind) = repmat(sd_init,height,width);

(Обратите внимание, что mean является встроенной функцией, поэтому я переименовал ваши переменные в w_mean и w_sd.)

Вызов sub2ind дает вам линейные индексы, которые соответствуют индексам. (Прямые подписки не будут работать; z([a1 a2 a3],[b1 b2 b3],[c1 c2 c3]) относится к 27 элементам в массиве z с индексами, которые являются декартовым произведением указанных индексов, а не z(a1,b1,c1) и z(a2,b2,c2) и z(a3,b3,c3), которые вы можете ожидать .)

Вот иллюстрация этой техники:

>> height = 6; width = 4;
>> w = randi(1000,height,width,2)

w(:,:,1) =

   426   599    69   719
   313   471   320   969
   162   696   531   532
   179   700   655   326
   423   639   408   106
    95    34   820   611


w(:,:,2) =

   779   441   638   696
   424   528   958    68
    91   458   241   255
   267   876   677   225
   154   519   290   668
   282   944   672   845

>> [min_w, min_w_index] = min(w, [], 3);
>> min_w_index

min_w_index =

     1     2     1     2
     1     1     1     2
     2     2     2     2
     1     1     1     2
     2     2     2     1
     1     1     2     1

>> z = zeros(height,width,2);
>> r = repmat((1:height)',1,width);
>> c = repmat(1:width,height,1);
>> ind = sub2ind(size(w),r(:),c(:),min_w_index(:));
>> z(ind) = 1

z(:,:,1) =

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


z(:,:,2) =

     0     1     0     1
     0     0     0     1
     1     1     1     1
     0     0     0     1
     1     1     1     0
     0     0     1     0
0 голосов
/ 04 мая 2011

Несколько комментариев к вашему коду:

  1. Вы имели в виду if вместо sif?

  2. Код не указанв настоящее время не может быть воспроизведено, поскольку вы не предоставили примеры переменных w, fr_bw и sd_init.Это затрудняет точный ответ.

  3. Похоже, что вы присваиваете переменную с именем mean.Это затеняет функцию mean и, вероятно, вызовет у вас горе.

  4. Я просто догадываюсь, но я не думаю, что double делает то, что вы думаете, что делает.Вам не нужно преобразовывать отдельные элементы числовой матрицы в тип double;они уже правильного типа.(С другой стороны, если fr_bw - это другой тип, скажем, целые числа, то вам следует создать новую переменную dbl_fr_bw = double(fr_bw); перед циклами.

Возможно, вам придется настроитьизмерение, по которому вы вычисляете минимумы, но первая строка цикла может быть заменена на

[min_w, min_w_index] = min(w, [], 3)

Вторая строка на

mean_values(:, :, min_w_index) = double(fr_bw)

Не уверен насчет третьей строки, так как я не знаю, что sd_init есть / делает.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...