Problems with indexing in multidimensional array

1 view (last 30 days)
Hi Community!
I have trouble understanding how matlab handles dimensions if I loop though one of the inner dimensions and try to build a result array which has the same size as the original one.
I have written an example:
clear test;
clear test2;
test = ones(4,1,1,3,3,4);
size(test)
for ii = 1:size(test,4)
test2(:,:,:,ii,:,:) = ii*test(:,:,:,ii,:,:);
end
size(test2)
The size of test changes from 4,1,1,3,3,4 to test2 size of 4,3,4,3. My intention was to take the original array and multiply every element where the 4.dimension is 1 by 1, where it is 2 by 2 and so on. My expected result array test2 would have the exact same dimensions as test.
The multiplication by ii is just an example. In my original code I do a more complex calculation which I can't substitute by a matrix operation.
What am I doing wrong? What's the correct way to achieve my goal?
Thanks in advance folks!

Accepted Answer

Guillaume
Guillaume on 20 Mar 2017
Edited: Guillaume on 20 Mar 2017
Well, to see the problem, simply do:
clear test;
clear test2;
test = ones(4,1,1,3,3,4);
test2(:, :, :, 1, :, :) = test(:, :, :, 1, :, :);
size(test2)
The reason is that you're assigning something 4x1x1x1x3x4 to something that does not exists (test2). So matlab creates a matrix big enough to hold whatever your assigning, ignoring the singular dimensions. So you get a 4x3x4 matrix.
To solve this you need to tell matlab what the size of test2 is supposed to be, before you start the loop, so:
test2 = zeros(size(test));
for ...
and matlab won't have to guess (and get it wrong) what shape test2 is supposed to be. Other benefits of this:
  • faster code. With your code, the size of test2 increases at each step of the loop, so matlab has to reallocate a new array at each step, copy the old one over and add the new elements
  • no need for clear anymore, since if the variables already exist, you're replacing them.
Note that if you'd written your code in the editor, you'd have seen a wiggly line under test2 in the loop telling you that test2 changes size at each iteration and to consider preallocation.
  2 Comments
Stephen23
Stephen23 on 20 Mar 2017
+1 for a clear explanation, and for pointing out that that editor gives useful advice.
Michael
Michael on 20 Mar 2017
Thanks a lot. I already knew that my method is bad in terms of performance. But I did not see the problem with the singleton dimension. As you wrote it creates the 4x3x4 matrix in the first loop run and in the second run the test2(:,:,:,ii,:,:) command adds another dimension so that I end up with 4x3x4x3.
Thanks for the quick reply!

Sign in to comment.

More Answers (0)

Categories

Find more on Creating and Concatenating Matrices in Help Center and File Exchange

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!