Assuming that:
- i starts at 1
- intersum starts at zeros
Here's a vectorized form of you code that produces the exact same result as your original:
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
To check the timing of both versions I used this test function:
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
And I got the following timings on my machine:
Elapsed time is 13.537738 seconds.
Elapsed time is 2.302747 seconds.
ans =
0
Now to why I changed it that way...
A xor operation over an array of logicals is pretty much checking the parity of the sum (treating true values as 1). Furhtermore, intersum is being used as an accumulator, so there's who's values eventually ends up in C so we skip it altogether. Taking the rows for which G(j,i) is 1 can be done by logical indexing.
And finally, even if you don't like this proposed version, I'd recommend preallocating your your C and intersum vectors (in case you're not doing so already). That has made a lot of difference for me in the past.
iand what isKin the last loop?xoritself is already vectorized, perhaps it's helpful for you: mathworks.de/help/techdoc/ref/xor.html Otherwise you could have a look atarrayfun- tim