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