3
$\begingroup$

I noticed that 'Eigen' matrices with dynamic dimension are less efficient than the matrices with static dimension. My algorithm uses a lot of matrices which don't need to be resized, so I wanted to use static dimensions, but the dimension is not known in advance and this doesn't work:

const size_t n = 3;
Eigen::Matrix<double, n, n> A;

Is there a workaround? Perhaps with a macro? (I'm not fluent in C/C++ and I don't know macros yet, sorry if my question is silly).

$\endgroup$
2
  • $\begingroup$ That code compiled for me with Visual Studio 2019. But in general, you need to know the size at compile time. There is a little used feature that allows you to define a maximum size, which can be a useful compromise. const size_t max_size = 10; Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, Eigen::ColMajor, max_size, max_size> A; $\endgroup$
    – Charlie S
    Commented Nov 4, 2020 at 20:21
  • 3
    $\begingroup$ You can use constexpr instead of const if the value is known during compile time. $\endgroup$ Commented Nov 4, 2020 at 20:22

1 Answer 1

6
$\begingroup$

No, in the general case, there is no suitable workaround. C++ is a statically typed language, and the compiler needs to know all types at compilation time. If your code worked, the following would also

const size_t n = std::rand();
Eigen::Matrix<double, n, n> A;

and rand() only gives a random number at run-time, which, at compile-time is unknown.

Moreover, I would not rely too much on the statement that fixed-size matrices lead to faster code execution than dynamic ones. There is an optimization effect, but it pays only for small dimensions. The Eigen help-page states that it should be used "typically up to 4x4, sometimes up to 16x16" but not for larger matrices.

Here are the possibilities for special cases:

  • static const and constexpr tells the compiler that the variable is a compile-time expression. You can use it as a placeholder, and this avoids typing the magic number repeatedly:

    static constexpr size_t n = 3;
    Eigen::Matrix<double, n, n> A;
    Eigen::Matrix<double, n, n> B;
    

    But still you can't use that for dynamic numbers.

  • The best you can do is when you can boil down your dimensions to a few special cases. Say you want to optimize for dimensions n=2,3,4. Then you can wrap up your calculations into a big function template calculate<n> and let the compiler explicitly instantiate the few special cases, e.g. by

    if(n==2)
    {
        calculate<2>();
    }
    else if(n==3)
    {
        calculate<3>();
    }
    ...
    

    (There are smarter techniques for this, but this "if-loop" perfectly gives the idea)

    By this, you increase the compilation time by a factor that corresponds to the number of special cases, but the runtime will prossibly be faster. And then, you can choose n dynamically at least from the chosen range.

    If you're further interested in this technique, let me know.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.