# Implicit expansion with empty arrays

7 views (last 30 days)
Matt J on 21 Aug 2019
Commented: Bruno Luong on 22 Aug 2019
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 on 21 Aug 2019
Edited: James Tursa on 21 Aug 2019
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.

Rik on 22 Aug 2019
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 on 22 Aug 2019
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.
But how would those inputs be replicated? repmat style or repelem style? Collated or uncollated?
>> 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 on 22 Aug 2019
Steve: "But how would those inputs be replicated? "
Following Rik's method just above my post.