Предполагая, что:
- 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
Теперь о том, почему я изменил его таким образом ...
Операция xor
над массивом из logical
s в значительной степени проверяет четность суммы (обрабатывает true
значениякак 1).Furhtermore, intersum
используется в качестве аккумулятора, поэтому есть чьи значения, которые в конечном итоге заканчиваются на C
, поэтому мы пропускаем его полностью.Взятие строк, для которых G(j,i)
равно 1, может быть выполнено с помощью логического индексирования .
И, наконец, даже если вам не нравится эта предложенная версия, я рекомендую предварительно выделить вашC
и intersum
векторов (если вы этого еще не сделали).Это имело большое значение для меня в прошлом.