what is another logic that has execution time faster than randi?

5 views (last 30 days)
here,part of my following code.
clc
clear all
A=8;
B=12;
C=10;
for ii=1:C;
for x=1:2:A-1;
%make first random matrice
[vals RandomMatriceA(x,:,ii)]=sort(rand(1,B),2);
done=false;
while ~done,
%make row of second random matrice
NewRowRandomMatriceB=randi([0 2],1,B);
%Make sure sum all element per row in RandomMatriceB <=11
done=sum(NewRowRandomMatriceB)<12;
end
RandomMatriceB(x,:,ii)=NewRowRandomMatriceB;
...
end
for h=2:2:A;
doneA=false;
while ~doneA,
[vals RandomMatriceA(h,:,ii)]=sort(rand(1,B),2);
doneB=false;
while ~doneB,
NewRowRandomMatriceB=randi([0 2],1,B);
doneB= sum(NewRowRandomMatriceB)<12;
end
RandomMatriceB(h,:,ii)=NewRowRandomMatriceB;
...
end
...
when I tried to use profile viewer to check my code. above part that makes my code took longer time. so, I want suggestion to speed my above code, specially in "randi"
  3 Comments
Febri
Febri on 6 Sep 2012
well @Matt Fig :
Actually, I want to make a matrices(A,85,C) that is result of combining two matrices (RandomMatriceA and RandomMatriceB). RandomMatriceA is a Matrices (8,12) which has random permutation value [1 12] per row. RandomMatriceB(8,12) which has random value [0 2]. every row In RandomMatriceB must have value [0 2] with length 12 that has sum of them <12. To combine two above matrice, I have to convert both of them to another matrices : ProcessRandomMatriceA,EndProcess,StartProcess, and then StartPost. ProcessRandomMatriceA is Matrices that show value RandomMatriceA converted by ProcessTime Matrices.
ProcessTime= [ 11 11 11 11 4 4 4 4 4 4 4 2 ]; %Converting Matrice show that per column is value in RandoMatriceA( example: in RandomMatrice A has value 3 so, 3 will have value 11).
%Pre-Allocating Size.
RandomMatriceA=zeros(A,B,C);
RandomMatriceB=zeros(A,B,C);
ProcessRandomMatriceA=zeros(A,B,C);
StartProcess=zeros(A,B,C);
EndProcess=zeros(A,B,C);
TimeOff=zeros(A,B,C);
StartPost=zeros(A,B,C);
for ii=1:C;
for x=1:2:A-1;
timeoff=false;
while ~timeoff,
%make first random matrice
[vals RandomMatriceA(x,:,ii)]=sort(rand(1,B),2);
doneA=false;
while ~doneA,
%make row of second random matrice
NewRowRandomMatriceB=randi([0 2],1,B);
%Make sure sum all element per row in RandomMatriceB <=11
%weeks
%Make sure maximum consecutive of hoilday <= 12 weeks
idxA= bitand(RandomMatriceA(x,:,ii) >= 1,...
RandomMatriceA(x,:,ii) <= 4);
NewRowRandomMatriceB([false(size(idxA, 1), 1)...
idxA(:,1:end-1)]) = 1;
NewRowRandomMatriceB(idxA)=1;
doneA=(sum(NewRowRandomMatriceB)<12) &&...
(~any(diff([0,find(NewRowRandomMatriceB),B+1])>3));
end
RandomMatriceB(x,:,ii)=NewRowRandomMatriceB;
%After making RandomMatriceA and RandomMatriceB, then Make New
%Matrice
%To know varible of new matrice which is result of combining
%RandomMatriceA,RandomMatriceB and ProcessTime
ProcessRandomMatriceA(x,:,ii)=...
ProcessTime(RandomMatriceA(x,:,ii))+...
RandomMatriceB(x,:,ii);
%secondVaribale:to know in which column
%The Consecutive value RandomMatrice will be end
EndProcess(x,:,ii)=cumsum(ProcessRandomMatriceA(x,:,ii),2);
%ThirdVariable:to know in which column
%The Consecutive Value will be start
StartProcess(x,:,ii)=EndProcess(x,:,ii)-...
(ProcessTime(RandomMatriceA(x,:,ii))-1);
%To make sure 43th column only has zeros
TimeOff(x,:,ii)=(StartProcess(x,:,ii)-...
RandomMatriceB(x,:,ii)).*(RandomMatriceB(x,:,ii)~=0);
timeoff=any(TimeOff(x,:,ii)==43);
end
for yy=1:B;
N=RandomMatriceA(x,yy,ii);
StartPost(x,N,ii)=StartProcess(x,yy,ii);
end
end
for h=2:2:A;
doneB=false;
while ~doneB,
[vals RandomMatriceA(h,:,ii)]=sort(rand(1,B),2);
doneC=false;
while ~doneC,
NewRowRandomMatriceB=randi([0 2],1,B);
%Make sure maximum consecutive holiday <=12 Weeks
idxB= bitand(RandomMatriceA(h,:,ii) >= 1,...
RandomMatriceA(h,:,ii) <= 4);
NewRowRandomMatriceB([false(size(idxB, 1), 1)...
idxB(:,1:end-1)]) = 1;
NewRowRandomMatriceB(idxB)=1;
doneC= (sum(NewRowRandomMatriceB)<12)&&...
(~any(diff([0,find(NewRowRandomMatriceB),B+1])>3));
end
RandomMatriceB(h,:,ii)=NewRowRandomMatriceB;
ProcessRandomMatriceA(h,:,ii)=...
ProcessTime(RandomMatriceA(h,:,ii))+...
RandomMatriceB(h,:,ii);
%secondVaribale:to know in which column
%The Consecutive value RandomMatrice will be end
EndProcess(h,:,ii)=cumsum(ProcessRandomMatriceA(h,:,ii),2);
%ThirdVariable:to know in which column
%The Consecutive Value will be start
StartProcess(h,:,ii)=EndProcess(h,:,ii)-...
(ProcessTime(RandomMatriceA(h,:,ii))-1);
TimeOff(h,:,ii)=(StartProcess(h,:,ii)-...
RandomMatriceB(h,:,ii)).*(RandomMatriceB(h,:,ii)~=0);
for z=1:B;
N=RandomMatriceA(h,z,ii);
StartPost(h,N,ii)=StartProcess(h,z,ii);
end
doneB =all(ismembc(StartPost(h,1:4,ii),...
sort(StartPost(h-1,1:4,ii)))) && any(TimeOff(h,:,ii)==43);
end
%arrange value in column 1 until 4
%in order that it will have same
%value
StartPost(h,1:4,ii)=StartPost(h-1,1:4,ii);
end
end
Matt Fig
Matt Fig on 6 Sep 2012
To run the above code, I have to know what you use for (A,B,C) or the general relation between them. As it is now, the code you pasted above is not running because these are missing....

