# NAG C Library Function Document

## 1Purpose

nag_1d_spline_deriv (e02bcc) evaluates a cubic spline and its first three derivatives from its B-spline representation.

## 2Specification

 #include #include
 void nag_1d_spline_deriv (Nag_DerivType derivs, double x, double s[], Nag_Spline *spline, NagError *fail)

## 3Description

nag_1d_spline_deriv (e02bcc) evaluates the cubic spline $s\left(x\right)$ and its first three derivatives at a prescribed argument $x$. It is assumed that $s\left(x\right)$ is represented in terms of its B-spline coefficients ${c}_{\mathit{i}}$, for $\mathit{i}=1,2,\dots ,\stackrel{-}{n}+3$ and (augmented) ordered knot set ${\lambda }_{\mathit{i}}$, for $\mathit{i}=1,2,\dots ,\stackrel{-}{n}+7$, (see nag_1d_spline_fit_knots (e02bac)), i.e.,
 $s x = ∑ i=1 q c i N i x$
Here $q=\stackrel{-}{n}+3$, $\stackrel{-}{n}$ is the number of intervals of the spline and ${N}_{i}\left(x\right)$ denotes the normalized B-spline of degree 3 (order 4) defined upon the knots ${\lambda }_{i},{\lambda }_{i+1},\dots ,{\lambda }_{i+4}$. The prescribed argument $x$ must satisfy ${\lambda }_{4}\le x\le {\lambda }_{\stackrel{-}{n}+4}$.
At a simple knot ${\lambda }_{i}$ (i.e., one satisfying ${\lambda }_{i-1}<{\lambda }_{i}<{\lambda }_{i+1}$), the third derivative of the spline is in general discontinuous. At a multiple knot (i.e., two or more knots with the same value), lower derivatives, and even the spline itself, may be discontinuous. Specifically, at a point $x=u$ where (exactly) $\mathit{r}$ knots coincide (such a point is termed a knot of multiplicity $\mathit{r}$), the values of the derivatives of order $4-\mathit{j}$, for $\mathit{j}=1,2,\dots ,r$, are in general discontinuous. (Here $1\le r\le 4;r>4$ is not meaningful.) You must specify whether the value at such a point is required to be the left- or right-hand derivative.
The method employed is based upon:
 (i) carrying out a binary search for the knot interval containing the argument $x$ (see Cox (1978)), (ii) evaluating the nonzero B-splines of orders 1,2,3 and 4 by recurrence (see Cox (1972) and Cox (1978)), (iii) computing all derivatives of the B-splines of order 4 by applying a second recurrence to these computed B-spline values (see de Boor (1972)), (iv) multiplying the 4th-order B-spline values and their derivative by the appropriate B-spline coefficients, and summing, to yield the values of $s\left(x\right)$ and its derivatives.
nag_1d_spline_deriv (e02bcc) can be used to compute the values and derivatives of cubic spline fits and interpolants produced by nag_1d_spline_fit_knots (e02bac), nag_1d_spline_fit (e02bec) or nag_1d_spline_interpolant (e01bac).
If only values and not derivatives are required, nag_1d_spline_evaluate (e02bbc) may be used instead of nag_1d_spline_deriv (e02bcc), which takes about 50% longer than nag_1d_spline_evaluate (e02bbc).

## 4References

Cox M G (1972) The numerical evaluation of B-splines J. Inst. Math. Appl. 10 134–149
Cox M G (1978) The numerical evaluation of a spline from its B-spline representation J. Inst. Math. Appl. 21 135–143
de Boor C (1972) On calculating with B-splines J. Approx. Theory 6 50–62

## 5Arguments

