6
$\begingroup$

I want to add two matrices, the first one containing a 2D vector at each position the other one a list of 2D vectors. The 2D vector from the first matrix should be added to each of the 2D vectors at the same position in the other matrix. The way I know of is using MapThread, but is there a faster way?

So basically I have two matrices defined like this:

MA = Table[RandomReal[], {i, 10}, {j, 10}, {k, 2}];
MB = Table[RandomReal[], {i, 10}, {j, 10}, {k, 3}, {l, 2}];

The output of MA+MB should be Mout[[i,j]] = {MA[[i,j]]+MB[[i,j,1]],MA[[i,j]]+MB[[i,j,1]],MA[[i,j]]+MB[[i,j,1]]} for each pair of indices i,j.

The one method I am using right now is a combination of MapThread and Map:

Mout = MapThread[Function[{x,y},x+#&/@y],{MA,MB},2]

This works but is rather slow. Is there a faster and maybe more elegant way to do this?

$\endgroup$
6
$\begingroup$

A fast way to do it is to transpose MB to swap levels 3 and 4. Plus will then automatically thread over the arrays, after which you transpose back again:

Mout = Transpose[MA + Transpose[MB, {1, 2, 4, 3}], {1, 2, 4, 3}];

In the question Kuba linked to, my smartThread function attempts to automate this method. You would use it like this:

Mout = smartThread[MA + MB, 1];

However, this is slower than the explicit Transpose code above.

$\endgroup$
  • $\begingroup$ As speed is important I will stick to the proposed Tranposition Method. Thank you. $\endgroup$ – Wizard Oct 16 '13 at 19:51

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.