Help in optimizing a for loop in matlab
I have a 1 by N double array consisting of 1 and 0. I would like to map all the 1 to symbol '开发者_开发技巧-3' and '3' and all the 0 to symbol '-1' and '1' equally. Below is my code. As my array is approx 1 by 8 million, it is taking a very long time. How to speed things up?
[row,ll] = size(Data);
sym_zero = -1;
sym_one = -3;
for loop = 1 : row
if Data(loop,1) == 0
Data2(loop,1) = sym_zero;
if sym_zero == -1
sym_zero = 1;
else
sym_zero = -1;
end
else
Data2(loop,1) = sym_one;
if sym_one == -3
sym_zero = 3;
else
sym_zero = -3;
end
end
end
Here's a very important MATLAB optimization tip.
Preallocate!
Your code is much faster with a simple preallocation. Just add
Data2 = zeros(size(Data));
for loop = 1: row
...
before your for
loop.
On my computer your code with preallocation terminated in 0.322s
, and your original code is still running. I removed my original solution since yours is pretty fast with this optimization :).
Also since we're talking about MATLAB, it's faster to work on column vectors.
Hope you can follow this and I hope that I have understood your code correctly:
nOnes = sum(Data);
nZeroes = size(Data,2) - nOnes;
Data2(find(Data)) = repmat([-3 3],1,nOnes/2)
Data2(find(Data==0)) = repmat([-1 1],1,nZeroes/2)
I'll leave it to you to deal with the odd 1
s and 0
s.
So, disregarding negative signs, the equation for the output item Data2[loop,1] = Data[loop,1]*2 + 1. So why not first do that using a simple multiply-- that should be fast since it can be vectorized. Then create an array of half the original array length of 1s, half the original array length of -1s, call randperm on that. Then multiply by that. Everything's vectorized and should be much faster.
[row,ll] = size(Data);
sym_zero = -1;
sym_one = -3;
for loop = 1 : row
if ( Data(loop,1) ) // is 1
Data2(loop,1) = sym_one;
sym_one = sym_one * -1; // flip the sign
else
Data2(loop,1) = sym_zero;
sym_zero = sym_zero * -1; // flip the sign
end
end
精彩评论