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

Cedric
Cedric 2017년 9월 30일
편집: Cedric 2017년 9월 30일
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).
Vijay
Vijay 2017년 10월 1일
Well, H is 5 by 10 logical matrix. 'newbitvalues' is again a 5 by 10 logical matrix. 'recdmsg' is a 1 by 10 logical vector.

댓글을 달려면 로그인하십시오.

 채택된 답변

OCDER
OCDER 2017년 9월 30일

1 개 추천

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

댓글 수: 4

Sorry, for the late reply. But when I use this command
tempr = newbitvalues(LDPC.H(:, i), i);
MATLAB throws me an error
'Subscript indices must either be real positive integers or logicals.'
Vijay
Vijay 2017년 10월 1일
While the vectorized version is undoubtedly more efficient and faster, it combines three steps of the algorithm into one single line of code. That will raise a lot of questions from my advisor. Thanks for the help anyway.
Try
tempr = newbitvalues(logical(LDPC.H(:, i)), i);
OCDER
OCDER 2017년 10월 1일
편집: OCDER 2017년 10월 1일
Hm, interesting that your advisor would question an "undoubtedly more efficient and faster" and simpler code...

댓글을 달려면 로그인하십시오.

추가 답변 (0개)

카테고리

도움말 센터File Exchange에서 Loops and Conditional Statements에 대해 자세히 알아보기

질문:

2017년 9월 30일

편집:

2017년 10월 1일

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by