1

As far as I understand, the interface of Ceres requires each residual to be defined as a functor where operator() is a const member function. Here is an example of what I'm interested in:

class some_residual
{
   public:
    template<typename type>
    bool operator()(const type* const some_params, type* residual) const;

    Eigen::MatrixXd m_M;/*The explanation follows. Nevermind its type, all
                          that matters is that it is not a raw buffer*/
};

Now, I am in a particular case where I need the "helper" matrix m_M, that I would like to use inside operator(). There are a few options for that, for example, I could declare it as mutable Eigen::MatrixXd m_M; or change it to std::shared_ptr<Eigen::MatrixXd> m_pM; and update *mP from inside operator() (or similarly, I could use a reference). As another alternative, I could just pass the data of this matrix as a raw C pointer to operator(), and fix them in the Ceres optimization.

I prefer to avoid raw pointers whenever I can, and I'm inclinded to think that using mutable is the best solution. Is that good or bad practice in general, and in particular, is it safe to use that with Ceres? What other alternatives do I have?

Ash
  • 4,611
  • 6
  • 27
  • 41
  • 1
    Functors are usually light weight objects and algorithms sometimes take advantage of this and copy the functor multiple times (eg recursive algorithms). You need to check the implementation details before passing a heavy object to such algorithms. – Richard Critten Apr 20 '18 at 10:09
  • @RichardCritten Thanks. So in that case the `std::shared_ptr` member seems to be the better option. – Ash Apr 20 '18 at 10:17

1 Answers1

2

mutable is a bad idea.

The reason the call to operator() is const is because if you decide to use the same functor in multiple CostFunctions, or the same CostFunction in multiple ResidualBlocks, then you risk having race conditions if and when Ceres is using multiple threads to evaluate residuals/Jacobians.

Sameer Agarwal
  • 592
  • 2
  • 4