help-octave
[Top][All Lists]

## Re: Meaning of * (mtimes) for nd-arrays

 From: Nicholas Jankowski Subject: Re: Meaning of * (mtimes) for nd-arrays Date: Tue, 16 Feb 2016 14:13:58 -0500

On Tue, Feb 16, 2016 at 2:02 PM, Juan Pablo Carbajal wrote:
On Tue, Feb 16, 2016 at 6:55 PM, Nicholas Jankowski <address@hidden> wrote:
> On Mon, Feb 15, 2016 at 8:01 AM, Juan Pablo Carbajal <address@hidden>
> wrote:
>>
>>
>>
>> On Mon, Feb 15, 2016 at 10:53 AM, Marco Atzeri <address@hidden>
>> wrote:
>>>
>>> On 15/02/2016 10:41, Marco Caliari wrote:
>>>>
>>>> Dear all,
>>>>
>>>> I recently discovered that [1;2;3;4]*ones(1,1,3), for instance, gives a
>>>> four-by-three matrix. I would have expected an error (like in Matlab) or
>>>> a four-by-one-by-three array. So, what is the definition? Is it just
>>>> squeeze("outer product")? Is it documented? A similar thing happens with
>>>> kron.
>>>>
>>>> Thanks,
>>>>
>>>> Marco
>>>>
>>>
>>>
>>>
>>>
>>> _______________________________________________
>>> Help-octave mailing list
>>> https://lists.gnu.org/mailman/listinfo/help-octave
>>
>>
>> [1;2;3;4] * ones(1,1,3) is the same as [1;2;3;4] * ones(1,3) and is not
>> boradcasting. It is simply applying the rule of multiplication in matrices
>> by ignoring the leading singletons. I think matlab would do the same, can
>> you verify?
>>
>> Boradcasting would be produce the same as
>>
>> bsxfun(@mtimes,[1;2;3;4],ones(1,1,3))
>>
>> which is shortened in Octave (and not in matlab) with
>>
>> [1;2;3;4] .* ones(1,1,3)
>>
>
> was playing with nD arrays a bit last summer and this caught my eye.
>
> ones(1,1,3) is not the same as ones(1,3).  it produces a 1x1x3 array,
> whereas the latter produces a 1x3 array  (ones does not apply a squeeze or
> anything to force 2D)
>
> in Matlab:
>
>>> [1;2;3;4] * ones(1,1,3)
> Error using *
> Inputs must be 2-D, or at least one input must be scalar.
> To compute elementwise TIMES, use TIMES (.*) instead.
>
>
>>> [1;2;3;4] * ones(1,3)
> ans =
> 1 1 1
> 2 2 2
> 3 3 3
> 4 4 4
>
>>> bsxfun(@mtimes,[1;2;3;4],ones(1,1,3))
>
> ans(:,:,1) =
>  1
>  2
>  3
>  4
>
> ans(:,:,2) =
>  1
>  2
>  3
>  4
>
> ans(:,:,3) =
>  1
>  2
>  3
>  4
>
> (which is the same output in octave using .* as you said)
>
> ALL THAT SAID...
>
> In Octave:
>
>>> [1;2;3;4]*ones(1,1,3)
>
> ans =
>
>    1   1   1
>    2   2   2
>    3   3   3
>    4   4   4
>
>
> so there's something off here.
>
> Nick J

one(1,1,3) is not the same as one(1,3). I never said the oposite. The
behavior when multiplying by a vector is what is equivalent (it seems
only in Octave). You see, a singleton left dimension is rather
useless...but I grant that one could stick to that. But as Jordi
mentioned many times there are plenty of generalizations, e.g.
if (n x 1) * (1 x m) gives n x m, then  (n x 1) * (1 x 1 x m) gives (1
x n x m), or (n x 1 x m), or (n x m)? note, tat the last one is the
"squeeze" of the first one and it seems what the programmer chose.

So I guess we will have to stick to matlab idiosyncrasy and fix this
to give an error... anyways, is this the results of broadcasting? No
way of checking the Octave:broadcast warning anymore, but I wouldn't
think so.

Yes, sorry I was being a bit pedantic on that. I figured you knew the difference but I was just being explicit.

In any case, I'd argue that a singleton left dimension is not completely useless. I put a model together last year that made heavy use of n-vectors to orthogonalize the process. Combined with broadcasting, it made bookkeeping rather straight forward with dims 1 and 2 being the 2x2 transfer functions, 3 being the spatial degree of freedom, 4 being the eigenvalue d.o.f., 5 being ... something else.

In any case, almost no basic matrix functions accept anything with ndims ~= 2. I think some people have written n-D array functions, but the base * should throw an error rather than squeeze the user's data for them. I wouldn't think broadcasting would be to blame here, as it shouldn't come up without invoking .*  , should it?

nickj