2-dimensional data interpolation with Boost cpp

Viewed 1427

There are many interpolation libraries in Boost, but all of them are one-dimensional interpolations. Is there a way I can try to make them work for 2-dimensional interpolation?

By default one uses the interpolation for 1-dimension like this

#include <iostream>
#include <boost/math/interpolators/cardinal_cubic_b_spline.hpp>
#include <vector>

int main(int argc, char *argv[])
{
//f is the data
std::vector<double> f{0.01, -0.02, 0.3, 0.8, 1.9, -8.78, -22.6};

//the start of the functions domain
double x0 = 0;

//step size
double dx = 0.01;

boost::math::interpolators::cardinal_cubic_b_spline<double> spline(f.begin(), f.end(), x0, dx);

//find the interpolant at a point
double y = spline(0.055);
std::cout << y << std::endl;
return 0;
}

This example is taken from their official documentation.

Can I do 2-dimensional interpolation using Boost? Can you suggest any other header-only template-based C++ library that can help me accomplish this job?

In the search for 2d interpolation function, I came across

  • https://www.alglib.net, but this library has its own implementation of arrays. My code uses the STL vector library to store data, so using this means I'll have to change a lot of my codebase.
2 Answers

It's been a while since you asked this question and I don't know whether you've found the answer already, but here is one classic way of performing 2D interpolations.

Say you have a function f defined on a regular grid {x_i, y_j}, where i - (0, M] and j - (0, N]. You want to interpolate for query point (px, py).

step 1. You can construct N 1-D interpolation objects, one for each row of data (sharing the same y - call these functions f_j(x). Interpolate and find f_j(px) for all j, which we'll call FY_j.

step 2. Now you have another 1D vector Y_j, j-(0, N] (same size as the column). Construct a final interpolation object on FY_j(y_j), and interpolate to find FY_j(py). And you're done!

If this was confusing, see if this picture from wikipedia will help. This is for a single "grid". Since spline is a global interpolation, you will need to involve all the rows in the first step instead of just 2 shown here.

wikipedia - bilinear interpolation

Consider using 1-D splines on both x and y. The centripetal Catmull-Rom splines are pretty nice in terms of behavior. Here are blue data points connected with 10-interior-spline-points between them. The point at (-3,10) was the dummy first and last point added to the data set as a linear extension from the first two and last two points (which happened to be the same).

https://replit.com/@smichr/interpolate-2d#main.py

Related