cubSplineInterpECnd

Computes a cubic spline interpolant, specifying various endpoint conditions. The default interpolant satisfies the “not-a-knot” condition.

Synopsis

cubSplineInterpECnd (xdata, fdata)

Required Arguments

float xdata[] (Input)
Array with ndata components containing the abscissas of the interpolation problem.
float fdata[] (Input)
Array with ndata components containing the ordinates for the interpolation problem.

Return Value

The structure that represents the cubic spline interpolant. If an interpolant cannot be computed, then None is returned.

Optional Arguments

left, int ileft, float left (Input)
Set the value for the first or second derivative of the interpolant at the left endpoint. If ileft = i, then the interpolant s satisfies
\[s^{(i)}(x_L) = \texttt{left}\]

where \(x_L\) is the leftmost abscissa. The only valid values for ileft are 1 or 2.

right, int iright, float right (Input)
Set the value for the first or second derivative of the interpolant at the right endpoint. If iright = i, then the interpolant s satisfies
\[s^{(i)}(x_R)= \texttt{right}\]

where \(x_R\) is the rightmost abscissa. The only valid values for iright are 1 or 2.

periodic
Compute the \(C^2\) periodic interpolant to the data. That is, we require
\[s^{(i)}(x_L) = s^{(i)}(x_R) i = 0, 1, 2\]

where s, \(x_L\), and \(x_R\) are defined above.

Description

The function cubSplineInterpECnd computes a \(C^2\) cubic spline interpolant to a set of data points (\(x_i\), \(f_i\)) for i = 0, …, ndata − 1 = n. The breakpoints of the spline are the abscissas. We emphasize here that for all the univariate interpolation functions, the abscissas need not be sorted. Endpoint conditions are to be selected by the user. The user may specify “not-a-knot” or first derivative or second derivative at each endpoint, or \(C^2\) periodicity may be requested (see de Boor 1978, Chapter 4). If no defaults are selected, then the “not-a-knot” spline interpolant is computed. If the periodic keyword is selected, then all other keywords are ignored; and a \(C^2\) periodic interpolant is computed. In this case, if the fdata values at the left and right endpoints are not the same, then a warning message is issued; and we set the right value equal to the left. If left or right are selected (in the absence of periodic), then the user has the ability to select the values of the first or second derivative at either endpoint. The default case (when the keyword is not used) is the “not-a-knot” condition on that endpoint. Thus, when no optional arguments are chosen, this function produces the “not-a-knot” interpolant.

If the data (including the endpoint conditions) arise from the values of a smooth (say \(C^4\)) function f, i.e., \(f_i = f(x_i)\), then the error will behave in a predictable fashion. Let ξ be the breakpoint vector for the above spline interpolant. Then, the maximum absolute error satisfies

\[\|f-s\|_{\left[\xi_0,\xi_n\right]} \leq C\left\|f^{(4)}\right\|_{\left[\xi_0,\xi_n\right]}|\xi|^4\]

where

\[|\xi| := \max_{i=0,\ldots,n-1} \left|\xi_{i+1}-\xi_i\right|\]

For more details, see de Boor (1978, Chapters 4 and 5).

The return value for this function is the structure ppoly. This structure contains all the information to determine the spline (stored as a piecewise polynomial) that is computed by this function. For example, the following code sequence evaluates this spline at x and returns the value in y

y = cubSplineValue (x, ppoly, 0)

The difference between the default (“not-a-knot”) spline and the interpolating cubic spline, which has first derivative set to 1 at the left end and the second derivative set to −90 at the right end, is illustrated in the following figure.

../../_images/Figure-TwoInterpolatingSplines.png

Figure 3.1 — Two Interpolating Splines

Examples

Example 1

In this example, a cubic spline interpolant to a function f is computed. The values of this spline are then compared with the exact function values. Since we are using the default settings, the interpolant is determined by the “not-a-knot” condition (see de Boor 1978).

