3

I have the following problem and can not think of a way around without for loops.

Consider two matrices:

a=rand(N,3), b=rand(3,N)

What I want to get is: b(:, i)*a(i, :) (a 3*3 matrix) concatenated in the third dimension for all i.

Thus for the above example the result should be a (3*3*N) matrix.

jez
  • 14,867
  • 5
  • 37
  • 64
Paramar
  • 287
  • 1
  • 5
  • 22
  • No it is `(3x1)*(1x3) -> 3x3` b has N columns which are vectors 3x1 and a has N rows which are vectors 1x3 – Paramar Feb 13 '17 at 15:37
  • I am sure there is a very nice solution using `kron` and `reshape` but I can not figure it out. Else just loop it – Ander Biguri Feb 13 '17 at 15:42
  • Are you sure the correction you made is correct? I think it is a multiplication of a 1x3 x 3x1 ->1x1. By the way the kronecker product seems to make more computations than necessary here. You can see it from their dimensions 3x3xN and 3Nx3N. – Paramar Feb 13 '17 at 15:53
  • You are absolutely right, I apologize. I would just loop this, it seems the most straightforward solution and MATLAB has gotten quite good in computational times with loops – Ander Biguri Feb 13 '17 at 15:57
  • This would allow you to do it efficiently in one line: https://www.mathworks.com/matlabcentral/fileexchange/16275-tprod-arbitary-tensor-products-between-n-d-arrays – jez Feb 13 '17 at 16:05

1 Answers1

7

Matlab R2016b version:

c = reshape(a.',[1,3,N]) .* reshape(b,[3,1,N]);

Earlier Matlab versions:

c = repmat(reshape(a.',[1,3,N]),[3,1,1]) .* repmat(reshape(b,[3,1,N]),[1,3,1]);

edit: Here is a quick benchmark on Matlab R2016b (Win7x64). Speedup of vectorization is around a factor of 50.

Benchmark on R2016b (Win7x64)

Florian
  • 1,804
  • 2
  • 9
  • 19
  • 1
    ah! exploiting broadcasting! neat. – Ander Biguri Feb 13 '17 at 17:56
  • @AnderBiguri What is broadcasting? Never heard of it before. Is [this](https://mathworks.com/help/distcomp/broadcast-variables.html) the definition? Just curious. Thanks. – codeaviator Feb 13 '17 at 23:50
  • 1
    @Cebri No its not, and maybe officially MATLAB uses another name for it, broadcasting is definitely the one used in Python. I could explain but [this python tutorial](https://docs.scipy.org/doc/numpy/user/basics.broadcasting.html) is very nice. In MATLAB < 2016b this would be a `matrix dimensions mismatch` but now MATLAB can deal with it. In short, when matrices are not the same size one of them is repeated as many times as needed automatically – Ander Biguri Feb 14 '17 at 10:32
  • 2
    In Matlab parlance, it is called Binary Singleton Expansion. From R2016 onward, Matlab does it automatically, before you had to call `bsxfun` or use `repmat` like I did. – Florian Feb 14 '17 at 11:44
  • @AnderBiguri & Florian Thanks a lot for the info guys, I understand it now. I learnt something new today. Nice answer! – codeaviator Feb 14 '17 at 16:43
  • Broadcasting starts from 2016**b**. Also, in earlier versions, it appears that [`bsxfun` is a quicker solution](http://stackoverflow.com/questions/29719674/comparing-bsxfun-and-repmat). – EBH Feb 15 '17 at 11:49