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