Python: Add support for @ infix operator matrix multiplication #56276

Closed
opened 2018-08-08 17:00:18 +02:00 by Andrew Hale · 9 comments
Member

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
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
Bastien Montagne was assigned by Andrew Hale 2018-08-08 17:00:18 +02:00
Author
Member
Added subscribers: @truman, @brita, @NumesSanguis-3, @JacquesLucke, @intrah, @gfxcoder, @vitorbalbio-3, @nathanvollmer, @monique, @Jeroen-Bakker, @lvxejay, @jta, @bliblubli, @Januz, @satishgoda1, @KerimBorchaev, @RayMairlot, @Ko, @Sergey, @VukGardasevic, @mano-wii, @JamesCrowther, @StephenSwaney, @jasperge-2, @dfelinto, @BrianSavery, @dr.sybren, @tetha.z, @MikeErwin, @BrendonMurphy, @mont29, @ideasman42
Bastien Montagne removed their assignment 2018-08-08 20:21:36 +02:00
Campbell Barton was assigned by Bastien Montagne 2018-08-08 20:21:36 +02:00

Not sure why that’s assigned to me… Guess @ideasman42 will want to check on that?

Not sure why that’s assigned to me… Guess @ideasman42 will want to check on that?
Member

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.

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.

@brita / @truman, what about following numpy conventions for cases which are disputable?

@brita / @truman, what about following numpy conventions for cases which are disputable?
Author
Member

@brita / @ideasman42

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

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

In #56276#525498, @ideasman42 wrote:
@brita / @truman, 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)

In #56276#525496, @brita wrote:
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)
@brita / @ideasman42 As per review comments on [D3587](https://archive.blender.org/developer/D3587), I've also implemented: - `matrix @= matrix` - `matrix *= matrix/float` - `quat @= quat` - `quat *= quat/float` > In #56276#525498, @ideasman42 wrote: > @brita / @truman, 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) ``` > In #56276#525496, @brita wrote: > 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) ```
Member

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 :)

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 :)
Author
Member

Changed status from 'Open' to: 'Resolved'

Changed status from 'Open' to: 'Resolved'
Author
Member
Implemented in blender/blender@aa5a96430e

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

Note that this is now enabled in master (for 2.90 release).
Sign in to join this conversation.
No Milestone
No project
No Assignees
4 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: blender/blender-addons#56276
No description provided.