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(
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                                    .map(|(self_ab_ij, comparator_ab_ij)| {
65                                        self_ab_ij
66                                            .iter()
67                                            .zip(comparator_ab_ij.iter())
68                                            .filter(|&(&self_ab_ijk, &comparator_ab_ijk)| {
69                                                &(self_ab_ijk - comparator_ab_ijk).abs() >= tol_abs
70                                                    && &(self_ab_ijk / comparator_ab_ijk - 1.0)
71                                                        .abs()
72                                                        >= tol_rel
73                                            })
74                                            .count()
75                                    })
76                                    .sum::<usize>()
77                            })
78                            .sum::<usize>()
79                    })
80                    .sum::<usize>()
81            })
82            .sum();
83        if error_count > 0 {
84            Some(error_count)
85        } else {
86            None
87        }
88    }
89    fn error_fd(&self, comparator: &Self, epsilon: &TensorRank0) -> Option<(bool, usize)> {
90        let error_count = self
91            .iter()
92            .zip(comparator.iter())
93            .map(|(self_a, comparator_a)| {
94                self_a
95                    .iter()
96                    .zip(comparator_a.iter())
97                    .map(|(self_ab, comparator_ab)| {
98                        self_ab
99                            .iter()
100                            .zip(comparator_ab.iter())
101                            .map(|(self_ab_i, comparator_ab_i)| {
102                                self_ab_i
103                                    .iter()
104                                    .zip(comparator_ab_i.iter())
105                                    .map(|(self_ab_ij, comparator_ab_ij)| {
106                                        self_ab_ij
107                                            .iter()
108                                            .zip(comparator_ab_ij.iter())
109                                            .filter(|&(&self_ab_ijk, &comparator_ab_ijk)| {
110                                                &(self_ab_ijk / comparator_ab_ijk - 1.0).abs()
111                                                    >= epsilon
112                                                    && (&self_ab_ijk.abs() >= epsilon
113                                                        || &comparator_ab_ijk.abs() >= epsilon)
114                                            })
115                                            .count()
116                                    })
117                                    .sum::<usize>()
118                            })
119                            .sum::<usize>()
120                    })
121                    .sum::<usize>()
122            })
123            .sum();
124        if error_count > 0 {
125            Some((true, error_count))
126        } else {
127            None
128        }
129    }
130}
131
132impl<const D: usize, const I: usize, const J: usize, const K: usize, const W: usize, const X: usize>
133    Tensor for TensorRank3List2D<D, I, J, K, W, X>
134{
135    type Item = TensorRank3List<D, I, J, K, W>;
136    fn iter(&self) -> impl Iterator<Item = &Self::Item> {
137        self.0.iter()
138    }
139    fn iter_mut(&mut self) -> impl Iterator<Item = &mut Self::Item> {
140        self.0.iter_mut()
141    }
142}
143
144impl<const D: usize, const I: usize, const J: usize, const K: usize, const W: usize, const X: usize>
145    TensorArray for TensorRank3List2D<D, I, J, K, W, X>
146{
147    type Array = [[[[[TensorRank0; D]; D]; D]; W]; X];
148    type Item = TensorRank3List<D, I, J, K, W>;
149    fn as_array(&self) -> Self::Array {
150        let mut array = [[[[[0.0; D]; D]; D]; W]; X];
151        array
152            .iter_mut()
153            .zip(self.iter())
154            .for_each(|(entry_rank_4_list, tensor_rank_4_list)| {
155                *entry_rank_4_list = tensor_rank_4_list.as_array()
156            });
157        array
158    }
159    fn identity() -> Self {
160        Self(from_fn(|_| Self::Item::identity()))
161    }
162    fn new(array: Self::Array) -> Self {
163        array.into_iter().map(Self::Item::new).collect()
164    }
165    fn zero() -> Self {
166        Self(from_fn(|_| Self::Item::zero()))
167    }
168}
169
170impl<const D: usize, const I: usize, const J: usize, const K: usize, const W: usize, const X: usize>
171    FromIterator<TensorRank3List<D, I, J, K, W>> for TensorRank3List2D<D, I, J, K, W, X>
172{
173    fn from_iter<Ii: IntoIterator<Item = TensorRank3List<D, I, J, K, W>>>(
174        into_iterator: Ii,
175    ) -> Self {
176        let mut tensor_rank_3_list_2d = Self::zero();
177        tensor_rank_3_list_2d
178            .iter_mut()
179            .zip(into_iterator)
180            .for_each(|(tensor_rank_3_list, entry)| *tensor_rank_3_list = entry);
181        tensor_rank_3_list_2d
182    }
183}
184
185impl<const D: usize, const I: usize, const J: usize, const K: usize, const W: usize, const X: usize>
186    Index<usize> for TensorRank3List2D<D, I, J, K, W, X>
187{
188    type Output = TensorRank3List<D, I, J, K, W>;
189    fn index(&self, index: usize) -> &Self::Output {
190        &self.0[index]
191    }
192}
193
194impl<const D: usize, const I: usize, const J: usize, const K: usize, const W: usize, const X: usize>
195    IndexMut<usize> for TensorRank3List2D<D, I, J, K, W, X>
196{
197    fn index_mut(&mut self, index: usize) -> &mut Self::Output {
198        &mut self.0[index]
199    }
200}
201
202impl<const D: usize, const I: usize, const J: usize, const K: usize, const W: usize, const X: usize>
203    Add for TensorRank3List2D<D, I, J, K, W, X>
204{
205    type Output = Self;
206    fn add(mut self, tensor_rank_3_list_2d: Self) -> Self::Output {
207        self += tensor_rank_3_list_2d;
208        self
209    }
210}
211
212impl<const D: usize, const I: usize, const J: usize, const K: usize, const W: usize, const X: usize>
213    Add<&Self> for TensorRank3List2D<D, I, J, K, W, X>
214{
215    type Output = Self;
216    fn add(mut self, tensor_rank_3_list_2d: &Self) -> Self::Output {
217        self += tensor_rank_3_list_2d;
218        self
219    }
220}
221
222impl<const D: usize, const I: usize, const J: usize, const K: usize, const W: usize, const X: usize>
223    AddAssign for TensorRank3List2D<D, I, J, K, W, X>
224{
225    fn add_assign(&mut self, tensor_rank_3_list_2d: Self) {
226        self.iter_mut()
227            .zip(tensor_rank_3_list_2d.iter())
228            .for_each(|(self_entry, tensor_rank_3_list_2d)| *self_entry += tensor_rank_3_list_2d);
229    }
230}
231
232impl<const D: usize, const I: usize, const J: usize, const K: usize, const W: usize, const X: usize>
233    AddAssign<&Self> for TensorRank3List2D<D, I, J, K, W, X>
234{
235    fn add_assign(&mut self, tensor_rank_3_list_2d: &Self) {
236        self.iter_mut()
237            .zip(tensor_rank_3_list_2d.iter())
238            .for_each(|(self_entry, tensor_rank_3_list_2d)| *self_entry += tensor_rank_3_list_2d);
239    }
240}
241
242impl<const D: usize, const I: usize, const J: usize, const K: usize, const W: usize, const X: usize>
243    Div<TensorRank0> for TensorRank3List2D<D, I, J, K, W, X>
244{
245    type Output = Self;
246    fn div(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    Div<&TensorRank0> for TensorRank3List2D<D, I, J, K, W, X>
254{
255    type Output = Self;
256    fn div(mut self, tensor_rank_0: &TensorRank0) -> Self::Output {
257        self /= tensor_rank_0;
258        self
259    }
260}
261
262impl<const D: usize, const I: usize, const J: usize, const K: usize, const W: usize, const X: usize>
263    DivAssign<TensorRank0> for TensorRank3List2D<D, I, J, K, W, X>
264{
265    fn div_assign(&mut self, tensor_rank_0: TensorRank0) {
266        self.iter_mut().for_each(|entry| *entry /= &tensor_rank_0);
267    }
268}
269
270impl<const D: usize, const I: usize, const J: usize, const K: usize, const W: usize, const X: usize>
271    DivAssign<&TensorRank0> for TensorRank3List2D<D, I, J, K, W, X>
272{
273    fn div_assign(&mut self, tensor_rank_0: &TensorRank0) {
274        self.iter_mut().for_each(|entry| *entry /= tensor_rank_0);
275    }
276}
277
278impl<const D: usize, const I: usize, const J: usize, const K: usize, const W: usize, const X: usize>
279    Mul<TensorRank0> for TensorRank3List2D<D, I, J, K, W, X>
280{
281    type Output = Self;
282    fn mul(mut self, tensor_rank_0: TensorRank0) -> Self::Output {
283        self *= &tensor_rank_0;
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    Mul<&TensorRank0> for TensorRank3List2D<D, I, J, K, W, X>
290{
291    type Output = Self;
292    fn mul(mut self, tensor_rank_0: &TensorRank0) -> Self::Output {
293        self *= tensor_rank_0;
294        self
295    }
296}
297
298impl<const D: usize, const I: usize, const J: usize, const K: usize, const W: usize, const X: usize>
299    MulAssign<TensorRank0> for TensorRank3List2D<D, I, J, K, W, X>
300{
301    fn mul_assign(&mut self, tensor_rank_0: TensorRank0) {
302        self.iter_mut().for_each(|entry| *entry *= &tensor_rank_0);
303    }
304}
305
306impl<const D: usize, const I: usize, const J: usize, const K: usize, const W: usize, const X: usize>
307    MulAssign<&TensorRank0> for TensorRank3List2D<D, I, J, K, W, X>
308{
309    fn mul_assign(&mut self, tensor_rank_0: &TensorRank0) {
310        self.iter_mut().for_each(|entry| *entry *= tensor_rank_0);
311    }
312}
313
314impl<const D: usize, const I: usize, const J: usize, const K: usize, const W: usize, const X: usize>
315    Sub for TensorRank3List2D<D, I, J, K, W, X>
316{
317    type Output = Self;
318    fn sub(mut self, tensor_rank_3_list_2d: Self) -> Self::Output {
319        self -= tensor_rank_3_list_2d;
320        self
321    }
322}
323
324impl<const D: usize, const I: usize, const J: usize, const K: usize, const W: usize, const X: usize>
325    Sub<&Self> for TensorRank3List2D<D, I, J, K, W, X>
326{
327    type Output = Self;
328    fn sub(mut self, tensor_rank_3_list_2d: &Self) -> Self::Output {
329        self -= tensor_rank_3_list_2d;
330        self
331    }
332}
333
334impl<const D: usize, const I: usize, const J: usize, const K: usize, const W: usize, const X: usize>
335    SubAssign for TensorRank3List2D<D, I, J, K, W, X>
336{
337    fn sub_assign(&mut self, tensor_rank_3_list_2d: Self) {
338        self.iter_mut()
339            .zip(tensor_rank_3_list_2d.iter())
340            .for_each(|(self_entry, tensor_rank_3_list)| *self_entry -= tensor_rank_3_list);
341    }
342}
343
344impl<const D: usize, const I: usize, const J: usize, const K: usize, const W: usize, const X: usize>
345    SubAssign<&Self> for TensorRank3List2D<D, I, J, K, W, X>
346{
347    fn sub_assign(&mut self, tensor_rank_3_list_2d: &Self) {
348        self.iter_mut()
349            .zip(tensor_rank_3_list_2d.iter())
350            .for_each(|(self_entry, tensor_rank_3_list)| *self_entry -= tensor_rank_3_list);
351    }
352}