tea_core/
testing.rs

1use std::fmt::Debug;
2
3use tea_dtype::{IsNone, Number};
4
5use crate::prelude::{Vec1View, EPS};
6
7/// Asserts that two 1-dimensional vectors are approximately equal within a specified epsilon.
8///
9/// This function compares two vectors element by element, considering numeric equality
10/// within the given epsilon and handling special cases like NaN and None values.
11///
12/// # Arguments
13///
14/// * `v1` - A reference to the first vector implementing `Vec1View<T>`
15/// * `v2` - A reference to the second vector implementing `Vec1View<T>`
16/// * `epsilon` - An optional f64 value specifying the maximum allowed difference between elements.
17///               If None, the default `EPS` value is used.
18///
19/// # Type Parameters
20///
21/// * `T` - The element type, which must implement `IsNone` and `Debug`
22/// * `V1`, `V2` - Types implementing `Vec1View<T>`
23///
24/// # Panics
25///
26/// This function will panic if:
27/// - The lengths of `v1` and `v2` are not equal
28/// - One vector has a None value where the other doesn't
29/// - The absolute difference between corresponding non-NaN elements exceeds epsilon
30/// - One element is NaN while the other isn't
31pub fn assert_vec1d_equal_numeric<T: IsNone + Debug, V1: Vec1View<T>, V2: Vec1View<T>>(
32    v1: &V1,
33    v2: &V2,
34    epsilon: Option<f64>,
35) where
36    T::Inner: Number,
37{
38    assert_eq!(v1.len(), v2.len());
39    let epsilon = epsilon.unwrap_or(EPS);
40    for (x, y) in v1.titer().zip(v2.titer()) {
41        if x.is_none() && y.is_none() {
42            continue;
43        } else if x.is_none() || y.is_none() {
44            panic!(
45                "Vectors are not approximately equal, x: {:?}, y: {:?}",
46                x, y
47            );
48        } else {
49            let x = x.unwrap().f64();
50            let y = y.unwrap().f64();
51            if !(x.is_nan() && y.is_nan()) {
52                assert!(
53                    (x - y).abs() < epsilon,
54                    "Vectors are not approximately equal, x: {}, y: {}",
55                    x,
56                    y
57                );
58            } else if x.is_nan() && y.is_nan() {
59                continue;
60            } else {
61                panic!(
62                    "Vectors are not approximately equal, x: {:?}, y: {:?}",
63                    x, y
64                );
65            }
66        }
67    }
68}