Find Corresponding Interpolate Value in Spline Chart Data Using Math.NET

(Pierre Gouffran) #1

I created a graph in spline type using Microsoft C# Chart tool. I have two root arrays which have double type elements; the first one is X array and the next one is Y array. The element of each X array corresponds to an element of Y array. Like at below. These arrays contain more than ten float or int values.

double [] X = …
double [] Y = …

I want to find an interpolation value using Math.NET with any method. It can be linear, non-linear, regression, cubic or more complex.

I need the specific points between the X-Y data values which I used. I have known only the Y value of these points, but I can’t find the corresponding X value.

Most of the solutions have an error like “System.IndexOutOfRangeException occurred”. Therefore, I need a permanent solution.

(Peter Vanderwaart) #2

First, here is sample code for a simple cubic spline. This assumes the values in X[] are monotonically increasing.

           using MathNet.Numerics.Interpolation; // required header

            double[] x = new double[13];
            double[] y = new double[13];
            for (int i = 0; i <= 12; i++)
                x[i] = i * Math.PI / 12;
                y[i] = Math.Sin(x[i]);
            // create spline
            CubicSpline CSpline = CubicSpline.InterpolateNatural(x, y);

            // try test value
            double test_x = 1.5 * Math.PI / 12; // this value not in x[]
            double test_y = CSpline.Interpolate(test_x); // returns 0.3826

            Console.WriteLine(test_x.ToString() + "  " + test_y.ToString());

Now the hard part. Your question says you want to find the X that corresponds to a given Y. If the Y values are monotonic (increasing or decreasing), you can just swap the arrays and create a spline for X = f{(Y). If the Y values are not monotonic, as in the example, the InterpolateNatural method will not work. I tried it, and it returned an NaN. One of the other methods might work; I don’t know.

If the Y values are not monotonic, there is an underlying math issue. There will be more than one X value that corresponding to a given Y and no algorithm can reliably determine which one you want. In the example, 0.25PI and 0.75PI would return the same value of Y.

Edit: I belatedly saw the graph you posted on Stack Overflow with this question. It illustrates my last point. If you were to ask for a point where sales = $6000, it could return a date in either February or March. I don’t know your objective here, but in most cases a regression line would be more appropriate than a spline for this data.

(Christoph Rüegg) #3

If you know the region where to look for and where there is a unique solution, you can also use FindRoots to numerically find the corresponding x value. For example, the following will find a value close to test_x (corresponding to test_y), knowing that it is between 0.2 and 0.4:

FindRoots.OfFunction(z => CSpline.Interpolate(z) - test_y, 0.2, 0.4, 1e-12)

(Pierre Gouffran) #4

Yeah, it works. Thanks a lot.