How can I create a new dimension when adding/multiplying vectors and matrices? (Python and NumPy)

Welcome to Programming Tutorial official website. Today - we are going to cover how to solve / find the solution of this error How can I create a new dimension when adding/multiplying vectors and matrices? (Python and NumPy) on this date .

I would like to compute:

```matrix1 + vector * matrix2
```

where:

```In: matrix1.shape
Out: (3, 3)

In: vector.shape
Out: (15,)

In: matrix2.shape
Out: (3, 3)
```

I did it this way:

```answer = []
for i in vector:
answer_i = matrix1 + i * matrix2
```

So, I get a list of len(vector) in which each answer is shape (3,3). I wonder how to do the exact same thing, but without “for” loop and with NumPy arrays. The answer would be an array of shape (3, 3, 15). The answer may be simple but I don’t have a lot of experience.

For example:

```In: matrix1
Out: array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])

In: vector
Out: array([-7., -6., -5., -4., -3., -2., -1.,  0.,  1.,  2.,  3.,  4., 5., 6.,  7.])

In: matrix2
Out: array([[ 5,  5,  5],
[10, 10, 10],
[20, 20, 20]])
```

My output (a list of len 15 for now):

```[array([[ -34.,  -33.,  -32.],
[ -66.,  -65.,  -64.],
[-133., -132., -131.]]),
array([[ -29.,  -28.,  -27.],
[ -56.,  -55.,  -54.],
[-113., -112., -111.]]),
array([[-24., -23., -22.],
[-46., -45., -44.],
[-93., -92., -91.]]),
array([[-19., -18., -17.],
[-36., -35., -34.],
[-73., -72., -71.]]),
array([[-14., -13., -12.],
[-26., -25., -24.],
[-53., -52., -51.]]),
array([[ -9.,  -8.,  -7.],
[-16., -15., -14.],
[-33., -32., -31.]]),
array([[ -4.,  -3.,  -2.],
[ -6.,  -5.,  -4.],
[-13., -12., -11.]]),
array([[1., 2., 3.],
[4., 5., 6.],
[7., 8., 9.]]),
array([[ 6.,  7.,  8.],
[14., 15., 16.],
[27., 28., 29.]]),
array([[11., 12., 13.],
[24., 25., 26.],
[47., 48., 49.]]),
array([[16., 17., 18.],
[34., 35., 36.],
[67., 68., 69.]]),
array([[21., 22., 23.],
[44., 45., 46.],
[87., 88., 89.]]),
array([[ 26.,  27.,  28.],
[ 54.,  55.,  56.],
[107., 108., 109.]]),
array([[ 31.,  32.,  33.],
[ 64.,  65.,  66.],
[127., 128., 129.]]),
array([[ 36.,  37.,  38.],
[ 74.,  75.,  76.],
[147., 148., 149.]])]
```

I would like the output to be an array of shape (3, 3, 15).

```In [1]: m1 = np.arange(1,10).reshape(3,3)
In [2]: vector = np.array([-7., -6., -5., -4., -3., -2., -1.,  0.,  1.,  2.,  3.
...: ,  4., 5., 6.,  7.])
In [4]: m2 = np.array([5,10,20])[:,None]+np.zeros(3,int)
In [5]: m2
Out[5]:
array([[ 5,  5,  5],
[10, 10, 10],
[20, 20, 20]])
In [6]: vector.shape
Out[6]: (15,)
```

`np.array(answer)` will produce a (15,3,3) array. With `numpy` broadcasting, we can get the same with:

```In [12]: (m1+vector[:,None,None]*m2)
Out[12]:
array([[[ -34.,  -33.,  -32.],
[ -66.,  -65.,  -64.],
[-133., -132., -131.]],

[[ -29.,  -28.,  -27.],
[ -56.,  -55.,  -54.],
[-113., -112., -111.]],

...

[[  36.,   37.,   38.],
[  74.,   75.,   76.],
[ 147.,  148.,  149.]]])
```

`vector` becomes (15,1,1) and the `m's` (1,3,3) to match, together making (15,3,3).

But if you want the (15,) `vector` dimension to be last we need to do:

```In [13]: (m1[:,:,None]+vector*m2[:,:,None])
Out[13]:
array([[[ -34.,  -29.,  -24.,  -19.,  -14.,   -9.,   -4.,    1.,    6.,
11.,   16.,   21.,   26.,   31.,   36.],
[ -33.,  -28.,  -23.,  -18.,  -13.,   -8.,   -3.,    2.,    7.,
12.,   17.,   22.,   27.,   32.,   37.],
[ -32.,  -27.,  -22.,  -17.,  -12.,   -7.,   -2.,    3.,    8.,
13.,   18.,   23.,   28.,   33.,   38.]],
...
[-131., -111.,  -91.,  -71.,  -51.,  -31.,  -11.,    9.,   29.,
49.,   69.,   89.,  109.,  129.,  149.]]])
```

Here the broadcasting is (3,3,1) with (15,) => (3,3,15)

We could have also applied a transpose to the first case, changing the (15,3,3) shape to (3,3,15):

```(m1+vector[:,None,None]*m2).transpose(1,2,0)
```

Another way is to join the 15 arrays on a new last axis.

```np.stack(answer, axis=2)
```