3

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
3
  • From your code it looks like you have an N by 1 array. Commented May 2, 2010 at 16:29
  • Also, MATLAB question number 1234! Commented May 2, 2010 at 16:31
  • Preallocate! Check my answer :) Commented May 2, 2010 at 16:51

4 Answers 4

8

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.

Sign up to request clarification or add additional context in comments.

Comments

2

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.

Comments

1

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.

2 Comments

Your idea is good, but I will increase the symbol pattern to more than 1 and 3 in the latter part of my project.
@HH: So long as there is a simple mapping of input values to output symbols, you can make a linear equation which will produce the result (and which can be vectorized efficiently by MATLAB), but it sounds like you have a sufficient solution already by using preallocation.
0
[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

1 Comment

I don't see a significant difference in the performance, when using your code. So, it didn't really work.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.