7

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?

Wizard
  • 2,720
  • 17
  • 28

1 Answers1

6

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.

Simon Woods
  • 84,945
  • 8
  • 175
  • 324