# Take the dot product for each column with itself and store in new array dimension

I need to take the dot-product of each column with the transpose of itself, in a given 2D array. Currently, I am using loops and it is slow and ugly so I am wondering how to do this with pure array operations (if possible) and e.g. using `einsum` and similar tools.

MWE:

``````import numpy as np
A = np.random.randint(2,15,size=(2,3))

>>>A
array([[14,  9,  4],
[12,  8,  2]])
``````

Here’s what I want, including the way I am currently doing it:

``````AA = [A[:,i].reshape(-1,1).dot(A[:,i].reshape(-1,1).T) for i in range(3)]
>>>AA
[array([[196, 168],
[168, 144]]),
array([[81, 72],
[72, 64]]),
array([[16,  8],
[ 8,  4]])]
``````

And finally

``````>>>np.stack(AA,axis=0)
array([[[196, 168],
[168, 144]],

[[ 81,  72],
[ 72,  64]],

[[ 16,   8],
[  8,   4]]])
``````

which has shape `(3,2,2)`.

Now obviously in my real problem, `A` is huge so the current approach is not feasible. Hence how can this be done better?

## Solution

You can use numpy.einsum:

``````import numpy as np
A = np.array([
[14,  9,  4],
[12,  8,  2]
])

np.einsum('ik,jk->kij', A, A)
array([[[196, 168],
[168, 144]],

[[ 81,  72],
[ 72,  64]],

[[ 16,   8],
[  8,   4]]])

`````` ﻿﻿