开发者

Help in optimizing a for loop in matlab

开发者 https://www.devze.com 2022-12-29 02:18 出处:网络
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 ar

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 1s and 0s.


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
0

精彩评论

暂无评论...
验证码 换一张
取 消