在尝试将算法从C#移植到Matlab时,我发现Matlab在运行循环时效率很低。因此我想对算法进行矢量化。
我有以下输入:
lowrange:
[ 00 10 20 30 40 50 ... ]
高变速:
[ 10 20 30 40 50 60 ... ]
这些数组的长度相等。
我现在有第三个数组Values
(可以是任意长度),对于这个数组,我想计算Values
和lowerange(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'向量'方式思考,所以我无法想出任何其他内容,更不用说从内存中了解所有适用的指令。
答案 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)];