# 2.1.17.5.8 ocmath_2d_spline_interpolant

## Description

Computes a bicubic spline interpolating surface through a set of data values, given on a rectangular grid in the x-y plane.

## Syntax

int ocmath_2d_spline_interpolant( int nX, int nY, const double * pX, const double * pY, const double * pZ, ocmath_2dSpline * spline )

## Parameters

nX
[input] Number of x abcissae ( nX > 4 )
nY
[input] Number of y abcissae ( nY > 4 )
pX
[input] pointer to x abcissae values (size nX), Must be strictly increasing.
pY
[input] pointer to y abcissae values (size nY), Must be strictly increasing.
pZ
[input] pointer to function values to interpolate. (size nX by nY)
spline
[output]
spline->nx = nX + 4
spline->ny = nY + 4
spline->lamda = pointer to the knots in the x direction. (size nX + 4)
spline->mu = pointer to the knots in the y direction. (size nY + 4)
spline->c = pointer to coefficients of the B-spline interpolant.(size nX by nY)

## Return

NE_NOERROR (code 0) --- success

NE_INT_ARG_LT (error code 11) --- nX < 4 or nY < 4

NE_NOT_STRICTLY_INCREASING (error code 63) --- pX[i] or pY[i] is not strictly increasing

NE_ALLOC_FAIL (error code 73) --- memory allocation failed

NE_DATA_ILL_CONDITIONED (error code 252) --- An intermediate set of linear equations is singular, the data is too ill-conditioned to compute B-spline coefficients

## Examples

EX1

//This program reads in values of mx, xq for q = 1, 2, . . .,mx, my
//and yr for r = 1, 2, . . .,my, followed by values of the
//ordinates fq,r defined at the grid points (xq, yr). It then calls
//ocmath_2d_spline_interpolant to compute a bicubic spline interpolant
//of the data values, and prints the values of the knots and
//B-spline coefficients. Finally it evaluates the spline at a
//small sample of points on a rectangular grid.
void ocmath_2d_spline_interpolant_ex1()
{
int i, j, mx, my, npx, npy;
double fg[400], tx[20], ty[20];
double xhi, yhi, xlo, ylo, step;
ocmath_2dSpline spline;

mx = 7;
my = 6;
double x[20] = {1.0, 1.10, 1.30, 1.50, 1.60, 1.80, 2.00};

double y[20] = {0.00, 0.10, 0.40, 0.70, 0.90, 1.00};

double f[400] = {1.00, 1.10, 1.40, 1.70, 1.90, 2.00, 1.21, 1.31, 1.61, 1.91,
2.11, 2.21, 1.69, 1.79, 2.09, 2.39, 2.59, 2.69, 2.25, 2.35,
2.65, 2.95, 3.15, 3.25, 2.56, 2.66, 2.96, 3.26, 3.46, 3.56,
3.24, 3.34, 3.64, 3.94, 4.14, 4.24, 4.00, 4.10, 4.40, 4.70,
4.90, 5.00};

ocmath_2d_spline_interpolant(mx, my, x, y, f, &spline);

printf("Distinct knots in x direction located at\n");
for (j=3; j<spline.nx-3; j++)
{
printf("%12.4f",spline.lamda[j]);
if((j-3)%5==4 || j==spline.nx - 4)
printf("\n");
}

printf("\nDistinct knots in y direction located at\n");
for (j=3; j<spline.ny-3; j++)
{
printf("%12.4f",spline.mu[j]);
if((j-3)%5==4 || j==spline.ny-4)
printf("\n");
}

printf("\nThe B-Spline coefficients:\n");
for (i=0; i<mx; i++)
{
for (j=0; j<my; j++)
printf("%9.4f",spline.c[my*i+j]);
printf("\n");
}

npx = 6;
npy = 6;
xlo = 1.0;
ylo = 0.0;
xhi = 2.0;
yhi = 1.0;

step = (xhi-xlo)/(1.0*(npx-1));
printf("\nSpline evaluated on a regular mesh (x across, y down): \n ");

for (i=0; i<npx; i++)
{
if(xlo + i * step > xhi)
tx[i] = xhi;
else
tx[i] = xlo + i * step;
printf(" %5.2f ",tx[i]);
}

step = (yhi-ylo)/(npy-1);
for (i=0; i<npy; i++)
{
if(ylo + i * step > yhi)
ty[i] = yhi;
else
ty[i] = ylo + i * step;
}
for(i=0; i<npx; i++)
for(j=0; j<npy; j++)
ocmath_2d_spline_eval(1, &tx[i], &ty[j], &fg[i*npx + j], &spline);

printf("\n");
for (j=0; j<npy; j++)
{
printf("%5.2f",ty[j]);
for (i=0; i<npx; i++)
printf("%8.3f ",fg[npy*i+j]);
printf("\n");
}
ocmath_free(spline.lamda);
ocmath_free(spline.mu);
ocmath_free(spline.c);
}