如何在Matlab中对for循环应用矢量化?

时间:2014-02-12 05:44:12

标签: performance matlab vectorization

有谁能告诉我如何对以下内容进行矢量化:

a = randi([6 10],5);; 
c = unique(a);
d = [1:5]; % some comparison Values length should be equal to length(c)

Mat = zeros(size(a));
for i = 1:length(c)
  Mat(a==c(i)) = d(i);
end

结果:

     3     1     5     3     3
     3     5     4     2     3
     5     1     3     3     3
     2     2     2     3     3
     3     5     5     3     4

这里将6替换为1,7,将其替换为2,等等。

这当然只是一个例子;我的真实Mat更像是2000×2000。

2 个答案:

答案 0 :(得分:2)

注意:首先阅读我的其他答案

要回答最新编辑中的问题:

[~, inds] = histc(a(:), c);
Mat = reshape(d(inds), size(a));

对600×100数据进行类似测试:

a = randi(500,[600 100]); 
c = unique(a);
d = randi(20, size(c));

tic
Mat = zeros(size(a));
for ii = 1:length(c)
  Mat(a==c(ii)) = d(ii);
end
toc


tic
[~, inds] = histc(a(:), c);
Mat2 = reshape(d(inds), size(a));
toc

isequal(Mat,Mat2)

给出以下内容:

Elapsed time is 0.166673 seconds.  %// your method
Elapsed time is 0.006669 seconds.  %// my method
ans =                              %// yes they're equal
    1

速度再次相差约250倍。

答案 1 :(得分:0)

注意:这是对原始问题的回答;第二次编辑完全改变了问题,因此下面的答案不再适用。编辑大大简化了问题,因此这个答案仍然是一个很好的起点。

基本上,a的所有唯一值都将替换为b中的相应值。这意味着要分析的矩阵是b,唯一的困难在于条件b < d必须适用于b对应的索引。

要执行此操作,您只需将a定义在c定义的组中的所有元素,然后确定b中每个元素所属的组。该信息可用于在d中找到正确的索引。

换句话说:

NewMat = b;
[~, inds] = histc(a(:), c);
NewMat(NewMat(:) > d(inds)) = 0;

一个小测试,用于比较性能并验证两种方法的相等性:

a = randi(1000, 74,100);
b = randi(1000, 74,100);

c = unique(a);
d = randi(1000, size(c)); % some comparison Values

%// Your method
tic
NewMat = zeros(size(a));
for i = 1:length(c)
  Mat = zeros(size(a));
  Mat(a==c(i)) = b(a==c(i));
  Mat(Mat > d(i)) =0;
  NewMat = NewMat + Mat;
end
NewMat1 = NewMat;
toc

%// My method
tic
[~,inds] = histc(a(:), c);
b(b(:) > d(inds)) = 0;
NewMat2 = b;
toc

%// validate solution
isequal(NewMat1, NewMat2)

结果:

%// 74 × 100
Elapsed time is 0.151808 seconds.   %// your method 
Elapsed time is 0.001007 seconds.   %// my method
ans =                               %// yes, they're equal
     1

因此性能提升约150倍。使用不是74×100而是740×1000给出

%// 740 × 1000
Elapsed time is 27.587543 seconds.  %// your method
Elapsed time is 0.111467 seconds.   %// my method
ans =                               %// yes, they're equal
     1

或〜250差异的因素。显然,您的方法也比histc方法更差。