2014-09-26 45 views
3

在试图将算法从C#移植到Matlab时,我发现Matlab在运行for循环时效率低下。因此,我想要矢量化算法。在Matlab中向量化范围检查

我有下列输入:

lowrange:

[ 00 10 20 30 40 50 ... ] 

高变速:

[ 10 20 30 40 50 60 ... ] 

这些阵列在长度上相等。

我现在有第三阵列Values(可以是任何长度),该阵列我想算lowerange(i)highrange(i)之间Values元素的出现(你可以看到我从未来的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的“矢量”方式来思考,所以我不能想出其他的东西,更不用说从存储器中知道所有适用的指令。

+1

如果从'Values'任何元素落在什么像'10'或'20'这样的边界?另外,'lowrange'和'highrange'元素之间的间隔是相同的,在给定的数据中是'10'。 – Divakar 2014-09-26 08:31:26

+0

@Divakar好点......我的数据是通过物理过程生成的,因此可能发生某些东西完全落在边界上。但是,我认为其中一个答案中提出的命中可能会有这样一个事件的规定(但事实上,我需要检查它们是什么)。另一方面,是的,间隔总是不变的。 – Kris 2014-09-26 08:53:31

回答

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 
+0

我认为它会够快!智能移动以查看'histc'将适合在这里。 +1 – Divakar 2014-09-26 09:00:35

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

我想知道,在运行大量迭代时,这是否会比histc更快/更慢...... – Kris 2014-09-26 08:54:18

+0

@Kris LineData有多大?它的范围是多少(最小和最大)?你会在循环内运行这个计数问题吗? 'histc'被认为是非常快,如果你只是要计数,但你可以测试它,对吧? – Divakar 2014-09-26 09:01:43

+1

我的经验是''histc''既快速又可读性强。如果你比较速度,请包括一个''准确的''版本(我不希望在1d直方图的情况下获胜):''箱= floor(interp1(0:10:60,1:7 ,''''''后面跟着''out = accumarray(bins',ones(length(LineData),1));'' – Nras 2014-09-26 09:05:21