In python, does `@=` act on the left or the right?
It seems obvious to me that vector @= matrix
ought to mean vector = matrix @ vector
, contrary to the practice with most other binary operators. Unfortunately, any discussion of this is completely omitted from PEP 465; it states only that the @
operator is left-associative, and that the @=
operator corresponds to the __imatmul__
function.
Presumably, the override means that numerical libraries can choose this behavior if they like, but that leaves three closely related question:
- What is the default behavior if
__imatmul__
is not explicitly provided, but__matmul__
and__rmatmul__
are? - What is the behavior intended by the authors of the PEP?
- What behavior have numerical libraries such as numpy chosen to implement?
Like any other augmented assignment operator, x @= y
is an in-place-if-x
-supports-it version of x = x @ y
.
x = y @ x
might have seemed obvious to you, but I don't think anything other than x = x @ y
was ever considered a serious option, and I don't think any major math library has implemented anything like what you expected. sympy.Matrix
implements it as x = x @ y
(non-mutative, no __imatmul__
), and numpy.ndarray
says
TypeError: In-place matrix multiplication is not (yet) supported. Use 'a = a @ b' instead of 'a @= b'.
(Checked with NumPy 1.19.5 and 1.21.5).
Note that NumPy defines a useful meaning for "vector @ matrix" operations. NumPy does not force arrays to be 2D, so the most common vector representation in NumPy is a 1D array, not a column vector. A 1D array will behave like a row vector in a "vector @ matrix" operation, though the result will be 1D instead of a row vector.