Unexpected singleton dimension removal
조회 수: 5 (최근 30일)
이전 댓글 표시
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
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.
채택된 답변
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.
댓글 수: 0
추가 답변 (1개)
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
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 Center 및 File Exchange에서 Matrices and Arrays에 대해 자세히 알아보기
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!