Why is this script so slow and how can i make it faster?

조회 수: 1 (최근 30일)
Tobias
Tobias 2014년 1월 29일
답변: Roger Stafford 2014년 1월 29일
Hello,
I am a student at the TU Delft in holland and i have a problem with this matlab script. It takes for ever to run the whole script and the problem is that i have to do it a couple of times. Does someone knows how to make this script faster?
M=rand(100,110,130);
p=1
for i=1:100;
for j=1:110;
for k=1:130;
if M(i,j,k)<0,5;
x(p)=i;
y(p)=j;
z(p)=k;
p=p+1
else
p=p
end
end
end
end
Thanks for the help

답변 (7개)

Jos (10584)
Jos (10584) 2014년 1월 29일
First, when you use loops, try to pre-allocate the outcome
N = 1000 ;
p = zeros(N,1) ; % pre-allocation
for k=1:N
p(k) =
end
Second, matlab can handle matrices at once. You can take advantage of that, rather than going through each element one by one. In your case:
M=rand(5,3,2); % a smaller example
tf = M < 0.5
idx = find(tf) % linear index
[x,y,z] = ind2sub(size(M), idx)
% which can be one-lined into [x,y,z] = ind2sub(size(M), find(tf<0.5))
Now these will give the same result:
R1 = M(tf) ;
R2 = M(idx) ;
R3 = zeros(size(x)) ; % see, pre-allocation again
for k=1:numel(x),
R3(k) = M(x(k),y(k),z(k)) ;
end
disp(R1)
isequal(R1,R2,R3)
  댓글 수: 2
Tobias
Tobias 2014년 1월 29일
First of all thank you very much, This is indeed much faster. The only problem is that the x,y,z vectors are not lineair. They numbers in this vector have to go from lowest to highest. How can i fix this problem?
Jos (10584)
Jos (10584) 2014년 1월 29일
I do not completely get this point, I'm afraid.
Note that x,y, and z are three(!) vectors. Moreover, they are coupled, meaning that an element x(k) belongs to y(k) and z(k). You can sort one of them of course, but then you have to re-arrange the others as well.

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


Niklas Nylén
Niklas Nylén 2014년 1월 29일
편집: Niklas Nylén 2014년 1월 29일
In addition to Jos' answer, the most time consuming part of your code seems to be printing out p every time it is increased by one. By putting a semicolon after p=p+1 and completely removing the else statement since it does nothing, the execution time is reduced by approximately 95 % (from 20 to 0.5 s on my computer)

Azzi Abdelmalek
Azzi Abdelmalek 2014년 1월 29일
편집: Azzi Abdelmalek 2014년 1월 29일
idx=find(M<0.5);
[ii,jj,kk]=ind2sub(size(M),idx);
[a,idx1]=sortrows([ii jj kk],[1 2 3]);
x=a(:,1)';
y=a(:,2)';
z=a(:,3)';

Bjorn Gustavsson
Bjorn Gustavsson 2014년 1월 29일
Wouldn't this solve the (homework-) problem:
[x,y,z] = find(M<0.5);
HTH.
  댓글 수: 2
Azzi Abdelmalek
Azzi Abdelmalek 2014년 1월 29일
This doesn't solve his question. You can compare your result and his.
Bjorn Gustavsson
Bjorn Gustavsson 2014년 1월 29일
True, I didn't even bother reading the help on find, it's in there. But that halfbaked higher-dimension functionality reminds me of 4.2. Now I have to think a bit about shading the builtin find with something along your line.

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


Andrei Bobrov
Andrei Bobrov 2014년 1월 29일
[i1,i2]=find(M<.5);
c = num2cell(sortrows([i1,rem(i2-1,4)+1,ceil(i2/4)]),1);
[x,y,z] = c{:}

Azzi Abdelmalek
Azzi Abdelmalek 2014년 1월 29일
편집: Azzi Abdelmalek 2014년 1월 29일
Without sortrows. This is much faster
M1=permute(M,[3 2 1]);
idx=find(M1<0.5);
[ii,jj,kk]=ind2sub(size(M1),idx);
x=kk';
y=jj';
z=ii';

Roger Stafford
Roger Stafford 2014년 1월 29일
M=rand(100,110,130);
[z,y,x] = ndgrid(1:130,1:110,1:100);
t = M<.5;
z = z(t);
y = y(t);
x = x(t);

카테고리

Help CenterFile Exchange에서 Matrix Indexing에 대해 자세히 알아보기

Community Treasure Hunt

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

Start Hunting!

Translated by