I have a cost function with a heavy core computation, that creates several residuals. I want to cache the results of the core computation, and then break it into multiple residual blocks. The advantage here is that a loss function can be applied to each residual block individually, but the core computation is done just once.
I could not figure out how to define this for Ceres.
Here is, generally, the outline.
class CachingComputation
{
private:
std::shared_ptr< std::vector<double> > mCachedParameters;
std::shared_ptr< std::vector<double> > mCachedResiduals;
int residualBlockIndex;
public:
template <typename T>
bool operator()(T const * const * parameters, T* residuals) const
{
// if the parameters are equal to the cached parameters, then just copy from mCachedResiduals
// to residuals (possibly casting, etc.) according to residualBlockIndex.
// Otherwise, do the core computation, cache the parameters
// and residuals, and then select the requested block
}
};
Of course, this syntax is not accurate, but the point is, I only want to do the core computation once and then distribute the residuals into multiple residual blocks.
The signature of operator() is such that all the residuals are moved to one block at a time. So, perhaps, AddResidualBlock should be called once for each desired residual block, but still use the same core object to do the heavy computation once. However, if this is the design, then the core object cannot know which of the residuals it is supposed to return with each call, and for this reason I added the residualBlockIndex field, which selects among all the residuals just the block being asked.
This is as far as I got in reading the documentation, but it's far from being what I want. Casting to Jet is one problem. A worse one is that even if I have it, I cannot tell that the same parameters will be passed to each instance of CachingComputation, so that the cache will actually be effective.
So I need something else, and I don't know what it might be.
Any idea?
Thanks
Ofri Sadowsky