Sign in to comment.

Accepted Answer

Sven
Sven on 5 Sep 2012
Edited: Sven on 5 Sep 2012
I agree with Matt - I bet there are faster ways to run your loop, and we can probably help out if you can describe what the loop is meant to do...
Nevertheless one way to keep your current code structure but speed it up a bit would be to pre-compute a buffer of randi integers between 0 and 2, rather than calling randi multiple times in the loop like this:
A=8;
B=12;
C=10;
bufferSz = 5000;
randBuffer = randi([0 2], bufferSz, B);
randUpTo = 1;
RandomMatriceB = zeros(A,B,C);
for ii=1:C;
for x=1:2:A-1;
%make first random matrice
[vals RandomMatriceA(x,:,ii)]=sort(rand(1,B),2);
done=false;
while ~done,
%make row of second random matrice
if randUpTo>bufferSz
randBuffer = randi([0 2], bufferSz, B);
randUpTo = 1;
end
NewRowRandomMatriceB = randBuffer(randUpTo,:);
randUpTo = randUpTo + 1;
%Make sure sum all element per row in RandomMatriceB <=11
done=sum(NewRowRandomMatriceB)<12;
end
RandomMatriceB(x,:,ii)=NewRowRandomMatriceB;
...
end
for h=2:2:A;
doneA=false;
while ~doneA,
[vals RandomMatriceA(h,:,ii)]=sort(rand(1,B),2);
doneB=false;
while ~doneB,
if randUpTo>bufferSz
randBuffer = randi([0 2], bufferSz, B);
randUpTo = 1;
end
NewRowRandomMatriceB = randBuffer(randUpTo,:);
randUpTo = randUpTo + 1;
doneB= sum(NewRowRandomMatriceB)<12;
end
RandomMatriceB(h,:,ii)=NewRowRandomMatriceB;
...
end
...
If you know the absolute maximum number of randi() integers you'll need, you won't even need the "check" that I put in that makes sure you don't try to access integers beyond the buffer size.
Did this speed things up for you Febri?
Oh, and do you initialize RandomMatriceB to a particular size? It doesn't look so..., so I bet that you'll get even more speedup by putting this line at the start of your code:
RandomMatriceB = zeros(A,B,C);
In fact, now that I look at your code a bit more, I think this would be the main issue.
  3 Comments
Febri
Febri on 6 Sep 2012
I think i cannot use npermutek in my old version matlab (R2009a). so what is the similar logic with it Mr.?
Matt Fig
Matt Fig on 6 Sep 2012
Did you click the link to download the file?? I gave the link in my previous comment. The function works in r2007b so it should work in r2009a!

Sign in to comment.

More Answers (0)

Tags

Community Treasure Hunt

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

Start Hunting!