choose n elements from array and increase sequentially
16 views (last 30 days)
Show older comments
I have a 1x100 matrix with its values varying from 0-50. I have to take 1st to 10th elements,check how many samples have values between 20-30, display the answer. then I have to take elements from 2nd to 11th (next 10 samples),check how any samples have values between 20-30. then take samples from 3 to 12 and continue so on.
How can I implement this?
2 Comments
Rik
on 26 Mar 2018
What have you tried so far? It seems like a for-loop would work (even if that probably isn't the fastest solution).
Answers (2)
John D'Errico
on 26 Mar 2018
Edited: John D'Errico
on 26 Mar 2018
Problems like this are always solvable in many ways. Easy to write is not always efficient. And there are often tradeoffs due to memory considerations. A vectorized solution might require a huge amount of memory if the vector is long.
Thus, suppose you have N elements in the vector, and a sliding window length of size W. So consider a vector V, of length 25:
V = round(rand(1,25)*50)
V =
4 17 35 45 18 12 37 3 49 42 25 16 44 9 9 0 26 41 21 12 35 17 5 13 29
Assume a sliding window length of 10.
N = length(V);
W = 10;
Vlims = [20,30];
Solution 1: A loop. Easy to write. I'm not gonna bother, because there are better ways to invest my time.
Solution 2: Replicate your vector into a matrix, of size W by N-W+1. So column 1 will be elements 1:W. Column 2 will be elements 2:(W+1), etc. Then you just count how many elements fall in the interval in each row. Easy to write this code, although you would need to build that matrix.
M = V((0:W-1)' + (1:N-W+1));
slidingcount = sum((M >= Vlims(1)) & (M<= Vlims(2)),1)
slidingcount =
0 1 1 1 1 1 1 2 2 3 3 2 2 2 2 3
The disadvantage of solution 2 is the amount of memory required if N or W are too large.
Solution 3: Like solution 2, but replicate only a boolean vector, which indicates whether a given element is in the interval of interest.
B = (V >= Vlims(1)) & (V<= Vlims(2));
slidingcount = sum(B((0:W-1)' + (1:N-W+1)),1)
slidingcount =
0 1 1 1 1 1 1 2 2 3 3 2 2 2 2 3
Thus, solution 3 works the same as solution 2, but uses considerably less memory, since the vector elements themselves were not replicated, but only a vector of booleans, so a logical vector.
Solution 4: Use conv to perform the summation implicitly. No array ever gets generated.
B = (V >= Vlims(1)) & (V<= Vlims(2));
slidingcount = conv(double(B),ones(1,W),'valid')
slidingcount =
0 1 1 1 1 1 1 2 2 3 3 2 2 2 2 3
So a good trick to remember is anytime you have a function that needs a sum over a sliding window, conv may be there to solve your problem.
0 Comments
David Fletcher
on 26 Mar 2018
Edited: David Fletcher
on 26 Mar 2018
dummyMatrix=randi(50,1,100)
result=zeros(1,91)
for iter=1:91
%extract 10 element window
extract=dummyMatrix(iter:9+iter)
%count elements that meet the condition
results(iter)=sum((extract>=20)&(extract<=30))
end
I assume you stop gathering the counts at element 91 (since the window will then be element 91 through to element 100)
0 Comments
See Also
Categories
Find more on Data Distribution Plots in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!