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.

+3


source to share


2 answers


How you want to make a basic histogram with given edges, you can use Matlabs built-in histc function:



values = [ 1 2 3 4 6 11 12 16 31 34 45 ];
edges = 0:10:60;
histc(values, edges)

ans =

 5     3     0     2     1     0     0

      

+5


source


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)]; 

      

+2


source







All Articles