1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
// SPDX-License-Identifier: Apache-2.0 OR MIT
// Copyright (c) 2021-2026, Harbers Bik LLC
//! # splinefit: B-Spline Curve and Surface Fitting
//!
//! A pure-Rust B-spline fitting library with an ergonomic high-level API, backed by a
//! line-by-line Rust translation of Paul Dierckx' classic Fortran fitting library.
//!
//! No Fortran compiler, no C compiler, no build-time dependencies — just Rust.
//!
//! The original Fortran library was written by Paul Dierckx in the mid-1980s and remains
//! one of the most complete and mathematically rigorous B-spline fitting libraries available.
//! It is described in detail in his book:
//! [Curve and Surface Fitting with Splines](https://www.google.com/books/edition/Curve_and_Surface_Fitting_with_Splines/-RIQ3SR0sZMC?hl=en),
//! Oxford University Press, 1993.
//!
//! Numerical output is verified against [scipy](https://docs.scipy.org/doc/scipy/reference/interpolate.html),
//! which wraps the original Fortran library.
//!
//! ## Usage
//!
//! Add this to your `Cargo.toml`:
//!
//! ```toml
//! [dependencies]
//! splinefit = "0.4.1"
//! ```
//!
//! ## Example
//!
//! Fit a smoothing cubic spline to noisy data, then evaluate it:
//!
//! ```rust
//! use splinefit::{CubicSplineFit, evaluate};
//! use std::f64::consts::PI;
//!
//! let m = 20usize;
//! let x: Vec<f64> = (0..m).map(|i| i as f64 * 2.0 * PI / (m - 1) as f64).collect();
//! let y: Vec<f64> = x.iter().map(|&xi| xi.sin()).collect();
//!
//! let spline = CubicSplineFit::new(x.clone(), y)
//! .smoothing_spline(0.05)
//! .expect("fit failed");
//!
//! let y_fit = evaluate::evaluate(&spline, &x).expect("evaluate failed");
//! assert!((y_fit[0] - x[0].sin()).abs() < 0.1);
//! ```
//!
//! ## Fit types
//!
//! | Type alias | Description |
//! |---|---|
//! | `CubicSplineFit` | Smoothing / interpolating 1-D cubic spline |
//! | `LinearSplineFit` / `QuinticSplineFit` | Same, degree 1 or 5 |
//! | `CubicSplineFit2D` | Parametric cubic curve in 2-D |
//! | `CubicSplineFit3D` | Parametric cubic curve in 3-D |
//! | `ClosedCubicSplineFit2D` | Closed (periodic) parametric curve in 2-D |
//! | `ClosedCubicSplineFit3D` | Closed (periodic) parametric curve in 3-D |
//!
//! Each fit type exposes three methods:
//!
//! | Method | Description |
//! |---|---|
//! | `.interpolating_spline()` | Exact interpolation through all data points |
//! | `.smoothing_spline(rms)` | Fewest knots with RMS error ≤ `rms` |
//! | `.cardinal_spline(dt)` | Weighted least-squares on a fixed equidistant knot grid |
//!
//! ## Relationship to `dierckx-sys` and `splinify`
//!
//! `dierckx-sys` wrapped the original Fortran sources via `gfortran`, requiring a Fortran
//! compiler at build time. `splinify` used `dierckx-sys` as its backend.
//!
//! This crate (`splinefit`) combines the high-level API from `splinify` with a pure-Rust
//! translation of the Fortran engine, so it builds anywhere Rust builds with no external
//! toolchain dependencies.
//!
//! ## Performance
//!
//! The pure-Rust engine matches or outperforms SciPy's Fortran-compiled FITPACK.
//! Benchmarks on Apple M1 (macOS), fitting and evaluating `sin(x)` on `[0, 2π]`:
//!
//! **1-D smoothing fit**
//!
//! | Data points | Rust | SciPy/Fortran |
//! |---:|---:|---:|
//! | 50 | 17 µs | 21 µs |
//! | 200 | 57 µs | 62 µs |
//! | 1 000 | 279 µs | 282 µs |
//! | 5 000 | 1.35 ms | 1.4 ms |
//!
//! **1-D evaluation (10× data points)**
//!
//! | Data points | Rust | SciPy/Fortran |
//! |---:|---:|---:|
//! | 50 | 12 µs | 18 µs |
//! | 200 | 50 µs | 61 µs |
//! | 1 000 | 254 µs | 307 µs |
//! | 5 000 | 1.27 ms | 1.5 ms |
//!
//! **2-D parametric evaluation (10× data points)**
//!
//! | Data points | Rust | SciPy/Fortran |
//! |---:|---:|---:|
//! | 50 | 12 µs | 34 µs |
//! | 200 | 50 µs | 121 µs |
//! | 1 000 | 248 µs | 611 µs |
//!
//! Reproduce with `cargo bench` (Rust) and `python3 benches/scipy_bench.py` (SciPy).
//!
//! ## WebAssembly / JavaScript
//!
//! This crate compiles to WebAssembly via [`wasm-pack`](https://rustwasm.github.io/wasm-pack/).
//! Enable the `wasm` feature to expose a `CubicSpline` class to JavaScript.
//!
//! ```html
//! <script type="module">
//! import init, { CubicSpline } from "https://esm.sh/@harbik/splinefit";
//! await init();
//!
//! // Fit a smoothing spline to sin(x)
//! const x = Float64Array.from({ length: 50 }, (_, i) => i * 2 * Math.PI / 49);
//! const y = x.map(Math.sin);
//! const spline = CubicSpline.smoothing(x, y, 0.05);
//!
//! // Evaluate at 200 points
//! const xNew = Float64Array.from({ length: 200 }, (_, i) => i * 2 * Math.PI / 199);
//! const yFit = spline.evaluate(xNew);
//!
//! // Integration and root-finding
//! const area = spline.integral(0, Math.PI); // ∫₀^π sin(x) dx ≈ 2
//! const zeros = spline.roots(); // interior zeros
//! </script>
//! ```
//!
//! ## License
//!
//! The original Dierckx Fortran algorithms (on which this translation is based) were
//! downloaded from [netlib.org](http://www.netlib.org/dierckx/) and carry no license
//! restrictions. Please acknowledge Paul Dierckx' work in your projects.
//!
//! All Rust source in this repository is © 2021–2026 Harbers Bik LLC, dual-licensed under:
//!
//! * Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE))
//! * MIT license ([LICENSE-MIT](LICENSE-MIT))
//!
//! at your option.
//!
//! ## Contribution
//!
//! Unless you explicitly state otherwise, any contribution intentionally submitted
//! for inclusion in the work by you, as defined in the Apache-2.0 license, shall be
//! dual licensed as above, without any additional terms or conditions.
// Private backend: pure-Rust translation of the Dierckx Fortran library.
// Public high-level API.
pub use *;
pub use *;
pub use *;
pub use *;
use error;
use fmt;
pub type Result<T> = Result;
// Single Output Spline Fit
pub type LinearSplineFit = ;
pub type CubicSplineFit = ;
pub type QuinticSplineFit = ;
// Multi-Output Parametrized Curve Fits
pub type LinearSplineFit1D = ;
pub type CubicSplineFit1D = ;
pub type QuinticSplineFit1D = ;
pub type LinearSplineFit2D = ;
pub type CubicSplineFit2D = ;
pub type QuinticSplineFit2D = ;
pub type LinearSplineFit3D = ;
pub type CubicSplineFit3D = ;
pub type QuinticSplineFit3D = ;
// Closed Periodic Curve Fits
pub type ClosedLinearSplineFit2D = ;
pub type ClosedCubicSplineFit2D = ;
pub type ClosedQuinticSplineFit2D = ;
pub type ClosedLinearSplineFit3D = ;
pub type ClosedCubicSplineFit3D = ;
pub type ClosedQuinticSplineFit3D = ;
;