pub mod spline;
pub mod woltring;
pub use crate::spline::GcvSpline;
pub use crate::woltring::support::FittingError;
#[cfg(test)]
mod tests {
use crate::woltring::{gcvspl::fit_gcv_spline, splder::evaluate_spline};
use crate::GcvSpline;
#[test]
fn test_sin_eval() {
let knots: Vec<f64> = (0..=100).map(|e| e as f64).collect();
let data = knots.iter().map(|e| (e * 0.01).sin()).collect();
let weights = vec![1.0; knots.len()];
let coefs = fit_gcv_spline(&knots, &data, &weights, 3, 0.0).unwrap();
let value = evaluate_spline(0, 3, 50.5, &knots, &coefs, 0);
assert!((value - 0.505_f64.sin()).abs() < 1e-15)
}
#[test]
fn test_sin_derivative() {
let knots: Vec<f64> = (0..=100).map(|e| e as f64).collect();
let data = knots.iter().map(|e| (e * 0.01).sin()).collect();
let weights = vec![1.0; knots.len()];
let coefs = fit_gcv_spline(&knots, &data, &weights, 3, 0.0).unwrap();
let value = evaluate_spline(1, 3, 50.5, &knots, &coefs, 0);
assert!((value - 0.01 * 0.505_f64.cos()).abs() < 1e-15)
}
#[test]
fn test_sin_second_derivative() {
let knots: Vec<f64> = (0..=100).map(|e| e as f64).collect();
let data = knots.iter().map(|e| (e * 0.01).sin()).collect();
let weights = vec![1.0; knots.len()];
let coefs = fit_gcv_spline(&knots, &data, &weights, 3, 0.0).unwrap();
let value = evaluate_spline(2, 3, 50.5, &knots, &coefs, 0);
assert!((value + 0.01 * 0.01 * 0.505_f64.sin()).abs() < 1e-15)
}
#[test]
fn test_default() {
let spline = GcvSpline::<f32>::new();
assert_eq!(spline.knots(), vec![0., 1.]);
}
#[test]
fn test_multiple_evaluations() {
let time: Vec<f64> = vec![0., 1., 3., 4., 5., 6.];
let values = vec![0., 1., 9., 16., 25., 36.];
let spline = GcvSpline::from_data(&time, &values).unwrap();
let interpolated = spline.points(&vec![2., 3.5, 5.]);
let derivatives = spline.derivative(&vec![2., 3.5, 5.], 1);
assert!((interpolated[0] - 2. * 2.).abs() < 1e-12);
assert!((interpolated[1] - 3.5 * 3.5).abs() < 1e-12);
assert!((interpolated[2] - 5. * 5.).abs() < 1e-12);
assert!((derivatives[0] - 2. * 2.).abs() < 1e-12);
assert!((derivatives[1] - 2. * 3.5).abs() < 1e-12);
assert!((derivatives[2] - 2. * 5.).abs() < 1e-12);
}
}