Is there a way to vectorize the 3 for loops?

for k=1:1:scolr
for j=1:1:scols
for i=1:1:srows
%Binary Conversion
esecretbin=dec2bin(secret(i,j,k),8);
esecreth(1:8)=str2num(esecretbin(:));
%Partial Share Generation
eoshare1{i,j}=esecreth;
%Dummy Initialization
cr=0;
zr=0;
%Random Integer Generation
ra{i,j,k}=randint(1,1,9);
while ra{i,j,k}==0
ra{i,j,k}=randint(1,1,9);
end
%Checking for 1s and 0s and replacing alternative 1s
for a=1:1:8
if eoshare1{i,j}(a)==1
o{i,j}=o{i,j}+1;
cr=cr+1;
if mod(o{i,j},2)==0;
eoshare1{i,j}(a)=0;
c{i,j}(a)=a;
insert1=1;
insert2=0;
else
c{i,j}(a)=0;
insert1=0;
insert2=1;
end
else
z{i,j}=z{i,j}+1;
c{i,j}(a)=0;
zr=zr+1;
end
if (cr<zr && insert1==0) || (cr<zr && insert1==1)
if c{i,j}(a)~=a
if eoshare1{i,j}(a)==0 && a~=ra{i,j,k}
eoshare1{i,j}(a)=1;
cr=cr+1;
zr=zr-1;
end
end
else if cr==zr && insert1==0
if c{i,j}(a)~=a
if eoshare1{i,j}(a)==0 && a~=ra{i,j,k}
eoshare1{i,j}(a)=1;
cr=cr+1;
zr=zr-1;
end
end
end
end
if cr>zr && insert1==0
break;
else if cr==zr && insert1==1
break;
end
end
end
%Performing bitxor to obtain Old Share2
eoshare2{i,j}=bitxor(eoshare1{i,j},esecreth);
%Insertion of the selected number at the random location in share1
enshare1{i,j}(1:ra{i,j,k}-1)=eoshare1{i,j}(1:ra{i,j,k}-1);
enshare1{i,j}(ra{i,j,k})=insert1;
enshare1{i,j}(ra{i,j,k}+1:9)=eoshare1{i,j}(ra{i,j,k}:8);
%Insertion of the selected number at the random location in share2
enshare2{i,j}(1:ra{i,j,k}-1)=eoshare2{i,j}(1:ra{i,j,k}-1);
enshare2{i,j}(ra{i,j,k})=insert2;
enshare2{i,j}(ra{i,j,k}+1:9)=eoshare2{i,j}(ra{i,j,k}:8);
%Cover image enhancement
if cover1(i,j,k)<256
cover1(i,j,k)=cover1(i,j,k)+1;
end
if cover2(i,j,k)<256
cover2(i,j,k)=cover2(i,j,k)+1;
end
isOne = enshare1{i,j} == 1 ;
enshare1{i,j}(:) = cover1(i,j,k)-1 ;
enshare1{i,j}(isOne) = cover1(i,j,k) ;
isOne = enshare2{i,j} == 1 ;
enshare2{i,j}(:) = cover2(i,j,k)-1 ;
enshare2{i,j}(isOne) = cover2(i,j,k) ;
%Reshaping into 3x3 matrix
etshare1{i,j}=reshape(enshare1{i,j},3,3);
eshare1{i,j}=transpose(etshare1{i,j});
etshare2{i,j}=reshape(enshare2{i,j},3,3);
eshare2{i,j}=transpose(etshare2{i,j});
%Dummy initialization
ro=(3*i)-2;
co=(3*j)-2;
%Replacement of cover pixels
s11=eshare1{i,j};
s1(ro:ro+2,co:co+2,k)=s11;
s22=eshare2{i,j};
s2(ro:ro+2,co:co+2,k)=s22;
end
end
end
Is there any way to vectorize the 3 for loops or atleast the inner 'a' for loop?

6 Comments

Your code is long and difficult to decipher. It is also impossible for us to run and test, since it refers to data (e.g., secret) that we don't have and functions (e.g. RANDINT) that are not native MATLAB functions.
It might be more fruitful to explain in words what the code is doing instead.
If you read my comment in your previous question, you can probably achieve that by yourself. Would be a good exercise!
Actually, the first thing that you should do is use the profiler to see where your code is spending time.
>> profile viewer
My guess is that in addition to vectorizing these inner loops (for a=...), you'll want to work on
%Binary Conversion
esecretbin=dec2bin(secret(i,j,k),8);
esecreth(1:8)=str2num(esecretbin(:));
and build a solution based on bit-level operations like BITGET, BITAND, etc, instead of having conversions to and from strings.
Also, the following
%Random Integer Generation
ra{i,j,k}=randint(1,1,9);
while ra{i,j,k}==0
ra{i,j,k}=randint(1,1,9);
end
can probably be achieved in one line without a loop (especially one like that, that will take an arbitrary time).
@Matt J
  • The code is actually taking in a 160x160x3 image(referred to as secret) and initially converting it into a 8 bit image.
  • Each of these 8bit numbers are converted into a string so that I can access each element in the string.
  • Either 1 or 0 is inserted in the 8 bit string and the position for insertion of this number is determined by the number generated by randint(between 1 and 9).
  • After the insertion of the number, I convert the alternative 1s to 0s.(The number previously inserted is not taken into consideration in this step)
  • In order to avoid that, I constructed this structure
