Page MenuHome

Python: Add support for @ infix operator matrix multiplication
Closed, ResolvedPublicTO DO

Description

This subtask is to add support for the @ infix operator in python for matrix multiplication. The following combinations are permitted:

  • Matrix @ Matrix
  • Matrix @ Vector (vector interpreted as column vector)
  • Vector @ Matrix (vector interpreted as row vector)
  • Vector @ Vector (dot product)
  • Quaternion @ Quaternion (cross product)
  • Quaternion @ Vector

The subtask also covers element-wise multiplication but will be disabled. This will allow current usage of * for matrix multiplication in scripts to be identified and transitioned before the change to element-wise multiplication is introduced. A notable exception to this is that constant * matrix/vector/quaternion (and vice versa) is still permitted. The combinations to be supported are:

  • Matrix * Matrix
  • Vector * Vector
  • Vector *= Vector
  • Quaternion * Quaternion (is this useful?)
  • Float * Matrix/Vector/Quaternion
  • Matrix/Vector/Quaternion * Float

Event Timeline

Andrew Hale (trumanblending) lowered the priority of this task from 90 to Normal.Aug 8 2018, 5:00 PM
Andrew Hale (trumanblending) created this task.
Andrew Hale (trumanblending) created this object with edit policy "Moderators (Project)".

Not sure why that’s assigned to me… Guess @Campbell Barton (campbellbarton) will want to check on that?

I suggest to leave this one out, since Blender uses column vector convention. Having it, could confuse people as to the order of multiplication of the matrices.
Vector @ Matrix (vector interpreted as row vector)

This one usually goes component-wise in shading languages.
Vector @ Vector (dot product)
I think it can be potentially confusing which operation it does ( I would write dot or cross explicitly always and for component-wise I wouldn't even know what to write, since that's usually the default.) You wouln't use vector-vector multiplication inline with matrix multiplications of transform code.

@Inês Almeida (brita_) / @Andrew Hale (trumanblending), what about following numpy conventions for cases which are disputable?

@Inês Almeida (brita_) / @Campbell Barton (campbellbarton)

As per review comments on D3587, I've also implemented:

  • matrix @= matrix
  • matrix *= matrix/float
  • quat @= quat
  • quat *= quat/float

@Inês Almeida (brita_) / @Andrew Hale (trumanblending), what about following numpy conventions for cases which are disputable?

This seems like a reasonable approach. See below code, both numpy and mathutils produce the dot product for vector @ vector. Eventually element-wise multiplication will be exposed using vector * vector which matches numpy.

import numpy as np
from mathutils import Vector as V

np_vec = np.array([1, 2, 3], dtype=np.float32)
print(np_vec @ np_vec)

mu_vec = V(np_vec)
print(mu_vec @ mu_vec)

I suggest to leave this one out, since Blender uses column vector convention. Having it, could confuse people as to the order of multiplication of the matrices.
Vector @ Matrix (vector interpreted as row vector)

The current API allows for matrix * vector and vector * matrix, so it shouldn't introduce any additional confusion. Both are valid in numpy and produce the same results as mathutils (see below). Are we happy to maintain the status quo and allow both?

import numpy as np
from mathutils import Vector as V, Matrix as M

mu_vec = V((1, 2, 3))
mu_mat = M.Rotation(1, 3, 'Y')
print("mathutils: m@v", mu_mat @ mu_vec)
print("mathutils: m@v", mu_vec @ mu_mat)

np_vec = np.array(mu_vec, dtype=np.float32)
np_mat = np.array(mu_mat, dtype=np.float32)
print("numpy: m@v", np_mat @ np_vec)
print("numpy: v@m", np_vec @ np_mat)

If at least vector * vector doesn't do a dot product, I'm happy ^^
I wasn't aware of the @ possibility and I am also not familiar with numpy, but it definitely sounds like a good idea to follow a similar convention :)

Andrew Hale (trumanblending) changed the task status from Unknown Status to Resolved.Aug 10 2018, 3:29 PM

Implemented in rBaa5a96430ea0

Note that this is now enabled in master (for 2.90 release).