Vectorized range check in Matlab
While trying to port the algorithm from C # to Matlab, I found that Matlab is inefficient at startup for loops. As such, I want to vectorize the algorithm.
I have the following inputs:
lowrange:
[ 00 10 20 30 40 50 ... ]
High frequency:
[ 10 20 30 40 50 60 ... ]
These arrays are equal in length.
Now I have a third array Values
(which can be of any length), and for this array, I want to count the occurrences of the elements Values
between lowerange(i)
and highrange(i)
(you can see that I am coming from the for loop).
The output signal must be an array of lowrange / highrange length.
So with the above arrays and inputs LineData
:
[ 1 2 3 4 6 11 12 16 31 34 45 ]
I expect to receive:
[ 05 03 00 02 01 00 ... ]
I tried (for me) the obvious thing:
LineData(LineData < PixelEnd & LineData > PixelStart)
But it doesn't work because it just checks LineData on item by item. It doesn't try to apply all-value comparison in LineData
.
Unfortunately, I can't think of anything else, since I'm not used to thinking about Matlab's "vector" method yet, let alone having all the useful instructions stored in memory.
source to share
For ranges with equal intervals and starting from 0
, here's a bsxfun
count-based approach -
LineData = [ 1 2 3 4 6 11 12 16 31 34 45 ] %// Input
interval = 10; %// interval width
num_itervals = 6; %// number of intervals
%// Get matches for each interval and sum them within each interval for the counts
out = sum(bsxfun(@eq,ceil(LineData(:)/interval),1:num_itervals))
Output -
LineData = 1 2 3 4 6 11 12 16 31 34 45 out = 5 3 0 2 1 0
Assuming that the last interval will contain the maximum of the input, you can try out the diff
+ indexing
- method as well
LineData = [ 1 2 3 4 6 11 12 16 31 34 45 ] %// Input
interval = 10; %// interval width
labels = ceil(LineData(:)/interval); %// set labels to each input entry
df_labels = diff(labels)~=0; %// mark the change of labels
df_labels_pos = find([df_labels; 1]); %// get the positions of label change
intv_pos= labels([true;df_labels]);%// position of each interval with nonzero counts
%// get counts from interval between label position change and put at right places
out(intv_pos) = [ df_labels_pos(1) ; diff(df_labels_pos)];
source to share