vendredi 13 mai 2022

Covariant return type on Eigen Matrix for base class method

Suppose that I have two different solvers that both will be called at run time.

  • I want to call solvers' api and get resulted Eigen matrix through the base class pointer.
  • The solved matrix size are selected from a few known values depending on some runtime variable. I need to use compiled time fixed size matrix in this case.

The solver derived class definitions are as follow.

template <int VarSize>
class SolverA : Solver {
 public:
  SolverA() {}

  bool Solve() override {
    // SolverA specific implementations.
  }
  const Eigen::Matrix<double, VarSize, 1>& solution() override {
    return solution_;
  }
 private:
  Eigen::Matrix<double, VarSize, 1> solution_;
}


template <int VarSize>
class SolverB : Solver {
 public:
  SolverB() {}

  bool Solve() override {
    // SolverB specific implementations.
  }
  const Eigen::Matrix<double, VarSize, 1>& solution() override {
    return solution_;
  }
 private:
  Eigen::Matrix<double, VarSize, 1> solution_;
}

Now the problem is how I can write the base class solution() method to get the resulted Eigen matrix, since the template parameter VarSize are not known in the base declaration.

class Solver {
 public:
  virtual bool Solve() = 0;
  // not covariant type, won't compile.
  // virtual const Eigen::VectorXd& solution() = 0;
}

constexpr int kEasyProbSize = 5;
constexpr int kHardProbSize = 20;

int main() {
  Solver* solver;

  if (GetComplexity() > 30) {
    solver = &SolverB<kHardProbSize>();
  } else {
    solver = &SolverA<kEasyProbSize>();
  }
  solver->Solve();
  std::cout << solver->solution() << std::endl;
}

Some thoughts:

  • Eigen::Matrix<double, VarSize, 1> does not derive from Eigen::VectorXd so it cannot override.
  • I also cannot use const Eigen::MatrixBase<Derived>& since there is no that derived information and virtual method won't allow template.
  • I need to call from base class pointer so I cannot make the base class a template class.
  • The solved solution_ is already allocated and doesn't make sense to return a copy or converted to a dynamic size matrix.

Is this fixed size matrix getting from base class pointer even possible?

Aucun commentaire:

Enregistrer un commentaire