Interpolate function using Apache Commons Math
Asked Answered
C

1

8

I'm trying to implement some Interpolation functions to plot some values where the X value = Date.seconds and the Y value = double.

I'v been researching using the Apache Commons Math lib to achieve this and I've found a method I think I might be able to use here

The method I'm trying to understand:

public double linearInterp(double[] x, double[] y, double xi) {
   // return linear interpolation of (x,y) on xi
   LinearInterpolator li = new LinearInterpolator();
   PolynomialSplineFunction psf = li.interpolate(x, y);
   double yi = psf.value(xi);
   return yi;
}

I don't understand where I'm supposed to get the xi value from?

What is xi what value do I pass into this method for xi, am I supposed to loop through my array of X values and pass in the ith element of X with the array of X and Y?

And when I want to plot this new data do I use the returned yi along with the passed in xi to plot?

Changeable answered 9/4, 2016 at 22:19 Comment(2)
Do you want to plot the interpolation function itself, i.e. create images like en.wikipedia.org/wiki/File:Interpolation_example_linear.svg or en.wikipedia.org/wiki/File:Interpolation_example_polynomial.svg using a set of X/Y points? Or do you want to get the Y value(s) for X value(s) that aren't in your original dataset and plot those?Mariomariology
I want to plot the interpolation function itself, I'm using highchart.js to plot the data. My ultimate goal is to have an extrapolation function to plot points in the future using the using my set of X/Y points. maybe using something like this: https://mcmap.net/q/1322911/-extrapolation-in-java But I've been led to believe if I have an interpolation function, I can use that function to extrapolate.Changeable
Z
21

The interpolate method expects arrays of pairs (here called x and y) and returns a function (psf) that fits these values as best as possible.

This function is then used to interpolate the yi-value of a given xi-value (which is normally not contained in the x/y array used to define the function).

So you have pairs containing of x- and y-values defining a function and use this function to interpolate missing values.

See the userguide on Apache Commons (Chapter 4.4: Interpolation).


Example:

badly drawn example of a spline interpolation

The green dots are known value pairs. These are defined by the x and y value arrays.

When calling interpolate, the returned PolynomialSplineFunction returns the function that is approximated using the known value pairs. The shape of the funtion is defined by the type of UnivariateInterpolator that is used. In the question example, a LinearInterpolator is used. The drawing shows the function returned by a spline interpolator.

The red dot symbolizes a value with an unknown y-value on the interpolated function (this would be the value with an x-value of xi in the question example).

If you need to calculate more than one extra value, use a function like this

public double[] linearInterp(double[] x, double[] y, double[] xi) {
   LinearInterpolator li = new LinearInterpolator(); // or other interpolator
   PolynomialSplineFunction psf = li.interpolate(x, y);

   double[] yi = new double[xi.length];
   for (int i = 0; i < xi.length; i++) {
       yi[i] = psf.value(xi[i]);
   }
   return yi;
}

A calculation example:

public class Interpolate {

    public static void main(String[] args) {
        double[] x = { 0, 50, 100 };
        double[] y = { 0, 50, 200 };

        LinearInterpolator interp = new LinearInterpolator();
        PolynomialSplineFunction f = interp.interpolate(x, y);

        System.out.println("Piecewise functions:");
        Arrays.stream(f.getPolynomials()).forEach(System.out::println);

        double value = f.value(70);
        System.out.println("y for xi = 70: " + value);
    }
}

Three known value pairs are given:

(0, 0)
(50, 50)
(100, 200)

One value is unknown:

(70, ?)

The LinearInterpolator interpolates the given values and generates a function with two piecewise, linear polynomials:

y = x             (for x values < 50)
y = 50 + 3 * x    (for x-values >= 50)

The value of the interpolated xi (here: 70) is

y = 50 + 3 * (70 - 50) = 110
Zoology answered 9/4, 2016 at 22:52 Comment(5)
I have a much better understanding after reading that, thank you. How would I choosing an xi value to use, assuming I want to use a value not found in the set, is there a method of choosing an appropriate xi, do I use the same xi to interpolate the entire data set? I'm guessing yes and then change xi and run through the sets again for a different result?Changeable
@Johntk do I use the same xi to interpolate the entire data set? - It's actually the other way round: you use the dataset to interpolate xi. I'll add a little example.Zoology
@Johntk I added more explanation, hope this helps.Zoology
Thank you for taking the time to write this answer, I understand how it works now, in my example the xi is a date and passing a new date in would be my xi or passing in several dates would be my xi[i], I would then use the data set to interpolate xi[i] I ran into a OutOfRangeException when I tried to extrapolate with the method you provided, but the extrapolation method I linked to in the initial question works, but I'm having trouble getting good results back due to using dates rather than coordinates, I'll need to post a new question I think. thanks again for your help.Changeable
Sorry i should have said the OutOfRangeException was due to me passing in values outside the data set range, nothing wrong with the function you provided me with.Changeable

© 2022 - 2024 — McMap. All rights reserved.