Coverage Report

Created: 2025-02-21 07:11

/rust/registry/src/index.crates.io-6f17d22bba15001f/ndarray-0.15.6/src/array_approx.rs
Line
Count
Source (jump to first uncovered line)
1
#[cfg(feature = "approx")]
2
mod approx_methods {
3
    use crate::imp_prelude::*;
4
5
    impl<A, S, D> ArrayBase<S, D>
6
    where
7
        S: Data<Elem = A>,
8
        D: Dimension,
9
    {
10
        /// A test for equality that uses the elementwise absolute difference to compute the
11
        /// approximate equality of two arrays.
12
        ///
13
        /// **Requires crate feature `"approx"`**
14
0
        pub fn abs_diff_eq<S2>(&self, other: &ArrayBase<S2, D>, epsilon: A::Epsilon) -> bool
15
0
        where
16
0
            A: ::approx::AbsDiffEq<S2::Elem>,
17
0
            A::Epsilon: Clone,
18
0
            S2: Data,
19
0
        {
20
0
            <Self as ::approx::AbsDiffEq<_>>::abs_diff_eq(self, other, epsilon)
21
0
        }
22
23
        /// A test for equality that uses an elementwise relative comparison if the values are far
24
        /// apart; and the absolute difference otherwise.
25
        ///
26
        /// **Requires crate feature `"approx"`**
27
0
        pub fn relative_eq<S2>(
28
0
            &self,
29
0
            other: &ArrayBase<S2, D>,
30
0
            epsilon: A::Epsilon,
31
0
            max_relative: A::Epsilon,
32
0
        ) -> bool
33
0
        where
34
0
            A: ::approx::RelativeEq<S2::Elem>,
35
0
            A::Epsilon: Clone,
36
0
            S2: Data,
37
0
        {
38
0
            <Self as ::approx::RelativeEq<_>>::relative_eq(self, other, epsilon, max_relative)
39
0
        }
40
    }
41
}
42
43
macro_rules! impl_approx_traits {
44
    ($approx:ident, $doc:expr) => {
45
        mod $approx {
46
            use crate::imp_prelude::*;
47
            use crate::Zip;
48
            use $approx::{AbsDiffEq, RelativeEq, UlpsEq};
49
50
            #[doc = $doc]
51
            impl<A, B, S, S2, D> AbsDiffEq<ArrayBase<S2, D>> for ArrayBase<S, D>
52
            where
53
                A: AbsDiffEq<B>,
54
                A::Epsilon: Clone,
55
                S: Data<Elem = A>,
56
                S2: Data<Elem = B>,
57
                D: Dimension,
58
            {
59
                type Epsilon = A::Epsilon;
60
61
0
                fn default_epsilon() -> A::Epsilon {
62
0
                    A::default_epsilon()
63
0
                }
64
65
0
                fn abs_diff_eq(&self, other: &ArrayBase<S2, D>, epsilon: A::Epsilon) -> bool {
66
0
                    if self.shape() != other.shape() {
67
0
                        return false;
68
0
                    }
69
0
70
0
                    Zip::from(self)
71
0
                        .and(other)
72
0
                        .all(move |a, b| A::abs_diff_eq(a, b, epsilon.clone()))
73
0
                }
74
            }
75
76
            #[doc = $doc]
77
            impl<A, B, S, S2, D> RelativeEq<ArrayBase<S2, D>> for ArrayBase<S, D>
78
            where
79
                A: RelativeEq<B>,
80
                A::Epsilon: Clone,
81
                S: Data<Elem = A>,
82
                S2: Data<Elem = B>,
83
                D: Dimension,
84
            {
85
0
                fn default_max_relative() -> A::Epsilon {
86
0
                    A::default_max_relative()
87
0
                }
88
89
0
                fn relative_eq(
90
0
                    &self,
91
0
                    other: &ArrayBase<S2, D>,
92
0
                    epsilon: A::Epsilon,
93
0
                    max_relative: A::Epsilon,
94
0
                ) -> bool {
95
0
                    if self.shape() != other.shape() {
96
0
                        return false;
97
0
                    }
98
0
99
0
                    Zip::from(self).and(other).all(move |a, b| {
100
0
                        A::relative_eq(a, b, epsilon.clone(), max_relative.clone())
101
0
                    })
102
0
                }
103
            }
104
105
            #[doc = $doc]
106
            impl<A, B, S, S2, D> UlpsEq<ArrayBase<S2, D>> for ArrayBase<S, D>
107
            where
108
                A: UlpsEq<B>,
109
                A::Epsilon: Clone,
110
                S: Data<Elem = A>,
111
                S2: Data<Elem = B>,
112
                D: Dimension,
113
            {
114
0
                fn default_max_ulps() -> u32 {
115
0
                    A::default_max_ulps()
116
0
                }
117
118
0
                fn ulps_eq(
119
0
                    &self,
120
0
                    other: &ArrayBase<S2, D>,
121
0
                    epsilon: A::Epsilon,
122
0
                    max_ulps: u32,
123
0
                ) -> bool {
124
0
                    if self.shape() != other.shape() {
125
0
                        return false;
126
0
                    }
127
0
128
0
                    Zip::from(self)
129
0
                        .and(other)
130
0
                        .all(move |a, b| A::ulps_eq(a, b, epsilon.clone(), max_ulps))
131
0
                }
132
            }
133
134
            #[cfg(test)]
135
            mod tests {
136
                use crate::prelude::*;
137
                use alloc::vec;
138
                use $approx::{
139
                    assert_abs_diff_eq, assert_abs_diff_ne, assert_relative_eq, assert_relative_ne,
140
                    assert_ulps_eq, assert_ulps_ne,
141
                };
142
143
                #[test]
144
                fn abs_diff_eq() {
145
                    let a: Array2<f32> = array![[0., 2.], [-0.000010001, 100000000.]];
146
                    let mut b: Array2<f32> = array![[0., 1.], [-0.000010002, 100000001.]];
147
                    assert_abs_diff_ne!(a, b);
148
                    b[(0, 1)] = 2.;
149
                    assert_abs_diff_eq!(a, b);
150
151
                    // Check epsilon.
152
                    assert_abs_diff_eq!(array![0.0f32], array![1e-40f32], epsilon = 1e-40f32);
153
                    assert_abs_diff_ne!(array![0.0f32], array![1e-40f32], epsilon = 1e-41f32);
154
155
                    // Make sure we can compare different shapes without failure.
156
                    let c = array![[1., 2.]];
157
                    assert_abs_diff_ne!(a, c);
158
                }
159
160
                #[test]
161
                fn relative_eq() {
162
                    let a: Array2<f32> = array![[1., 2.], [-0.000010001, 100000000.]];
163
                    let mut b: Array2<f32> = array![[1., 1.], [-0.000010002, 100000001.]];
164
                    assert_relative_ne!(a, b);
165
                    b[(0, 1)] = 2.;
166
                    assert_relative_eq!(a, b);
167
168
                    // Check epsilon.
169
                    assert_relative_eq!(array![0.0f32], array![1e-40f32], epsilon = 1e-40f32);
170
                    assert_relative_ne!(array![0.0f32], array![1e-40f32], epsilon = 1e-41f32);
171
172
                    // Make sure we can compare different shapes without failure.
173
                    let c = array![[1., 2.]];
174
                    assert_relative_ne!(a, c);
175
                }
176
177
                #[test]
178
                fn ulps_eq() {
179
                    let a: Array2<f32> = array![[1., 2.], [-0.000010001, 100000000.]];
180
                    let mut b: Array2<f32> = array![[1., 1.], [-0.000010002, 100000001.]];
181
                    assert_ulps_ne!(a, b);
182
                    b[(0, 1)] = 2.;
183
                    assert_ulps_eq!(a, b);
184
185
                    // Check epsilon.
186
                    assert_ulps_eq!(array![0.0f32], array![1e-40f32], epsilon = 1e-40f32);
187
                    assert_ulps_ne!(array![0.0f32], array![1e-40f32], epsilon = 1e-41f32);
188
189
                    // Make sure we can compare different shapes without failure.
190
                    let c = array![[1., 2.]];
191
                    assert_ulps_ne!(a, c);
192
                }
193
            }
194
        }
195
    };
196
}
197
198
#[cfg(feature = "approx")]
199
impl_approx_traits!(approx, "**Requires crate feature `\"approx\"`.**");
200
201
#[cfg(feature = "approx-0_5")]
202
impl_approx_traits!(approx_0_5, "**Requires crate feature `\"approx-0_5\"`.**");