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

1#[cfg(test)]
2use super::super::test::ErrorTensor;
3
4use crate::math::{Tensor, TensorArray, TensorRank0, TensorRank2, TensorVec};
5use std::{
6    fmt::{Display, Formatter, Result},
7    ops::{Add, AddAssign, Div, DivAssign, Index, IndexMut, Mul, MulAssign, Sub, SubAssign},
8};
9
10/// A 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 TensorRank2Vec<const D: usize, const I: usize, const J: usize>(
15    Vec<TensorRank2<D, I, J>>,
16);
17
18impl<const D: usize, const I: usize, const J: usize> Display for TensorRank2Vec<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 TensorRank2Vec<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_a_i, comparator_a_i)| {
40                        self_a_i
41                            .iter()
42                            .zip(comparator_a_i.iter())
43                            .filter(|&(&self_a_ij, &comparator_a_ij)| {
44                                &(self_a_ij - comparator_a_ij).abs() >= tol_abs
45                                    && &(self_a_ij / comparator_a_ij - 1.0).abs() >= tol_rel
46                            })
47                            .count()
48                    })
49                    .sum::<usize>()
50            })
51            .sum();
52        if error_count > 0 {
53            Some(error_count)
54        } else {
55            None
56        }
57    }
58    fn error_fd(&self, comparator: &Self, epsilon: &TensorRank0) -> Option<(bool, usize)> {
59        let error_count = self
60            .iter()
61            .zip(comparator.iter())
62            .map(|(self_a, comparator_a)| {
63                self_a
64                    .iter()
65                    .zip(comparator_a.iter())
66                    .map(|(self_a_i, comparator_a_i)| {
67                        self_a_i
68                            .iter()
69                            .zip(comparator_a_i.iter())
70                            .filter(|&(&self_a_ij, &comparator_a_ij)| {
71                                &(self_a_ij / comparator_a_ij - 1.0).abs() >= epsilon
72                                    && (&self_a_ij.abs() >= epsilon
73                                        || &comparator_a_ij.abs() >= epsilon)
74                            })
75                            .count()
76                    })
77                    .sum::<usize>()
78            })
79            .sum();
80        if error_count > 0 {
81            Some((true, error_count))
82        } else {
83            None
84        }
85    }
86}
87
88impl<const D: usize, const I: usize, const J: usize> FromIterator<TensorRank2<D, I, J>>
89    for TensorRank2Vec<D, I, J>
90{
91    fn from_iter<Ii: IntoIterator<Item = TensorRank2<D, I, J>>>(into_iterator: Ii) -> Self {
92        Self(Vec::from_iter(into_iterator))
93    }
94}
95
96impl<const D: usize, const I: usize, const J: usize> Index<usize> for TensorRank2Vec<D, I, J> {
97    type Output = TensorRank2<D, I, J>;
98    fn index(&self, index: usize) -> &Self::Output {
99        &self.0[index]
100    }
101}
102
103impl<const D: usize, const I: usize, const J: usize> IndexMut<usize> for TensorRank2Vec<D, I, J> {
104    fn index_mut(&mut self, index: usize) -> &mut Self::Output {
105        &mut self.0[index]
106    }
107}
108
109impl<const D: usize, const I: usize, const J: usize> TensorVec for TensorRank2Vec<D, I, J> {
110    type Item = TensorRank2<D, I, J>;
111    type Slice<'a> = &'a [[[TensorRank0; D]; D]];
112    fn append(&mut self, other: &mut Self) {
113        self.0.append(&mut other.0)
114    }
115    fn is_empty(&self) -> bool {
116        self.0.is_empty()
117    }
118    fn len(&self) -> usize {
119        self.0.len()
120    }
121    fn new(slice: Self::Slice<'_>) -> Self {
122        slice
123            .iter()
124            .map(|slice_entry| Self::Item::new(*slice_entry))
125            .collect()
126    }
127    fn push(&mut self, item: Self::Item) {
128        self.0.push(item)
129    }
130    fn zero(len: usize) -> Self {
131        (0..len).map(|_| Self::Item::zero()).collect()
132    }
133}
134
135impl<const D: usize, const I: usize, const J: usize> Tensor for TensorRank2Vec<D, I, J> {
136    type Item = TensorRank2<D, I, J>;
137    fn iter(&self) -> impl Iterator<Item = &Self::Item> {
138        self.0.iter()
139    }
140    fn iter_mut(&mut self) -> impl Iterator<Item = &mut Self::Item> {
141        self.0.iter_mut()
142    }
143}
144
145impl<const D: usize, const I: usize, const J: usize> IntoIterator for TensorRank2Vec<D, I, J> {
146    type Item = TensorRank2<D, I, J>;
147    type IntoIter = std::vec::IntoIter<Self::Item>;
148    fn into_iter(self) -> Self::IntoIter {
149        self.0.into_iter()
150    }
151}
152
153impl<const D: usize, const I: usize, const J: usize> Add for TensorRank2Vec<D, I, J> {
154    type Output = Self;
155    fn add(mut self, tensor_rank_2_vec: Self) -> Self::Output {
156        self += tensor_rank_2_vec;
157        self
158    }
159}
160
161impl<const D: usize, const I: usize, const J: usize> Add<&Self> for TensorRank2Vec<D, I, J> {
162    type Output = Self;
163    fn add(mut self, tensor_rank_2_vec: &Self) -> Self::Output {
164        self += tensor_rank_2_vec;
165        self
166    }
167}
168
169impl<const D: usize, const I: usize, const J: usize> AddAssign for TensorRank2Vec<D, I, J> {
170    fn add_assign(&mut self, tensor_rank_2_vec: Self) {
171        self.iter_mut()
172            .zip(tensor_rank_2_vec.iter())
173            .for_each(|(self_entry, tensor_rank_2)| *self_entry += tensor_rank_2);
174    }
175}
176
177impl<const D: usize, const I: usize, const J: usize> AddAssign<&Self> for TensorRank2Vec<D, I, J> {
178    fn add_assign(&mut self, tensor_rank_2_vec: &Self) {
179        self.iter_mut()
180            .zip(tensor_rank_2_vec.iter())
181            .for_each(|(self_entry, tensor_rank_2)| *self_entry += tensor_rank_2);
182    }
183}
184
185impl<const D: usize, const I: usize, const J: usize> Div<TensorRank0> for TensorRank2Vec<D, I, J> {
186    type Output = Self;
187    fn div(mut self, tensor_rank_0: TensorRank0) -> Self::Output {
188        self /= &tensor_rank_0;
189        self
190    }
191}
192
193impl<const D: usize, const I: usize, const J: usize> Div<&TensorRank0> for TensorRank2Vec<D, I, J> {
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> DivAssign<TensorRank0>
202    for TensorRank2Vec<D, I, J>
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> DivAssign<&TensorRank0>
210    for TensorRank2Vec<D, I, J>
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> Mul<TensorRank0> for TensorRank2Vec<D, I, J> {
218    type Output = Self;
219    fn mul(mut self, tensor_rank_0: TensorRank0) -> Self::Output {
220        self *= &tensor_rank_0;
221        self
222    }
223}
224
225impl<const D: usize, const I: usize, const J: usize> Mul<&TensorRank0> for TensorRank2Vec<D, I, J> {
226    type Output = Self;
227    fn mul(mut self, tensor_rank_0: &TensorRank0) -> Self::Output {
228        self *= tensor_rank_0;
229        self
230    }
231}
232
233impl<const D: usize, const I: usize, const J: usize> MulAssign<TensorRank0>
234    for TensorRank2Vec<D, I, J>
235{
236    fn mul_assign(&mut self, tensor_rank_0: TensorRank0) {
237        self.iter_mut().for_each(|entry| *entry *= &tensor_rank_0);
238    }
239}
240
241impl<const D: usize, const I: usize, const J: usize> MulAssign<&TensorRank0>
242    for TensorRank2Vec<D, I, J>
243{
244    fn mul_assign(&mut self, tensor_rank_0: &TensorRank0) {
245        self.iter_mut().for_each(|entry| *entry *= tensor_rank_0);
246    }
247}
248
249impl<const D: usize, const I: usize, const J: usize> Sub for TensorRank2Vec<D, I, J> {
250    type Output = Self;
251    fn sub(mut self, tensor_rank_2_vec: Self) -> Self::Output {
252        self -= tensor_rank_2_vec;
253        self
254    }
255}
256
257impl<const D: usize, const I: usize, const J: usize> Sub<&Self> for TensorRank2Vec<D, I, J> {
258    type Output = Self;
259    fn sub(mut self, tensor_rank_2_vec: &Self) -> Self::Output {
260        self -= tensor_rank_2_vec;
261        self
262    }
263}
264
265impl<const D: usize, const I: usize, const J: usize> SubAssign for TensorRank2Vec<D, I, J> {
266    fn sub_assign(&mut self, tensor_rank_2_vec: Self) {
267        self.iter_mut()
268            .zip(tensor_rank_2_vec.iter())
269            .for_each(|(self_entry, tensor_rank_2)| *self_entry -= tensor_rank_2);
270    }
271}
272
273impl<const D: usize, const I: usize, const J: usize> SubAssign<&Self> for TensorRank2Vec<D, I, J> {
274    fn sub_assign(&mut self, tensor_rank_2_vec: &Self) {
275        self.iter_mut()
276            .zip(tensor_rank_2_vec.iter())
277            .for_each(|(self_entry, tensor_rank_2)| *self_entry -= tensor_rank_2);
278    }
279}