|
fitpack
Modern Fortran library for curve and surface fitting with splines
|
This tutorial covers two specialized surface types for data on rectangular parameter grids: fitpack_grid_surface for scalar-valued surfaces \( z = s(x, y) \), and fitpack_parametric_surface for multi-component surfaces \( \mathbf{s}(u, v) \in \mathbb{R}^d \).
Both exploit the Kronecker product structure of tensor-product B-splines on rectangular grids. When the data points \( (x_i, y_j) \) form a full grid, the normal equations decouple into smaller systems along each axis, reducing the computational cost from \( \mathcal{O}(n_x \, n_y) \) to \( \mathcal{O}(n_x + n_y) \) per iteration. This makes gridded fitting significantly faster than the general scattered-data algorithm (surfit).
Construct a grid surface from coordinate vectors x(nx), y(ny) and function values z(ny, nx). Note that the first index of z corresponds to y and the second to x:
The smoothing parameter controls the trade-off between fidelity and smoothness, just as for curves. Setting smoothing=zero produces an interpolating spline. An optional order argument sets the B-spline degree (default 3, i.e. bicubic).
Evaluate the fitted surface at scattered points or on a rectangular output grid:
The gsurf\eval generic dispatches to scattered-point evaluation (bispeu), while gsurf\eval_ongrid uses the faster grid evaluator (bispev) and returns an array with shape (size(y_out), size(x_out)).
Compute partial derivatives \( \partial^{n_x + n_y} s / \partial x^{n_x} \partial y^{n_y} \):
The integer arguments are the derivative orders \( n_x \) and \( n_y \) (both must satisfy \( 0 \leq n_x < k_x \) and \( 0 \leq n_y < k_y \)).
Compute the double integral over a rectangular sub-domain:
\[ I = \iint_{[x_1, x_2] \times [y_1, y_2]} s(x, y) \, dx \, dy \]
The two arguments are the lower and upper corners of the integration rectangle.
Extract a 1D profile at a fixed coordinate value:
The returned fitpack_curve is a full 1D spline that can be evaluated, differentiated, and integrated independently.
To build a new surface object whose evaluation gives a partial derivative:
fitpack_parametric_surface fits a bicubic tensor-product spline surface \( \mathbf{s}(u, v) = (s_1(u,v), \ldots, s_d(u,v)) \) through data given on a rectangular parameter grid \( (u_i, v_j) \). This is the natural choice for geometry embedded in \( \mathbb{R}^3 \) (or higher dimensions) where the surface is described by a mapping from a 2D parameter domain.
The data array z has shape (nv, nu, idim), where idim is the number of coordinate components:
The periodic_BC argument is a 2-element logical array [periodic_u, periodic_v]. When an element is .true., the corresponding parameter direction is treated as periodic, enforcing continuity of the spline and its derivatives across the boundary.
Evaluation returns an array with the surface coordinates:
A torus with major radius \( R \) and tube radius \( r \) is periodic in both \( u \) (around the hole) and \( v \) (around the tube):
\[ \mathbf{s}(u, v) = \begin{pmatrix} (R + r \cos v) \cos u \\ (R + r \cos v) \sin u \\ r \sin v \end{pmatrix}, \quad u, v \in [0, 2\pi). \]
Choose the surface type based on the structure of your input data:
| Criterion | fitpack_grid_surface | fitpack_surface |
|---|---|---|
| Input layout | Rectangular grid \( z(y_j, x_i) \) | Arbitrary \( (x_i, y_i, z_i) \) |
| Core routine | regrid | surfit |
| Speed | Fast (Kronecker structure) | General |
| Weights | Not supported | Per-point weights |
| Typical use | Tabulated functions, image data | Sensor readings, scattered measurements |
Rule of thumb: if the data can be arranged on a rectangular grid with no missing values, fitpack_grid_surface is always the better choice. For irregular point clouds, use fitpack_surface.
For surfaces embedded in \( \mathbb{R}^d \) (e.g. geometry defined by a parameter mapping), use fitpack_parametric_surface instead.
A full working program demonstrating both fitpack_grid_surface (peaks function with evaluation, integration, cross-sections, and derivative splines) and fitpack_parametric_surface (torus with periodic boundary conditions) is available in:
Build and run it with: