cdahms
cdahms

Reputation: 3760

How does NumPy calculate inner product of two 2D matrices?

I'm unable to understand how NumPy calculates the inner product of two 2D matrices.

For example, this program:

mat = [[1, 2, 3, 4],
       [5, 6, 7, 8]]

result = np.inner(mat, mat)

print('\n' + 'result: ')
print(result)
print('')

produces this output:

result: 
[[ 30  70]
 [ 70 174]]

How are these numbers calculated ??

Before somebody says "read the documentation" I did, https://numpy.org/doc/stable/reference/generated/numpy.inner.html, it's not clear to me from this how this result is calculated.

Before somebody says "check the Wikipedia article" I did, https://en.wikipedia.org/wiki/Frobenius_inner_product shows various math symbols I'm not familiar with and does not explain how a calculation such as the one above is performed.

Before somebody says "Google it", I did, most examples are for 1-d arrays (which is an easy calculation), and others like this video https://www.youtube.com/watch?v=_YtHyjcQ1gw produce a different result than NumPy does.

Any clarification would be greatly appreciated.

Upvotes: 0

Views: 180

Answers (2)

hpaulj
hpaulj

Reputation: 231540

In [55]: mat = [[1, 2, 3, 4],
    ...:        [5, 6, 7, 8]]
    ...: 
In [56]: arr = np.array(mat)

In [58]: arr.dot(arr.T)
Out[58]: 
array([[ 30,  70],
       [ 70, 174]])

That's a matrix product of a (2,4) with a (4,2), resulting in a (2,2). This is the usual 'scan across the columns, down the rows' method.

A couple of other expressions that do this:

I like the expressiveness of einsum, where the sum-of-products is on the j dimension:

In [60]: np.einsum('ij,kj->ik',arr,arr)
Out[60]: 
array([[ 30,  70],
       [ 70, 174]])

With broadcasted elementwise multiplication and summation:

In [61]: (arr[:,None,:]*arr[None,:,:]).sum(axis=-1)
Out[61]: 
array([[ 30,  70],
       [ 70, 174]])

Without the sum, the products are:

In [62]: (arr[:,None,:]*arr[None,:,:])
Out[62]: 
array([[[ 1,  4,  9, 16],
        [ 5, 12, 21, 32]],

       [[ 5, 12, 21, 32],
        [25, 36, 49, 64]]])

Which are the values you discovered.

Upvotes: 1

cdahms
cdahms

Reputation: 3760

I finally found this site https://www.tutorialspoint.com/numpy/numpy_inner.htm which explains things a little better. The above is computed as follows:

(1*1)+(2*2)+(3*3)+(4*4)     (1*5)+(2*6)+(3*7)+(4*8)
  1  +  4  +  9  + 16         5  + 12  + 21  + 32
         = 30                        = 70

(5*1)+(6*2)+(7*3)+(8*4)     (5*5)+(6*6)+(7*7)+(8*8)
  5  + 12  + 21  + 32        25  + 36  + 49  + 64
         = 70                        = 174

Upvotes: 0

Related Questions