Unexpected singleton dimension removal

19 ビュー (過去 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 Center および File ExchangeLogical についてさらに検索

Community Treasure Hunt

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

Start Hunting!

Translated by