0

I am very new to Matlab, and I feel completely overwhelmed by the use of arrays. What is the most efficient implementation of the following C++ code in Matlab?

A = std::vector<double>();

for (int i = 0; i < 100; i++) {
  if (complicatedBoolFunction(i)) {
    A.push_back(i);
  }
}

Edit: By efficiency I mean to use as little resources as possible to grow the array A - that is, to avoid copy-pasting it into temporary memory

0

2 Answers 2

5

You can do this 2 ways

  1. Pre-allocating for the maximum size, and removing unused elements. This has the advantage of pre-allocating memory in case the condition is often met...

    A = NaN(100,1)
    for ii = 0:99
        if rand > 0.5    % some condition
            A(ii+1) = ii; % some value
        end
    end
    A(isnan(A)) = []; % remove unused elements
    
  2. Appending to the array. This avoids making A way too large if appending is unlikely...

    A = []; % empty array
    for ii = 0:99
        if rand > 0.5 % some condition
            A(end+1, 1) = ii; % some value. Equivalent to 'A = [A; ii];'
        end
    end
    

A better, and more Matlab-esque way of doing this would be to vectorise your conditional function. This way you avoid looping and allocation issues...

ii = 0:99;
A = ii(rand(100, 1) > 0.5);

You can use any Boolean function you like as an indexing array, as long as it returns a logical array with the same number of elements as the array you're indexing (ii here) or integer indices of the elements to choose.

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

5 Comments

I like the third, Matlab-esque way, it's not always practical but it seems the most efficient way - no looping
@user2305193: Loops are no longer slow in MATLAB, I've noticed sometimes code slows down after vectorizing a loop! See for example here: stackoverflow.com/a/48220174/7328782
Agreed @Cris, not necessarily slow, although for this example it is clearly neater if the Boolean function call can be vectorised. Whilst the newer JIT compiler is pretty decent with loops, vectorising code can still yield decent performance improvements for some operations.
I agree. And oftentimes (as in this case) vectorized code is easier to read too. But some vectorization optimizations are really hard to decipher! :)
@CrisLuengo I was aware loops aren't punitatively slow in Matlab and I couldn't agree more, it's more practical to use loops especially with iteratively increased variables/pushing values to vectors in terms of higher readability and being able to modify it faster on-the-fly. But Matlab seems to be layed out for the 'boolean-way', it would be surprising if it wouldn't handle these faster than (or at least equally fast as) 'conventional' loops
1

The most efficient implementation of such C++ code would be

i = 0:99;
A = i(complicatedBoolFunction(i));

Anyway you can grow an array with concatenation, which is (or was) usually not recommended, like the following

A = [];

for i = 0:99
  if (complicatedBoolFunction(i))
    A = [A i];
  end
end

or much more efficiently like this:

A = [];

for i = 0:99
  if (complicatedBoolFunction(i))
    A(end + 1) = i;
  end
end

3 Comments

Thanks for reply, Marko. The last two suggestions work well. The first suggestion, with a simple example of i = 0:99; A = i(mod(i, 2)) fails with Subscript indices must either be real positive integers or logicals
Because the return of mod(i, 2) is an array of double values. Try with mod(i, 2) == 0
The second form to grow the array is much more efficient, as the first form copies the array at every iteration. See here: stackoverflow.com/q/48351041/7328782 (compare graphs in the question and the answer).

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.