Implicit expansion with empty arrays
現在この質問をフォロー中です
- フォローしているコンテンツ フィードに更新が表示されます。
- コミュニケーション基本設定に応じて電子メールを受け取ることができます。
エラーが発生しました
ページに変更が加えられたため、アクションを完了できません。ページを再度読み込み、更新された状態を確認してください。
古いコメントを表示
I was just idly curious why scalar expansion of an empty array seems to work here (R2018a),
>> [1,2,3;4 5 6]-zeros(2,3,0)
ans =
2×3×0 empty double array
but not here,
>> [1,2,3;4 5 6]-zeros(2,0,0)
Error using -
Array dimensions must match for binary array op.
採用された回答
James Tursa
2019 年 8 月 21 日
編集済み: James Tursa
2019 年 8 月 21 日
In the 1st case, you are expanding a dimension of 1 (the 3rd dimension of the first operand) to 0, so it is scalar expansion.
In the 2nd case, you are trying to expand a dimension of 3 (the 2nd dimension of the first operand) to 0, so it is not scalar expansion ... it is simply a dimension mismatch.
11 件のコメント
Matt J
2019 年 8 月 21 日
OK. It's interesting that you can "expand" from 1 to 0.
Steven Lord
2019 年 8 月 21 日
That predates implicit expansion. It worked with scalar expansion.
>> 1-[]
ans =
[]
The minus operator is being called with two operands, a 1-by-1 and a 0-by-0. The 1-by-1 is scalar "expanded" to the same size as the other operand, the 0-by-0, and so the result is 0-by-0.
Rik
2019 年 8 月 21 日
I don't see why the reverse of this answer is not true. If you can expand 1 to 0, why can't you expand 3 to 0? bsxfun gives a different error: non-singleton dimensions must match. Does that mean 0 is regarded as a singleton dimension for operations like this? Because normally it isn't.
In short, can you expand a bit on your explanation? (double pun definitely intended)
Bruno Luong
2019 年 8 月 21 日
編集済み: Bruno Luong
2019 年 8 月 21 日
"If you can expand 1 to 0, why can't you expand 3 to 0?"
Because a singleton is dimension with length 1, and expansion by definition works on singleton dimension, it take the scalar value (length 1) and fill the array along that dimension with the same value (including empty, i.e. length 0).
Dimension with length 3 is not a singleton. Granted there is no ambiguity to "contract" anything to empty, but that is not defined as expansion, and it's good that is throw an error IMO to avoid somehing that is exception and likely a mistake rather than intentional.
Also please tell us a good reason of why the dimension of (assuming possible operation)
rand(3,1) + rand(0,1)
is 0 x 1? I might argue nan(3,1) is a valid result as well!!!
Rik
2019 年 8 月 21 日
Ah, I think I understand now. It is not that the 0 has a special status, just that a singleton dim can also be resized to match 0. That is just a case where the name doesn't match the operation.
As for your question: I would explain it the same as how you explain expansion. You proces each element along the non-matching dimension and contatenate the result of each element along that dimension.
A=rand(3,1,10);
B=rand(0,1,10);
clear C
for n=1:3
C{n}=A(n,:,:)+B;
end
C=cat(1,C{:})
Bruno Luong
2019 年 8 月 22 日
編集済み: Bruno Luong
2019 年 8 月 22 日
So if you apply your method to
rand(3,10) + rand(2,10);
you would get 6 x 10 result.
Just be aware that A + B is different than B + A.
I woud say "Why not?"
Note that such result as you defined can be achieve with reshape + expansion (no loop at cat is needed). Just split the unmatches dimension to 2 adjadcent dimensions (with singleton), do the operation then merge back the dimension to obtain the result.
reshape( reshape(A,[1 3 10]) + reshape(B,[2 1 10]), [6 10])
Personally I prefer leave it like that and people who want such result, they must use RESHAPE to avoid silence bug of too flexible syntax.
Rik
2019 年 8 月 22 日
I wasn't proposing my code as a real method per se, just as an illustration. But since you insist on more robust code:
A=rand(3,1,10);
B=rand(0,1,10);
clear C
for n=1:max(size(A,1),size(B,1))
if size(A,1)>1 && size(B,1)>1
C{n}=A(n,:,:)+B(n,:,:);
elseif size(A,1)>1 && size(B,1)<=1
C{n}=A(n,:,:)+B(:,:,:);
else
C{n}=A(:,:,:)+B(n,:,:);
end
end
C=cat(1,C{:})
Note: >1 instead of ==1 because you can't use 1 as an index if the dim length is 0. I also wasn't intending on A+B having a different output from B+A.
Personally, I would have voted for extending bsxfun to support more functions, instead of enabling implicit expansion for all operations.
Bruno Luong
2019 年 8 月 22 日
編集済み: Bruno Luong
2019 年 8 月 22 日
"Personally, I would have voted for extending bsxfun to support more functions, instead of enabling implicit expansion for all operations."
Any concrete example of binary function not supported by BSXFUN?
Rik
2019 年 8 月 22 日
I think we're getting a bit off topic here, but ok. I don't have an example of a binary function, which is why I didn't specify that. I was thinking more along the lines of this:
fun=@(a,b) a+b;
A=1:5;B=A';
C=arrayfun(fun,A,B);%no need for meshgrid/ndgrid
I don't have good suggestions about how that could best be implemented, but I don't work for Mathworks, so I have the luxury of expressing a wish without having to consider the feasibility.
%maybe this?
C=bsxfun(@arrayfun,fun,A,B);
Steven Lord
2019 年 8 月 22 日
Rik wrote: That is just a case where the name doesn't match the operation.
Yes, but "scalar {or implicit} expansion except when the size of the other operand in a particular dimension is 0 in which case it is scalar {or implicit} contraction" is a bit of a mouthful.
Bruno wrote: So if you apply your method to
rand(3,10) + rand(2,10);
you would get 6 x 10 result.
>> x = reshape(1:6, [2 3]);
>> x1 = repmat(x, [3 1]);
>> x2 = repelem(x, 3, 1);
>> isequal(x1, x2) % false
If you're replicating in a singleton dimension, they're the same. Collating multiple copies of a 1-page document is the same as not collating them.
>> y = 1:10;
>> isequal(repmat(y, 3, 1), repelem(y, 3, 1)) % true
Rik wrote: Personally, I would have voted for extending bsxfun to support more functions, instead of enabling implicit expansion for all operations.
You can pass a function handle that accepts two inputs into bsxfun.
>> fun=@(a,b) a+b;
>> A=1:5;B=A';
>> C1 = bsxfun(fun, A, B);
>> C2 = A + B; % Implicit expansion
>> isequal(C1, C2) % true
>> bsxfun(@besselj, A, B) % works
Bruno Luong
2019 年 8 月 22 日
Steve: "But how would those inputs be replicated? "
Following Rik's method just above my post.
その他の回答 (0 件)
カテゴリ
ヘルプ センター および File Exchange で Creating and Concatenating Matrices についてさらに検索
参考
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!Web サイトの選択
Web サイトを選択すると、翻訳されたコンテンツにアクセスし、地域のイベントやサービスを確認できます。現在の位置情報に基づき、次のサイトの選択を推奨します:
また、以下のリストから Web サイトを選択することもできます。
最適なサイトパフォーマンスの取得方法
中国のサイト (中国語または英語) を選択することで、最適なサイトパフォーマンスが得られます。その他の国の MathWorks のサイトは、お客様の地域からのアクセスが最適化されていません。
南北アメリカ
- América Latina (Español)
- Canada (English)
- United States (English)
ヨーロッパ
- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)
- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom (English)
