four dimensions array's expression

A=rand(2,3,3)
B=cat(4,A(:,:,1),A(:,:,2),A(:,:,3))
B(:,:,1,1)=
B(:,:,1,2)=
B(:,:,1,3)=
B(:,:,1,4)=
Why not
B(:,:,1,1)=
B(:,:,2,1)=
B(:,:,3,1)=
B(:,:,4,1)=

Answers (2)

>> size(B)
ans =
2 3 1 3
the statement
B = cat(4,A(:,:,1),A(:,:,2),A(:,:,3))
concatenates three 2D arrays along the fourth dimension. I don't think this case is described in the documentation. However, Matlab obviously adds a third dimension of size one.

3 Comments

Stephen23
Stephen23 on 3 Apr 2019
Edited: Stephen23 on 3 Apr 2019
"I don't think this case is described in the documentation."
I don't see anything special happening here that requires a special description: MATLAB simply concatenates some arrays along the requested dimension (in this example the fourth). By definition of concatenation, this leaves all of the other dimensions unchanged: the fact that one of the other dimensions (the third) has size 1 is irrelevant.
So far there is absolutely nothing here that is new or unusual or inconsistent or that is any way a special "case" that would need a special description: what the OP has described is simply an example of concatenation.
"However, Matlab obviously adds a third dimension of size one."
Not really: those arrays already had size 1 the third dimension. In fact all MATLAB arrays implictly have infinite trailing singleton dimensions. This has been discussed in the TMW blogs:
and many times on this forum:
and on other forums:
and (until very recently when this was removed) also in the MATLAB documentation:
Why the third dimension is 1, not (1,2,3)?
But I also told matlab A(:,:,2).

Sign in to comment.

Stephen23
Stephen23 on 3 Apr 2019
Edited: Stephen23 on 3 Apr 2019
"Why the third dimension is 1, not (1,2,3)?"
Part 1: Indexing
Because that is exactly what you told MATLAB to do, when you wrote your indexing, where you defined three arrays of size 2x3(x1x1x1...) like this:
A(:,:,1)
% ^ this tells MATLAB you want just ONE page from the 3rd dimension.
This applies to every dimension:
  • if you pick one row via one index you will get one row (and not tree rows),
  • if you pick one column via one index you will get one column (and not three columns),
  • if you pick one page via one index you will get one page (and not three pages),
  • etc. etc. the same applies to all dimensions of all arrays in MATLAB.
The term "page" is used in the documentation for the third dimension (just like the terms "row" used for the first dimension and "column" for the second dimension):
Part 2: Concatenation
In your example you take a 2x3x3(x1x1x1...) array and split it into three 2x3(x1x1x1...) arrays. Then you concatenate these three array along the fourth dimension, giving you a single 2x3x1x3(x1x1x1...) array. Concatenation does not change any of the other dimensions: it concatenates along the dimension of your choice, all of the other dimensions will remain exactly the same. The size of your original array is also totally irrelevant, only the sizes of the three array that you are concatenating is important.
In your example, those three arrays must have the same sizes along the other dimensions:
  • 1st dim size is 2 -> CAT -> 1st dim size is 2
  • 2nd dim size is 3 -> CAT -> 2nd dim size is 3
  • 3rd dim size is 1 -> CAT -> 3rd dim size is 1
Do you notice the pattern: they are all unchanged. The ONLY dimension that might change (depending on the input array sizes) is the one that you are concatenating along. In your case you are concatenating three arrays whose sizes in the fourth dimension are all 1:
  • 4th dim sizes are 1, 1, and 1 -> CAT -> 4th dim size is 3.
Consider this: If you concatenate two row vectors together vertically, do you expect the number of columns to change? If those two vectors are two halves of a longer vector (or rows of a matrix, or pages in an ND array, etc), does this make any difference to the concatenation? (hint: no, the concatenation operator does not know anything about where those two rows vectors came from ofr what size it might have had)

9 Comments

