Search code examples
c++eigenceres-solver

How do I use ceres::CubicInterpolator with data not on a uniform grid


Ceres solver allows interpolation with a piecewise cubic hermite interpolant, which I'm trying to use to create a cubic interpolant for Eigen.

This snippet from ceres/examples shows how to set up an interpolator. Adapting it to provide a toy example for my use case:

const int kNumSamples = 4;
double x[kNumSamples];
x[0] = 12.5; x[1] = 13.9; x[2] = 14.0; x[3] = 21.4;

double values[kNumSamples];
for (int i = 0; i < kNumSamples; ++i) {
    values[i] = (x[i] - 4.5) * (x[i]- 4.5);
}

Grid1D<double> array(values, 0, kNumSamples);
CubicInterpolator<Grid1D<double> > interpolator(array);

Which I believe can be evaluated at a location between the given data points like:

double x_interp = 1.5;
double y_interp;
double dydx_interp;
double yi = interpolator_.Evaluate(x_interp, &y_interp, &dydx_interp);

But the Grid1D object has no concept of what the x values are. It always assumes the data is on a regular grid, starting at some index (in this case 0) and containing kNumSamples (in this case 4) samples.

The Question

How can I make Grid1D aware of the actual input x locations? Alternatively, what mapping should I be doing to my x_interp values to get the right answer out?

Thanks for any help!


Solution

  • CubicInterpolator cannot handle non-uniformly distributed data. You will have to use something like a cubic spline yourself to do that.