如何在matlab中矢量化xor操作

时间:2012-02-01 06:55:29

标签: matlab vectorization xor

我在Matlab的Profiler中运行了以下代码,对我来说这是非常必要的,因为我认为这是一个不必要的for循环。

我有2个矩阵G和source_data。 G中的每一列都将确定我需要从source_data中获取的行,并将它们放在一起。

我正在使用以下代码

创建G和source_data
for i=1:10
 source_data(i,:)=rand(1,20)<.8;
end 

for i=1:15
 G(:,i)=rand(10,1)<.9;
end

我正在使用下面的for循环执行xor操作:

z=1;
while(i<=15) 
for j=1:10
    if(G(j,i)==1)
       intersum(z+1,:)=xor(intersum(z,:), source_data(j,:));
        z=z+1;
    end
end
C(i,:)=intersum(z,:);
i=i+1;
end

有没有办法对这段代码进行矢量化?时间滞后对于小矩阵是可接受的,但对于大矩阵,这个代码非常有效。

谢谢,

Bhavya

1 个答案:

答案 0 :(得分:1)

假设:

  • 我从1开始
  • intersum从零开始

这是您的代码的矢量化形式,它产生与原始代码完全相同的结果:

function C = version_a()
  source_data = rand(10,20)<.8;
  G = rand(10,15)<.9;

  intersum = zeros(1, size(source_data,2));
  z = 1;
  i = 1;
  while i <= 15
    for j=1:10
        if(G(j,i)==1)
           intersum(z+1,:)=xor(intersum(z,:), source_data(j,:));
            z=z+1;
        end
    end

    C(i,:)=intersum(z,:);
    i=i+1;
  end
  ret = C;
end

function C = version_b()
  source_data = rand(10,20)<.8; % Can initialize in a single call
  G = rand(10,15)<.9;           % Same here
  C = zeros(size(G,2),size(source_data,2));

  C(1,:) = mod(sum(source_data(G(:,1),:)),2);
  for i = 2:15
    C(i,:) = mod(C(i-1,:) + sum(source_data(G(:,i),:)),2);
  end
end

为了检查两个版本的时间,我使用了这个测试功能:

function ret = xor_test()
  ret = 0;

  seed = 123456789;
  laps = 10000;

  tic
  for i = 1:laps
    RandStream.getDefaultStream.reset(seed);
    a = version_a();
  end
  toc

  tic
  for i = 1:laps
    RandStream.getDefaultStream.reset(seed);
    b = version_b();
  end
  toc

  ret = ret + sum(sum(b ~= a));
end

我的机器上有以下时间:

Elapsed time is 13.537738 seconds.
Elapsed time is 2.302747 seconds.
ans =
     0

现在为什么我这样改变了......

xor数组上的logical操作几乎检查总和的奇偶校验(将true值视为1)。此外,intersum被用作累加器,所以有人的值最终会在C中结束,所以我们完全跳过它。取G(j,i)为1的行可以通过logical indexing完成。

最后,即使您不喜欢此建议版本,我也建议您预先分配您的Cintersum向量(如果您还没有这样做)。这对我来说有很大的不同。