I think the answer should be:
B(:,:,1,1)=
B(:,:,1,2)=
B(:,:,1,3)=
B(:,:,1,4)=
B(:,:,2,1)=
B(:,:,2,2)=
B(:,:,2,3)=
B(:,:,2,4)=
B(:,:,3,1)=
B(:,:,3,2)=
B(:,:,3,3)=
B(:,:,3,4)=
"I think the answer should be:"
Then you need to learn how concatenation works.
All of the input arrays have size 1 on the third dimension and you are concatenating along the fourth dimension, so why do you expect the size of the third dimension size to change?
Based on exactly the same (incorrect) logic you would also expect the concatenation of two column vectors along the third dimension to also change the number of columns:
>> A = [1;2;3]; % size 3x1(x1x1x1...)
>> B = [4;5;6]; % size 3x1(x1x1x1...)
>> C = cat(3,A,B) % should give 3x1x2(x1x1x1...)
C(:,:,1) =
1
2
3
C(:,:,2) =
4
5
6
>> size(C)
ans =
3 1 2
Please explain why this should actually result in a 3x3x2 or 3x2x2 array, as you think.
If you concatenate along the Xth dimension, why do you expect the Yth dimension to change? Can you show us a single example of this happening in MATLAB, or in any other mathematical programming language, or in any standard mathematical or computing textbook?
Why not let the third demension size to change, and keep the fourth size not change?
In your example, when we concatenate two two dimensions arrays (3*1) to three dimensions, we can get a array about 3*1*2. However, why when we concatenate two two dimensions arrays (3*1) to four dimensions, we can get a array about 3*1*1*2? I guess the later should contain the former's changes.
Stephen23
Stephen23 on 3 Apr 2019
Edited: Stephen23 on 3 Apr 2019
"Why not let the third demension size to change, and keep the fourth size not change?"
Because that is what you told MATLAB to do: you told it to concatenate along the fourth dimension (so this will change size), not the third dimension (which will not change size). If you tell MATLAB to concatenate along the fourth dimension, why would you expect it to concatenate along the third dimension? Why not also change the first and second and fifth and twenty-third dimensions? What is so special about the third dimension that you think it needs to change? What about all the other ones?
"concatenate two two dimensions arrays (3*1) to three dimensions, we can get a array about 3*1*2."
Yes, that is what I would expect to get.
"However, why when we concatenate two two dimensions arrays (3*1) to four dimensions, we can get a array about 3*1*1*2?"
Yes, because if you tell MATLAB to concatenate along the fourth dimension, then that is exactly what it does.
I don't see why you write "however": if you tell MATLAB to concatenate along the fourth dimension, what does the third dimension have to do with it? If you imagine that singleton dimensions should magically "disappear" then please go a write such an operator, try it, and you will find out how completely unusable it is (because every time your data reduces down to just one row/column/page the operation returns a totally different output which your code cannot process without lots of special cases. By the way, this is exactly the reason why experienced MATLAB users do not use the LENGTH command).
"I guess the later should contain the former's changes"
I have absolutely no idea what that means. An array has a size property. It does not have a "changes" property.
A=rand(2,3,3)
B=cat(4,A(:,:,1),A(:,:,2),A(:,:,3))
The A has three dimensions in which A changes. But why in B, B changes only in three dimensions, not in four dimensions? So, what is the difference between A and B?
If the answer is:
B(:,:,1,1)=
B(:,:,1,2)=
B(:,:,1,3)=
B(:,:,1,4)=
B(:,:,2,1)=
B(:,:,2,2)=
B(:,:,2,3)=
B(:,:,2,4)=
B(:,:,3,1)=
B(:,:,3,2)=
B(:,:,3,3)=
B(:,:,3,4)=
Then, B changes in four dimensions.
A has three dimensions. When you extend A's dimensions from three to four, A is changed into B. But B still has three dimensions which changes because the third dimension is firm. In A, the third dimension changes, but when A is extend to B, the third dimension is firm. I feel it weird.
"A has three dimensions...."
The number of dimensions of A is irrelevant: the only important thing are the sizes of the arrays being concatenated. You are also ingoring the infinite singleton scalar dimensions, which makes the entire concept of "three dimensions" very poorly defined.
In your example you are not concatenating A., you are concatenating three unnamed arrays which each have size 2x3(x1x1x1x1...). It makes no difference where these arrays came from, the only thing that is important is their size when they are concatenated.
"When you extend A's dimensions from three to four,"
Where does this happen? Nowhere in your example do you do anything with the fourth dimension of A. You define A like this:
A=rand(2,3,3) % no reference to fourth dimension!
and then you do subscript indexing into the 1st, 2nd, and 3rd dimensions of A like this:
A(:,:,1) % no reference to fourth dimension!
Nothing in your code "extends A" or has anything to do with its fourth dimension. Actually you do the opposite of "extends": you use indexing to get sub-arrays of A.
"A is changed into B"
No. Actually you extract three arrays from A. And you concatenate three arrays to create B.
The origin of the three arrays makes no difference to their concatenation.
"But B still has three dimensions which changes because the third dimension is firm. In A, the third dimension changes, but when A is extend to B, the third dimension is firm."
A is NOT "extended" to B. These two arrays have nothing directly to do with each other.
"I feel it weird."
That is clear. You need to learn about variables, dimensions, and concatenation.
"So, what is the difference between A and B?"
Well that is very simple: they are different arrays. They both contain the same three matrices, which in A are concatenated along the third dimension and in B are concatenated along the fourth dimension. Exactly as you told MATLAB to do!
Here is an adaption of your original example:
>> A = rand(2,3,1,1,1,1,3);
>> B = cat(4,A(:,:,1,1,1,1,1),A(:,:,1,1,1,1,2),A(:,:,1,1,1,1,3))
Question: what size would you expect the output to be? (hint: exactly the same as in your example, because the three arrays being concatenated have exactly the same sizes too. The size of A is irrelevant, only the sizes of the three arrays is important, just like in your example).
>> A = rand(2,3,1,1,1,1,3);
>> B = cat(4,A(:,:,1,1,1,1,1),A(:,:,1,1,1,1,2),A(:,:,1,1,1,1,3))
Why the answer is :
B(:,:,1,1) =
0.8147 0.1270 0.6324
0.9058 0.9134 0.0975
B(:,:,1,2) =
0.2785 0.9575 0.1576
0.5469 0.9649 0.9706
B(:,:,1,3) =
0.9572 0.8003 0.4218
0.4854 0.1419 0.9157
We can see the answer delete the fifth, sixth, and seventh dimensions because the deleted dimensions are all the same. But the third dimension is all 1, why the answer not delete the third dimension?
"We can see the answer delete the fifth, sixth, and seventh dimensions because the deleted dimensions are all the same."
Trailing singleton dimensions are NOT deleted. They might not be displayed, but they are (implicitly) always there, exactly as I discussed seven hours ago:
For example, you can always access them using indexing:
>> X = [2,3,5]; % size 1x3(x1x1x1x1...)
>> X(1,3,1,1,1,1,1)
ans = 5
and you can always measure them using SIZE:
>> size(X,5) % 5th dim NOT deleted!
ans = 1
>> size(X) % does not show 5th dim, but it is still there!
ans =
1 3
Which is also why I have written the sizes showing the trailing singleton dimensions, e.g.
size(B) = 2x3x1x3(x1x1x1x...)
Although sometimes MATLAB is inconsistent and has some special cases, in this case it is very consistent: trailing dimemensions do NOT get "deleted" when they are singleton.
Your concept (that singleton dimensions are somehow "deleted") would make MATLAB almost unusable, because arrays would entirely change when the data reduces down to one row/column/page/..., which would make code impossible to write without many many ugly special cases.

Sign in to comment.

Categories

Products

Tags

Asked:

on 3 Apr 2019

Edited:

on 4 Apr 2019

Community Treasure Hunt

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

Start Hunting!