Nonuniform Splines
Nonuniform grids
In order to create nonuniform spline objects, we must first create the
nonuniform grids on which the spline will be defined. For
multidimensional grids, a grid object is needed for each dimension
(though a single grid object pointer may be used for more than one
dimension).
Grid creation
Currently, there are two nonuniform grids implemented:
Center grid
The center grid grid is a set of points which are more closely
packed near the center of the interval than out the outside. It is
created by specifying four quantities:
- The first point
- The last point
- The ratio of the largest to smallest grid spacing
- The number of points
A center grid is created with the call
NUgrid*
create_center_grid (double start, double end, double ratio,
int num_points);
The center grid function has an analytic inverse, which can be used to
find the nearest grid point to a given point very quickly.
General grid
The general grid is a catch-all for all other types of grids. It is
created with a call to
NUgrid*
create_general_grid (double *points, int num_points);
points is an array of points, which must be
sorted in assending order. num_points is
self-explanatory. While general_grid can be used for any type of grid
spacing, it has the disadvantage that a bisection search must be
performed to find the nearest grid point.
Grid destruction
Grids created with create_x_grid can
be destroyed with a call to
void
destroy_grid (NUgrid* grid);
Nonuniform spline creation
After the necessary grids have been created, a nonuniform spline can
be created using a very similar routines to the uniform ones. The
most apparent difference is that the nonuniform grids are passed
through pointers. Note that the nonuniform grids should not be
destroyed until after the splines which use them.
Function prototypes:
Single-precision real:
NUBspline_1d_s * create_NUBspline_1d_s (NUgrid* x_grid, BCtype_s xBC, float *data);
NUBspline_2d_s * create_NUBspline_2d_s (NUgrid* x_grid, NUgrid* y_grid,
BCtype_s xBC, BCtype_s yBC, float *data);
NUBspline_3d_s * create_NUBspline_3d_s (NUgrid* x_grid, NUgrid* y_grid, NUgrid* z_grid,
BCtype_s xBC, BCtype_s yBC, BCtype_s zBC, float *data);
Single-precision complex:
NUBspline_1d_c * create_NUBspline_1d_c (NUgrid* x_grid, BCtype_c xBC, complex_float *data);
NUBspline_2d_c * create_NUBspline_2d_c (NUgrid* x_grid, NUgrid* y_grid,
BCtype_c xBC, BCtype_c yBC, complex_float *data);
NUBspline_3d_c * create_NUBspline_3d_c (NUgrid* x_grid, NUgrid* y_grid, NUgrid* z_grid,
BCtype_c xBC, BCtype_c yBC, BCtype_c zBC,
complex_float *data);
Double-precision real:
NUBspline_1d_d * create_NUBspline_1d_d (NUgrid* x_grid, BCtype_d xBC, double *data);
NUBspline_2d_d * create_NUBspline_2d_d (NUgrid* x_grid, NUgrid* y_grid,
BCtype_d xBC, BCtype_d yBC, double *data);
NUBspline_3d_d * create_NUBspline_3d_d (NUgrid* x_grid, NUgrid* y_grid, NUgrid* z_grid,
BCtype_d xBC, BCtype_d yBC, BCtype_d zBC, double *data);
Double-precision complex:
NUBspline_1d_z * create_NUBspline_1d_z (NUgrid* x_grid, BCtype_z xBC, complex_double *data);
NUBspline_2d_z * create_NUBspline_2d_z (NUgrid* x_grid, NUgrid* y_grid,
BCtype_z xBC, BCtype_z yBC, complex_double *data);
NUBspline_3d_z * create_NUBspline_3d_z (NUgrid* x_grid, NUgrid* y_grid, NUgrid* z_grid,
BCtype_z xBC, BCtype_z yBC, BCtype_z zBC,
complex_double *data);
Nonuniform spline destruction
The memory used for spline storage can be freed simply by a call to
void
destroy_Bspline (void *spline);
The spline parameter can be a spline of any type and dimension,
uniform or nonuniform.
Nonuniform spline evaluation
For each of the four datatypes, there are four evaluation routines, depending on
which quantities need to be computed:
- Value only
- Value and gradient
- Value, gradient, and Laplacian
- Value, gradient, and Hessian (matrix of 2nd derivatives)
For consistency, all results are returned through pointers passed to the evaluation
routines. Currently, no bounds checking is done for the sake of speed. The user is
responsible for ensuring that the points passed to the evaluation functions fall within
the grids specified at the time of spline creation.
Function prototypes:
Single-precision real:
1D
inline void
eval_NUBspline_1d_s (NUBspline_1d_s * restrict spline,
double x, float* restrict val);
inline void
eval_NUBspline_1d_s_vg (NUBspline_1d_s * restrict spline, double x,
float* restrict val, float* restrict grad);
inline void
eval_NUBspline_1d_s_vgl (NUBspline_1d_s * restrict spline, double x,
float* restrict val, float* restrict grad, float* restrict lapl);
inline void /* identical to above routine in 1D */
eval_NUBspline_1d_s_vgh (NUBspline_1d_s * restrict spline, double x,
float* restrict val, float* restrict grad, float* restrict hess);
2D
inline void
eval_NUBspline_2d_s (NUBspline_2d_s * restrict spline, double x, double y,
float* restrict val);
inline void
eval_NUBspline_2d_s_vg (NUBspline_2d_s * restrict spline, double x, double y,
float* restrict val, float* restrict grad);
inline void
eval_NUBspline_2d_s_vgl (NUBspline_2d_s * restrict spline, double x, double y,
float* restrict val, float* restrict grad, float* restrict lapl);
inline void
eval_NUBspline_2d_s_vgh (NUBspline_2d_s * restrict spline, double x, double y,
float* restrict val, float* restrict grad, float* restrict hess);
3D
inline void
eval_NUBspline_3d_s (NUBspline_3d_s * restrict spline, double x, double y, double z,
float* restrict val);
inline void
eval_NUBspline_3d_s_vg (NUBspline_3d_s * restrict spline, double x, double y, double z,
float* restrict val, float* restrict grad);
inline void
eval_NUBspline_3d_s_vgl (NUBspline_3d_s * restrict spline, double x, double y, double z,
float* restrict val, float* restrict grad, float* restrict lapl);
inline void
eval_NUBspline_3d_s_vgh (NUBspline_3d_s * restrict spline, double x, double y,
float* restrict val, float* restrict grad, float* restrict hess);
Single-precision complex:
1D
inline void
eval_NUBspline_1d_c (NUBspline_1d_c * restrict spline,
double x, complex_float* restrict val);
inline void
eval_NUBspline_1d_c_vg (NUBspline_1d_c * restrict spline, double x,
complex_float* restrict val, complex_float* restrict grad);
inline void
eval_NUBspline_1d_c_vgl (NUBspline_1d_c * restrict spline, double x,
complex_float* restrict val, complex_float* restrict grad, complex_float* restrict lapl);
inline void /* identical to above routine in 1D */
eval_NUBspline_1d_c_vgh (NUBspline_1d_c * restrict spline, double x,
complex_float* restrict val, complex_float* restrict grad, complex_float* restrict hess);
2D
inline void
eval_NUBspline_2d_c (NUBspline_2d_c * restrict spline, double x, double y,
complex_float* restrict val);
inline void
eval_NUBspline_2d_c_vg (NUBspline_2d_c * restrict spline, double x, double y,
complex_float* restrict val, complex_float* restrict grad);
inline void
eval_NUBspline_2d_c_vgl (NUBspline_2d_c * restrict spline, double x, double y,
complex_float* restrict val, complex_float* restrict grad, complex_float* restrict lapl);
inline void
eval_NUBspline_2d_c_vgh (NUBspline_2d_c * restrict spline, double x, double y,
complex_float* restrict val, complex_float* restrict grad, complex_float* restrict hess);
3D
inline void
eval_NUBspline_3d_c (NUBspline_3d_c * restrict spline, double x, double y, double z,
complex_float* restrict val);
inline void
eval_NUBspline_3d_c_vg (NUBspline_3d_c * restrict spline, double x, double y, double z,
complex_float* restrict val, complex_float* restrict grad);
inline void
eval_NUBspline_3d_c_vgl (NUBspline_3d_c * restrict spline, double x, double y, double z,
complex_float* restrict val, complex_float* restrict grad, complex_float* restrict lapl);
inline void
eval_NUBspline_3d_c_vgh (NUBspline_3d_c * restrict spline, double x, double y,
complex_float* restrict val, complex_float* restrict grad, complex_float* restrict hess);
Double-precision real:
1D
inline void
eval_NUBspline_1d_d (NUBspline_1d_d * restrict spline,
double x, double* restrict val);
inline void
eval_NUBspline_1d_d_vg (NUBspline_1d_d * restrict spline, double x,
double* restrict val, double* restrict grad);
inline void
eval_NUBspline_1d_d_vgl (NUBspline_1d_d * restrict spline, double x,
double* restrict val, double* restrict grad, double* restrict lapl);
inline void /* identical to above routine in 1D */
eval_NUBspline_1d_d_vgh (NUBspline_1d_d * restrict spline, double x,
double* restrict val, double* restrict grad, double* restrict hess);
2D
inline void
eval_NUBspline_2d_d (NUBspline_2d_d * restrict spline, double x, double y,
double* restrict val);
inline void
eval_NUBspline_2d_d_vg (NUBspline_2d_d * restrict spline, double x, double y,
double* restrict val, double* restrict grad);
inline void
eval_NUBspline_2d_d_vgl (NUBspline_2d_d * restrict spline, double x, double y,
double* restrict val, double* restrict grad, double* restrict lapl);
inline void
eval_NUBspline_2d_d_vgh (NUBspline_2d_d * restrict spline, double x, double y,
double* restrict val, double* restrict grad, double* restrict hess);
3D
inline void
eval_NUBspline_3d_d (NUBspline_3d_d * restrict spline, double x, double y, double z,
double* restrict val);
inline void
eval_NUBspline_3d_d_vg (NUBspline_3d_d * restrict spline, double x, double y, double z,
double* restrict val, double* restrict grad);
inline void
eval_NUBspline_3d_d_vgl (NUBspline_3d_d * restrict spline, double x, double y, double z,
double* restrict val, double* restrict grad, double* restrict lapl);
inline void
eval_NUBspline_3d_d_vgh (NUBspline_3d_d * restrict spline, double x, double y,
double* restrict val, double* restrict grad, double* restrict hess);
Double-precision complex:
1D
inline void
eval_NUBspline_1d_z (NUBspline_1d_z * restrict spline,
double x, complex_double* restrict val);
inline void
eval_NUBspline_1d_z_vg (NUBspline_1d_z * restrict spline, double x,
complex_double* restrict val, complex_double* restrict grad);
inline void
eval_NUBspline_1d_z_vgl (NUBspline_1d_z * restrict spline, double x,
complex_double* restrict val, complex_double* restrict grad, complex_double* restrict lapl);
inline void /* identical to above routine in 1D */
eval_NUBspline_1d_z_vgh (NUBspline_1d_z * restrict spline, double x,
complex_double* restrict val, complex_double* restrict grad, complex_double* restrict hess);
2D
inline void
eval_NUBspline_2d_z (NUBspline_2d_z * restrict spline, double x, double y,
complex_double* restrict val);
inline void
eval_NUBspline_2d_z_vg (NUBspline_2d_z * restrict spline, double x, double y,
complex_double* restrict val, complex_double* restrict grad);
inline void
eval_NUBspline_2d_z_vgl (NUBspline_2d_z * restrict spline, double x, double y,
complex_double* restrict val, complex_double* restrict grad, complex_double* restrict lapl);
inline void
eval_NUBspline_2d_z_vgh (NUBspline_2d_z * restrict spline, double x, double y,
complex_double* restrict val, complex_double* restrict grad, complex_double* restrict hess);
3D
inline void
eval_NUBspline_3d_z (NUBspline_3d_z * restrict spline, double x, double y, double z,
complex_double* restrict val);
inline void
eval_NUBspline_3d_z_vg (NUBspline_3d_z * restrict spline, double x, double y, double z,
complex_double* restrict val, complex_double* restrict grad);
inline void
eval_NUBspline_3d_z_vgl (NUBspline_3d_z * restrict spline, double x, double y, double z,
complex_double* restrict val, complex_double* restrict grad, complex_double* restrict lapl);
inline void
eval_NUBspline_3d_z_vgh (NUBspline_3d_z * restrict spline, double x, double y,
complex_double* restrict val, complex_double* restrict grad, complex_double* restrict hess);