MATLAB Answers

How to operate properly with multidimensional matrices and cells.

1 view (last 30 days)
Johannes
Johannes on 14 Jun 2021
Edited: Jan on 14 Jun 2021
Let's create as an example the following 3D-cell:
l=0;for i=1:3;for j=1:3;for k=1:3;l=l+1;C{i,j,k}=l;end;end;end
Or the corresponding 3D matrix:
M=cell2mat(C);
Then my issue is that, unlike what I expected, Matlab doesn't appear to be able to operate on multidimensional matrices and cells the way it can handle a simple 2D object, when it should be straight forward. Matlab appears to consider the objects as a series of 2D matrices/cells with the first two entries being their dimensions, and the last entry being the series.
This shows when I want to extract a 2D set from the 3D matrix.
If we ask for
M(:,:,1)
Then there's no issue. Matlab can extract the matrix just fine and we get:
ans =
1 4 7
10 13 16
19 22 25
For the other two, however, it goes wrong:
M(1,:,:)
ans(:,:,1) =
1 4 7
ans(:,:,2) =
2 5 8
ans(:,:,3) =
3 6 9
M(:,1,:)
ans(:,:,1) =
1
10
19
ans(:,:,2) =
2
11
20
ans(:,:,3) =
3
12
21
So here's my question:
I'm working on a project that gives me results in Vector and matrix forms. However, there are several ways of doing these.
For example, I have several modes, identification methods, and correlation functions, and my objective is to compare their performance.
If I were to only do one method, the problem of course does not exist, as the dimension would be e.g. m*n*1*1*1,which means the results are 2D. But because I want to compare the different approaches, the results become multidimensional.
So for the 3D example above, imagine the 2D matrix as a square, and the 3D as a cube, and me as the person wanting to be able to slice it into bits orthogonal to any of the 3 dimensions.
In short, what is the straight forward way to do this? It's permute, right?
I.e:
permute(M(:,:,1),[1 2 3])%essentially the same as just skipping the permutation
permute(M(:,1,:),[1 3 2])
permute(M(1,:,:),[3 2 1])
And the answer to slicing it any way other than standard will have to be to do a permutation first?
So I think I answered my own question whilst asking it, but just to make sure, I'd greatly appreciate any feedback to this.
I'm wondering if there's a more straight forward way, if I've overlooked something, and if anyone here has some tips as to what one should or shouldn't do in this regard? Thank you in advance for having read through this and any answer you might be about to give.
Also, I haven't yet gone ahead and tested it on 4D, but if anyone has, can you give me a heads up as to whether this extrapolates to this additional dimension or if there are additional pitfalls?
  2 Comments
Stephen
Stephen on 14 Jun 2021
"Matlab doesn't appear to be able to operate on multidimensional matrices and cells the way it can handle a simple 2D object, when it should be straight forward."
It is very straightforward.
The simple constistency of MATLAB'S everything-is-an-array-regardless-of-how-many-dimensions-it-has philosophy is one of the main reasons that I am still using it, even after using Julia (ugh, the transpose confusion), numpy, R, etc...
"For the other two, however, it goes wrong:"
How exactly are they "wrong"?
In this example your indexing specifies one row, all columns, and all pages... and that is exactly what MATLAB returns:
M(1,:,:)
ans(:,:,1) =
1 4 7
ans(:,:,2) =
2 5 8
ans(:,:,3) =
3 6 9
In this example your indexing specifies all rows, one column, and all pages... and that is exactly what MATLAB returns:
M(:,1,:)
ans(:,:,1) =
1
10
19
ans(:,:,2) =
2
11
20
ans(:,:,3) =
3
12
21
"Matlab appears to consider the objects as a series of 2D matrices/cells with the first two entries being their dimensions, and the last entry being the series."
MATLAB's multi-dimensional arrays behave like multi-dimensional arrays. Your explanation does not match my experience of using multi-dimensional arrays inm MATLAB, nor what the MATLAB documentation explains:
Because "series" is not defined in your question (nor used in the MATLAB documentation), it is unclear what you expect those (apparently perfectly consistent, correct, reliable) indexing operations to achieve.
Are you expecting MATLAB to make dimensions disappear when you perform indexing? (e.g. to magically remove scalar dimensions, thus leading to unpredictable, totally unusable code and everyone abandoning MATLAB) Or to return everything as a 2D matrix, regardless of the actual dimensions the data really has? (ugh... the horror!) Or to automatically permute the dimensions according to some (so far unwritten) rule that suits only your needs?
"So for the 3D example above, imagine the 2D matrix as a square, and the 3D as a cube"
Seems reasonable... and it explains exactly the examples shown in your question.
So far you have not explained why you think that those correct outputs are "wrong".

Sign in to comment.

Accepted Answer

Jan
Jan on 14 Jun 2021
Edited: Jan on 14 Jun 2021
"For the other two, however, it goes wrong:"
No, nothing goes wrong. This is exactly what is expected and needed.
Only the display in the command window might look different to what you expect. But for calculations you can use X(:, :, 1) as well as X(1, :, :). The first has the advantage, that the memory for the data is contiguos, while the latter uses slices in the memory. But Matlab handles this automatically, so you do not have to care for it.
Do you know the command squeeze() to remove singelton dimensions? Using reshape directly is an option also to remove singelton dimensions.
  3 Comments
Jan
Jan on 14 Jun 2021
Instead of using squeeze I prefer to call reshape directly, because this save some microseconds.

Sign in to comment.

More Answers (1)

J. Alex Lee
J. Alex Lee on 14 Jun 2021
You might be looking for squeeze()?
l=0;
% preallocate
C = cell(3,3,3);
M = nan(3,3,3);
% construct 3D cell and matrix together
for i=1:3
for j=1:3
for k=1:3
l=l+1;
C{i,j,k} = l;
M(i,j,k) = l;
end
end
end
C2M = cell2mat(C);
% here is a way to generate inline depending on what you need
MIL = permute(reshape(1:27,3,3,3),[3,2,1]);
% check equality of results
isequal(M,C2M)
isequal(M,MIL)
% i believe this is what you are looking for
squeeze(M(1,:,:))

Products


Release

R2020b

Community Treasure Hunt

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

Start Hunting!

Translated by