1:    $\mathbf{derivs}$Nag_DerivTypeInput
On entry: derivs, of type Nag_DerivType, specifies whether left- or right-hand values of the spline and its derivatives are to be computed (see Section 3). Left- or right-hand values are formed according to whether derivs is equal to $\mathrm{Nag_LeftDerivs}$ or $\mathrm{Nag_RightDerivs}$ respectively. If $x$ does not coincide with a knot, the value of derivs is immaterial. If $x=\mathbf{spline}\mathbf{\to }\mathbf{lamda}\left[3\right]$, right-hand values are computed, and if $x=\mathbf{spline}\mathbf{\to }\mathbf{lamda}\left[\mathbf{spline}\mathbf{\to }\mathbf{n}-4\right]$), left-hand values are formed, regardless of the value of derivs.
Constraint: ${\mathbf{derivs}}=\mathrm{Nag_LeftDerivs}$ or $\mathrm{Nag_RightDerivs}$.
2:    $\mathbf{x}$doubleInput
On entry: the argument $x$ at which the cubic spline and its derivatives are to be evaluated.
Constraint: $\mathbf{spline}\mathbf{\to }\mathbf{lamda}\left[3\right]\le {\mathbf{x}}\le \mathbf{spline}\mathbf{\to }\mathbf{lamda}\left[\mathbf{spline}\mathbf{\to }\mathbf{n}-4\right]$.
3:    $\mathbf{s}\left[4\right]$doubleOutput
On exit: ${\mathbf{s}}\left[\mathit{j}\right]$ contains the value of the $\mathit{j}$th derivative of the spline at the argument $x$, for $\mathit{j}=0,1,2,3$. Note that ${\mathbf{s}}\left[0\right]$ contains the value of the spline.
4:    $\mathbf{spline}$Nag_Spline *
Pointer to structure of type Nag_Spline with the following members:
nIntegerInput
On entry: $\stackrel{-}{n}+7$, where $\stackrel{-}{n}$ is the number of intervals of the spline (which is one greater than the number of interior knots, i.e., the knots strictly within the range ${\lambda }_{4}$ to ${\lambda }_{\stackrel{-}{n}+4}$ over which the spline is defined).
Constraint: $\mathbf{spline}\mathbf{\to }\mathbf{n}\ge 8$.
lamdadoubleInput
On entry: a pointer to which memory of size $\mathbf{spline}\mathbf{\to }\mathbf{n}$ must be allocated. $\mathbf{spline}\mathbf{\to }\mathbf{lamda}\left[\mathit{j}-1\right]$ must be set to the value of the $\mathit{j}$th member of the complete set of knots, ${\lambda }_{\mathit{j}}$, for $\mathit{j}=1,2,\dots ,\stackrel{-}{n}+7$.
Constraint: the ${\lambda }_{j}$ must be in nondecreasing order with $\mathbf{spline}\mathbf{\to }\mathbf{lamda}\left[\mathbf{spline}\mathbf{\to }\mathbf{n}-4\right]>\mathbf{spline}\mathbf{\to }\mathbf{lamda}\left[3\right]$.
cdoubleInput
On entry: a pointer to which memory of size $\mathbf{spline}\mathbf{\to }\mathbf{n}-4$ must be allocated. $\mathbf{spline}\mathbf{\to }\mathbf{c}$ holds the coefficient ${c}_{\mathit{i}}$ of the B-spline ${N}_{\mathit{i}}\left(x\right)$, for $\mathit{i}=1,2,\dots ,\stackrel{-}{n}+3$.
Under normal usage, the call to nag_1d_spline_deriv (e02bcc) will follow a call to nag_1d_spline_fit_knots (e02bac), nag_1d_spline_interpolant (e01bac) or nag_1d_spline_fit (e02bec). In that case, the structure spline will have been set up correctly for input to nag_1d_spline_deriv (e02bcc).
5:    $\mathbf{fail}$NagError *Input/Output
The NAG error argument (see Section 3.7 in How to Use the NAG Library and its Documentation).

## 6Error Indicators and Warnings

