Skip to content

lecopivo/Interpolation

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

15 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Interpolation library

This library provides various interpolations such as piece-wise constant, linear or cubic interpolation. Right now the main feature is that it provides a function which takes bunch of one dimensional interpolations and creates an interpolation in arbitrary dimension.

One dimensional interpolation

Assume we have a function double fun(int) defined on integers and we want to extend this function to floating point numbers with piece-wise interpolation, i.e. to get double fun(double). This library provides a function LinearInterpolation

   auto LinearInterpolation = [](auto fun) {
     return [=](double x) {
	 double wx = x - floor(x);
	 int ix = (int)floor(x);

	 return wx * fun(ix + 1) + (1 - wx) * fun(ix);
     };
   }

LinearInterpolation takes a function, assuming it is of type double fun(int), and return a function defined on floating point nubers: double fun(double). The following code demonstrate a use:

// define a function `fun :: int -> double`
auto fun = [](int i) -> double { return sin(i); }

// extend `fun` to `ifun :: double -> double`
auto ifun = LinearInterpolation(ifun);

ifun(1.5); // == 0.5*sin(1)+0.5*sin(2)

General one dimensional interpolation

A general one dimensional interpolation is assumed to be a function which takse a function Float fun(Integer) and generates Float fun(Float), where Float is any floating point type and Integer is an integer like type. Therefore any one dimensional interpolation is assumed to be of type Interpolation :: (Integer -> Float) -> (Float -> Float).

Interpolation on containers

The resulting function of an interpolation holds a copy of the original function. Therefore, the function to be interpolated should be a light object if you want to avoid unnecessary copies. When you want to preform interpolation over a container such as a std::vector we recommend wrap the container into a lambda function which holds a reference to the container, this way you can also handle out of bound access. The following code demonstrates interpolation of a container:

     std::vector<double> vec;

     // initialize `vec`

     auto fun = [&vec](int i) {
	i = std::clamp(i, 0, vec.size() - 1);
	return vec[i];
     };

     auto ifun = LinearInterpolation(fun);

     ifun(1.5); // == 0.5*vec[1]+0.5*vec[2];

Multi-dimensional interpolation

Dimension-wise interpolation

The library provides a functionality how to glue one dimensional interpolations to do multidimensional interpolation. We can take a function double fun(int, int, int) and turn it into a function double fun(double,double,double) by preforming linear interpolation on each argument. This is demonstrated with the following code:

     auto fun = [](int i, int j, int k) -> double {
	return sin(i) + sin(j) + sin(k);
     };

     auto LinearInterpol3D = InterpolationDimWise(
	  LinearInterpolation, LinearInterpolation, LinearInterpolation);

     auto ifun = LinearInterpol3D(fun);

     ifun(1.5, 2.1, 3.7);

We first define a function double fun(int, int, int), then we create a three dimensional interpolation function, which can take a function on integers and with linear interpolation extends this function to floating points numbers. The third line actually extends fun from integer to floating point numbers and in the final step we just evaluate the function at a arbitrary point.

We can also preform cubic interpolation on the first argument, linear on the second and constant(nearest neighbour) on the third one.

auto Interpol3D = InterpolationDimWise(CubicInterpolation, LinearInterpolation,
					     ConstantInterpolation);

auto ifun = Interpol3D(fun);

ifun(1.5, 2.1, 3.7);

Interpolation order

Sometimes, when doing multidimensional interpolation is it important in which order is the interpolation done.

Explain the problem of interpolation order

Installation

Examples

Goals

Implement custom interpolation order for dimension wise interpolation

Monotone cubic interpolation

Lagrange interpolation

Spline interpolation

Currying ?

Can we implement currying in some way? This might be useful when we need to compute fun(x,y) for many different y but fixed x and the interpolation over y has quite expensive precomputation.

About

N-dimensional interpolation library in C++

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published