from __future__ import print_function
from numpy import *
from pyimsl.math.cubSplineInterpECnd import cubSplineInterpECnd
from pyimsl.math.cubSplineValue import cubSplineValue

# Define function


def F(x):
    return sin(15.0 * x)


# Compute xdata and fdata
ndata = 11
xdata = empty(ndata)
fdata = empty(ndata)
for i in range(0, ndata):
    xdata[i] = float(i) / (ndata - 1)
    fdata[i] = F(xdata[i])

# Compute cubic spline interpolant
pp = cubSplineInterpECnd(xdata, fdata)

# Print results
print("     x        F(x)     Interpolant     Error")
for i in range(0, 2 * ndata - 1):
    x = float(i) / (2 * ndata - 2)
    y = cubSplineValue(x, pp)
    print('%6.3f  %10.3f   %10.3f   %10.4f' % (x, F(x), y, abs(F(x) - y)))

Output

     x        F(x)     Interpolant     Error
 0.000       0.000        0.000       0.0000
 0.050       0.682        0.809       0.1270
 0.100       0.997        0.997       0.0000
 0.150       0.778        0.723       0.0552
 0.200       0.141        0.141       0.0000
 0.250      -0.572       -0.549       0.0228
 0.300      -0.978       -0.978       0.0000
 0.350      -0.859       -0.843       0.0162
 0.400      -0.279       -0.279       0.0000
 0.450       0.450        0.441       0.0093
 0.500       0.938        0.938       0.0000
 0.550       0.923        0.903       0.0199
 0.600       0.412        0.412       0.0000
 0.650      -0.320       -0.315       0.0049
 0.700      -0.880       -0.880       0.0000
 0.750      -0.968       -0.938       0.0295
 0.800      -0.537       -0.537       0.0000
 0.850       0.183        0.148       0.0347
 0.900       0.804        0.804       0.0000
 0.950       0.994        1.086       0.0926
 1.000       0.650        0.650       0.0000

Example 2

In this example, a cubic spline interpolant to a function f is computed. The value of the derivative at the left endpoint and the value of the second derivative at the right endpoint are specified. The values of this spline are then compared with the exact function values.

from __future__ import print_function
from numpy import *
from pyimsl.math.cubSplineInterpECnd import cubSplineInterpECnd
from pyimsl.math.cubSplineValue import cubSplineValue

# Define function


def F(x):
    return sin(15.0 * x)


# Compute xdata and fdata
ndata = 11
xdata = empty(ndata)
fdata = empty(ndata)
for i in range(0, ndata):
    xdata[i] = float(i) / (ndata - 1)
    fdata[i] = F(xdata[i])

# Specify end conditions
ileft = 1
left = 0.0
iright = 2
right = -225. * sin(15.0)

# Compute cubic spline interpolant
pp = cubSplineInterpECnd(xdata, fdata,
                         left={'ileft': ileft, 'left': left},
                         right={'iright': iright, 'right': right})

# Print results for first half of interval
print("     x        F(x)     Interpolant     Error")
for i in range(0, ndata):
    x = float(i) / (2 * ndata - 2)
    y = cubSplineValue(x, pp)
    print('%6.3f  %10.3f   %10.3f   %10.4f' % (x, F(x), y, abs(F(x) - y)))

Output

     x        F(x)     Interpolant     Error
 0.000       0.000        0.000       0.0000
 0.050       0.682        0.438       0.2441
 0.100       0.997        0.997       0.0000
 0.150       0.778        0.822       0.0442
 0.200       0.141        0.141       0.0000
 0.250      -0.572       -0.575       0.0038
 0.300      -0.978       -0.978       0.0000
 0.350      -0.859       -0.836       0.0233
 0.400      -0.279       -0.279       0.0000
 0.450       0.450        0.439       0.0111
 0.500       0.938        0.938       0.0000

Example 3

