sgorsten / linalg

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

Feature request: Disable operator * for matrices? #26

Closed PeterHiber closed 3 years ago

PeterHiber commented 3 years ago

Hi and thanks for the lib! It's by far one of the least bloated linear algebra libs we have found, and we have had great success with it so far!

Well, except for one aspect. We have had quite a few bugs where people implicitly assumed that the * operator was matrix multiply (and not element-wise multiply). We have become more used to using mul() now, but it's still a problem that pops up every now and then.

So the feature request we have is to be able to disable operator * for matrices (but not for vectors) so that we don't accidentally do element-wise multiplication instead of matrix multiplication.

Have a nice day!

sgorsten commented 3 years ago

This is probably the single most frequently raised issue among users of this library, and not without good reason. It turns out my own unit tests contained an erroneous usage of operator * when matrix multiplication was intended. Through some quirk of fate, the specific version of doctest I was using wasn't correctly invoking templated test cases, and the broken test slipped through.

I've decided to deprecate operator * between pairs of matrices, and provide an unambiguous cmul(...) function that can be called by users who actually want the component-wise (Hadamard) product between matrices. operator * will remain supported for all other patterns with its original semantics.

It took a little bespoke machinery to do so, but I was able to split the definition of operator * into two overloads, one for matrix * matrix, and one for everything else, and attached a deprecation attribute to the matrix * matrix overload, so it should raise a warning any time it is used.

Furthermore, if you #define LINALG_FORWARD_COMPATIBLE, either before including linalg.h or globally across your project, it will remove the matrix * matrix overload completely, making that construct a hard compiler error.

Take care, and happy coding!

PeterHiber commented 3 years ago

This is excellent! Huge thanks for this, it helps us a lot! 🎉👍