如何在Matlab中对此代码进行矢量化?

时间:2013-03-08 19:35:36

标签: matlab vectorization

如何在不使用for循环的情况下实现此Matlab代码?

b=10:10:50
a=50*rand(1,50);

for ii=2:numel(b)
    ind{ii}=find(a<b(ii) & a>b(ii-1));
end

2 个答案:

答案 0 :(得分:3)

看起来你正在做直方图并跟踪哪个元素最终在哪个bin中。这意味着你可以通过以下几行“几乎”得到你想要的东西:

a = 50 * rand(1, 50);
b = 10:10:50;
[h c] = histc(a, b);

现在c包含a中每个元素的“bin”的索引。例如,如果

a = [15 22 9 7 25];

然后

c = [1 2 0 0 2];

不确定将这些收集到单元格数组中的价值 - 在我看来,ind中的值可以用c来完成。

我怀疑用“向量”操作创建一个单元格数组(可能有不同长度)可能很难(这意味着长度相同的东西)...有兴趣看到有人产生反例!

编辑:我发现了我自己的反例...以下行生成了一个单元数组ind就像你的代码一样(arrayfun命令确实有一个隐含的for循环但是被认为是“矢量化”)。

ind = arrayfun(@(x)find(x==c),1:numel(b)-1, 'uniformoutput', false);

注意,完成此操作后,单元格数组ind的值将从单元格ind{1}开始,而原始代码则从单元格ind{2}索引。如果这是一个问题,我相信你可以解决它......

另请注意,您的代码会在050之间生成随机数,但您的“有效容器”仅在1050之间(因为您的方式)写了你的算法)。因此,收集的指数总和将略低于50(平均为40)。

答案 1 :(得分:2)

下面的脚本会做同样的事情。矩阵newInd将包含分配给ind的相同值,并由循环打印出来。

b=10:10:50;
a=sort(randi(50,1,10));

% create shifted version of vector b to account
% for comparison between i and i-1
newB1 = b(1:end-1);
newB2 = b(2:end);

% create tiled version of a and b
newB1 = repmat(newB1',1,numel(a));
newB2 = repmat(newB2',1,numel(a));
newA = repmat(a,numel(b)-1,1);

%find linear indices that meet required conditions
LinearInd = find(newA<newB2 & newA>newB1);
%convert linear indices to subscripts
[i,newInd] = ind2sub(size(newA),LinearInd);
% display indices that correspond to ind
newInd