在某个移动范围内的数字的矢量化版本

时间:2015-12-28 08:44:22

标签: matlab vectorization

我有类似于以下内容的东西,它计算某个范围内的元素数量:

N = 10000;
%// Setup arrays, only included here to be a working example (slow, does not matter)
x = 1:N;
y = [];
for i=1:N/10 y=[y,1:10]; end
%// Find number of x elements in a certain range for each n
window=500;
step=100;
for n=1:10
    temp = x(y==n); % filter x for each n in y
    %// Instead of the below for loop ...
    %//j=1;
    %//for i=window:step:N-window
    %//  num(j,n) = numel(find(temp>i-window & temp<i));
    %//  j=j+1;
    %//end
    %// this vectorized version ...
    num(:,n) = sum(bsxfun(@gt,temp,(0:step:N-window)')' ...
                   & bsxfun(@lt,temp,(window:step:N)')');
end

我是第一个,通过x中的索引过滤数据y。然后对于这些y中的每一个,计算作为移动窗口的范围中的元素数量。

我不确定如何对其进行矢量化我无法通过向量来查找例如find(temp>[1:10] & temp<[5:15])

1 个答案:

答案 0 :(得分:1)

第1步: temp = x(y==n)

您正在执行logical indexingx "x(y==n)"选择元素,这些元素存储为temp。然后,您正在使用temp并对其进行比较并对其进行计数。因此,temp将具有可变数量的元素,这不利于向量化。因此,我们必须尝试使用​​equalities n为所有y==n保留bsxfun(eq的2D掩码。

第2步: temp>i-window & temp<i

接下来,我们有"(temp>i-window & temp<i)",我们可以使用bsxfunbsxfun(gt再次使用bsxfun(lt来模拟它们。

最后,我们尝试匹配 equality maskcomparison mask,即步骤12并执行计数,其中{ {1}}会给我们一个很好的帮助。

因此,通用输入matrix-multiplicationx的实现将是 -

y

结束评论:执行%// Array version of iterator n : "for n=1:10" n_arr = 1:10; %// Array version of iterator i : "for i=window:step:N-window" I = window:step:N-window; %// Simulate "y==n" (equalities mask) in a vectorized manner step_mask = bsxfun(@eq,y(:),n_arr); %// Simulate "(temp>i-window & temp<i)" (comparisons mask) in a vectorized manner comp_mask = bsxfun(@gt,x(:),I-window) & bsxfun(@lt,x(:),I); %// Peform selection of elements from x in "x(y==n)" and the counting in %// one go with powerful matrix-multiplication num_out = double(comp_mask).'*double(step_mask); 时,请务必强烈考虑vectorization