Is there a way to vectorize the 3 for loops?
Show older comments
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
Matt J
on 10 Mar 2013
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.
Cedric
on 10 Mar 2013
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).
Navneet
on 10 Mar 2013
Navneet
on 10 Mar 2013
>> 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 ].
Answers (2)
Daniel Shub
on 10 Mar 2013
0 votes
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
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.
Daniel Shub
on 10 Mar 2013
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.
Matt J
on 10 Mar 2013
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...
Daniel Shub
on 11 Mar 2013
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....
Jan
on 11 Mar 2013
@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.
Jan
on 10 Mar 2013
0 votes
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
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!