NE_ABSCI_OUTSIDE_KNOT_INTVL
On entry, x must satisfy $\mathbf{spline}\mathbf{\to }\mathbf{lamda}\left[3\right]\le {\mathbf{x}}\le \mathbf{spline}\mathbf{\to }\mathbf{lamda}\left[\mathbf{spline}\mathbf{\to }\mathbf{n}-4\right]$:
$\mathbf{spline}\mathbf{\to }\mathbf{lamda}\left[3\right]=〈\mathit{\text{value}}〉$, ${\mathbf{x}}=〈\mathit{\text{value}}〉$, $\mathbf{spline}\mathbf{\to }\mathbf{lamda}\left[〈\mathit{\text{value}}〉\right]=〈\mathit{\text{value}}〉$.
NE_BAD_PARAM
On entry, argument derivs had an illegal value.
NE_INT_ARG_LT
On entry, $\mathbf{spline}\mathbf{\to }\mathbf{n}$ must not be less than 8: $\mathbf{spline}\mathbf{\to }\mathbf{n}=〈\mathit{\text{value}}〉$.
NE_SPLINE_RANGE_INVALID
On entry, the cubic spline range is invalid:
$\mathbf{spline}\mathbf{\to }\mathbf{lamda}\left[3\right]=〈\mathit{\text{value}}〉$ while $\mathbf{spline}\mathbf{\to }\mathbf{lamda}\left[\mathbf{spline}\mathbf{\to }\mathbf{n}-4\right]=〈\mathit{\text{value}}〉$.
These must satisfy $\mathbf{spline}\mathbf{\to }\mathbf{lamda}\left[3\right]<\mathbf{spline}\mathbf{\to }\mathbf{lamda}\left[\mathbf{spline}\mathbf{\to }\mathbf{n}-4\right]$.

## 7Accuracy

The computed value of $s\left(x\right)$ has negligible error in most practical situations. Specifically, this value has an absolute error bounded in modulus by $18×{c}_{\mathrm{max}}×$ machine precision, where ${c}_{\mathrm{max}}$ is the largest in modulus of ${c}_{j},{c}_{j+1},{c}_{j+2}$ and ${c}_{j+3}$, and $j$ is an integer such that ${\lambda }_{j+3}\le x\le {\lambda }_{j+4}$. If ${c}_{j},{c}_{j+1},{c}_{j+2}$ and ${c}_{j+3}$ are all of the same sign, then the computed value of $s\left(x\right)$ has relative error bounded by $20×$ machine precision. For full details see Cox (1978).
No complete error analysis is available for the computation of the derivatives of $s\left(x\right)$. However, for most practical purposes the absolute errors in the computed derivatives should be small.

## 8Parallelism and Performance

nag_1d_spline_deriv (e02bcc) is not threaded in any implementation.

## 9Further Comments

The time taken by this function is approximately linear in $\mathrm{log}\left(\stackrel{-}{n}+7\right)$.
Note: the function does not test all the conditions on the knots given in the description of $\mathbf{spline}\mathbf{\to }\mathbf{lamda}$ in Section 5, since to do this would result in a computation time approximately linear in $\stackrel{-}{n}+7$ instead of $\mathrm{log}\left(\stackrel{-}{n}+7\right)$. All the conditions are tested in nag_1d_spline_fit_knots (e02bac), however, and the knots returned by nag_1d_spline_interpolant (e01bac) or nag_1d_spline_fit (e02bec) will satisfy the conditions.

## 10Example

Compute, at the 7 arguments $x=0$, $1$, $2$, $3$, $4$, $5$, $6$, the left- and right-hand values and first 3 derivatives of the cubic spline defined over the interval $0\le x\le 6$ having the 6 interior knots $x=1$, $3$, $3$, $3$, $4$, $4$, the 8 additional knots $0$, $0$, $0$, $0$, $6$, $6$, $6$, $6$, and the 10 B-spline coefficients $10$, $12$, $13$, $15$, $22$, $26$, $24$, $18$, $14$, 12.
The input data items (using the notation of Section 5) comprise the following values in the order indicated:
 $\stackrel{-}{n}$ $m$ $\mathbf{spline}\mathbf{\to }\mathbf{lamda}\left[j\right]$ for $j=0,1,\dots ,\stackrel{-}{n}+6$ $\mathbf{spline}\mathbf{\to }\mathbf{c}\left[j\right]$, for $j=0,1,\dots ,\stackrel{-}{n}+2$ x m values of x
The example program is written in a general form that will enable the values and derivatives of a cubic spline having an arbitrary number of knots to be evaluated at a set of arbitrary points. Any number of datasets may be supplied.

### 10.1Program Text

Program Text (e02bcce.c)

### 10.2Program Data

Program Data (e02bcce.d)

### 10.3Program Results

Program Results (e02bcce.r)