/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\"`.**"); |