1#[cfg(test)]
2use super::super::test::ErrorTensor;
3
4use crate::math::{Tensor, TensorRank0, TensorRank2, TensorRank2Vec, TensorVec};
5use std::{
6 fmt::{Display, Formatter, Result},
7 ops::{Add, AddAssign, Div, DivAssign, Index, IndexMut, Mul, MulAssign, Sub, SubAssign},
8};
9
10#[derive(Clone, Debug)]
14pub struct TensorRank2Vec2D<const D: usize, const I: usize, const J: usize>(
15 Vec<TensorRank2Vec<D, I, J>>,
16);
17
18impl<const D: usize, const I: usize, const J: usize> Display for TensorRank2Vec2D<D, I, J> {
19 fn fmt(&self, _f: &mut Formatter) -> Result {
20 Ok(())
21 }
22}
23
24#[cfg(test)]
25impl<const D: usize, const I: usize, const J: usize> ErrorTensor for TensorRank2Vec2D<D, I, J> {
26 fn error(
27 &self,
28 comparator: &Self,
29 tol_abs: &TensorRank0,
30 tol_rel: &TensorRank0,
31 ) -> Option<usize> {
32 let error_count = self
33 .iter()
34 .zip(comparator.iter())
35 .map(|(self_a, comparator_a)| {
36 self_a
37 .iter()
38 .zip(comparator_a.iter())
39 .map(|(self_ab, comparator_ab)| {
40 self_ab
41 .iter()
42 .zip(comparator_ab.iter())
43 .map(|(self_ab_i, comparator_ab_i)| {
44 self_ab_i
45 .iter()
46 .zip(comparator_ab_i.iter())
47 .filter(|(&self_ab_ij, &comparator_ab_ij)| {
48 &(self_ab_ij - comparator_ab_ij).abs() >= tol_abs
49 && &(self_ab_ij / comparator_ab_ij - 1.0).abs()
50 >= tol_rel
51 })
52 .count()
53 })
54 .sum::<usize>()
55 })
56 .sum::<usize>()
57 })
58 .sum();
59 if error_count > 0 {
60 Some(error_count)
61 } else {
62 None
63 }
64 }
65 fn error_fd(&self, comparator: &Self, epsilon: &TensorRank0) -> Option<(bool, usize)> {
66 let error_count = self
67 .iter()
68 .zip(comparator.iter())
69 .map(|(self_a, comparator_a)| {
70 self_a
71 .iter()
72 .zip(comparator_a.iter())
73 .map(|(self_ab, comparator_ab)| {
74 self_ab
75 .iter()
76 .zip(comparator_ab.iter())
77 .map(|(self_ab_i, comparator_ab_i)| {
78 self_ab_i
79 .iter()
80 .zip(comparator_ab_i.iter())
81 .filter(|(&self_ab_ij, &comparator_ab_ij)| {
82 &(self_ab_ij / comparator_ab_ij - 1.0).abs() >= epsilon
83 && (&self_ab_ij.abs() >= epsilon
84 || &comparator_ab_ij.abs() >= epsilon)
85 })
86 .count()
87 })
88 .sum::<usize>()
89 })
90 .sum::<usize>()
91 })
92 .sum();
93 if error_count > 0 {
94 let auxillary = self
95 .iter()
96 .zip(comparator.iter())
97 .map(|(self_a, comparator_a)| {
98 self_a
99 .iter()
100 .zip(comparator_a.iter())
101 .map(|(self_ab, comparator_ab)| {
102 self_ab
103 .iter()
104 .zip(comparator_ab.iter())
105 .map(|(self_ab_i, comparator_ab_i)| {
106 self_ab_i
107 .iter()
108 .zip(comparator_ab_i.iter())
109 .filter(|(&self_ab_ij, &comparator_ab_ij)| {
110 &(self_ab_ij / comparator_ab_ij - 1.0).abs() >= epsilon
111 && &(self_ab_ij - comparator_ab_ij).abs() >= epsilon
112 && (&self_ab_ij.abs() >= epsilon
113 || &comparator_ab_ij.abs() >= epsilon)
114 })
115 .count()
116 })
117 .sum::<usize>()
118 })
119 .sum::<usize>()
120 })
121 .sum::<usize>()
122 > 0;
123 Some((auxillary, error_count))
124 } else {
125 None
126 }
127 }
128}
129
130impl<const D: usize, const I: usize, const J: usize> FromIterator<TensorRank2Vec<D, I, J>>
131 for TensorRank2Vec2D<D, I, J>
132{
133 fn from_iter<Ii: IntoIterator<Item = TensorRank2Vec<D, I, J>>>(into_iterator: Ii) -> Self {
134 Self(Vec::from_iter(into_iterator))
135 }
136}
137
138impl<const D: usize, const I: usize, const J: usize> Index<usize> for TensorRank2Vec2D<D, I, J> {
139 type Output = TensorRank2Vec<D, I, J>;
140 fn index(&self, index: usize) -> &Self::Output {
141 &self.0[index]
142 }
143}
144
145impl<const D: usize, const I: usize, const J: usize> IndexMut<usize> for TensorRank2Vec2D<D, I, J> {
146 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
147 &mut self.0[index]
148 }
149}
150
151impl<const D: usize, const I: usize, const J: usize> TensorVec for TensorRank2Vec2D<D, I, J> {
152 type Item = TensorRank2Vec<D, I, J>;
153 type Slice<'a> = &'a [&'a [[[TensorRank0; D]; D]]];
154 fn append(&mut self, other: &mut Self) {
155 self.0.append(&mut other.0)
156 }
157 fn is_empty(&self) -> bool {
158 self.0.is_empty()
159 }
160 fn len(&self) -> usize {
161 self.0.len()
162 }
163 fn new(slice: Self::Slice<'_>) -> Self {
164 slice
165 .iter()
166 .map(|slice_entry| Self::Item::new(slice_entry))
167 .collect()
168 }
169 fn push(&mut self, item: Self::Item) {
170 self.0.push(item)
171 }
172 fn zero(len: usize) -> Self {
173 (0..len).map(|_| Self::Item::zero(len)).collect()
174 }
175}
176
177impl<const D: usize, const I: usize, const J: usize> Tensor for TensorRank2Vec2D<D, I, J> {
178 type Item = TensorRank2Vec<D, I, J>;
179 fn iter(&self) -> impl Iterator<Item = &Self::Item> {
180 self.0.iter()
181 }
182 fn iter_mut(&mut self) -> impl Iterator<Item = &mut Self::Item> {
183 self.0.iter_mut()
184 }
185}
186
187impl<const D: usize, const I: usize, const J: usize, const K: usize> Mul<TensorRank2<D, J, K>>
188 for TensorRank2Vec2D<D, I, J>
189{
190 type Output = TensorRank2Vec2D<D, I, K>;
191 fn mul(self, tensor_rank_2: TensorRank2<D, J, K>) -> Self::Output {
192 self.iter()
193 .map(|self_entry| {
194 self_entry
195 .iter()
196 .map(|self_tensor_rank_2| self_tensor_rank_2 * &tensor_rank_2)
197 .collect()
198 })
199 .collect()
200 }
201}
202
203impl<const D: usize, const I: usize, const J: usize, const K: usize> Mul<&TensorRank2<D, J, K>>
204 for TensorRank2Vec2D<D, I, J>
205{
206 type Output = TensorRank2Vec2D<D, I, K>;
207 fn mul(self, tensor_rank_2: &TensorRank2<D, J, K>) -> Self::Output {
208 self.iter()
209 .map(|self_entry| {
210 self_entry
211 .iter()
212 .map(|self_tensor_rank_2| self_tensor_rank_2 * tensor_rank_2)
213 .collect()
214 })
215 .collect()
216 }
217}
218
219impl<const D: usize, const I: usize, const J: usize> Add for TensorRank2Vec2D<D, I, J> {
220 type Output = Self;
221 fn add(mut self, tensor_rank_2_vec_2d: Self) -> Self::Output {
222 self += tensor_rank_2_vec_2d;
223 self
224 }
225}
226
227impl<const D: usize, const I: usize, const J: usize> Add<&Self> for TensorRank2Vec2D<D, I, J> {
228 type Output = Self;
229 fn add(mut self, tensor_rank_2_vec_2d: &Self) -> Self::Output {
230 self += tensor_rank_2_vec_2d;
231 self
232 }
233}
234
235impl<const D: usize, const I: usize, const J: usize> AddAssign for TensorRank2Vec2D<D, I, J> {
236 fn add_assign(&mut self, tensor_rank_2_vec_2d: Self) {
237 self.iter_mut()
238 .zip(tensor_rank_2_vec_2d.iter())
239 .for_each(|(self_entry, tensor_rank_2_vec)| *self_entry += tensor_rank_2_vec);
240 }
241}
242
243impl<const D: usize, const I: usize, const J: usize> AddAssign<&Self>
244 for TensorRank2Vec2D<D, I, J>
245{
246 fn add_assign(&mut self, tensor_rank_2_vec_2d: &Self) {
247 self.iter_mut()
248 .zip(tensor_rank_2_vec_2d.iter())
249 .for_each(|(self_entry, tensor_rank_2_vec)| *self_entry += tensor_rank_2_vec);
250 }
251}
252
253impl<const D: usize, const I: usize, const J: usize> Div<TensorRank0>
254 for TensorRank2Vec2D<D, I, J>
255{
256 type Output = Self;
257 fn div(mut self, tensor_rank_0: TensorRank0) -> Self::Output {
258 self /= &tensor_rank_0;
259 self
260 }
261}
262
263impl<const D: usize, const I: usize, const J: usize> Div<&TensorRank0>
264 for TensorRank2Vec2D<D, I, J>
265{
266 type Output = Self;
267 fn div(mut self, tensor_rank_0: &TensorRank0) -> Self::Output {
268 self /= tensor_rank_0;
269 self
270 }
271}
272
273impl<const D: usize, const I: usize, const J: usize> DivAssign<TensorRank0>
274 for TensorRank2Vec2D<D, I, J>
275{
276 fn div_assign(&mut self, tensor_rank_0: TensorRank0) {
277 self.iter_mut().for_each(|entry| *entry /= &tensor_rank_0);
278 }
279}
280
281impl<const D: usize, const I: usize, const J: usize> DivAssign<&TensorRank0>
282 for TensorRank2Vec2D<D, I, J>
283{
284 fn div_assign(&mut self, tensor_rank_0: &TensorRank0) {
285 self.iter_mut().for_each(|entry| *entry /= tensor_rank_0);
286 }
287}
288
289impl<const D: usize, const I: usize, const J: usize> Mul<TensorRank0>
290 for TensorRank2Vec2D<D, I, J>
291{
292 type Output = Self;
293 fn mul(mut self, tensor_rank_0: TensorRank0) -> Self::Output {
294 self *= &tensor_rank_0;
295 self
296 }
297}
298
299impl<const D: usize, const I: usize, const J: usize> Mul<&TensorRank0>
300 for TensorRank2Vec2D<D, I, J>
301{
302 type Output = Self;
303 fn mul(mut self, tensor_rank_0: &TensorRank0) -> Self::Output {
304 self *= tensor_rank_0;
305 self
306 }
307}
308
309impl<const D: usize, const I: usize, const J: usize> MulAssign<TensorRank0>
310 for TensorRank2Vec2D<D, I, J>
311{
312 fn mul_assign(&mut self, tensor_rank_0: TensorRank0) {
313 self.iter_mut().for_each(|entry| *entry *= &tensor_rank_0);
314 }
315}
316
317impl<const D: usize, const I: usize, const J: usize> MulAssign<&TensorRank0>
318 for TensorRank2Vec2D<D, I, J>
319{
320 fn mul_assign(&mut self, tensor_rank_0: &TensorRank0) {
321 self.iter_mut().for_each(|entry| *entry *= tensor_rank_0);
322 }
323}
324
325impl<const D: usize, const I: usize, const J: usize> Sub for TensorRank2Vec2D<D, I, J> {
326 type Output = Self;
327 fn sub(mut self, tensor_rank_2_vec_2d: Self) -> Self::Output {
328 self -= tensor_rank_2_vec_2d;
329 self
330 }
331}
332
333impl<const D: usize, const I: usize, const J: usize> Sub<&Self> for TensorRank2Vec2D<D, I, J> {
334 type Output = Self;
335 fn sub(mut self, tensor_rank_2_vec_2d: &Self) -> Self::Output {
336 self -= tensor_rank_2_vec_2d;
337 self
338 }
339}
340
341impl<const D: usize, const I: usize, const J: usize> SubAssign for TensorRank2Vec2D<D, I, J> {
342 fn sub_assign(&mut self, tensor_rank_2_vec_2d: Self) {
343 self.iter_mut()
344 .zip(tensor_rank_2_vec_2d.iter())
345 .for_each(|(self_entry, tensor_rank_2_vec)| *self_entry -= tensor_rank_2_vec);
346 }
347}
348
349impl<const D: usize, const I: usize, const J: usize> SubAssign<&Self>
350 for TensorRank2Vec2D<D, I, J>
351{
352 fn sub_assign(&mut self, tensor_rank_2_vec_2d: &Self) {
353 self.iter_mut()
354 .zip(tensor_rank_2_vec_2d.iter())
355 .for_each(|(self_entry, tensor_rank_2_vec)| *self_entry -= tensor_rank_2_vec);
356 }
357}