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