27

What is the syntax to add a vector v1 to each vector in a list of vectors v2?

I know it has to be simple, but I really have searched and not found it.

v1 = {a, b, c}
v2 = {{d, e, f}, {g, h, i}, {j, k, l}}

i.e., sum them in a way to give:

{{a + d, b + e,c + f}, {a + g, b + h, c + i}, {a + j, b + k, c + l}}
DrBubbles
  • 1,391
  • 9
  • 17

10 Answers10

30

I recommend using Transpose twice since it is more efficient than other approaches. Moreover Plus has the Listable attribute, thus one need not map Plus over a list (vector).

Transpose[v1 + Transpose[v2]]
{{a + d, b + e, c + f}, {a + g, b + h, c + i}, {a + j, b + k, c + l}}

Having said that remember that one can rewrite it very concisely in the Front-End: Esc tr Esc :

enter image description here

Artes
  • 57,212
  • 12
  • 157
  • 245
  • Hah, clearly my knowledge of Inner isn't well enough entrenched yet. I failed to notice that my Inner effectively simplified to Transpose @* Plus! – Patrick Stevens Sep 19 '15 at 22:28
  • @ciao Thanks, unfortunately someone unupvoted my answer (it was edited) so I guess it is inadvisable to improve posts. – Artes Sep 20 '15 at 00:23
  • 3
    @Artes Of course it is advisable to improve posts! – Dr. belisarius Sep 20 '15 at 18:24
  • 1
    In similar contexts ... While I use Transpose all the time - for intuitive clarity and readability, sometimes one can get faster performance using Part and All in its place ... just FYI testData = Table[{{i, 2 i}, 3 i}, {i, 1000000}]; Print@Timing[ Length[ Last[ Transpose[testData]]]]; Print@Timing[ Length[ Part[ testData, All, 2]]]; Print@Timing[ Length[ testData[[ All, 2]]]]; – Mark Samuel Tuttle Sep 23 '15 at 13:32
17

To achieve what you need requires to distribute the sum over v2:

(v1 + # &) /@ v2

which is a short form of:

Map[ v1 + # &, v2 ]
user8074
  • 1,592
  • 8
  • 7
10

Alternative method using the magic that is Inner:

Inner[Plus, {a, b, c}, Transpose@{{d, e, f}, {g, h, i}, {j, k, l}}, List]
Patrick Stevens
  • 6,107
  • 1
  • 16
  • 42
10

Also:

Plus @@@ Thread[{v1, v2}, List, {2}]
SquareOne
  • 7,575
  • 1
  • 15
  • 34
6

Using Outer is also an efficient approach, in some cases faster than using Transpose twice, the undocumented function Statistics`Library`MatrixRowTranslate may be the fastest

v1 = RandomReal[1, 10^5];
v2 = RandomReal[1, {10^3, 10^5}];

r1 = Transpose[v1 + Transpose[v2]]; // RepeatedTiming r2 = Outer[Plus, {v1}, v2, 1][[1]]; // RepeatedTiming r3 = Block[{res=v2}, StatisticsLibraryMatrixRowTranslate[res, v1]; res]; // RepeatedTiming

r1===r2===r3

Output

{0.541983, Null}
{0.446791, Null}
{0.241258, Null}
True

Related link:
Improving Map Function on Lists

Elegant operations on matrix rows and columns

chyanog
  • 15,542
  • 3
  • 40
  • 78
6

I couldn't resist adding this:

TranslationTransform[v1] /@ v2
J. M.'s missing motivation
  • 124,525
  • 11
  • 401
  • 574
5

In versions 13.1+ you can wrap v1 with Threaded:

Threaded[v1] + v2
{{a + d, b + e, c + f}, {a + g, b + h, c + i}, {a + j, b + k, c + l}}
kglr
  • 394,356
  • 18
  • 477
  • 896
4
Total[Tuples[{{v1}, v2}], {2}]
 {{a + d, b + e, c + f}, {a + g, b + h, c + i}, {a + j, b + k, c + l}}
Distribute[{{v1}, v2}, List, List, List, Plus]
 {{a + d, b + e, c + f}, {a + g, b + h, c + i}, {a + j, b + k, c + l}}
kglr
  • 394,356
  • 18
  • 477
  • 896
2

In versions 13.1+ you can use ReplaceAt:

ReplaceAt[{v2}, _ -> Map[#1 + v1 &], 0]

({{a + d, b + e, c + f}, {a + g, b + h, c + i}, {a + j, b + k, c + l}})

E. Chan-López
  • 23,117
  • 3
  • 21
  • 44
2

Here was my first thought...

ConstantArray[v1, 3] + v2

or more generally

ConstantArray[v1, Length[v2]] + v2
bill s
  • 68,936
  • 4
  • 101
  • 191