The NumPy matmul() and dot() Functions are Too Helpful

Sometimes the functions in a code library can be too helpful. I like Python and Numpy, but the matmul() and dot() functions are mildly annoying to me because they try to be too versatile.

Let me explain.

The dot() function is massively overloaded to allow different forms of matrix multiplication, and matmul() allows you to pass a matrix and a vector as arguments.

The dot() function should be the simple mathematical vector dot product function that accepts two vectors that have the same length and returns the sum of the products of the elements. For example, if v1 = (2.0, 6.0, 1.0) and v2 = (3.0, 0.0, 4.0) then dot(v1, v2) = (2 * 3) + (6 * 0) + (1 * 4) = 10.0. But for reasons that are unknown to me, the dot() function allows you to pass two matrices, or a matrix and a vector, in which case dot() performs matrix multiplication. This is not helpful, it’s just confusing (at least to me).

To add to the messiness, the dot() function also allows you to pass a vector and a scalar and the result is scalar multiplication. For example dot([2, 5, 1], 3) = [6, 15, 3].

The matmul() function should be ordinary mathematical matrix multiplication that accepts two matrices that are conformable (the number of columns of the first matrix equals the number of rows of the second matrix). For example, if A is 3×4, and B is 4×5, then A * B is 3×5. But for reasons that are unknown to me, the Python matmul() function allows you to pass a matrix and a vector, and the result is a vector. This is not helpful, it’s just confusing.

By the way, I’m also mildly irked that matmul(A, B) can be written as A @ B, and A * B is element-wise multiplication, but that’s another topic.

In the end, it is what it is. Every programming language and code library has quirks that must be worked with.



I’m not a fan of massively overloaded library functions like the NumPy dot() function. But massively overloaded musical instruments are another matter.

This is a screenshot from the “Pipe Dream” video by the amazing animusic.com company. It’s hard to describe unless you’ve seen some of these remarkable videos. This particular animation was made circa 1999. Balls come flying out of the pipes and land on all kinds of sub-instruments and play a wonderful song. Sadly, it seems like animusic is no longer an active company.


Demo code:

# matmul_vs_dot.py

import numpy as np

print("\nBegin matmul() vs dot() ")

A = np.array(
  [[3.0, 5.0, 1.0, 2.0],
   [4.0, 0.0, 9.0, 1.0],
   [6.0, 8.0, 7.0, 5.0]],
  dtype=np.float32)  # 3x4
print("\nA = ")
print(A)

v = np.array([11.0, 14.0, 10.0, 12.0],
  dtype=np.float32)
print("\nv = ")
print(v)

w = np.array([2.0, 3.0, 4.0],
  dtype=np.float32)
print("\nw = ")
print(w)

Av = np.matmul(A, v)  # 3x4 * 4
print("\nmatmul(A, v) = ")
print(Av)  # [137. 146. 308.]

Av = np.dot(A, v)
print("\ndot(A, v) = ")
print(Av)  # [137. 146. 308.]

wA = np.matmul(w, A)  # 3 * 3x4
print("\nmatmul(w, A) = ")
print(wA) # [42. 42. 57. 27.]

v2 = np.dot(v, 2)
print("\ndot(v, 2) = ")
print(v2);  # [22. 28. 20. 24.]

# w = v.reshape(4,1)
# Aw = np.matmul(A, w)  # 3x4 * 4x1 = 3x1
# print(Aw)
# [[137.], [146.], [308.]]  # 3x1

# vA = np.matmul(v, A)  # error
# print(vA)

# x = np.dot(v, 2*v)
# print(x)  # 1122.0

print("\nEnd program ")
This entry was posted in Machine Learning. Bookmark the permalink.

Leave a Reply