rbf-interpolation

Radial basis function (RBF) network for scattered data interpolation and function approximation.

#include <mathtoolbox/rbf-interpolation.hpp>

Math

Overview

Given input data:

this technique calculates an interpolated value for a specified point by

where is a user-selected RBF, and

are the weights that are calculated in pre-computation.

Pre-Computation

The weight values need to be calculated in pre-computation. Let

where

The following linear system is solved for :

LU decomposition can be used for solving this problem.

This approach offers exact interpolation: the interpolated function passes through all the scattered data points exactly.

Pre-Computation with Regularization

The original formulation above is not robust when the data points are dense and noisy. For such cases, it is effective to use a feature called regularization in pre-computation. In other words, this feature enables scattered data approximation rather than scattered data (exact) interpolation.

This feature is achieved by considering a regularization term in the calculation of the weight values. More specifically, the following minimization problem is solved:

The derivative of this objective function with respect to is

Thus, the solution of the above minimization problem is obtained by solving the below linear system:

Adding Polynomial Term (and Polyharmonic Spline)

The above techniques can be extended by adding a polynomial term; that is,

This extension is also referred to as polyharmonic spline when it is used with polyharmonic RBF kernels (e.g., the linear kernel, the thin plate spline kernel, and the cubic kernel).

This extension offers several nice properties; for example, this makes the extrapolation behavior much more reasonable as shown below. See [Anjyo et al. 2014] for details.

This extension is recommended to always use and enabled by default.

Usage

First, instantiate the class RbfInterpolator. In its constructor, an arbitrary RBF kernel (in the form of std::function<double(double)>) can be specified.

The followings are pre-implemented as function objects and can be easily specified:

  • GaussianRbfKernel:
  • LinearRbfKernel:
  • ThinPlateSplineRbfKernel:
  • CubicRbfKernel:

If no kernel is passed to the constructor, ThinPlateSplineRbfKernel is chosen by default.

Then, set the target scattered data by the method:

void SetData(const Eigen::MatrixXd& X, const Eigen::VectorXd& y);

where

represents the data points and

represents their values.

Next, calculate the weight values by the method:

void ComputeWeights(const bool   use_regularization = false,
                    const double lambda             = 0.001);

When use_regularization is set true, the weights are calculated in the manner of scattered data approximation, rather than scattered data interpolation. When the data is noisy, approximation is usually a better choice.

Once the above procedures are performed, the instance is ready to calculate interpolated values. This is performed by the method

double CalcValue(const Eigen::VectorXd& x) const;

Time Complexity

The pre-computation needs to solve a linear system, which takes more than . An interpolated value calculation takes . See [Carr et al. 2001] for details.

Useful Resources