How To Vectorize a For loop
조회 수: 5 (최근 30일)
이전 댓글 표시
I Have the following piece of code I want to vectorize.
function [Averages, Counts]=GetLocalAverage(X,numbins)
%%This function computes the local average of X,
%%i.e. if X=[1:1:10]'; numbins=5; then Averages=[3; 8];
Min=min(X)*(1-1e-6); %A little smaller than Minmimum value of X
Max=max(X)*(1+1e-6); %A little bigger than Maximum value of X
Inc=(Max-Min)/(numbins); %Width of bins
Edges=[Min:Inc:Max]; %The Edges of the Bins, Just for Troubleshooting
Index=floor((X(:,1)-Min)/Inc)+1; %Figure out which bin each element of X goes into
%Preallocate
Counts=zeros(numbins,1); %Running Tally of Number of elements in each bin
BinSum=zeros(numbins,size(X,2)); %Running Tally of sum of elements in each bin
for n=1:size(X,1)
Counts(Index(n))=Counts(Index(n))+1;
BinSum(Index(n),:)=BinSum(Index(n))+X(n,:);
end
Averages=BinSum./Counts;
end
The problem is that the X vector I have is enormous (10^9 elements), so the for loop is really slow. What I want is something like:
Counts(Index)=Counts(Index)+1;
BinSum(Index)=BinSum(Index)+X(Index);
But this doesn't work because there can be multiple entries in X with that go to the same value in Index, and then this implementation leads to Counts only having values of 0 or 1.
댓글 수: 0
채택된 답변
Bruno Luong
2018년 10월 31일
편집: Bruno Luong
2018년 10월 31일
Min=min(X)*(1-1e-6); %A little smaller than Minmimum value of X
Max=max(X)*(1+1e-6); %A little bigger than Maximum value of X
Inc=(Max-Min)/(numbins); %Width of bins
Edges=[Min:Inc:Max]; %The Edges of the Bins, Just for Troubleshooting
Index=floor((X(:,1)-Min)/Inc)+1; %Figure out which bin each element of X goes into
% This replace the for-loop
[I,C] = ndgrid(Index,1:size(X,2));
Averages = accumarray([I(:),C(:)],X(:))./accumarray(Index,1);
댓글 수: 0
추가 답변 (0개)
참고 항목
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!