Why is this script so slow and how can i make it faster?
3 次查看(过去 30 天)
显示 更早的评论
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
0 个评论
回答(7 个)
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 个评论
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
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)
0 个评论
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)';
0 个评论
Bjorn Gustavsson
2014-1-29
Wouldn't this solve the (homework-) problem:
[x,y,z] = find(M<0.5);
HTH.
2 个评论
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
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{:}
0 个评论
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';
0 个评论
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);
0 个评论
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 Matrix Indexing 的更多信息
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!