conspire/math/tensor/rank_2/list_2d/
mod.rs

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