Cubic spline interpolation realization

354 Views Asked by At

dear mathematicians! I was trying to code cubic spline interpolation algorythm. So I found one here.

But I was confused. Let's see why. So let say I got 2 vectors - vector $X$ and $Y$ (with different points ofc)

like

var y = [1, 2, 3, 1, 3, 1, 4, 5];
var x = [1, 4, 5, 7, 10, 11, 14, 15]

So I started to write the function to get result. But I can't finish it because of I don't understand what should I use like an $x$ in ${S}_{j} \left ( x \right ) = a_j + b_j \left ( x-x_j \right ) + c_j {\left ( x-x_j \right ) }^{2} + d_j {\left ( x-x_j \right ) }^{3}$

I mean that after I get all the data I need what should I set as $x$ when I get to 11th step?

Because they set everything there but not the $x$ itself!

So what should I use as $x$? Or maybe I understood everthing wrong? (offtopic: I haven't doing math for a while so sorry for my stupidity, even forgot how to solve integral equations)

Here's the code.

     function getSpline(vectorX, vectorY){
            var a = vectorY; //new array a
            var b, d;
            var h = new Array();

            var n = vectorX.length;

            for(var i=0; i< n; i++){
                h.push(vectorX[i+1] - vectorX[i]);
            }
            var alpha = new Array();
            for(var i=1; i < n - 1; i++){
               alpha.push( (3/h[i])*(a[i+1]-a[i]) - (3/h[i-1])*(a[i]-a[i-1]));
            }

              var b = new Array(vectorX.length);
              var d = new Array(vectorX.length);
            var c = new Array(vectorX.length+1);
            var mu = new Array(vectorX.length+1);
            var z = new Array(vectorX.length+1);
            var l = new Array(vectorX.length+1);
            l.push(1); mu.push(0); z.push(0);

            for (var i=1; i < n - 1; i++){
                l.push(2*(vectorX[i+1] - vectorX[i-1]) - h[i-1]*mu[i-1]);   
                mu.push(h[i]/l[i]);
                z.push((alpha[i] - h[i-1]*z[i-1])/l[i]);
            }    
             l.push(1); z.push(0); c[c.length] = 0;

            for(var j = n-1; j > 0; j--){
               c[j] = z[j] - mu[j]*c[j+1];
               b[j] = ((a[j+1] - a[j])/h[j]) - (h[j](c[j+1] + 2*c[j])/3);
               d[j] = (c[j+1] - c[j])/3*h[j] 
            } 

            var outputset = new Array();

    }

  function S(j, a, b, c, d, x, xindex){
           return (a + b*(x - xindex) + c*(x - xi)*(x - xi) + d*(x - xi)*(x - xi)*(x - xi));
  }
1

There are 1 best solutions below

4
On BEST ANSWER

The reason that they don't set $x$ is because it's the variable that you'll use to interpolate between your known $x_j$ and $x_{j+1}$. In other words, the point is to calculate the coefficients of your spline, and then run something like this:

// First compute spline coefficients using the given points (x[j],y[j]).
// (i.e., compute all the a[j], b[j], c[j], d[j])

getSpline(X,Y)

// We now can choose any x and find the corresponding y value.
// For example, to draw a curve from (x[0],y[0]) through (x[n],y[n]),
//  set an arbitrary step size and increment x accordingly:

stepsize = 0.1
for j = 0 to n-1
{
  for x = x[j] to x[j+1] by stepsize
  {
    y = S[j](x)
    draw (x,y)
  }
}

Addendum:

For a comparison to a simpler problem, consider the case where you have two points, $(x_0,y_0)$ and $(x_1,y_1)$, and you want to find the line segment $y=mx+b$ joining them. The point is to calculate $m$ and $b$. The question you asked is, what value should $x$ be? And the answer is: $x$ is a variable and doesn't enter into the calculation of $m$ and $b$. Once you have $m$ and $b$, however, you can set $x$ to any value between $x_0$ and $x_1$, and using $y=mx+b$, you'll find the corresponding $y$.