conspire/math/tensor/rank_3/list_3d/
mod.rs

1#[cfg(test)]
2pub mod test;
3
4#[cfg(test)]
5use super::super::test::ErrorTensor;
6
7use super::{
8    super::{Tensor, TensorArray},
9    TensorRank0,
10    list_2d::TensorRank3List2D,
11};
12use std::{
13    array::from_fn,
14    fmt::{Display, Formatter, Result},
15    ops::{Add, AddAssign, Div, DivAssign, Index, IndexMut, Mul, MulAssign, Sub, SubAssign},
16};
17
18/// A 3D list of *d*-dimensional tensors of rank 3.
19///
20/// `D` is the dimension, `I`, `J`, `K` are the configurations `W`, `X`, and `Y` are the list lengths.
21#[derive(Clone, Debug)]
22pub struct TensorRank3List3D<
23    const D: usize,
24    const I: usize,
25    const J: usize,
26    const K: usize,
27    const W: usize,
28    const X: usize,
29    const Y: usize,
30>([TensorRank3List2D<D, I, J, K, W, X>; Y]);
31
32impl<
33    const D: usize,
34    const I: usize,
35    const J: usize,
36    const K: usize,
37    const W: usize,
38    const X: usize,
39    const Y: usize,
40> Display for TensorRank3List3D<D, I, J, K, W, X, Y>
41{
42    fn fmt(&self, _f: &mut Formatter) -> Result {
43        Ok(())
44    }
45}
46
47#[cfg(test)]
48impl<
49    const D: usize,
50    const I: usize,
51    const J: usize,
52    const K: usize,
53    const W: usize,
54    const X: usize,
55    const Y: usize,
56> ErrorTensor for TensorRank3List3D<D, I, J, K, W, X, Y>
57{
58    fn error(
59        &self,
60        comparator: &Self,
61        tol_abs: &TensorRank0,
62        tol_rel: &TensorRank0,
63    ) -> Option<usize> {
64        let error_count = self
65            .iter()
66            .zip(comparator.iter())
67            .map(|(self_a, comparator_a)| {
68                self_a
69                    .iter()
70                    .zip(comparator_a.iter())
71                    .map(|(self_ab, comparator_ab)| {
72                        self_ab
73                            .iter()
74                            .zip(comparator_ab.iter())
75                            .map(|(self_abc, comparator_abc)| {
76                                self_abc
77                                    .iter()
78                                    .zip(comparator_abc.iter())
79                                    .map(|(self_abc_i, comparator_abc_i)| {
80                                        self_abc_i
81                                            .iter()
82                                            .zip(comparator_abc_i.iter())
83                                            .map(|(self_abc_ij, comparator_abc_ij)| {
84                                                self_abc_ij
85                                                    .iter()
86                                                    .zip(comparator_abc_ij.iter())
87                                                    .filter(
88                                                        |&(&self_abc_ijk, &comparator_abc_ijk)| {
89                                                            &(self_abc_ijk - comparator_abc_ijk)
90                                                                .abs()
91                                                                >= tol_abs
92                                                                && &(self_abc_ijk
93                                                                    / comparator_abc_ijk
94                                                                    - 1.0)
95                                                                    .abs()
96                                                                    >= tol_rel
97                                                        },
98                                                    )
99                                                    .count()
100                                            })
101                                            .sum::<usize>()
102                                    })
103                                    .sum::<usize>()
104                            })
105                            .sum::<usize>()
106                    })
107                    .sum::<usize>()
108            })
109            .sum();
110        if error_count > 0 {
111            Some(error_count)
112        } else {
113            None
114        }
115    }
116    fn error_fd(&self, comparator: &Self, epsilon: &TensorRank0) -> Option<(bool, usize)> {
117        let error_count = self
118            .iter()
119            .zip(comparator.iter())
120            .map(|(self_a, comparator_a)| {
121                self_a
122                    .iter()
123                    .zip(comparator_a.iter())
124                    .map(|(self_ab, comparator_ab)| {
125                        self_ab
126                            .iter()
127                            .zip(comparator_ab.iter())
128                            .map(|(self_abc, comparator_abc)| {
129                                self_abc
130                                    .iter()
131                                    .zip(comparator_abc.iter())
132                                    .map(|(self_abc_i, comparator_abc_i)| {
133                                        self_abc_i
134                                            .iter()
135                                            .zip(comparator_abc_i.iter())
136                                            .map(|(self_abc_ij, comparator_abc_ij)| {
137                                                self_abc_ij
138                                                    .iter()
139                                                    .zip(comparator_abc_ij.iter())
140                                                    .filter(
141                                                        |&(&self_abc_ijk, &comparator_abc_ijk)| {
142                                                            &(self_abc_ijk / comparator_abc_ijk
143                                                                - 1.0)
144                                                                .abs()
145                                                                >= epsilon
146                                                                && (&self_abc_ijk.abs() >= epsilon
147                                                                    || &comparator_abc_ijk.abs()
148                                                                        >= epsilon)
149                                                        },
150                                                    )
151                                                    .count()
152                                            })
153                                            .sum::<usize>()
154                                    })
155                                    .sum::<usize>()
156                            })
157                            .sum::<usize>()
158                    })
159                    .sum::<usize>()
160            })
161            .sum();
162        if error_count > 0 {
163            Some((true, error_count))
164        } else {
165            None
166        }
167    }
168}
169
170impl<
171    const D: usize,
172    const I: usize,
173    const J: usize,
174    const K: usize,
175    const W: usize,
176    const X: usize,
177    const Y: usize,
178> Tensor for TensorRank3List3D<D, I, J, K, W, X, Y>
179{
180    type Item = TensorRank3List2D<D, I, J, K, W, X>;
181    fn iter(&self) -> impl Iterator<Item = &Self::Item> {
182        self.0.iter()
183    }
184    fn iter_mut(&mut self) -> impl Iterator<Item = &mut Self::Item> {
185        self.0.iter_mut()
186    }
187}
188
189impl<
190    const D: usize,
191    const I: usize,
192    const J: usize,
193    const K: usize,
194    const W: usize,
195    const X: usize,
196    const Y: usize,
197> TensorArray for TensorRank3List3D<D, I, J, K, W, X, Y>
198{
199    type Array = [[[[[[TensorRank0; D]; D]; D]; W]; X]; Y];
200    type Item = TensorRank3List2D<D, I, J, K, W, X>;
201    fn as_array(&self) -> Self::Array {
202        let mut array = [[[[[[0.0; D]; D]; D]; W]; X]; Y];
203        array.iter_mut().zip(self.iter()).for_each(
204            |(entry_rank_3_list_2d, tensor_rank_3_list_2d)| {
205                *entry_rank_3_list_2d = tensor_rank_3_list_2d.as_array()
206            },
207        );
208        array
209    }
210    fn identity() -> Self {
211        Self(from_fn(|_| Self::Item::identity()))
212    }
213    fn new(array: Self::Array) -> Self {
214        array.into_iter().map(Self::Item::new).collect()
215    }
216    fn zero() -> Self {
217        Self(from_fn(|_| Self::Item::zero()))
218    }
219}
220
221impl<
222    const D: usize,
223    const I: usize,
224    const J: usize,
225    const K: usize,
226    const W: usize,
227    const X: usize,
228    const Y: usize,
229> FromIterator<TensorRank3List2D<D, I, J, K, W, X>> for TensorRank3List3D<D, I, J, K, W, X, Y>
230{
231    fn from_iter<Ii: IntoIterator<Item = TensorRank3List2D<D, I, J, K, W, X>>>(
232        into_iterator: Ii,
233    ) -> Self {
234        let mut tensor_rank_3_list_3d = Self::zero();
235        tensor_rank_3_list_3d
236            .iter_mut()
237            .zip(into_iterator)
238            .for_each(|(tensor_rank_3_list_2d, entry)| *tensor_rank_3_list_2d = entry);
239        tensor_rank_3_list_3d
240    }
241}
242
243impl<
244    const D: usize,
245    const I: usize,
246    const J: usize,
247    const K: usize,
248    const W: usize,
249    const X: usize,
250    const Y: usize,
251> Index<usize> for TensorRank3List3D<D, I, J, K, W, X, Y>
252{
253    type Output = TensorRank3List2D<D, I, J, K, W, X>;
254    fn index(&self, index: usize) -> &Self::Output {
255        &self.0[index]
256    }
257}
258
259impl<
260    const D: usize,
261    const I: usize,
262    const J: usize,
263    const K: usize,
264    const W: usize,
265    const X: usize,
266    const Y: usize,
267> IndexMut<usize> for TensorRank3List3D<D, I, J, K, W, X, Y>
268{
269    fn index_mut(&mut self, index: usize) -> &mut Self::Output {
270        &mut self.0[index]
271    }
272}
273
274impl<
275    const D: usize,
276    const I: usize,
277    const J: usize,
278    const K: usize,
279    const W: usize,
280    const X: usize,
281    const Y: usize,
282> Add for TensorRank3List3D<D, I, J, K, W, X, Y>
283{
284    type Output = Self;
285    fn add(mut self, tensor_rank_3_list_3d: Self) -> Self::Output {
286        self += tensor_rank_3_list_3d;
287        self
288    }
289}
290
291impl<
292    const D: usize,
293    const I: usize,
294    const J: usize,
295    const K: usize,
296    const W: usize,
297    const X: usize,
298    const Y: usize,
299> Add<&Self> for TensorRank3List3D<D, I, J, K, W, X, Y>
300{
301    type Output = Self;
302    fn add(mut self, tensor_rank_3_list_3d: &Self) -> Self::Output {
303        self += tensor_rank_3_list_3d;
304        self
305    }
306}
307
308impl<
309    const D: usize,
310    const I: usize,
311    const J: usize,
312    const K: usize,
313    const W: usize,
314    const X: usize,
315    const Y: usize,
316> AddAssign for TensorRank3List3D<D, I, J, K, W, X, Y>
317{
318    fn add_assign(&mut self, tensor_rank_3_list_3d: Self) {
319        self.iter_mut()
320            .zip(tensor_rank_3_list_3d.iter())
321            .for_each(|(self_entry, tensor_rank_3_list_2d)| *self_entry += tensor_rank_3_list_2d);
322    }
323}
324
325impl<
326    const D: usize,
327    const I: usize,
328    const J: usize,
329    const K: usize,
330    const W: usize,
331    const X: usize,
332    const Y: usize,
333> AddAssign<&Self> for TensorRank3List3D<D, I, J, K, W, X, Y>
334{
335    fn add_assign(&mut self, tensor_rank_3_list_3d: &Self) {
336        self.iter_mut()
337            .zip(tensor_rank_3_list_3d.iter())
338            .for_each(|(self_entry, tensor_rank_3_list_2d)| *self_entry += tensor_rank_3_list_2d);
339    }
340}
341
342impl<
343    const D: usize,
344    const I: usize,
345    const J: usize,
346    const K: usize,
347    const W: usize,
348    const X: usize,
349    const Y: usize,
350> Div<TensorRank0> for TensorRank3List3D<D, I, J, K, W, X, Y>
351{
352    type Output = Self;
353    fn div(mut self, tensor_rank_0: TensorRank0) -> Self::Output {
354        self /= &tensor_rank_0;
355        self
356    }
357}
358
359impl<
360    const D: usize,
361    const I: usize,
362    const J: usize,
363    const K: usize,
364    const W: usize,
365    const X: usize,
366    const Y: usize,
367> Div<&TensorRank0> for TensorRank3List3D<D, I, J, K, W, X, Y>
368{
369    type Output = Self;
370    fn div(mut self, tensor_rank_0: &TensorRank0) -> Self::Output {
371        self /= tensor_rank_0;
372        self
373    }
374}
375
376impl<
377    const D: usize,
378    const I: usize,
379    const J: usize,
380    const K: usize,
381    const W: usize,
382    const X: usize,
383    const Y: usize,
384> DivAssign<TensorRank0> for TensorRank3List3D<D, I, J, K, W, X, Y>
385{
386    fn div_assign(&mut self, tensor_rank_0: TensorRank0) {
387        self.iter_mut().for_each(|entry| *entry /= &tensor_rank_0);
388    }
389}
390
391impl<
392    const D: usize,
393    const I: usize,
394    const J: usize,
395    const K: usize,
396    const W: usize,
397    const X: usize,
398    const Y: usize,
399> DivAssign<&TensorRank0> for TensorRank3List3D<D, I, J, K, W, X, Y>
400{
401    fn div_assign(&mut self, tensor_rank_0: &TensorRank0) {
402        self.iter_mut().for_each(|entry| *entry /= tensor_rank_0);
403    }
404}
405
406impl<
407    const D: usize,
408    const I: usize,
409    const J: usize,
410    const K: usize,
411    const W: usize,
412    const X: usize,
413    const Y: usize,
414> Mul<TensorRank0> for TensorRank3List3D<D, I, J, K, W, X, Y>
415{
416    type Output = Self;
417    fn mul(mut self, tensor_rank_0: TensorRank0) -> Self::Output {
418        self *= &tensor_rank_0;
419        self
420    }
421}
422
423impl<
424    const D: usize,
425    const I: usize,
426    const J: usize,
427    const K: usize,
428    const W: usize,
429    const X: usize,
430    const Y: usize,
431> Mul<&TensorRank0> for TensorRank3List3D<D, I, J, K, W, X, Y>
432{
433    type Output = Self;
434    fn mul(mut self, tensor_rank_0: &TensorRank0) -> Self::Output {
435        self *= tensor_rank_0;
436        self
437    }
438}
439
440impl<
441    const D: usize,
442    const I: usize,
443    const J: usize,
444    const K: usize,
445    const W: usize,
446    const X: usize,
447    const Y: usize,
448> MulAssign<TensorRank0> for TensorRank3List3D<D, I, J, K, W, X, Y>
449{
450    fn mul_assign(&mut self, tensor_rank_0: TensorRank0) {
451        self.iter_mut().for_each(|entry| *entry *= &tensor_rank_0);
452    }
453}
454
455impl<
456    const D: usize,
457    const I: usize,
458    const J: usize,
459    const K: usize,
460    const W: usize,
461    const X: usize,
462    const Y: usize,
463> MulAssign<&TensorRank0> for TensorRank3List3D<D, I, J, K, W, X, Y>
464{
465    fn mul_assign(&mut self, tensor_rank_0: &TensorRank0) {
466        self.iter_mut().for_each(|entry| *entry *= tensor_rank_0);
467    }
468}
469
470impl<
471    const D: usize,
472    const I: usize,
473    const J: usize,
474    const K: usize,
475    const W: usize,
476    const X: usize,
477    const Y: usize,
478> Sub for TensorRank3List3D<D, I, J, K, W, X, Y>
479{
480    type Output = Self;
481    fn sub(mut self, tensor_rank_3_list_3d: Self) -> Self::Output {
482        self -= tensor_rank_3_list_3d;
483        self
484    }
485}
486
487impl<
488    const D: usize,
489    const I: usize,
490    const J: usize,
491    const K: usize,
492    const W: usize,
493    const X: usize,
494    const Y: usize,
495> Sub<&Self> for TensorRank3List3D<D, I, J, K, W, X, Y>
496{
497    type Output = Self;
498    fn sub(mut self, tensor_rank_3_list_3d: &Self) -> Self::Output {
499        self -= tensor_rank_3_list_3d;
500        self
501    }
502}
503
504impl<
505    const D: usize,
506    const I: usize,
507    const J: usize,
508    const K: usize,
509    const W: usize,
510    const X: usize,
511    const Y: usize,
512> SubAssign for TensorRank3List3D<D, I, J, K, W, X, Y>
513{
514    fn sub_assign(&mut self, tensor_rank_3_list_3d: Self) {
515        self.iter_mut()
516            .zip(tensor_rank_3_list_3d.iter())
517            .for_each(|(self_entry, tensor_rank_3_list_2d)| *self_entry -= tensor_rank_3_list_2d);
518    }
519}
520
521impl<
522    const D: usize,
523    const I: usize,
524    const J: usize,
525    const K: usize,
526    const W: usize,
527    const X: usize,
528    const Y: usize,
529> SubAssign<&Self> for TensorRank3List3D<D, I, J, K, W, X, Y>
530{
531    fn sub_assign(&mut self, tensor_rank_3_list_3d: &Self) {
532        self.iter_mut()
533            .zip(tensor_rank_3_list_3d.iter())
534            .for_each(|(self_entry, tensor_rank_3_list_2d)| *self_entry -= tensor_rank_3_list_2d);
535    }
536}