Explain why it makes sense that matrix A( :, :, 1) is two-dimensions, while A( :, 1, :) and A(1, :, :) return three dimensions

5 views (last 30 days)
Will someone please explain to me why it makes sense that Matlab returns the following:
A = zeros(3,3,3);
Size1 = size(A(1,:,:)); % Returns [1,3,3]
Size2 = size(A(:,1,:)); % Returns [3,1,3]
Size3 = size(A(:,:,1)); % Returns [3,3]
Specifically, I don't understand why it is beneficial that two of the returns are 3D sets, and one is 2D. This problem arises when I try to do something like the following:
Sheet1 = zeros(3,3);
A(1,:,:) = Sheet1(:,:); % Doesn't work
A(:,:,1) = Sheet1(:,:); % Does work
To me, they should all return 2D "sheets"

Answers (3)

dpb
dpb on 2 Apr 2014
Easiest is probably just to look at what you get...
>> a=rand(3,3,3)
a(:,:,1) =
0.0811 0.4868 0.3063
0.9294 0.4359 0.5085
0.7757 0.4468 0.5108
a(:,:,2) =
0.8176 0.3786 0.3507
0.7948 0.8116 0.9390
0.6443 0.5328 0.8759
a(:,:,3) =
0.5502 0.2077 0.2305
0.6225 0.3012 0.8443
0.5870 0.4709 0.1948
>> a(:,:,1)
ans =
0.0811 0.4868 0.3063
0.9294 0.4359 0.5085
0.7757 0.4468 0.5108
>> a(:,1,:)
ans(:,:,1) =
0.0811
0.9294
0.7757
ans(:,:,2) =
0.8176
0.7948
0.6443
ans(:,:,3) =
0.5502
0.6225
0.5870
>>
If you want to reduce unit dimensions, use squeeze
>> squeeze(a(:,1,:))
ans =
0.0811 0.8176 0.5502
0.9294 0.7948 0.6225
0.7757 0.6443 0.5870
>>
  1 Comment
Stephen23
Stephen23 on 7 Dec 2021
To avoid potential bugs it is much more robust to use PERMUTE, rather than SQUEEZE. Otherwise any data set that one happens to have just one row, or one column, or etc. of data will cause errors or erroneous results without warning.

Sign in to comment.


Cory K
Cory K on 2 Apr 2014
Edited: Cory K on 2 Apr 2014
Thanks for the reply. The squeeze function certainly does "fix" the problem. I already understand what Matlab gives as output, I just don't like that it requires the squeeze function depending on what subset of the matrix you specify in order to return the same dimensionality for each version. My question was more about why Matlab does this? My only explanation for it is that it preserves the spatial orientation of the subset relative to the parent matrix. If this is the reason, why is this an advantage? To me it seems as much of a disadvantage as an advantage. Apparently, I am not the only one who thinks this is more of a disadvantage than an advantage: http://www.mathworks.com/matlabcentral/newsreader/view_thread/311725
  1 Comment
dpb
dpb on 2 Apr 2014
Why? "Because"
I'm not in on internal TMW design decision conversations but I presume it is because it's consistent with the dimension of the original which may also have benefits in cases where there are other commensurate arrays extant.

Sign in to comment.


Stephen23
Stephen23 on 7 Dec 2021
Edited: Stephen23 on 7 Dec 2021
So far no one has really answered why this makes sense, which is what the original question asked.
"My question was more about why Matlab does this?"
Because this leads to consistent, repeatable data which can be used in simple code. It gives consistently oriented data even if any of the (indexed) dimensions happen to be scalar, which means that special case handling is not required.
In contrast if indexing caused non-trailing indexed scalar dimensions to disappear without warning it would lead to data that is extremely difficult to work with and would require a lot of special case handling and lead to many latent bugs when users forget to do this. It would be very nearly unusable.
Lets have a look at a very simple example.
We have a data array D with dimensions A*B*C, where we want to select a subset of the A dimension and then first calculate the MEAN over the C dimension, and then later the MAX of this over the B dimension. This is trivial using the existing, reliable, consistent indexing:
M = mean(D(X,:,:),3) % A*B*C -> X*B*C -> M = X*B*1 for all D
We can always refer to the rows knowing that they correspond to whatever the rows represent, so we can do any operations knowing that the dimensions are still in exactly the same locations. So at some point later in the code we can simply do this:
max(M,[],2) % X*B*1 -> X*1*1 for all D
And we are done. This works even if X only returns one row of D.
Now lets consider your proposal. To allow for scalar dimensions magically disappearing without warning we would have to adapt the simple code above to:
if something_that_reliably_tests_if_X_returns_a_scalar_dimension
M = mean(D(X,:,:),2) % A*B*C -> B*C -> M = B*1
else
M = mean(D(X,:,:),3) % A*B*C -> X*B*C -> M = X*B*1
end
and then we still have the problem that now M has the data dimensions permuted, requiring further special handling for our MAX calculation. But we have a problem: later in the code we have an array M but a numeric array does not have a "memory" so it cannot somehow "remember" what its dimensions corresponded to many operations previously. So what dimension should we MAX over? Should we keep track of it, e.g. by adding some kind of flag variable? Please show the MAX command that would work correctly after magically removing any of D's dimensions, without knowing which dimensions they were (because this happens completely without warning).
Note that I wrote the IF to check the index: it would need to work with both subscript and logical indices. You might consider checking output array size, but of course in that case it is impossible to distinguish between an array that happened to have a particular size when it was provided vs one that ended up that size due to scalar dimensions magically disappearing without warning.
So that leads to significantly more complex and obfuscated code, even just with this very very simple example.
Imagine how it would be working with multiple indices or higher dimensions: the number of special cases increases exponentially with the number of dimensions and indices: if we use two indices, how many permutations of magically disappearing dimensions are there? If we use three indices, how many permutations?
Note that every permutation requires special-case handling.
"To me, they should all return 2D "sheets""
No thanks, I would rather keep my array dimensions reliably where they are, it is much simpler to work with.

Categories

Find more on Operators and Elementary Operations in Help Center and File Exchange

Products

Community Treasure Hunt

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

Start Hunting!