Why does numpy.dot behave this way?

I am trying to understand why the numpy function dotbehaves like this:

M = np.ones((9, 9))
V1 = np.ones((9,))
V2 = np.ones((9, 5))
V3 = np.ones((2, 9, 5))
V4 = np.ones((3, 2, 9, 5))

Now np.dot(M, V1)and np.dot(M, V2)behave as expected. But for V3and the V4result is unexpectedly I:

>>> np.dot(M, V3).shape
(9, 2, 5)
>>> np.dot(M, V4).shape
(9, 3, 2, 5)

I expected (2, 9, 5)and (3, 2, 9, 5)accordingly. On the other hand, np.matmul it does what I expect: the matrix is ​​multiplied by the first N - 2 dimensions of the second argument and the result has the same form:

>>> np.matmul(M, V3).shape
(2, 9, 5)
>>> np.matmul(M, V4).shape
(3, 2, 9, 5)

So my question is this: what is the basis for np.dotbehaving as it is? Does it have a specific purpose, or is it the result of applying some general rule?

+4
4

np.dot:

, 1-D - ( ). N a, b:

dot(a, b)[i,j,k,m] = sum(a[i,j,:] * b[k,:,m])

np.dot(M, V3),

(9, 9), (2, 9, 5) --> (9, 2, 5)

np.dot(M, V4),

(9, 9), (3, 2, 9, 5) --> (9, 3, 2, 5)

, .


, np.matmul N- "" 2D-:

.

  • 2-D, .
  • N-D, N > 2, , , , .

, . np.matmul :

for ii in range(V3.shape[0]):
    out1[ii, :, :] = np.dot(M[:, :], V3[ii, :, :])

for ii in range(V4.shape[0]):
    for jj in range(V4.shape[1]):
        out2[ii, jj, :, :] = np.dot(M[:, :], V4[ii, jj, :, :])
+6

numpy.matmul:

matmul dot .

  • .
  • , .

, -, .

, numpy.dot . ,...

b:

dot(a, b)[i,j,k,m] = sum(a[i,j,:] * b[k,:,m])

[: numpy.dot]

() . numpy.dot . , .

+3

einsum:

In [92]: np.einsum('ij,kjm->kim',M,V3).shape
Out[92]: (2, 9, 5)
In [93]: np.einsum('ij,lkjm->lkim',M,V4).shape
Out[93]: (3, 2, 9, 5)

, dot, ij, lkjm- > ilkm ', , "matmul", ij, lkjm- > lkim'.

+1

:

dot matmult - 2D *. , , ,...

dot matmul : enter image description here

dot ( ) , () .

matmul .

Numpy , dot out=dot(image(s),transformation(s)). (. dot docs numpy book, p92).

:

from pylab import *
image=imread('stackoverflow.png')

identity=eye(3)
NB=ones((3,3))/3
swap_rg=identity[[1,0,2]]
randoms=[rand(3,3) for _ in range(6)]

transformations=[identity,NB,swap_rg]+randoms
out=dot(image,transformations)

for k in range(9): 
    subplot(3,3,k+1)
    imshow (out[...,k,:])

so

matmul , dot, . (matmul(image,transformations[:,None]) ).

, .

+1

Source: https://habr.com/ru/post/1617890/