Unexpected singleton dimension removal

조회 수: 5 (최근 30일)
Thomas
Thomas 2014년 7월 8일
댓글: Matt J 2014년 11월 11일
When I create a three dimensional array and assign it to an undefined array, the assignment does not behave as I expect if the first two dimensions are singletons:
>> it = rand(1,1,3)
it(:,:,1) =
0.9157
it(:,:,2) =
0.7922
it(:,:,3) =
0.9595
>> vom(1,:,:) = it
vom =
0.9157 0.7922 0.9595
>> vom(:,1,:) = it
vom =
0.2769
0.0462
0.0971
I know there are a million ways around this, but this behavior seems unnatural to me. Is this singleton dimension removal documented anywhere?
  댓글 수: 5
Sara
Sara 2014년 7월 8일
But what are you trying to achieve? If you want to assign it to vom, you don't need any indexing. vom1(1,1,1:3) = it will do not remove any dimension.
Thomas
Thomas 2014년 7월 8일
As I said there are plenty of ways around this, in my case size(it,2) is not fixed, and I was doing the assigment
vom(m,:,:) = it;
in a loop. Alternatives are
1) initialize vom by
vom = zeros(0, size(it,2),3)
2) do the assignment as
vom(m, 1:size(it,2), :) = it
3) Initialize vom as empty and assign via concatenation
vom = [vom;it]
Doubtless there are other ways to do this.

댓글을 달려면 로그인하십시오.

채택된 답변

Matt J
Matt J 2014년 11월 11일
편집: Matt J 2014년 11월 11일
Is this singleton dimension removal documented anywhere?
I think the best documentation you'll find will be this excerpt from the SUBSASGN documentation, note the portion in bold
"For multidimensional arrays, a(I,J,K,...) = b assigns b to the specified elements of a. b must be length(I)-by-length(J)-by-length(K)-... or be shiftable to that size by adding or removing singleton dimensions. "
So, in other words, it is applying shiftdim() to the right hand side "b", until it reaches a shape that will work. The question is, when vom is undefined, how does it choose the direction to shift? What accounts for differences in the 3 tests below? I believe the answer is, it will start with a right-shift of 1 and continue to right shift until it finds a shape that will work.
>> clear vom; vom(1,:,:) = it
vom =
0.9134 0.6324 0.0975
>> clear vom; vom(1,:,:) = it(:)
vom =
0.9134 0.6324 0.0975
>> clear vom; vom(1,:,:) = it(:)'
vom(:,:,1) =
0.9134
vom(:,:,2) =
0.6324
vom(:,:,3) =
0.0975
So, in the first test above, "it" is right shiftdimmed by 1 making it into a column vector, but a column vector is not a shape compatible with the indexing vom(1,:,:). The target shape has to be either a row vector or 1x1x3. So, "it" is right shifted again, making it a row vector, which works.
Similarly, in the second test, the right hand side starts as a column vector, gets right shifted by 1, making it a row vector which is a legal target shape, and so that's the shape that gets chosen
Finally, the 3rd test is the most interesting. The given right hand side it(:)' starts as a row vector, and the sensible thing would be to stop there, since this is a legal target shape. However, as I mentioned, the rule is that the code will always attempt at least one right shift and so it converts the right hand side to 1x1x3. But this is also a legal target shape and so that's the shape that gets selected.

추가 답변 (1개)

John D'Errico
John D'Errico 2014년 7월 8일
Clearly, "vom" stands for Volatile Organic Matter, and "it" always means Information Technology. But put them together and you get ... something that makes MATLAB upset.
Seriously, I was a bit surprised myself at first. Apparently MATLAB sees a vector as a vector, as just a vector and no more.
A = rand(1,3);
clear B
B(1,:) = A
B =
0.98946 0.86134 0.70694
clear B
B(:,1) = A
B =
0.98946
0.86134
0.70694
An array is a different thing though.
A = rand(2,2);
clear B
B(1,:) = A
Subscripted assignment dimension mismatch.
I'd prefer there was consistency, but I'll bet this is a legacy thing, harking back to the days of MATLAV Version 1.
  댓글 수: 1
Matt J
Matt J 2014년 11월 11일
An array is a different thing though.
Not as different as you might think:
>> A=rand(2,2)
A =
0.8003 0.4218
0.1419 0.9157
>> clear B; B(1,:,:)=A
B(:,:,1) =
0.8003 0.1419
B(:,:,2) =
0.4218 0.9157

댓글을 달려면 로그인하십시오.

카테고리

Help CenterFile Exchange에서 Matrices and Arrays에 대해 자세히 알아보기

Community Treasure Hunt

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

Start Hunting!

Translated by