【问题标题】:how to vectorise an xor operation in matlab如何在matlab中对异或运算进行矢量化
【发布时间】:2012-02-01 18:00:32
【问题描述】:

我已经在 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 循环执行异或操作:

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

有没有办法对这段代码进行矢量化?对于小矩阵,时间延迟是可以接受的,但对于大矩阵,此代码效率很高。

谢谢,

佛系

【问题讨论】:

  • 最后一个循环中的iK 是什么? xor 本身已经矢量化了,也许对你有帮助:mathworks.de/help/techdoc/ref/xor.html 否则你可以看看arrayfun
  • @Alexandrew 感谢您指出这一点编辑上述问题

标签: matlab vectorization xor


【解决方案1】:

假设:

  • i 从 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

现在我为什么要这样改变它......

logicals 数组的xor 操作几乎是检查总和的奇偶性(将true 值视为1)。此外,intersum 被用作累加器,所以谁的值最终以C 结束,所以我们完全跳过它。取G(j,i) 为1 的行可以由logical indexing 完成。

最后,即使您不喜欢这个提议的版本,我建议您预先分配您的 Cintersum 向量(以防您还没有这样做)。在过去,这对我产生了很大的影响。

【讨论】:

  • 非常感谢您提供此代码。它确实比早期版本运行得更快。但我只是逐行检查两个函数生成的矩阵 C,使用 isequal 方法,发现它们有很大不同。
  • 只是为了确定...您使用的是相同的Gsource_data 吗?即使您重新设定 RNG 的种子,但按照以前的方式生成数字,您也会得到不同的结果。这就是为什么我在version_a 中也更改了生成Gsource_data
  • 我正在使用您在上面提供的代码,并尝试将矢量化 xor 操作的结果与我在上面发布的扩展 for 循环中的 xor 操作进行比较。当我比较两种情况下的编码数据矩阵时,我得到了不同的结果。
  • 我不确定这是否与随机数生成器有关。因为我使用的是 Matlab 7.6,所以我有一个统一的伪随机数生成器,我使用 rand('twister',seed) 进行初始化,而不是使用上面代码中提供的语句。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-07-08
  • 2015-04-07
  • 2020-11-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多