use crate::error::InterpolateResult;
use crate::traits::InterpolationFloat;
use scirs2_core::ndarray::Array1;
pub fn create_large_test_data<T: InterpolationFloat>(
size: usize,
) -> InterpolateResult<(Array1<T>, Array1<T>)> {
let x = Array1::linspace(
T::zero(),
T::from_f64(10.0).expect("Operation failed"),
size,
);
let y = x.mapv(|xi| {
xi.sin()
+ T::from_f64(0.1).expect("Operation failed")
* (xi * T::from_f64(10.0).expect("Operation failed")).cos()
});
Ok((x, y))
}
pub fn create_constant_data<T: InterpolationFloat>(
size: usize,
) -> InterpolateResult<(Array1<T>, Array1<T>)> {
let x = Array1::linspace(
T::zero(),
T::from_f64(10.0).expect("Operation failed"),
size,
);
let y = Array1::from_elem(size, T::from_f64(5.0).expect("Operation failed"));
Ok((x, y))
}
pub fn create_duplicate_x_data<T: InterpolationFloat>(
size: usize,
) -> InterpolateResult<(Array1<T>, Array1<T>)> {
let mut x = Array1::linspace(
T::zero(),
T::from_f64(10.0).expect("Operation failed"),
size,
);
let y = Array1::ones(size);
if size > 10 {
x[size / 2] = x[size / 2 - 1];
x[size / 4] = x[size / 4 - 1];
}
Ok((x, y))
}
pub fn create_extreme_y_data<T: InterpolationFloat>(
size: usize,
) -> InterpolateResult<(Array1<T>, Array1<T>)> {
let x = Array1::linspace(
T::zero(),
T::from_f64(10.0).expect("Operation failed"),
size,
);
let mut y = Array1::zeros(size);
for (i, &_xi) in x.iter().enumerate() {
y[i] = if i % 2 == 0 {
T::from_f64(1e10).expect("Operation failed")
} else {
T::from_f64(-1e10).expect("Operation failed")
};
}
Ok((x, y))
}
pub fn create_nan_inf_data<T: InterpolationFloat>(
size: usize,
) -> InterpolateResult<(Array1<T>, Array1<T>)> {
let x = Array1::linspace(
T::zero(),
T::from_f64(10.0).expect("Operation failed"),
size,
);
let mut y = x.mapv(|xi| xi.sin());
if size > 10 {
y[size / 4] = T::infinity();
y[size / 2] = T::neg_infinity();
}
Ok((x, y))
}
pub fn create_sparse_data<T: InterpolationFloat>(
size: usize,
) -> InterpolateResult<(Array1<T>, Array1<T>)> {
let sparse_size = (size / 100).max(3);
let x = Array1::linspace(
T::zero(),
T::from_f64(1000.0).expect("Operation failed"),
sparse_size,
);
let y = x.mapv(|xi| xi.sin());
Ok((x, y))
}
pub fn create_oscillatory_data<T: InterpolationFloat>(
size: usize,
) -> InterpolateResult<(Array1<T>, Array1<T>)> {
let x = Array1::linspace(
T::zero(),
T::from_f64(10.0).expect("Operation failed"),
size,
);
let y = x.mapv(|xi| (xi * T::from_f64(100.0).expect("Operation failed")).sin());
Ok((x, y))
}
pub fn create_monotonic_extreme_data<T: InterpolationFloat>(
size: usize,
) -> InterpolateResult<(Array1<T>, Array1<T>)> {
let x = Array1::linspace(
T::zero(),
T::from_f64(10.0).expect("Operation failed"),
size,
);
let y = x.mapv(|xi| xi.powi(10));
Ok((x, y))
}
pub fn create_edge_case_data<T: InterpolationFloat>(
size: usize,
min_val: f64,
max_val: f64,
) -> InterpolateResult<(Array1<T>, Array1<T>)> {
let x = Array1::linspace(
T::from_f64(min_val).expect("Operation failed"),
T::from_f64(max_val).expect("Operation failed"),
size,
);
let y = x.mapv(|xi| xi * T::from_f64(1.1).expect("Operation failed"));
Ok((x, y))
}
pub fn create_linear_data<T: InterpolationFloat>(
size: usize,
) -> InterpolateResult<(Array1<T>, Array1<T>)> {
let x = Array1::linspace(
T::zero(),
T::from_f64(10.0).expect("Operation failed"),
size,
);
let y = x.mapv(|xi| {
xi * T::from_f64(2.0).expect("Operation failed")
+ T::from_f64(3.0).expect("Operation failed")
});
Ok((x, y))
}
pub fn create_quadratic_data<T: InterpolationFloat>(
size: usize,
) -> InterpolateResult<(Array1<T>, Array1<T>)> {
let x = Array1::linspace(
T::from_f64(-5.0).expect("Operation failed"),
T::from_f64(5.0).expect("Operation failed"),
size,
);
let y = x.mapv(|xi| {
xi * xi
+ T::from_f64(2.0).expect("Operation failed") * xi
+ T::from_f64(1.0).expect("Operation failed")
});
Ok((x, y))
}
pub fn create_noisy_data<T: InterpolationFloat>(
size: usize,
noise_level: f64,
) -> InterpolateResult<(Array1<T>, Array1<T>)> {
let x = Array1::linspace(
T::zero(),
T::from_f64(10.0).expect("Operation failed"),
size,
);
let mut y = x.mapv(|xi| xi.sin());
for (i, yi) in y.iter_mut().enumerate() {
let noise = T::from_f64(noise_level * ((i as f64 * 12345.0).sin() * 0.1))
.expect("Operation failed");
*yi += noise;
}
Ok((x, y))
}
pub fn create_exponential_data<T: InterpolationFloat>(
size: usize,
) -> InterpolateResult<(Array1<T>, Array1<T>)> {
let x = Array1::linspace(T::zero(), T::from_f64(5.0).expect("Operation failed"), size);
let y = x.mapv(|xi| (xi * T::from_f64(0.5).expect("Operation failed")).exp());
Ok((x, y))
}
pub fn create_step_data<T: InterpolationFloat>(
size: usize,
) -> InterpolateResult<(Array1<T>, Array1<T>)> {
let x = Array1::linspace(
T::zero(),
T::from_f64(10.0).expect("Operation failed"),
size,
);
let y = x.mapv(|xi| {
if xi < T::from_f64(5.0).expect("Operation failed") {
T::zero()
} else {
T::one()
}
});
Ok((x, y))
}
pub fn create_pseudo_random_data<T: InterpolationFloat>(
size: usize,
) -> InterpolateResult<(Array1<T>, Array1<T>)> {
let x = Array1::linspace(
T::zero(),
T::from_f64(10.0).expect("Operation failed"),
size,
);
let y = x.mapv(|xi| {
let val = xi.to_f64().expect("Operation failed");
T::from_f64((val * 12.34).sin() + (val * 56.78).cos() * 0.3).expect("Operation failed")
});
Ok((x, y))
}
pub fn create_rapid_change_data<T: InterpolationFloat>(
size: usize,
) -> InterpolateResult<(Array1<T>, Array1<T>)> {
let x = Array1::linspace(
T::zero(),
T::from_f64(10.0).expect("Operation failed"),
size,
);
let y = x.mapv(|xi| {
let val = xi.to_f64().expect("Operation failed");
if val > 4.9 && val < 5.1 {
T::from_f64(100.0).expect("Operation failed") } else {
xi
}
});
Ok((x, y))
}
pub fn create_empty_data<T: InterpolationFloat>() -> InterpolateResult<(Array1<T>, Array1<T>)> {
Ok((Array1::<T>::zeros(0), Array1::<T>::zeros(0)))
}
pub fn create_single_point_data<T: InterpolationFloat>() -> InterpolateResult<(Array1<T>, Array1<T>)>
{
Ok((
Array1::from_vec(vec![T::zero()]),
Array1::from_vec(vec![T::one()]),
))
}
pub fn create_mismatched_data<T: InterpolationFloat>() -> InterpolateResult<(Array1<T>, Array1<T>)>
{
Ok((Array1::<T>::zeros(10), Array1::<T>::zeros(5)))
}
pub fn create_unsorted_x_data<T: InterpolationFloat>() -> InterpolateResult<(Array1<T>, Array1<T>)>
{
let x = Array1::from_vec(vec![
T::from_f64(1.0).expect("Operation failed"),
T::from_f64(3.0).expect("Operation failed"),
T::from_f64(2.0).expect("Operation failed"),
T::from_f64(4.0).expect("Operation failed"),
]);
let y = Array1::ones(4);
Ok((x, y))
}
pub fn generate_test_data<T: InterpolationFloat>(
data_type: &str,
size: usize,
) -> InterpolateResult<(Array1<T>, Array1<T>)> {
match data_type {
"large" => create_large_test_data(size),
"constant" => create_constant_data(size),
"duplicate_x" => create_duplicate_x_data(size),
"extreme_y" => create_extreme_y_data(size),
"nan_inf" => create_nan_inf_data(size),
"sparse" => create_sparse_data(size),
"oscillatory" => create_oscillatory_data(size),
"monotonic_extreme" => create_monotonic_extreme_data(size),
"linear" => create_linear_data(size),
"quadratic" => create_quadratic_data(size),
"exponential" => create_exponential_data(size),
"step" => create_step_data(size),
"pseudo_random" => create_pseudo_random_data(size),
"rapid_change" => create_rapid_change_data(size),
"empty" => create_empty_data(),
"single_point" => create_single_point_data(),
"mismatched" => create_mismatched_data(),
"unsorted_x" => create_unsorted_x_data(),
"noisy_low" => create_noisy_data(size, 0.01),
"noisy_medium" => create_noisy_data(size, 0.1),
"noisy_high" => create_noisy_data(size, 0.5),
_ => create_large_test_data(size), }
}
pub fn get_pathological_data_types() -> Vec<&'static str> {
vec![
"constant",
"duplicate_x",
"extreme_y",
"nan_inf",
"sparse",
"oscillatory",
"monotonic_extreme",
]
}
pub fn get_error_test_data_types() -> Vec<&'static str> {
vec!["empty", "single_point", "mismatched", "unsorted_x"]
}
pub fn get_general_test_data_types() -> Vec<&'static str> {
vec![
"large",
"linear",
"quadratic",
"exponential",
"step",
"pseudo_random",
"rapid_change",
"noisy_low",
"noisy_medium",
"noisy_high",
]
}