2 views (last 30 days)

Show older comments

Hello, I need help understanding how Matlab applies flattening of arrays.

I know it uses a Fortran way of accessing information, so, given an N-D array, the dimension order that will change faster during eg. a reshape will be 1,2,3 etc. (and not N,N-1,N-2 etc as in C-manner). One would expect that, when one tries to reduce the dimensions of an array using colons, the reduction will be done in the same manner as the accessing. However this seems not to hold.

For example, we have an array A with dimensions (X,Y,Z). If we use A(:,:,:) we get the copy of the array. If we use A(:,:) we expect an array with dimensions (X*Y, Z), with the i,j element pointing at (i mod X, i div Y, j) element of A . However, no, what we get is an array (X, Y*Z), with the i,j element pointing at (i, j mod Y, j div Y) element of A. Why does this happen? Is it possible to determine/change this behavior?

Example:

x = cat(3,eye(3), eye(3), eye(3));

x(:,:)

ans =

1 0 0 1 0 0 1 0 0

0 1 0 0 1 0 0 1 0

0 0 1 0 0 1 0 0 1

whereas I would expect

1 1 1

0 0 0

0 0 0

0 0 0

1 1 1

0 0 0

0 0 0

0 0 0

1 1 1

same as when there is the 2 d analog

x = eye(3);

x(:)

1

0

0

0

1

0

0

0

1

Stephen
on 23 Sep 2021

"However this seems not to hold."

It most certainly does hold! Lets try it. Your example 3D array:

format compact

x = cat(3,eye(3), eye(3), eye(3))

has its elements stored in this order:

x(:) = 1:27

Using two subscripts keeps exactly the same order (just as expected):

y = x(:,:)

y(:) % absolutely no change in the order!

Your example appears to have the elements in exactly the same order, so it seems that you are mixing up the order of elements with the array size: whilst certainly related, these are not the same thing.

Stephen
on 23 Sep 2021

Edited: Stephen
on 23 Sep 2021

"If we use A(:,:) we expect an array with dimensions (X*Y, Z), with the i,j element pointing at (i mod X, i div Y, j) element of A"

No, we don't expect that at all.

In fact the last given index refers to that dimension and also to all infinite trailing dimensions. Your test-case is entirely consistent with that (and this paradigm also informs us that the concept of linear indexing is really just an edge-case of subscript indexing). So a general rule that describes both linear and subscript indexing is actually this:

A(dim1,dim2,..,dimN,ThisDimAndAllTrailingDim)

where N>=0.

And yes, it is documented here:

Loren writes: "Indexing with fewer indices than dimensions If the final dimension i<N, the right-hand dimensions collapse into the final dimension. E.g., if A = rand(1,3,4,1,7) and we type A(1,2,12), then we get the element as if A were reshaped to A(1,3,28) and then indexed into. 28 repesents the product of the final size of the final dimension addressed and the other "trailing" ones."

and she then proceeds to give a detailed example. Take a look!

"One would expect that, when one tries to reduce the dimensions of an array using colons, the reduction will be done in the same manner as the accessing."

It is.

" Is it possible to determine/change this behavior?"

I doubt that you would convince TMW to redesign this very simple indexing concept into your much more complicated concept that requires MOD and DIVISION and whatnot, but you can certainly try:

Sulaymon Eshkabilov
on 23 Sep 2021

How about this:

A = cat(3, eye(3), eye(3), eye(3))

B =reshape(A(:,:).',3,[])

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

Start Hunting!