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

1#[cfg(test)]
2use super::super::test::ErrorTensor;
3
4use crate::math::{Tensor, TensorRank0, TensorRank2, TensorRank2Vec, TensorVec};
5use std::{
6    fmt::{Display, Formatter, Result},
7    ops::{Add, AddAssign, Div, DivAssign, Index, IndexMut, Mul, MulAssign, Sub, SubAssign},
8};
9
10/// A 2D vector of *d*-dimensional tensors of rank 2.
11///
12/// `D` is the dimension, `I`, `J` are the configurations.
13#[derive(Clone, Debug)]
14pub struct TensorRank2Vec2D<const D: usize, const I: usize, const J: usize>(
15    Vec<TensorRank2Vec<D, I, J>>,
16);
17
18impl<const D: usize, const I: usize, const J: usize> Display for TensorRank2Vec2D<D, I, J> {
19    fn fmt(&self, _f: &mut Formatter) -> Result {
20        Ok(())
21    }
22}
23
24#[cfg(test)]
25impl<const D: usize, const I: usize, const J: usize> ErrorTensor for TensorRank2Vec2D<D, I, J> {
26    fn error(
27        &self,
28        comparator: &Self,
29        tol_abs: &TensorRank0,
30        tol_rel: &TensorRank0,
31    ) -> Option<usize> {
32        let error_count = self
33            .iter()
34            .zip(comparator.iter())
35            .map(|(self_a, comparator_a)| {
36                self_a
37                    .iter()
38                    .zip(comparator_a.iter())
39                    .map(|(self_ab, comparator_ab)| {
40                        self_ab
41                            .iter()
42                            .zip(comparator_ab.iter())
43                            .map(|(self_ab_i, comparator_ab_i)| {
44                                self_ab_i
45                                    .iter()
46                                    .zip(comparator_ab_i.iter())
47                                    .filter(|(&self_ab_ij, &comparator_ab_ij)| {
48                                        &(self_ab_ij - comparator_ab_ij).abs() >= tol_abs
49                                            && &(self_ab_ij / comparator_ab_ij - 1.0).abs()
50                                                >= tol_rel
51                                    })
52                                    .count()
53                            })
54                            .sum::<usize>()
55                    })
56                    .sum::<usize>()
57            })
58            .sum();
59        if error_count > 0 {
60            Some(error_count)
61        } else {
62            None
63        }
64    }
65    fn error_fd(&self, comparator: &Self, epsilon: &TensorRank0) -> Option<(bool, usize)> {
66        let error_count = self
67            .iter()
68            .zip(comparator.iter())
69            .map(|(self_a, comparator_a)| {
70                self_a
71                    .iter()
72                    .zip(comparator_a.iter())
73                    .map(|(self_ab, comparator_ab)| {
74                        self_ab
75                            .iter()
76                            .zip(comparator_ab.iter())
77                            .map(|(self_ab_i, comparator_ab_i)| {
78                                self_ab_i
79                                    .iter()
80                                    .zip(comparator_ab_i.iter())
81                                    .filter(|(&self_ab_ij, &comparator_ab_ij)| {
82                                        &(self_ab_ij / comparator_ab_ij - 1.0).abs() >= epsilon
83                                            && (&self_ab_ij.abs() >= epsilon
84                                                || &comparator_ab_ij.abs() >= epsilon)
85                                    })
86                                    .count()
87                            })
88                            .sum::<usize>()
89                    })
90                    .sum::<usize>()
91            })
92            .sum();
93        if error_count > 0 {
94            let auxillary = self
95                .iter()
96                .zip(comparator.iter())
97                .map(|(self_a, comparator_a)| {
98                    self_a
99                        .iter()
100                        .zip(comparator_a.iter())
101                        .map(|(self_ab, comparator_ab)| {
102                            self_ab
103                                .iter()
104                                .zip(comparator_ab.iter())
105                                .map(|(self_ab_i, comparator_ab_i)| {
106                                    self_ab_i
107                                        .iter()
108                                        .zip(comparator_ab_i.iter())
109                                        .filter(|(&self_ab_ij, &comparator_ab_ij)| {
110                                            &(self_ab_ij / comparator_ab_ij - 1.0).abs() >= epsilon
111                                                && &(self_ab_ij - comparator_ab_ij).abs() >= epsilon
112                                                && (&self_ab_ij.abs() >= epsilon
113                                                    || &comparator_ab_ij.abs() >= epsilon)
114                                        })
115                                        .count()
116                                })
117                                .sum::<usize>()
118                        })
119                        .sum::<usize>()
120                })
121                .sum::<usize>()
122                > 0;
123            Some((auxillary, error_count))
124        } else {
125            None
126        }
127    }
128}
129
130impl<const D: usize, const I: usize, const J: usize> FromIterator<TensorRank2Vec<D, I, J>>
131    for TensorRank2Vec2D<D, I, J>
132{
133    fn from_iter<Ii: IntoIterator<Item = TensorRank2Vec<D, I, J>>>(into_iterator: Ii) -> Self {
134        Self(Vec::from_iter(into_iterator))
135    }
136}
137
138impl<const D: usize, const I: usize, const J: usize> Index<usize> for TensorRank2Vec2D<D, I, J> {
139    type Output = TensorRank2Vec<D, I, J>;
140    fn index(&self, index: usize) -> &Self::Output {
141        &self.0[index]
142    }
143}
144
145impl<const D: usize, const I: usize, const J: usize> IndexMut<usize> for TensorRank2Vec2D<D, I, J> {
146    fn index_mut(&mut self, index: usize) -> &mut Self::Output {
147        &mut self.0[index]
148    }
149}
150
151impl<const D: usize, const I: usize, const J: usize> TensorVec for TensorRank2Vec2D<D, I, J> {
152    type Item = TensorRank2Vec<D, I, J>;
153    type Slice<'a> = &'a [&'a [[[TensorRank0; D]; D]]];
154    fn append(&mut self, other: &mut Self) {
155        self.0.append(&mut other.0)
156    }
157    fn is_empty(&self) -> bool {
158        self.0.is_empty()
159    }
160    fn len(&self) -> usize {
161        self.0.len()
162    }
163    fn new(slice: Self::Slice<'_>) -> Self {
164        slice
165            .iter()
166            .map(|slice_entry| Self::Item::new(slice_entry))
167            .collect()
168    }
169    fn push(&mut self, item: Self::Item) {
170        self.0.push(item)
171    }
172    fn zero(len: usize) -> Self {
173        (0..len).map(|_| Self::Item::zero(len)).collect()
174    }
175}
176
177impl<const D: usize, const I: usize, const J: usize> Tensor for TensorRank2Vec2D<D, I, J> {
178    type Item = TensorRank2Vec<D, I, J>;
179    fn iter(&self) -> impl Iterator<Item = &Self::Item> {
180        self.0.iter()
181    }
182    fn iter_mut(&mut self) -> impl Iterator<Item = &mut Self::Item> {
183        self.0.iter_mut()
184    }
185}
186
187impl<const D: usize, const I: usize, const J: usize, const K: usize> Mul<TensorRank2<D, J, K>>
188    for TensorRank2Vec2D<D, I, J>
189{
190    type Output = TensorRank2Vec2D<D, I, K>;
191    fn mul(self, tensor_rank_2: TensorRank2<D, J, K>) -> Self::Output {
192        self.iter()
193            .map(|self_entry| {
194                self_entry
195                    .iter()
196                    .map(|self_tensor_rank_2| self_tensor_rank_2 * &tensor_rank_2)
197                    .collect()
198            })
199            .collect()
200    }
201}
202
203impl<const D: usize, const I: usize, const J: usize, const K: usize> Mul<&TensorRank2<D, J, K>>
204    for TensorRank2Vec2D<D, I, J>
205{
206    type Output = TensorRank2Vec2D<D, I, K>;
207    fn mul(self, tensor_rank_2: &TensorRank2<D, J, K>) -> Self::Output {
208        self.iter()
209            .map(|self_entry| {
210                self_entry
211                    .iter()
212                    .map(|self_tensor_rank_2| self_tensor_rank_2 * tensor_rank_2)
213                    .collect()
214            })
215            .collect()
216    }
217}
218
219impl<const D: usize, const I: usize, const J: usize> Add for TensorRank2Vec2D<D, I, J> {
220    type Output = Self;
221    fn add(mut self, tensor_rank_2_vec_2d: Self) -> Self::Output {
222        self += tensor_rank_2_vec_2d;
223        self
224    }
225}
226
227impl<const D: usize, const I: usize, const J: usize> Add<&Self> for TensorRank2Vec2D<D, I, J> {
228    type Output = Self;
229    fn add(mut self, tensor_rank_2_vec_2d: &Self) -> Self::Output {
230        self += tensor_rank_2_vec_2d;
231        self
232    }
233}
234
235impl<const D: usize, const I: usize, const J: usize> AddAssign for TensorRank2Vec2D<D, I, J> {
236    fn add_assign(&mut self, tensor_rank_2_vec_2d: Self) {
237        self.iter_mut()
238            .zip(tensor_rank_2_vec_2d.iter())
239            .for_each(|(self_entry, tensor_rank_2_vec)| *self_entry += tensor_rank_2_vec);
240    }
241}
242
243impl<const D: usize, const I: usize, const J: usize> AddAssign<&Self>
244    for TensorRank2Vec2D<D, I, J>
245{
246    fn add_assign(&mut self, tensor_rank_2_vec_2d: &Self) {
247        self.iter_mut()
248            .zip(tensor_rank_2_vec_2d.iter())
249            .for_each(|(self_entry, tensor_rank_2_vec)| *self_entry += tensor_rank_2_vec);
250    }
251}
252
253impl<const D: usize, const I: usize, const J: usize> Div<TensorRank0>
254    for TensorRank2Vec2D<D, I, J>
255{
256    type Output = Self;
257    fn div(mut self, tensor_rank_0: TensorRank0) -> Self::Output {
258        self /= &tensor_rank_0;
259        self
260    }
261}
262
263impl<const D: usize, const I: usize, const J: usize> Div<&TensorRank0>
264    for TensorRank2Vec2D<D, I, J>
265{
266    type Output = Self;
267    fn div(mut self, tensor_rank_0: &TensorRank0) -> Self::Output {
268        self /= tensor_rank_0;
269        self
270    }
271}
272
273impl<const D: usize, const I: usize, const J: usize> DivAssign<TensorRank0>
274    for TensorRank2Vec2D<D, I, J>
275{
276    fn div_assign(&mut self, tensor_rank_0: TensorRank0) {
277        self.iter_mut().for_each(|entry| *entry /= &tensor_rank_0);
278    }
279}
280
281impl<const D: usize, const I: usize, const J: usize> DivAssign<&TensorRank0>
282    for TensorRank2Vec2D<D, I, J>
283{
284    fn div_assign(&mut self, tensor_rank_0: &TensorRank0) {
285        self.iter_mut().for_each(|entry| *entry /= tensor_rank_0);
286    }
287}
288
289impl<const D: usize, const I: usize, const J: usize> Mul<TensorRank0>
290    for TensorRank2Vec2D<D, I, J>
291{
292    type Output = Self;
293    fn mul(mut self, tensor_rank_0: TensorRank0) -> Self::Output {
294        self *= &tensor_rank_0;
295        self
296    }
297}
298
299impl<const D: usize, const I: usize, const J: usize> Mul<&TensorRank0>
300    for TensorRank2Vec2D<D, I, J>
301{
302    type Output = Self;
303    fn mul(mut self, tensor_rank_0: &TensorRank0) -> Self::Output {
304        self *= tensor_rank_0;
305        self
306    }
307}
308
309impl<const D: usize, const I: usize, const J: usize> MulAssign<TensorRank0>
310    for TensorRank2Vec2D<D, I, J>
311{
312    fn mul_assign(&mut self, tensor_rank_0: TensorRank0) {
313        self.iter_mut().for_each(|entry| *entry *= &tensor_rank_0);
314    }
315}
316
317impl<const D: usize, const I: usize, const J: usize> MulAssign<&TensorRank0>
318    for TensorRank2Vec2D<D, I, J>
319{
320    fn mul_assign(&mut self, tensor_rank_0: &TensorRank0) {
321        self.iter_mut().for_each(|entry| *entry *= tensor_rank_0);
322    }
323}
324
325impl<const D: usize, const I: usize, const J: usize> Sub for TensorRank2Vec2D<D, I, J> {
326    type Output = Self;
327    fn sub(mut self, tensor_rank_2_vec_2d: Self) -> Self::Output {
328        self -= tensor_rank_2_vec_2d;
329        self
330    }
331}
332
333impl<const D: usize, const I: usize, const J: usize> Sub<&Self> for TensorRank2Vec2D<D, I, J> {
334    type Output = Self;
335    fn sub(mut self, tensor_rank_2_vec_2d: &Self) -> Self::Output {
336        self -= tensor_rank_2_vec_2d;
337        self
338    }
339}
340
341impl<const D: usize, const I: usize, const J: usize> SubAssign for TensorRank2Vec2D<D, I, J> {
342    fn sub_assign(&mut self, tensor_rank_2_vec_2d: Self) {
343        self.iter_mut()
344            .zip(tensor_rank_2_vec_2d.iter())
345            .for_each(|(self_entry, tensor_rank_2_vec)| *self_entry -= tensor_rank_2_vec);
346    }
347}
348
349impl<const D: usize, const I: usize, const J: usize> SubAssign<&Self>
350    for TensorRank2Vec2D<D, I, J>
351{
352    fn sub_assign(&mut self, tensor_rank_2_vec_2d: &Self) {
353        self.iter_mut()
354            .zip(tensor_rank_2_vec_2d.iter())
355            .for_each(|(self_entry, tensor_rank_2_vec)| *self_entry -= tensor_rank_2_vec);
356    }
357}