5 Best Ways to Get the Inner Product of Two Multidimensional Arrays in Python

πŸ’‘ Problem Formulation: Calculating the inner (or dot) product of multidimensional arrays is a fundamental operation in linear algebra. It’s frequently used in machine learning, physics, and engineering applications. The inner product generalizes the notion of the dot product to higher dimensions and reflects the cosine of the angle between two vectors along with their magnitudes. Given two compatible arrays A and B, we aim to find their inner product which results in a single number or a new array depending on their dimensions.

Method 1: Using NumPy’s dot function

The numpy.dot() function calculates the dot product of two arrays. It can handle 2D arrays or matrices and higher-dimensional arrays, given that the last axis of the first array (a) and the second-to-last of the second array (b) have the same size.

Here’s an example:

import numpy as np

a = np.array([[1, 2], [3, 4]])
b = np.array([[5, 6], [7, 8]])

result = np.dot(a, b)

Output:

[[19 22]
 [43 50]]

This piece of code imports NumPy to be used for matrix operations. The two arrays a and b represent matrices with dimensions 2×2. The numpy.dot() function is then used to compute their inner product, which results in another 2×2 matrix containing the sum of products for corresponding elements.

Method 2: Using NumPy’s matmul function

NumPy’s numpy.matmul() function is similar to numpy.dot() but is more explicit for matrix multiplication and is preferred since Python 3.5. It enforces the rules of matrix multiplication and does not allow multiplication of arrays that do not follow these rules.

Here’s an example:

import numpy as np

a = np.array([[1, 2], [3, 4]])
b = np.array([[5, 6], [7, 8]])

result = np.matmul(a, b)

Output:

[[19 22]
 [43 50]]

Here we use the numpy.matmul() function to perform matrix multiplication on the 2×2 arrays a and b. The result is identical to the previous example, but matmul makes the intention of matrix multiplication more explicit.

Method 3: Using NumPy’s einsum function

The numpy.einsum() function provides an Einstein summation convention to calculate the inner product of two arrays. It’s a powerful function that can perform a variety of array operations, including multiplication and summing specific indices of multidimensional arrays.

Here’s an example:

import numpy as np

a = np.array([[1, 2], [3, 4]])
b = np.array([[5, 6], [7, 8]])

result = np.einsum('ij,jk', a, b)

Output:

[[19 22]
 [43 50]]

This code uses the numpy.einsum() function for specifying dimensions to be multiplied and summed over. It’s a more advanced method and allows for more control and potential optimization in complex operations. Here, ‘ij’ refers to the indices of the first array and ‘jk’ to those of the second array. The function thus sums over the common index ‘j’.

Method 4: Using a Manual Approach with List Comprehensions

A manual approach to calculating inner product involves using nested list comprehensions and summing the products of corresponding elements. This method does not require any additional libraries but is not the most efficient for large data sets.

Here’s an example:

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

result = [[sum(x * y for x, y in zip(row, col)) for col in zip(*b)] for row in a]

Output:

[[19 22]
 [43 50]]

The code snippet uses list comprehension to manually compute the dot product of two lists of lists, which represent matrices. It zips together individual rows of the first matrix with columns of the second matrix, multiplies the corresponding elements, and sums them to produce the result.

Bonus One-Liner Method 5: Using NumPy’s @ Operator

Python 3.5 introduced the matrix multiplication operator @, which when used with NumPy arrays, calculates the inner product in a concise and readable way. It is equivalent to using the numpy.matmul() function.

Here’s an example:

import numpy as np

a = np.array([[1, 2], [3, 4]])
b = np.array([[5, 6], [7, 8]])

result = a @ b

Output:

[[19 22]
 [43 50]]

With Python’s @ operator, we get a one-liner that performs matrix multiplication. The operands a and b are NumPy arrays and their matrix multiplication is represented simply as a @ b. This method provides a high level of readability and conciseness.

Summary/Discussion

  • Method 1: NumPy’s dot function. Best for backward compatibility; operates on two or more dimensions. Can be less explicit compared to matmul when working solely with matrices.
  • Method 2: NumPy’s matmul function. Preferred for matrix multiplication; explicit and avoids ambiguity. Cannot be used for higher-dimensional array (tensor) contraction.
  • Method 3: NumPy’s einsum function. Versatile and can optimize operations; perfect for complex tensor algebra operations. It may have a steeper learning curve for new users.
  • Method 4: Manual list comprehensions. No dependencies needed; good for understanding inner workings. Inefficient and non-idiomatic for larger datasets and arrays.
  • Bonus One-Liner Method 5: NumPy’s @ operator. Concise and Pythonic; ideal for matrix multiplication readability. Available only in newer Python versions (3.5+).