Home > OS >  Rationale for Eigen API for Matrix with Scalar operations
Rationale for Eigen API for Matrix with Scalar operations

Time:12-13

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.

  • Related