|
fitpack
Modern Fortran library for curve and surface fitting with splines
|
This tutorial covers shape-preserving spline fitting with fitpack_convex_curve, which enforces local convexity or concavity constraints on a cubic spline. Use it when the data represents a physical quantity that must be convex or concave — e.g. moisture content vs depth, dose-response curves, or thermodynamic isotherms — and an unconstrained spline would introduce spurious wiggles.
A cubic B-spline \( s(x) = \sum_j c_j B_j(x) \) is locally convex ( \( s''(x) \geq 0 \)) when the coefficient second differences satisfy
\[ c_{j-1} - 2\,c_j + c_{j+1} \geq 0 \]
and locally concave ( \( s''(x) \leq 0 \)) when
\[ c_{j-1} - 2\,c_j + c_{j+1} \leq 0 \]
FITPACK expresses these requirements through per-data-point flags \( v_i \in \{-1, 0, +1\} \) with the constraint \( s''(x_i)\,v_i \leq 0 \):
| Flag | Constraint | Shape |
|---|---|---|
| \( v_i = +1 \) | \( s''(x_i) \leq 0 \) | Concave (curves downward) |
| \( v_i = -1 \) | \( s''(x_i) \geq 0 \) | Convex (curves upward) |
| \( v_i = 0 \) | none | Unconstrained |
The fitting always uses cubic splines ( \( k = 3 \)). The core solver (concon) places knots automatically to satisfy the smoothing constraint while respecting the requested convexity at every data point.
Consider moisture-content measurements as a function of depth. The data rises quickly then levels off — a concave profile.
Call curve\fit with a smoothing parameter. The solver selects knots automatically while enforcing \( s''(x_i) \leq 0 \) at every data point:
Without constraints, a standard fitpack_curve may oscillate through noisy data, creating regions where the second derivative changes sign. The constrained fit eliminates these wiggles:
The constrained spline guarantees \( s''(x) \leq 0 \) throughout.
The constraint vector need not be uniform. Assign different flags per point for data that changes curvature sign:
Setting \( v_i = 0 \) leaves individual points unconstrained, which is useful at transition regions where the curvature sign is unknown.
A one-step constructor combines new_points, set_convexity, and fit:
fitpack_convex_curve extends fitpack_curve with convexity constraints. The spline degree is always cubic ( \( k = 3 \)).
| Method | Description |
|---|---|
curve\new_points(x, y, w) | Load data points and optional weights |
curve\set_convexity(v) | Set per-point convexity flags ( \( +1 \), \( -1 \), or \( 0 \)) |
curve\fit(smoothing) | Fit with automatic knots (calls concon) |
curve\least_squares() | Least-squares fit with current knots (calls cocosp) |
curve\eval(x) | Evaluate the spline |
curve\dfdx(x, order) | Evaluate derivatives |
curve\integral(a, b) | Definite integral over \( [a, b] \) |
curve\destroy() | Release allocated memory |
See examples/example_convex_curve.f90 (examples/example_convex_curve.f90) for a full working program that loads moisture-content data with endpoint-emphasized weights, fits at multiple smoothing levels, and prints a comparison table of knot count, residual, and maximum second derivative.