exchange cells with concerning time
1 次查看(过去 30 天)
显示 更早的评论
Hi I have a code. In this code p and D are matrices with 100 rows 100 columns and 4 in third dimension. D is (0-1) matrix. in my code cells one by one are selected and changed. if the value of function (here is not important what it is) is decreased, change is accepted. here I want to set the value of pp equal 0 for previous i's and j's and also previous j1's and j2's. because I didn't want to select cellS that be selected in previous selections. my code is very time consuming and I want to decrease it. My code:
for i=1:O1
for j=1:O2
s=find(D(i,j,:)==1);
pp=p(:,:,s).*(1-D(:,:,s));
w=sum(sum(pp));
p1=bsxfun(@rdivide,pp,w);
r=rand;
jj=find(r<=cumsum(p1(:)),1,'first');
[j1 j2]=ind2sub(size(p1),jj);
g=find(D(j1,j2,:)==1);
x1=D;
D(j1,j2,g)=0;
D(i,j,g)=1;
D(i,j,s)=0;
D(j1,j2,s)=1;
x2=D;
cost1=costfunction(full(x1));
cost2=costfunction(full(x2));
if cost1<cost2
D=ndSparse(x1);
elseif cost1>cost2
D=ndSparse(x2);
end
end
D;
end
1 个评论
Guillaume
2015-11-3
Can you explain the meaning of the four values in the third dimension? It looks like it's used to keep track of the values that have been changed but I'm not sure.
It would certainly help in telling you how to avoid processing the same thing twice.
It would be a good idea to use meaningful names for your variable. It immediately makes it clearer what the code does.
回答(2 个)
Jan
2015-11-3
100x100 ist not large. Converting this array from sparse to full repeatedly is expensive. Try to stay at full matrices.
Omit the "==1" ind find(D(i,j,:)==1), if D contains 0 or 1 only.
But most of all: Use the profiler to identify the bottleneck. If 95% of the time is spent in costfunction, improving the shown code cannot increase the speed by more then 5%.
Guillaume
2015-11-3
编辑:Guillaume
2015-11-3
As Jan says, a 100x100x4 matrix is not large at all, it's only 320 kB as double. In your case, you don't even need to have it as double. Since it only contains 0 or 1, you could use a logical matrix, which would only use 40 kB:
D = logical(D);
Another thing that is not needed is most of the find. Again you can use logical indexing instead. The line
s=find(D(i,j,:)==1);
can be replaced by
s = D(i,j,:) == 1; %s is a logical array
and will give the exact same result. The latter is faster. Even faster, since D is only 0 or 1 is:
s = logical(D(i,j,:));
and if D were a logical matrix, then:
s = D(i,j,:);
pp can also be calculated slightly faster, using logical operations instead of multiplication:
pp = p(:,:,s) & ~D(:,:,s); %regardless whether D is logical or not
Similarly, for g you do not need the find
g = logical(D(j1, j2, :)); %no need for logical if D is already logical
None of the above is going to vastly speed your code. You need to clarify what step you're hoping to shortcut.
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!