# Difference between numpy dot() and Python 3.5+ matrix multiplication @

I recently moved to Python 3.5 and noticed the new matrix multiplication operator (@) sometimes behaves differently from the numpy dot operator. In example, for 3d arrays:

```
import numpy as np
a = np.random.rand(8,13,13)
b = np.random.rand(8,13,13)
c = a @ b # Python 3.5+
d = np.dot(a, b)
```

The `@`

operator returns an array of shape:

```
c.shape
(8, 13, 13)
```

while the `np.dot()`

function returns:

```
d.shape
(8, 13, 8, 13)
```

How can I reproduce the same result with numpy dot? Are there any other significant differences?

The `@`

operator calls the array's `__matmul__`

method, not `dot`

. This method is also present in the API as the function `np.matmul`

.

```
>>> a = np.random.rand(8,13,13)
>>> b = np.random.rand(8,13,13)
>>> np.matmul(a, b).shape
(8, 13, 13)
```

From the documentation:

`matmul`

differs from`dot`

in two important ways.

- Multiplication by scalars is not allowed.
- Stacks of matrices are broadcast together as if the matrices were elements.

The last point makes it clear that `dot`

and `matmul`

methods behave differently when passed 3D (or higher dimensional) arrays. Quoting from the documentation some more:

For `matmul`

:

If either argument is N-D, N > 2, it is treated as a stack of matrices residing in the last two indexes and broadcast accordingly.

For `np.dot`

:

For 2-D arrays it is equivalent to matrix multiplication, and for 1-D arrays to inner product of vectors (without complex conjugation).

For N dimensions it is a sum product over the last axis of a and the second-to-last of bFrom: stackoverflow.com/q/34142485