Should Implicit Expansion be Applied to Additional Functions?
Show older comments
I know that some don't like implicit expansion. Given that it's likely here to stay, should it be made applicable to some additional functions? Just the other day I ran into a case like this, where one of X or Y is n x 3 and the other 1 x 3.
Z = X + Y;
Z = X - Y;
Z = dot(X,Y,2); % doesn't work
Is there some fundamental reason why dot can't support implicit expansion? If not, should it? Are there other functions, like cross, that should support implicit expansion?
Intresting to me is that the doc says: "Most binary (two-input) operators and functions in MATLAB® support numeric arrays that have compatible sizes. Two inputs have compatible sizes if, for every dimension, the dimension sizes of the inputs are either the same or one of them is 1." So most binary functions, but not all, support it. It would be nice if the doc had a single list of functions that support implicit expansion, or, if shorter, a list of binary functions that do not.
13 Comments
Bjorn Gustavsson
on 9 Oct 2020
Well, your example with dot not working is rather poorly chosen, don't you agree?
Paul
on 9 Oct 2020
Bjorn Gustavsson
on 9 Oct 2020
Edited: Bjorn Gustavsson
on 9 Oct 2020
To the best of my understanding you get the extension of the dot-product in that case with a normal matrix-vector-product:
r_nby3 = randn(12,3);
r_1by3 = randn(1,3);
l_nby1 = r_nby3*r_1by3';
Or are you thinking about something completely different?
Paul
on 9 Oct 2020
Rik
on 9 Oct 2020
I suspect one reason is that it might be difficult to distinguish between the case of wrong input and input that should be expanded.
Note that you can still use bsxfun (although I'm not sure how to write the call in this case, it is too complex to write on mobile).
Paul
on 9 Oct 2020
Bjorn Gustavsson
on 10 Oct 2020
I still think it is a dubious case for implicit expansion. If you have r1 [n x 3] and r2 [m x 3] one implicit expansion of the dot might be the outer product r1*r2' givin us all n-by-m dot-products, but that will clash with (at least my) "natural" idea of a dot-product of 2 m-by-3 arrays (which dot already handles if I transpose the arrays) giving us a result that's m-by-1.
Bruno Luong
on 10 Oct 2020
Edited: Bruno Luong
on 10 Oct 2020
I write my own DOT and CROSS (pretty easy, actually I don't do DOT just sum on .* directly is ) that can deal with auto-expansion. That's pretty often encounted when you do geometric calcuation on a bunch of points.
I guess TMW is prudent and don't want to break backward compatibility, which I can understand when I see a few peoples still complain.
To me auto-expansion is one of the most important progress step they made in recent years. It pretty cool, one can make code faster, shorter and more readable.
Paul
on 10 Oct 2020
Bjorn Gustavsson
on 11 Oct 2020
So then your back to one array with size n x 3 and the other 1 x 3 (or some transpose-combination.) - then it is just to figure out which matrix-vector multiplication to do. If you have arrays with sizes n x 3 and n x 3, that's something dot already handles...
Paul
on 11 Oct 2020
Bjorn Gustavsson
on 11 Oct 2020
Yes, "roll your own" is my opinion on this, whenever I've had these cases I've either handled it such that I know which sizes the input-arrays can have and used matrix-vector multiplication, or for cross-products explicit expressions for the cases. Since it is a couple of lines and with operations matlab is supposed to excell at I dont see the gain.
Paul
on 11 Oct 2020
Answers (2)
Walter Roberson
on 9 Oct 2020
Yes, it should be extended to datetime() objects.
>> datetime() + hours(1:5).' + hours(1:3)
Data inputs must be the same size, or any of them can be a scalar.
>> hours(1:5).' + hours(1:3) + datetime()
ans =
5×3 datetime array
09-Oct-2020 19:05:40 09-Oct-2020 20:05:40 09-Oct-2020 21:05:40
09-Oct-2020 20:05:40 09-Oct-2020 21:05:40 09-Oct-2020 22:05:40
09-Oct-2020 21:05:40 09-Oct-2020 22:05:40 09-Oct-2020 23:05:40
09-Oct-2020 22:05:40 09-Oct-2020 23:05:40 10-Oct-2020 00:05:40
09-Oct-2020 23:05:40 10-Oct-2020 00:05:40 10-Oct-2020 01:05:40
>> bsxfun(@plus,(datetime() + hours(1:5)).', hours(1:3))
Error using bsxfun
Operands must be numeric arrays.
6 Comments
Ah, I just ran in R2020b and it looks like this has been done.
datetime() + hours(1:5).' + hours(1:3)
hours(1:5).' + hours(1:3) + datetime()
bsxfun(@plus,(datetime() + hours(1:5)).', hours(1:3))
Rik
on 9 Oct 2020
So this is an example where implicit expansion works, but bsxfun does not? That seems like a very strange choice to me.
Walter Roberson
on 9 Oct 2020
I agree, it is odd!
madhan ravi
on 9 Oct 2020
Wow 😳
Steven Lord
on 9 Oct 2020
Yes, implicit expansion behavior was added to several operators and functions on datetime, duration, and/or calendarDuration in release R2020b.
Paul
on 10 Oct 2020
I wouldn't mind seeing it extended to the colon operator, instead of having to do things like this,
a=2;
b=[5,7,9];
c=arrayfun(@(q)a:q, b,'uni',0); %I'd rather just do a:b
c{:}
8 Comments
Matt J
on 10 Oct 2020
Paul's comment moved here:
This feature would be a bit more than implicit expansion because the color operator is currently not defined, per the doc, for the case:
[2,2,2]:[5,7,9] % see comment below
So first Matlab would have to define what the colon operator means for two non scalar inputs and then implicit expansion could be applied, at least for the two operand case.
Comment: Though the doc says that the operands to the colon operator are scalars, non-scalar inputs don't throw an error (much to my surprise)
>> [2,2,2]:[5,7,9]
ans =
2 3 4 5
So even if implicit expansion was applied and implemented for your example, the output would be different than what Matlab produces today, undocumented as it may be.
Steven Lord
on 10 Oct 2020
That behavior is documented, though not as prominently as it could be. On the documentation page for colon in the second syntax in the Description section: "If you specify nonscalar arrays, then MATLAB interprets j:i:k as j(1):i(1):k(1)."
Paul
on 10 Oct 2020
Bruno Luong
on 10 Oct 2020
I suspect this syntax does not have any interesting use case other than thet fact TMW programmers does not want to bother - or waste time for checking - for non-scalar arguments. This have been discovered and discussed when I prepare this FEX
Walter Roberson
on 10 Oct 2020
In some cases, MATLAB gives warnings for non-scalar arguments to colon.
It is unfortunately not uncommon to see people write something like
for i=1:size(x)
... and when they do, more often than not, it is really the number of columns they want rather than the number of rows...
I don't think I have ever seen a good reason to permit non-scalars in the colon operator.
I don't think I have ever seen a good reason to permit non-scalars in the colon operator.
I suppose I was really thinking that it might be good if combined with automatic comma separated list expansion. So, for example, instead of extracting a sub-array given its lower and upper limit vectors a and b,
M(a(1):2:b(1),a(2):2:b(2),a(3):2:b(3))
I could instead just do,
M(a:2:b)
Steven Lord
on 11 Oct 2020
I'm not completely certain, but I suspect Bruno Luong's answer is close to the mark. The colon operator dates back to a very early version of MATLAB, probably even Cleve's original Fortran MATLAB. I suspect Cleve didn't consider that people would use : with non-scalar values and so didn't check for that.
We've learned since then. Were we to redesign : today, we likely wouldn't allow non-scalar inputs without a good use case.
We've learned since then. Were we to redesign : today, we likely wouldn't allow non-scalar inputs without a good use case.
In addition to the one I raised above, I think that a good case would in the use of griddedInterpolant. Instead of upsampling an array V by doing,
F=griddedInterpolant(V);
[m,n,p]=size(V);
Vq=F({1:0.5:m,1:0.5:n,1:0.5:p})
it would be much more sleek to do,
Vq=F({1:0.5:size(V)})
Categories
Find more on Creating and Concatenating Matrices in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!