简体   繁体   中英

Why is the matrix @ product of two numpy (n,) vectors the dot product, rather than the outer product?

If I have x.shape = (n,) and y.shape = (n,), then x @ y returns their dot product, rather than their outer product. I was wondering if there was some underlying reason for this, or if its just for convenience.

Thanks.

Function np.matmul was added when @ operator was introduced to Python. The new function was designed to behave as similar to np.dot as reasonable.

So why np.dot(vector, vector) performs inner product?

Before @ , the function np.dot was used to perform matrix algebra in numpy. Actually, vectors in linear algebra are not 1D arrays but rather matrices with one of dimensions set to 1. In order to multiply 1D array by matrix, the former has to be somehow promoted to either row or column vector. We have 3 cases here:

  • vector by matrix, 1D array is promoted to row vector (1xN) to make operation valid
  • matrix by vector, 1D array is promoted to column vector (Nx1)
  • vector by vector, left operand is promoted to row vector, right to column vector, as in previous both cases

As result in the last case we have a normal inner product between two vectors. This policy is both logical and practical because inner products are used more often.

The wiki article for dot product defines it as

Algebraically, the dot product is the sum of the products of the corresponding entries of the two sequences of numbers.

(it mentions inner product many times, but outer none.)

If you think of 1d arrays as sequences of numbers, then A@B as dot product is natural.

The 2d matrix product can be described as the dot product of all rows of A with the columns of B.

The key term, in both matmul and dot is "sum of the products".

For 1d array, np.sum(A*B) is another expression of the sum of products, where * is elementwise mutiplication.

A (m,1) @ with a (1,n) does produce a (m,n) outer product, but that is actually a 2d matrix product with reduction on the shared size 1 dimensions.

We don't need the 'sum of products' mechanism to do a outer product of two 1d arrays:

In [29]: np.array([1,2,3])[:,None] * np.array([10,100])                         
Out[29]: 
array([[ 10, 100],
       [ 20, 200],
       [ 30, 300]])
In [30]: np.array([1,2,3])[:,None] @ np.array([10,100])[None,:]                 
Out[30]: 
array([[ 10, 100],
       [ 20, 200],
       [ 30, 300]])

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM