sgorsten / linalg

linalg.h is a single header, public domain, short vector math library for C++
The Unlicense
854 stars 68 forks source link

Fix semantics of operator overloads on matrices. #14

Closed sgorsten closed 5 years ago

sgorsten commented 6 years ago

Based on consistent feedback from many users, I have come to the conclusion that my original design decision of having all non-comparison operator overloads be defined in terms of element-wise application to values of the same dimensions to be in error.

Most users expect the expression matrix * matrix to perform matrix multiplication, and matrix * vector to perform matrix multiplication by interpreting the vector as a single column matrix, matching the semantics of GLSL. Currently, linalg.h has the somewhat surprising behavior of treating matrix * matrix as an element-wise multiplication.

It is my intention to modify the library to match users' expectations by restricting the set of operator overloads on matrices to those operations which are well defined in linear algebra, to more closely match users' expectations. This is a breaking change, and is thus targeted for v3.0.

meshula commented 6 years ago

In my libraries, I define a Hadamard operator for element-wise operations.

https://en.wikipedia.org/wiki/Hadamard_product_(matrices)

It's useful, and comes up frequently in signal processing and quantum computing. Some languages define an operator for it .* (dot star)

On the topic of matrix * vector, homogeneous and non-homogenous multiplies are interesting, as are v3f multiplications with an implicit w of 1.

mirmik commented 6 years ago

I think this is a question of semantics. Element-wise is behavior of ndarray. It is like numpy arrays etc. I still think it was a good decision to interpret matrix and vectors in ndarray's semantic.

If it go back to algebraic semantics, the library will no longer look so basic as it now looks.

On the question immediately comes to mind the question, what about the multiplication of quaternions? In the current state, this is simply the same superstructure above ndarray's semantics as algebraic matrix operations. If you put matrix operations at the center, the status of quaternions and other objects that can be built on the basis of this library will be strange.

P.S. I allow myself to express the opinion that feedback from users could be unrepresentative, since the number of messages from users who found the current state of affairs would obviously be less than the number of messages from those who found it strange, while the number of such users could be identical.

meshula commented 6 years ago

Indeed it is a question of semantics. I'm one of the authors of Imath, so naturally I am biased to the algebraic conventions found there :)

sgorsten commented 5 years ago

Implemented in the v3 branch, which additionally introduces a quat<T> type. Component-wise operations are still explicitly available via the apply(...) function, which subsumes the original behavior of map(...) and zip(...).

The most recent commit that retains the original semantics of the library has been tagged v2.1. I'll be open to providing small bugfixes and improvements to v2.1.