use akima_spline::*;
#[test]
fn test_interpolation() {
let xdata = vec![-2.0, -1.0, 0.0, 1.0, 2.0];
let ydata = vec![0.0, 1.0, 0.0, 1.0, 0.0];
let spline = AkimaSpline::new(xdata, ydata, None, None).unwrap();
let result = 0.5;
approx::assert_abs_diff_eq!(spline.eval(0.5).unwrap(), result, epsilon = 0.0001);
approx::assert_abs_diff_eq!(spline.eval(-0.5).unwrap(), result, epsilon = 0.0001);
let result = 0.896;
approx::assert_abs_diff_eq!(spline.eval(0.8).unwrap(), result, epsilon = 0.0001);
approx::assert_abs_diff_eq!(spline.eval(-0.8).unwrap(), result, epsilon = 0.0001);
let xdata = vec![-2.0, -1.5, -1.0, -0.5, 0.0, 0.5, 1.0, 1.5, 2.0];
let ydata: Vec<f64> = xdata.clone().into_iter().map(|x: f64| x.sin()).collect();
let spline = AkimaSpline::new(xdata, ydata, None, None).unwrap();
approx::assert_abs_diff_eq!(spline.eval(0.5).unwrap(), (0.5f64).sin(), epsilon = 0.0001);
approx::assert_abs_diff_eq!(spline.eval(0.25).unwrap(), 0.239712769, epsilon = 0.0001);
approx::assert_abs_diff_eq!(spline.eval(-2.0).unwrap(), -0.909297, epsilon = 0.0001);
approx::assert_abs_diff_eq!(spline.eval(2.0).unwrap(), 0.909297, epsilon = 0.0001);
assert!(spline.eval(-2.1).is_none()); assert!(spline.eval(2.1).is_none()); }
#[test]
fn test_extrapolation() {
{
let xdata = vec![0.0, 0.5, 1.0, 1.5, 2.0];
let ydata: Vec<f64> = xdata.clone().into_iter().map(|x: f64| x.sin()).collect();
let extrapl = Some(vec![1.0]);
let spline = AkimaSpline::new(xdata, ydata, extrapl, None).unwrap();
assert!(spline.eval(2.1).is_none()); approx::assert_abs_diff_eq!(spline.eval(-1.0).unwrap(), -1.0, epsilon = 0.0001);
}
{
let xdata = vec![-0.5, 0.0, 0.5, 1.0, 1.5];
let ydata: Vec<f64> = xdata.clone().into_iter().map(|x: f64| x.sin()).collect();
let extrapl = Some(vec![1.0]); let extrapr = Some(vec![1.0, 0.0]); let spline = AkimaSpline::new(xdata, ydata, extrapl, extrapr).unwrap();
approx::assert_abs_diff_eq!(spline.eval(-1.0).unwrap(), -0.9794, epsilon = 0.0001);
approx::assert_abs_diff_eq!(
spline.eval(2.0).unwrap(),
0.99749 + 0.5 * 0.5,
epsilon = 0.0001
);
approx::assert_abs_diff_eq!(
spline.eval(4.0).unwrap(),
0.99749 + 2.5 * 2.5,
epsilon = 0.0001
);
}
{
let xdata = vec![-0.5, 0.0, 0.5, 1.0, 1.5];
let ydata: Vec<f64> = xdata.clone(); let extrapl = Some(Vec::new()); let extrapr = Some(Vec::new()); let spline = AkimaSpline::new(xdata, ydata, extrapl, extrapr).unwrap();
assert_eq!(spline.eval(-1.0).unwrap(), -0.5);
assert_eq!(spline.eval(2.0).unwrap(), 1.5);
assert_eq!(spline.eval(10.0).unwrap(), 1.5);
}
}
#[test]
fn test_derivative() {
{
let xdata = vec![0.0, 0.5, 1.0, 1.5, 2.0];
let ydata = vec![1.0, 1.0, 1.0, 1.5, 2.0];
let spline = AkimaSpline::new(xdata, ydata, None, None).unwrap();
approx::assert_abs_diff_eq!(spline.derivative(0.0, 1).unwrap(), 0.0, epsilon = 0.0001);
approx::assert_abs_diff_eq!(spline.derivative(0.5, 1).unwrap(), 0.0, epsilon = 0.0001);
approx::assert_abs_diff_eq!(spline.derivative(1.5, 1).unwrap(), 1.0, epsilon = 0.0001);
}
{
let xdata = vec![-0.5, 0.0, 0.5, 1.0, 1.5];
let ydata: Vec<f64> = xdata.clone().into_iter().map(|x: f64| x.sin()).collect();
let extrapl = Some(vec![1.0]); let extrapr = Some(vec![1.0, 0.0]); let spline = AkimaSpline::new(xdata, ydata, extrapl, extrapr).unwrap();
approx::assert_abs_diff_eq!(spline.derivative(-0.5, 1).unwrap(), 1.0, epsilon = 0.0001);
approx::assert_abs_diff_eq!(
spline.derivative(-1e-8, 1).unwrap(),
0.95885,
epsilon = 0.0001
);
approx::assert_abs_diff_eq!(
spline.derivative(0.0, 1).unwrap(),
0.95885,
epsilon = 0.0001
);
approx::assert_abs_diff_eq!(
spline.derivative(1e-8, 1).unwrap(),
0.95885,
epsilon = 0.0001
);
assert_eq!(spline.derivative(-0.51, 1).unwrap(), 1.0);
assert_eq!(spline.derivative(-1.0, 1).unwrap(), 1.0);
approx::assert_abs_diff_eq!(
spline.derivative(-0.5, 2).unwrap(),
-0.3291913,
epsilon = 0.0001
);
approx::assert_abs_diff_eq!(
spline.derivative(-0.5, 3).unwrap(),
0.987574,
epsilon = 0.0001
);
assert_eq!(spline.derivative(2.0, 1).unwrap(), 1.0);
assert_eq!(spline.derivative(3.0, 1).unwrap(), 3.0);
assert_eq!(spline.derivative(2.0, 2).unwrap(), 2.0);
let xdata = vec![-0.5, 0.0, 0.5, 1.0, 1.5];
let ydata: Vec<f64> = xdata.clone().into_iter().map(|x: f64| x.sin()).collect();
let extrapl = Some(vec![2.0]); let extrapr = None; let spline = AkimaSpline::new(xdata, ydata, extrapl, extrapr).unwrap();
assert_eq!(spline.derivative(-0.6, 1).unwrap(), 2.0);
assert!(spline.derivative(2.0, 1).is_none());
}
}
#[test]
fn too_few_values() {
let xdata = vec![0.0, 0.5, 1.0, 1.5]; let ydata: Vec<f64> = xdata.clone().into_iter().map(|x: f64| x.sin()).collect();
assert!(AkimaSpline::new(xdata, ydata, None, None).is_err());
}
#[test]
fn ineq_length() {
let xdata = vec![0.0, 0.5, 1.0, 1.5, 2.0]; let ydata: Vec<f64> = vec![0.0, 0.5, 1.0, 1.5, 2.0, 2.5]; assert!(AkimaSpline::new(xdata, ydata, None, None).is_err());
}
#[test]
fn test_first_derivative_at_transition() {
{
let xs = vec![-2.0, -1.0, -0.8, 0.25, 1.0, 2.0];
let ys = vec![0.0, 1.0, 2.0, -1.5, 1.0, 3.0];
let extrapl = vec![2.0];
let extrapr = vec![3.0, -2.0];
let spline =
AkimaSpline::new(xs, ys, Some(extrapl), Some(extrapr)).expect("valid input data");
{
approx::assert_abs_diff_eq!(
spline.derivative(-2.0 - 1e-6, 1).unwrap(),
spline.derivative(-2.0 + 1e-6, 1).unwrap(),
epsilon = 1e-5
);
}
{
approx::assert_abs_diff_eq!(
spline.derivative(2.0 - 1e-6, 1).unwrap(),
spline.derivative(2.0 + 1e-6, 1).unwrap(),
epsilon = 1e-5
);
}
}
{
let xs = vec![-2.0, -1.0, -0.8, 0.25, 1.0, 2.0];
let ys = vec![0.0, 1.0, 2.0, -1.5, 1.0, 3.0];
let extrapl = vec![]; let extrapr = vec![3.0, -2.0, -3.0, 1.0, 0.0];
let spline =
AkimaSpline::new(xs, ys, Some(extrapl), Some(extrapr)).expect("valid input data");
{
approx::assert_abs_diff_eq!(
spline.derivative(-2.0 - 1e-6, 1).unwrap(),
spline.derivative(-2.0 + 1e-6, 1).unwrap(),
epsilon = 1e-5
);
approx::assert_abs_diff_eq!(
spline.derivative(2.0 - 1e-6, 1).unwrap(),
0.0,
epsilon = 1e-5
);
approx::assert_abs_diff_eq!(
spline.derivative(2.0 + 1e-6, 1).unwrap(),
0.0,
epsilon = 1e-5
);
}
{
approx::assert_abs_diff_eq!(
spline.derivative(2.0 - 1e-6, 1).unwrap(),
spline.derivative(2.0 + 1e-6, 1).unwrap(),
epsilon = 1e-5
);
approx::assert_abs_diff_eq!(
spline.derivative(2.0 - 1e-6, 1).unwrap(),
0.0,
epsilon = 1e-5
);
approx::assert_abs_diff_eq!(
spline.derivative(2.0 + 1e-6, 1).unwrap(),
0.0,
epsilon = 1e-5
);
}
}
}