Search code examples
c++matrixeigen

Multiply Eigen::MatrixXd(m,n) with 1x1 Matrix


I'm currently writing a GUI to input transition functions of physical dynamics for later simulation of an arbitrary environment.

I want to include linear algebra since it makes it much easier for the user (myself) to input data and define transition functions.

Now the problem is, that it can happen, that some sort of vector product (scalar) is multiplied with a matrix. This however results in a matrix dimension mismatch in the Eigen library.

A bit of background on how it is supposed to work. I use a std::map<std::string, Eigen::MatrixXd> variables to store all variable inputs from the user. Then the user can type in some function, it is auto generated and compiled and later used to simulate the given transitions.

For example:

The user inputs the variables delta_t = 1, a = 0.5, v = 0.0, x = 0.0.

Also the transition functions:

a = a
v = v + a * delta_t
x = x + v * delta_t

Now some code is autogenerated and the simulation can run with delta_t = 1 sec for each simulation step. This all works without a problem. If I now use Vectors instead of scalars however it becomes problematic. In the given example everything is a 1x1-Matrix so no complications during runtime. For the variables:

delta_t = 1
a = [0.5, 0.5, 0.5]
v = [0.0, 0.0, 0.0]
x = [0.0, 0.0, 0.0]

and the same transition functions I get a runtime error since there is a dimension mismatch between dt and a. Now in this particular situation I could include some guard during the generation of the code to catch such problems, however if the calculations get bigger and maybe there is some intermediate calculation which results in a scalar I could not catch that in before without calculating every dimension of every matrix/ vector product and checking if it is 1x1. Is there a way to do this n-by-m*1-by-1 calculation (best case in eigen) without having to manually check the dimensions for 1-by-1 matrices? If not do you have any ideas on how to tackle this problem? Or am I just missing something really obvious?


Solution

  • Formally, a 1x1 matrix and a scalar are not the same thing. It would have been possible to implement Eigen in a way that when a matrix (at runtime) happens to be 1x1, it should act exactly like a scalar (essentially, that is what Matlab does). However, this would require a lot of extra logic (i.e. runtime overhead) and could also hide a lot of unintentional mistakes. Also, this would break associativity, e.g.,

    (Matrix(1,n) *  Matrix(n,1)) * Matrix(m,m)  // possible
     Matrix(1,n) * (Matrix(n,1)  * Matrix(m,m)) // not possible
    

    So, if you want that behavior, I'm afraid you need to check this manually yourself at runtime, or make the user specify which variables are supposed to be scalars and which are vectors (e.g., store them in a different map).


    Note that for your example you could actually just write

    v = v + delta_t * a
    

    and so on, since multiplying a 1x1 with a 1xN matrix is possible. This works only as long as a is a row vector, of course.