A way to optimize this piece of code..
6 views (last 30 days)
Show older comments
I have a switch..case inside a nested 'for-loop'. This makes the program very slow, as the for-loops themselves run for a number of iterations. Can someone suggest me a way to optimize this piece of code?
for iter = 1 : 10
for i = 1 : 10
for j = 1 : 5
if (H(j,i) == 1)
tempr = [tempr, newbitvalues(j,i)];
end
end
nZeros = nnz(~tempr);
nOnes = nnz(tempr);
switch recdmsg(i)
case 1
if nZeros > nOnes
recdmsg(i) = ~recdmsg(i);
end
case 0
if nOnes > nZeros
recdmsg(i) = ~recdmsg(i);
end
end
tempr = [];
end
end
2 Comments
Cedric
on 30 Sep 2017
Edited: Cedric
on 30 Sep 2017
It would be easier if you explained what you are trying to achieve and provided test data/arrays. I assume that the outer loop is for multiplying the run time by 10 for measuring the performance, but in the rest of the code many operations make little sense (to me).
Accepted Answer
OCDER
on 30 Sep 2017
First, let's look at the original code and see how to improve that. Then I'll show the vectorized code.
%Making up some variables
% recdmsg0 = rand(1, 10) > 0.5;
newbitvalues = 10*randn(10, 10);
newbitvalues(newbitvalues < 0) = 0;
H = newbitvalues > 5;
recdmsg0 = [1 1 1 0 0 0 1 1 1 1];
recdmsg = recdmsg0;
for iter = 1 : 10
for i = 1 : 10
%Avoid this loop - growing a matrix is very slow since it's copying and deleting of matrices.
%for j = 1 : 5
% if (H(j,i) == 1)
% tempr = [tempr, newbitvalues(j,i)];
% end
%end
tempr = newbitvalues(H(:, i), i); %Use this instead, assuming H is a 2D logical array
nOnes = nnz(tempr);
nZeros = numel(tempr) - nOnes; % to prevent using nnz again for simple math. nnz(~tempr);
%switch recdmsg(i) %Looks like recdmsg is a logical array of 1, 0, and no other values.
% case 1
% if nZeros > nOnes
% recdmsg(i) = ~recdmsg(i); %This is the same operation as the elseif operation
% end
% case 0
% if nOnes > nZeros
% recdmsg(i) = ~recdmsg(i);
% end
%end
if (recdmsg(i) && nZeros > nOnes) || (~recdmsg(i) && nZeros < nOnes)
recdmsg(i) = ~recdmsg(i);
end
%tempr = []; No need for deletion of variable if you're going to override it completely
end
end
However, the loop inside "for i = 1:10 ... end" seems to just operate on all column, which can be avoided by:
recdmsg = recdmsg0;
for iter = 1 : 10
nZeros = sum((newbitvalues.*H + ~H) == 0, 1);
nOnes = sum(H, 1) - nZeros;
condit = (recdmsg & nZeros > nOnes) | (~recdmsg & nZeros < nOnes);
recdmsg(condit) = ~recdmsg(condit);
end
So why did I do "(newbitvalues.*H + ~H) == 0" ? It's just a workaround.
- H seems to be a logical array storing the index in newbitvalues for extracting certain elements of newbitvalues.
- However, accessing newbitvalues(H) does not work, as you lose the column location, and need to do extra steps to preserve that info.
- newbitvalues.*H will return a matrix similar to newbitvalues, but with H == 0 area set to 0 too.
- adding ~H ensures that 0 values in this matrix are ~0 so they don't get counted as zeros
More Answers (0)
See Also
Categories
Find more on Loops and Conditional Statements in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!