if (cr<zr && insert1==0) || (cr<zr && insert1==1)
if c{i,j}(a)~=a
if eoshare1{i,j}(a)==0 && a~=ra{i,j,k}
eoshare1{i,j}(a)=1;
cr=cr+1;
zr=zr-1;
end
end
else if cr==zr && insert1==0
if c{i,j}(a)~=a
if eoshare1{i,j}(a)==0 && a~=ra{i,j,k}
eoshare1{i,j}(a)=1;
cr=cr+1;
zr=zr-1;
end
end
end
end
if cr>zr && insert1==0
break;
else if cr==zr && insert1==1
break;
end
end
  • Here c{i,j} stores the position in which the number 1 has been inserted and avoids changing the 1 which has been recently inserted.
  • And then, only for the share1 I make the number of 1s>number of 0s. For this I change the 0s present into 1s from the LHS of the binary number. Again the previously inserted 0 should not be changed.
  • Later on I perform the bitxor and concatenate with the number to be inserted and get the new matrix.
  • I then reshape it and so on and so forth.
I hope I haven't confused you with all those pointers.
@Cedric
I saw your comment and I shall try that out. However, how do I vectorize the for loops of i,j and k? I understand the similarity between my previous question and the 'a' for loop over here. Let me try it out and get back.
With regards to the profile viewer, I tried it out. I did,
profile clear
profile on
profreport('filename.m')
However, it showed No profile information.
>> profile viewer
and type the call of the function or script that you want to run/profile in the field Run this code. Then press enter or click on [ Start Profiling ].

Sign in to comment.

Answers (2)

Why do you want to vectorize the code? Loops in MATLAB are no longer, and haven't been for a decade, inherently slow. Is your question perhaps "how can I optimize my code"? The first step is to use mlint. All those orange warning the MATLAB editor gives you are telling you important things. Once your function is all "green", it is time to use the profiler to find the bottleneck. Once you know what is slow, decide if it is worth speeding up.

5 Comments

Matt J
Matt J on 10 Mar 2013
Edited: Matt J on 10 Mar 2013
Loops in MATLAB are no longer, and haven't been for a decade, inherently slow
While it's true that some improvements have been made to for-loops over the years (especially if the body of the loop contains only array manipulation and indexing), it seems unlikely that this code will benefit from them.
AFAIK, any function calls made within the body of a for-loop will render the loop as slow as in the old days, and the OP's code makes lots of them. Things like dec2bin will still need to re-run redundant error checks with every loop iteration just to see if the input data types are of an acceptable class.
NO NO NO NO NO
Consider
function test
N = 1e6;
x = zeros(N, 1);
tic
for ii = 1:N
x(ii) = myfun(randn, randn);
end
toc
end
function x = myfun(a, b)
x = a+b;
end
Run it with
feature accel off
and
feature accel on
I get over an order of magnitude difference in run time.
Yes, a loop will still do all the error checking multiple times, but in that case you want to write a helper function that doesn't do the error checking (e.g., datenum and datenummx). In other words, it is not the loop that is the problem, but the code in the loop.
Ah well. Good news that it's not as slow as in the old days! But obviously, I don't want to be rewriting check-free versions of built-in MATLAB functions every time I want to optimize a for-loop...
Hopefully the checks are only a small portion of the run time and when they are not, hopefully there is already a compiled mex that runs without the checks....
@Daniel: Yes, hopefully. Unfortunately a lot of functions suffer from the overhead, e.g. polyfit: Disabling the warning temporarily needs more time than the actual processing, except for "large" problems.
In MEX files the checks require much less time, but they are much more important there. Inside C a bad input can cause a corrupted memory management, while inside Matlab this does not happen.

Sign in to comment.

Jan
Jan on 10 Mar 2013
What kind of reply do you expect? I strongly recommend to use the profiler at first, or even better some TIC/TOCs, which do not disable the JIT acceleration. Then post the relevant part of the code again.
The currently posted large code is not a fair task for a forum.

Categories

Find more on Loops and Conditional Statements in Help Center and File Exchange

Asked:

on 10 Mar 2013

Community Treasure Hunt

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

Start Hunting!