blaz - 1 year ago 207

Python Question

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

`@`

`c.shape`

(8, 13, 13)

while the

`np.dot()`

`d.shape`

(8, 13, 8, 13)

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

Answer Source

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 b