This example computes the natural cubic spline interpolant to a function f by forcing the second derivative of the interpolant to be zero at both endpoints. As in the previous example, the exact function values are computed with the values of the spline.

from __future__ import print_function
from numpy import *
from pyimsl.math.cubSplineInterpECnd import cubSplineInterpECnd
from pyimsl.math.cubSplineValue import cubSplineValue

# Define function


def F(x):
    return sin(15.0 * x)


# Compute xdata and fdata
ndata = 11
xdata = empty(ndata)
fdata = empty(ndata)
for i in range(0, ndata):
    xdata[i] = float(i) / (ndata - 1)
    fdata[i] = F(xdata[i])

# Specify end conditions
ileft = 2
left = 0.0
iright = 2
right = 0.0

# Compute cubic spline interpolant
pp = cubSplineInterpECnd(xdata, fdata,
                         left={'ileft': ileft, 'left': left},
                         right={'iright': iright, 'right': right})

# Print results for first half of interval
print("     x        F(x)     Interpolant     Error")
for i in range(0, ndata):
    x = float(i) / (2 * ndata - 2)
    y = cubSplineValue(x, pp)
    print('%6.3f  %10.3f   %10.3f   %10.4f' % (x, F(x), y, abs(F(x) - y)))

Output

     x        F(x)     Interpolant     Error
 0.000       0.000        0.000       0.0000
 0.050       0.682        0.667       0.0150
 0.100       0.997        0.997       0.0000
 0.150       0.778        0.761       0.0172
 0.200       0.141        0.141       0.0000
 0.250      -0.572       -0.559       0.0126
 0.300      -0.978       -0.978       0.0000
 0.350      -0.859       -0.840       0.0189
 0.400      -0.279       -0.279       0.0000
 0.450       0.450        0.440       0.0098
 0.500       0.938        0.938       0.0000

Example 4

This example computes the cubic spline interpolant to a functions, and imposes the periodic end conditions \(s(a) = s(b)\), \(s'(a) = s'(b)\), and \(s''(a) = s''(b)\), where a is the leftmost abscissa and b is the rightmost abscissa.

from __future__ import print_function
from numpy import *
from pyimsl.math.constant import constant
from pyimsl.math.cubSplineInterpECnd import cubSplineInterpECnd
from pyimsl.math.cubSplineValue import cubSplineValue

# Define function


def F(x):
    return sin(x)


# Compute xdata and fdata
twopi = 2.0 * constant("pi")
ndata = 11
xdata = empty(ndata)
fdata = empty(ndata)
for i in range(0, ndata):
    xdata[i] = twopi * float(i) / (ndata - 1)
    fdata[i] = F(xdata[i])
fdata[ndata - 1] = fdata[0]

# Compute periodic cubic spline interpolant
pp = cubSplineInterpECnd(xdata, fdata, periodic=True)

# Print results for first half of interval
print("     x        F(x)     Interpolant     Error")
for i in range(0, ndata):
    x = (twopi / 20.) * i
    y = cubSplineValue(x, pp)
    print('%6.3f  %10.3f   %10.3f   %10.4f' % (x, F(x), y, abs(F(x) - y)))

Output

     x        F(x)     Interpolant     Error
 0.000       0.000        0.000       0.0000
 0.314       0.309        0.309       0.0001
 0.628       0.588        0.588       0.0000
 0.942       0.809        0.809       0.0004
 1.257       0.951        0.951       0.0000
 1.571       1.000        1.000       0.0004
 1.885       0.951        0.951       0.0000
 2.199       0.809        0.809       0.0004
 2.513       0.588        0.588       0.0000
 2.827       0.309        0.309       0.0001
 3.142       0.000        0.000       0.0000

Warning Errors

IMSL_NOT_PERIODIC The data is not periodic. The rightmost fdata value is set to the leftmost fdata value.

Fatal Errors

IMSL_DUPLICATE_XDATA_VALUES The xdata values must be distinct.