1

I'm trying to replace a matrix library currently used in my code using Eigen. I've got several classes like this one adding custom methods to base matrix class. In this example I replaced the father class with Eigen:

#include <iostream>
#include <eigen3/Eigen/Dense>

class MyVectorType: public Eigen::Matrix<double, 3, 1> {
public:
    MyVectorType(void) :
            Eigen::Matrix<double, 3, 1>() {
    }
    typedef Eigen::Matrix<double, 3, 1> Base;
    // This constructor allows you to construct MyVectorType from Eigen expressions
    template<typename OtherDerived>
    MyVectorType(const Eigen::MatrixBase<OtherDerived>& other) :
            Eigen::Matrix<double, 3, 1>(other) {
    }
    // This method allows you to assign Eigen expressions to MyVectorType
    template<typename OtherDerived>
    MyVectorType & operator=(const Eigen::MatrixBase<OtherDerived>& other) {
        this->Base::operator=(other);
        return *this;
    }
    void customMethod() {
        //bla bla....
    }
};

The big problem is that is not really easy to manage custom classes in methods. Example:

void foo(MyVectorType& a) {
    ....
    a.customMethod();
}

void foo(Eigen::Ref<MyVectorType::Base> a) {
    ....
    a.customMethod(); <---can't call customMethod here
}

Eigen::Matrix<double, -1, -1, 0, 15, 15> m(3,1);
foo(m); <---can't call it with m;
Eigen::Map<Matrix<double, 3, 1> > map(m.data(), 3, 1);
Eigen::Ref<Matrix<double, 3, 1> > ref(map);
foo(ref); <---it works but I can't call custom method

Usually Eigen provides Ref template class but I cannot use it with custom classes because if I use Ref, I won't be able to call customMethod inside foo in this example, I should Eigen::Ref in my example. Avoiding the use of Ref is a big problem because using Map and Ref Eigen objects is quite important to cast dynamic matrix to fixed one and perform other cast operations. Final question: what's the best strategy to use Eigen in this case?

greywolf82
  • 21,813
  • 18
  • 54
  • 108

1 Answers1

3

There are at least three approaches:

  1. Get rid of MyVectorType and make customMethod a member of MatrixBase via the plugin mechanism.

  2. Get rid of MyVectorType and make customMethod a free function.

  3. Specialize Eigen::Ref<MyVectorType> by letting it inherit Ref<MyVectorType::Base> and its constructor, add a customMethod method and factorize the two methods by calling an internal free function customMethod_impl.

ggael
  • 28,425
  • 2
  • 65
  • 71
  • I guess I need to do something similar even with map to use directly my custom class, isn't it? – greywolf82 Feb 04 '19 at 10:43
  • If you really want to have `Map::customMethod` then yes, but you can still do: `Ref tmp = Map(...);` – ggael Feb 04 '19 at 11:49
  • oh ok, thanks. It would be great to have an example in the docs. Congratulations for the library, it's amazing. Keep up the great work. – greywolf82 Feb 04 '19 at 11:50