Loop step size issue
이전 댓글 표시
Hoping there is a very simple solution to this but being new to matlab can't quite see where I'm going wrong:
for i = 10:5:100;
sums = conv(S, ones(1, i), 'valid');
Output(i) = nnz(sums>2 & sums<3);
end
where S is a column vector of values The code searches for instances where the sum of a block of data contained in window (i) is either >2 or <3 and counts them.
I was expecting the Output to return 19 values based on the step size of 5. Instead I get 100 values. I only want to return the counts for window sizes equal to i. Any thoughts would be much appreciated.
댓글 수: 1
Image Analyst
2013년 1월 22일
That's because conv() moves the window over 1 element at a time. If you want to move in "jumps" of the window size, you need to use blockproc().
답변 (3개)
Walter Roberson
2013년 1월 22일
편집: Walter Roberson
2013년 1월 22일
ivals = 10:5:100;
ni = length(ivals);
for K = 1 : ni
i = ivals(K);
sums = conv(S, ones(1, i), 'valid');
Output(K) = nnz(sums>2 & sums<3);
end
댓글 수: 2
Swisslog
2013년 1월 22일
I don't think there's a way to vectorize fully, but if the S(i) are all non-negative, you should be sure to bail out of the loop once any(sums<3)==0. Enlarging the window from that point on will not change the result.
ivals = 10:5:100;
ni = length(ivals);
Output=zeros(ni,1);
flag=false;
for K = 1 : ni
i = ivals(K);
sums = conv(S, ones(1, i), 'valid');
Usums=sums<3;
if ~any(Usums)
break
end
Lsums=sums>2;
Output(K) = sum(Usums&Lsums);
end
Walter's solution is more efficient. If you want to do it quick
Output = nan(1, 100);
% your code here
Output = Output(Output(~isnan(Output));
Thorsten
2013년 1월 22일
This runs about 4 times faster on my machine:
cS = cumsum(S);
for K = 1 : ni
sums = cS(ivals(K):end) - [0 cS(1:end-ivals(K))];
Output(K) = nnz(sums>2 & sums<3);
end
댓글 수: 2
Not on mine.
S=rand(1,1e6);
ivals = 10:5:100;
ni = length(ivals);
Output=zeros(ni,1);
tic
for K = 1 : ni
i = ivals(K);
sums = conv(S, ones(1, i), 'valid');
Output(K) = nnz(sums>2 & sums<3);
end
toc
%Elapsed time is 0.313358 seconds.
tic;
cS = cumsum(S);
for K = 1 : ni
sums = cS(ivals(K):end) - [0 cS(1:end-ivals(K))];
Output(K) = sum(sums>2 & sums<3);
end
toc;
%Elapsed time is 0.437812 seconds.
Matt J
2013년 1월 22일
I really do think the CUMSUM approach should be the better one, though. A MEX is probably needed to avoid repeated memory allocation operations in
sums = cS(ivals(K):end) - [0 cS(1:end-ivals(K))];
카테고리
도움말 센터 및 File Exchange에서 Timing and presenting 2D and 3D stimuli에 대해 자세히 알아보기
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!