conspire/math/tensor/rank_3/list_2d/
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::TensorRank3List,
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 2D list of *d*-dimensional tensors of rank 3.
19///
20/// `D` is the dimension, `I`, `J`, `K` are the configurations `W` and `X` are the list lengths.
21#[derive(Clone, Debug)]
22pub struct TensorRank3List2D<
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>([TensorRank3List<D, I, J, K, W>; X]);
30
31impl<const D: usize, const I: usize, const J: usize, const K: usize, const W: usize, const X: usize>
32    Display for TensorRank3List2D<D, I, J, K, 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 K: usize, const W: usize, const X: usize>
41    ErrorTensor for TensorRank3List2D<D, I, J, K, W, X>
42{
43    fn error_fd(&self, comparator: &Self, epsilon: &TensorRank0) -> Option<(bool, usize)> {
44        let error_count = self
45            .iter()
46            .zip(comparator.iter())
47            .map(|(self_a, comparator_a)| {
48                self_a
49                    .iter()
50                    .zip(comparator_a.iter())
51                    .map(|(self_ab, comparator_ab)| {
52                        self_ab
53                            .iter()
54                            .zip(comparator_ab.iter())
55                            .map(|(self_ab_i, comparator_ab_i)| {
56                                self_ab_i
57                                    .iter()
58                                    .zip(comparator_ab_i.iter())
59                                    .map(|(self_ab_ij, comparator_ab_ij)| {
60                                        self_ab_ij
61                                            .iter()
62                                            .zip(comparator_ab_ij.iter())
63                                            .filter(|&(&self_ab_ijk, &comparator_ab_ijk)| {
64                                                &(self_ab_ijk / comparator_ab_ijk - 1.0).abs()
65                                                    >= epsilon
66                                                    && (&self_ab_ijk.abs() >= epsilon
67                                                        || &comparator_ab_ijk.abs() >= epsilon)
68                                            })
69                                            .count()
70                                    })
71                                    .sum::<usize>()
72                            })
73                            .sum::<usize>()
74                    })
75                    .sum::<usize>()
76            })
77            .sum();
78        if error_count > 0 {
79            Some((true, error_count))
80        } else {
81            None
82        }
83    }
84}
85
86impl<const D: usize, const I: usize, const J: usize, const K: usize, const W: usize, const X: usize>
87    Tensor for TensorRank3List2D<D, I, J, K, W, X>
88{
89    type Item = TensorRank3List<D, I, J, K, W>;
90    fn iter(&self) -> impl Iterator<Item = &Self::Item> {
91        self.0.iter()
92    }
93    fn iter_mut(&mut self) -> impl Iterator<Item = &mut Self::Item> {
94        self.0.iter_mut()
95    }
96}
97
98impl<const D: usize, const I: usize, const J: usize, const K: usize, const W: usize, const X: usize>
99    TensorArray for TensorRank3List2D<D, I, J, K, W, X>
100{
101    type Array = [[[[[TensorRank0; D]; D]; D]; W]; X];
102    type Item = TensorRank3List<D, I, J, K, W>;
103    fn as_array(&self) -> Self::Array {
104        let mut array = [[[[[0.0; D]; D]; D]; W]; X];
105        array
106            .iter_mut()
107            .zip(self.iter())
108            .for_each(|(entry_rank_4_list, tensor_rank_4_list)| {
109                *entry_rank_4_list = tensor_rank_4_list.as_array()
110            });
111        array
112    }
113    fn identity() -> Self {
114        Self(from_fn(|_| Self::Item::identity()))
115    }
116    fn new(array: Self::Array) -> Self {
117        array.into_iter().map(Self::Item::new).collect()
118    }
119    fn zero() -> Self {
120        Self(from_fn(|_| Self::Item::zero()))
121    }
122}
123
124impl<const D: usize, const I: usize, const J: usize, const K: usize, const W: usize, const X: usize>
125    FromIterator<TensorRank3List<D, I, J, K, W>> for TensorRank3List2D<D, I, J, K, W, X>
126{
127    fn from_iter<Ii: IntoIterator<Item = TensorRank3List<D, I, J, K, W>>>(
128        into_iterator: Ii,
129    ) -> Self {
130        let mut tensor_rank_3_list_2d = Self::zero();
131        tensor_rank_3_list_2d
132            .iter_mut()
133            .zip(into_iterator)
134            .for_each(|(tensor_rank_3_list, entry)| *tensor_rank_3_list = entry);
135        tensor_rank_3_list_2d
136    }
137}
138
139impl<const D: usize, const I: usize, const J: usize, const K: usize, const W: usize, const X: usize>
140    Index<usize> for TensorRank3List2D<D, I, J, K, W, X>
141{
142    type Output = TensorRank3List<D, I, J, K, W>;
143    fn index(&self, index: usize) -> &Self::Output {
144        &self.0[index]
145    }
146}
147
148impl<const D: usize, const I: usize, const J: usize, const K: usize, const W: usize, const X: usize>
149    IndexMut<usize> for TensorRank3List2D<D, I, J, K, W, X>
150{
151    fn index_mut(&mut self, index: usize) -> &mut Self::Output {
152        &mut self.0[index]
153    }
154}
155
156impl<const D: usize, const I: usize, const J: usize, const K: usize, const W: usize, const X: usize>
157    Add for TensorRank3List2D<D, I, J, K, W, X>
158{
159    type Output = Self;
160    fn add(mut self, tensor_rank_3_list_2d: Self) -> Self::Output {
161        self += tensor_rank_3_list_2d;
162        self
163    }
164}
165
166impl<const D: usize, const I: usize, const J: usize, const K: usize, const W: usize, const X: usize>
167    Add<&Self> for TensorRank3List2D<D, I, J, K, W, X>
168{
169    type Output = Self;
170    fn add(mut self, tensor_rank_3_list_2d: &Self) -> Self::Output {
171        self += tensor_rank_3_list_2d;
172        self
173    }
174}
175
176impl<const D: usize, const I: usize, const J: usize, const K: usize, const W: usize, const X: usize>
177    AddAssign for TensorRank3List2D<D, I, J, K, W, X>
178{
179    fn add_assign(&mut self, tensor_rank_3_list_2d: Self) {
180        self.iter_mut()
181            .zip(tensor_rank_3_list_2d.iter())
182            .for_each(|(self_entry, tensor_rank_3_list_2d)| *self_entry += tensor_rank_3_list_2d);
183    }
184}
185
186impl<const D: usize, const I: usize, const J: usize, const K: usize, const W: usize, const X: usize>
187    AddAssign<&Self> for TensorRank3List2D<D, I, J, K, W, X>
188{
189    fn add_assign(&mut self, tensor_rank_3_list_2d: &Self) {
190        self.iter_mut()
191            .zip(tensor_rank_3_list_2d.iter())
192            .for_each(|(self_entry, tensor_rank_3_list_2d)| *self_entry += tensor_rank_3_list_2d);
193    }
194}
195
196impl<const D: usize, const I: usize, const J: usize, const K: usize, const W: usize, const X: usize>
197    Div<TensorRank0> for TensorRank3List2D<D, I, J, K, W, X>
198{
199    type Output = Self;
200    fn div(mut self, tensor_rank_0: TensorRank0) -> Self::Output {
201        self /= &tensor_rank_0;
202        self
203    }
204}
205
206impl<const D: usize, const I: usize, const J: usize, const K: usize, const W: usize, const X: usize>
207    Div<&TensorRank0> for TensorRank3List2D<D, I, J, K, W, X>
208{
209    type Output = Self;
210    fn div(mut self, tensor_rank_0: &TensorRank0) -> Self::Output {
211        self /= tensor_rank_0;
212        self
213    }
214}
215
216impl<const D: usize, const I: usize, const J: usize, const K: usize, const W: usize, const X: usize>
217    DivAssign<TensorRank0> for TensorRank3List2D<D, I, J, K, W, X>
218{
219    fn div_assign(&mut self, tensor_rank_0: TensorRank0) {
220        self.iter_mut().for_each(|entry| *entry /= &tensor_rank_0);
221    }
222}
223
224impl<const D: usize, const I: usize, const J: usize, const K: usize, const W: usize, const X: usize>
225    DivAssign<&TensorRank0> for TensorRank3List2D<D, I, J, K, W, X>
226{
227    fn div_assign(&mut self, tensor_rank_0: &TensorRank0) {
228        self.iter_mut().for_each(|entry| *entry /= tensor_rank_0);
229    }
230}
231
232impl<const D: usize, const I: usize, const J: usize, const K: usize, const W: usize, const X: usize>
233    Mul<TensorRank0> for TensorRank3List2D<D, I, J, K, W, X>
234{
235    type Output = Self;
236    fn mul(mut self, tensor_rank_0: TensorRank0) -> Self::Output {
237        self *= &tensor_rank_0;
238        self
239    }
240}
241
242impl<const D: usize, const I: usize, const J: usize, const K: usize, const W: usize, const X: usize>
243    Mul<&TensorRank0> for TensorRank3List2D<D, I, J, K, W, X>
244{
245    type Output = Self;
246    fn mul(mut self, tensor_rank_0: &TensorRank0) -> Self::Output {
247        self *= tensor_rank_0;
248        self
249    }
250}
251
252impl<const D: usize, const I: usize, const J: usize, const K: usize, const W: usize, const X: usize>
253    MulAssign<TensorRank0> for TensorRank3List2D<D, I, J, K, W, X>
254{
255    fn mul_assign(&mut self, tensor_rank_0: TensorRank0) {
256        self.iter_mut().for_each(|entry| *entry *= &tensor_rank_0);
257    }
258}
259
260impl<const D: usize, const I: usize, const J: usize, const K: usize, const W: usize, const X: usize>
261    MulAssign<&TensorRank0> for TensorRank3List2D<D, I, J, K, W, X>
262{
263    fn mul_assign(&mut self, tensor_rank_0: &TensorRank0) {
264        self.iter_mut().for_each(|entry| *entry *= tensor_rank_0);
265    }
266}
267
268impl<const D: usize, const I: usize, const J: usize, const K: usize, const W: usize, const X: usize>
269    Sub for TensorRank3List2D<D, I, J, K, W, X>
270{
271    type Output = Self;
272    fn sub(mut self, tensor_rank_3_list_2d: Self) -> Self::Output {
273        self -= tensor_rank_3_list_2d;
274        self
275    }
276}
277
278impl<const D: usize, const I: usize, const J: usize, const K: usize, const W: usize, const X: usize>
279    Sub<&Self> for TensorRank3List2D<D, I, J, K, W, X>
280{
281    type Output = Self;
282    fn sub(mut self, tensor_rank_3_list_2d: &Self) -> Self::Output {
283        self -= tensor_rank_3_list_2d;
284        self
285    }
286}
287
288impl<const D: usize, const I: usize, const J: usize, const K: usize, const W: usize, const X: usize>
289    Sub for &TensorRank3List2D<D, I, J, K, W, X>
290{
291    type Output = TensorRank3List2D<D, I, J, K, W, X>;
292    fn sub(self, tensor_rank_3_list_2d: Self) -> Self::Output {
293        tensor_rank_3_list_2d
294            .iter()
295            .zip(self.iter())
296            .map(|(tensor_rank_3_list_2d_a, self_a)| self_a - tensor_rank_3_list_2d_a)
297            .collect()
298    }
299}
300
301impl<const D: usize, const I: usize, const J: usize, const K: usize, const W: usize, const X: usize>
302    SubAssign for TensorRank3List2D<D, I, J, K, W, X>
303{
304    fn sub_assign(&mut self, tensor_rank_3_list_2d: Self) {
305        self.iter_mut()
306            .zip(tensor_rank_3_list_2d.iter())
307            .for_each(|(self_entry, tensor_rank_3_list)| *self_entry -= tensor_rank_3_list);
308    }
309}
310
311impl<const D: usize, const I: usize, const J: usize, const K: usize, const W: usize, const X: usize>
312    SubAssign<&Self> for TensorRank3List2D<D, I, J, K, W, X>
313{
314    fn sub_assign(&mut self, tensor_rank_3_list_2d: &Self) {
315        self.iter_mut()
316            .zip(tensor_rank_3_list_2d.iter())
317            .for_each(|(self_entry, tensor_rank_3_list)| *self_entry -= tensor_rank_3_list);
318    }
319}