Consider the following code:
#include <Eigen/Core>
using Matrix = Eigen::Matrix<float, 2, 2>;
Matrix func1(const Matrix& mat) { return mat 0.5; }
Matrix func2(const Matrix& mat) { return mat / 0.5; }
func1()
does not compile; you need to replace mat
with mat.array()
in the function body to fix it ([1]). However, func2()
does compile as-is.
My question has to do with why the API is designed this way. Why is addition-with-scalar and division-by-scalar treated differently? What problems would arise if the following method is added to the Matrix
class, and why haven't those problems arisen already for the operator/
method?:
auto operator (Scalar s) const { return this->array() s; }
CodePudding user response:
From a mathematics perspective, a scalar added to a matrix "should" be the same as adding the scalar only to the diagonal. That is, a math text would usually use M 0.5
to mean M 0.5I
, for I
the identity matrix. There are many ways to justify this. For example, you can appeal to the analogy I = 1
, or you can appeal to the desire to say Mx 0.5x = (M 0.5)x
whenever x
is a vector, etc.
Alternatively, you could take M 0.5
to add 0.5
to every element. This is what you think is right if you don't think of matrices from a "linear algebra mindset" and treat them as just collections (arrays) of numbers, where it is natural to just "broadcast" scalar operations.
Since there are multiple "obvious" ways to handle
between a scalar and a matrix, where someone expecting one may be blindsided by the other, it is a good idea to do as Eigen does and ban such expressions. You are then forced to signify what you want in a less ambiguous way.
The natural definition of /
from an algebra perspective coincides with the array perspective, so no reason to ban it.