I was wondering if anyone could help me vectorize this piece of code.
fr_bw is a matrix.
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
I can't help you with this sif (match == 0)
stuff -- if it's supposed to be if (match == 0)
you're not changing match
so it could be brought outside the loop.
Otherwise, how about this:
[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);
(Please note that mean
is a built-in function so I renamed your variables to w_mean
and w_sd
.)
The sub2ind
call gives you linear indices that correspond to subscripts. (Direct subscripts won't work; z([a1 a2 a3],[b1 b2 b3],[c1 c2 c3])
refers to 27 elements in the z
array with subscripts that are the cartesian product of the specified subscripts, rather than z(a1,b1,c1)
and z(a2,b2,c2)
and z(a3,b3,c3)
that you might expect.)
Here's an illustration of this technique:
>> 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
A few comments on your code:
Did you mean if
rather than sif
?
The code isn't replicable at the moment, since you haven't provided examples of the variables w
, fr_bw
and sd_init
. This makes it tricky to give an exact answer.
It looks like you are assigning things to a variable named mean
. This will shadow the mean
function, and probably cause you grief.
I'm just guessing, but I don't think double
does what you think it does. You don't need to convert individual elements of a numeric matrix to type double
; they are already the correct type. (On the other hand, if fr_bw
is a different type, say integers, then you should create a new variable dbl_fr_bw = double(fr_bw);
before the loops.
You might need to adjust the dimension over which you calculate the minimums, but the first line of the loop can be replaced with
[min_w, min_w_index] = min(w, [], 3)
The second line with
mean_values(:, :, min_w_index) = double(fr_bw)
Not sure about the third line, since I don't know what sd_init
is/does.