|
fitpack
Modern Fortran library for curve and surface fitting with splines
|
This tutorial covers bivariate spline fitting on disc-shaped domains using FITPACK's polar coordinate types: fitpack_polar for scattered data and fitpack_grid_polar for gridded data.
Many physical problems produce data on disc-shaped or circular regions. FITPACK provides two types that handle the polar coordinate transformation internally and enforce the continuity constraints required at the origin:
| Type | Input data | Boundary | Core routine |
|---|---|---|---|
fitpack_polar | Scattered \( (x_i, y_i, z_i) \) | General \( r(\theta) \) | polar |
fitpack_grid_polar | Grid \( z(v_j, u_i) \) | Constant radius \( r \) | pogrid |
Always prefer fitpack_grid_polar when data lies on a polar grid – the pogrid algorithm exploits the grid structure and is significantly more efficient.
Given a disc bounded by \( r(\theta) \), FITPACK maps Cartesian coordinates to normalized polar coordinates \( (u, v) \):
\[ x = u \, r(v) \cos v, \quad y = u \, r(v) \sin v, \quad 0 \leq u \leq 1, \; -\pi \leq v \leq \pi \]
The normalized radial coordinate \( u = \sqrt{x^2 + y^2} / r(\theta) \) lies in \( [0, 1] \) regardless of boundary shape, and \( v = \theta \) is the polar angle. A bicubic spline \( s(u, v) \) is fitted in the rectangular parameter domain \( [0, 1] \times [-\pi, \pi] \).
Because all angles \( v \) map to the same physical point when \( u = 0 \), the spline must satisfy continuity constraints:
bc_continuity_origin | Constraint |
|---|---|
| 0 | \( C^0 \): \( s(0, v) = \text{const} \) |
| 1 | \( C^1 \): additionally \( \partial s / \partial u \) consistent across angles |
| 2 | \( C^2 \): second-order consistency (default for fitpack_polar) |
fitpack_polarfitpack_polar accepts scattered Cartesian coordinates and a user-supplied boundary function \( r(\theta) \):
| Argument | Description |
|---|---|
x(:), y(:) | Cartesian coordinates of the scattered data |
z(:) | Function values at those points |
boundary | Procedure matching fitpack_polar_boundary – returns \( r(\theta) \) |
w(:) | Optional per-point weights (default: unit weights) |
smoothing | Optional smoothing parameter \( s \) |
After the initial fit, adjust smoothing without resupplying data:
Evaluate at Cartesian points – the \( (u, v) \) transform is internal:
fitpack_grid_polarfitpack_grid_polar accepts data on a polar grid with a constant boundary radius:
| Argument | Description |
|---|---|
u(:) | Radial grid, \( 0 < u_1 < \cdots < u_{n_u} \leq 1 \) |
v(:) | Angular grid, \( -\pi \leq v_1 < \cdots < v_{n_v} < \pi \) |
r | Constant boundary radius |
z(nv, nu) | Function values (angular index first) |
z0 | Optional function value at origin \( u = 0 \) |
smoothing | Optional smoothing parameter \( s \) |
Use gpol\set_origin_BC to control spline behavior at the origin:
| Argument | Effect |
|---|---|
z0 | Prescribe the function value at the origin |
exact | .true.: interpolate \( z_0 \) exactly; .false.: approximate |
differentiable | .true.: enforce \( C^1 \) at origin; .false.: \( C^0 \) only |
When z0 is omitted, no origin constraint is imposed.
Evaluate on \( (u, v) \) coordinates:
The boundary function for fitpack_polar must match the abstract interface fitpack_polar_boundary – a pure function receiving \( \theta \in [-\pi, \pi] \) and returning a positive radius:
Unit disc (constant radius):
Ellipse with semi-axes \( a \) and \( b \):
A fully worked program covering both scattered and gridded polar fitting is provided in the source tree. Build and run with:
examples/example_polar.f90All routines return an integer(FP_FLAG) error code:
| Flag | Meaning |
|---|---|
FITPACK_OK (0) | Success |
FITPACK_INTERPOLATING_OK (-1) | Interpolating spline returned |
FITPACK_S_TOO_SMALL (1) | Smoothing too small for the knot budget |
FITPACK_MAXIT (2) | Maximum iterations reached |
FITPACK_INPUT_ERROR (10) | Invalid input data |