在Matlab中进行矢量化范围检查

时间:2014-09-26 08:28:16

标签: arrays algorithm matlab vector vectorization

在尝试将算法从C#移植到Matlab时,我发现Matlab在运行循环时效率很低。因此我想对算法进行矢量化。

我有以下输入:

lowrange:

[ 00 10 20 30 40 50 ... ]

高变速:

[ 10 20 30 40 50 60 ... ]

这些数组的长度相等。

我现在有第三个数组Values(可以是任意长度),对于这个数组,我想计算Valueslowerange(i)之间highrange(i)个元素的出现次数(你可以看到我来自for循环)。

输出应该是长度为低范围/高范围的数组。

所以使用上面的数组和输入LineData

[ 1 2 3 4 6 11 12 16 31 34 45 ]

我希望得到:

[ 05 03 00 02 01 00 ...  ]

我试过(对我而言)显而易见的事情:

LineData(LineData < PixelEnd & LineData > PixelStart) 

但这不起作用,因为它只是按元素方式检查元素上的LineData。它不会尝试对LineData中的所有值应用比较。

不幸的是,由于我还没有习惯以Matlab'向量'方式思考,所以我无法想出任何其他内容,更不用说从内存中了解所有适用的指令。

2 个答案:

答案 0 :(得分:5)

当您想要使用给定边缘执行基本直方图时,您可以使用Matlabs内置函数histc:

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

答案 1 :(得分:2)

对于具有相同间隔且从0开始的范围,这是基于bsxfun的计数方法 -

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

输出 -

LineData =
     1     2     3     4     6    11    12    16    31    34    45
out =
     5     3     0     2     1     0

假设最后一个时间间隔是输入数据最大的时间间隔,您也可以尝试基于diff + indexing的方法 -

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