DOC: Change vdot
docs to mention computing the standard inner product on a space of matrices
#26342
Labels
vdot
docs to mention computing the standard inner product on a space of matrices
#26342
Issue with current documentation:
The docs for
vdot
in NumPy 1.26 (link here) contain the following verbiage. I've emphasized some problematic text in bold.The bolded text is misleading because it doesn't account for the value of this function in computing the standard inner product on vector spaces of matrices. See below for details on this value in the cases of real and complex data.
Real matrices
If$\mathcal{H}$ the vector space of real $m \times n$ matrices, and $A,B$ are matrices in $\mathcal{H}$ , then their (standard) inner product is $\langle A, B \rangle_{\mathcal{H}} = \text{trace}(A^T B)$ . The naive way to implement this is to write
np.trace(A.T @ B)
. However, you can get the same result much more efficiently withnp.vdot(A, b)
.I see people use the naive method in their code all the time. That's bad, because the complexity difference of the two methods is stark. Here's a table comparing them. (Small disclaimer: I don't know how numpy implements
vdot
in C, but the following figures are easily achievable.)trace(A.T @ B)
vdot(A, B)
Complex matrices
Now suppose$\mathcal{H}$ is the vector space of complex $m \times n$ matrices. The standard inner product of matrices $A,B \in \mathcal{H}$ is $\langle A, B \rangle_{\mathcal{H}} = \text{trace}(A^\dagger B)$ , where $A^{\dagger}$ is the conjugate transpose of $A$ .
Here's a table comparing three ways one might compute this inner product. As before, I'm assuming that
vdot
's C implementation doesn't have any obvious inefficiencies. I'm also assuming that calling.conj()
returns a new (conjugated) array, rather than a view of an existing array.trace(A.T.conj() @ B)
dot(A.conj().ravel(), B.ravel())
vdot(A, B)
Besides the complexity considerations,
vdot
has a secondary advantage: it accounts for the fact that the standard inner product is conjugate-linear in the first argument and linear in the second argument. If someone isn't mindful of where they put the conjugate then it's easy to use the return value from something like `dot(A.conj().ravel(), B.ravel())`` in a way that's incorrect in the context of a larger project.Idea or request for content:
The documentation could be updated to something like the following.
The text was updated successfully, but these errors were encountered: