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 remove(&mut self, index: usize) -> Self::Item {
131        self.0.remove(index)
132    }
133    fn swap_remove(&mut self, index: usize) -> Self::Item {
134        self.0.swap_remove(index)
135    }
136    fn zero(len: usize) -> Self {
137        (0..len).map(|_| Self::Item::zero()).collect()
138    }
139}
140
141impl<const D: usize, const I: usize, const J: usize> Tensor for TensorRank2Vec<D, I, J> {
142    type Item = TensorRank2<D, I, J>;
143    fn iter(&self) -> impl Iterator<Item = &Self::Item> {
144        self.0.iter()
145    }
146    fn iter_mut(&mut self) -> impl Iterator<Item = &mut Self::Item> {
147        self.0.iter_mut()
148    }
149}
150
151impl<const D: usize, const I: usize, const J: usize> IntoIterator for TensorRank2Vec<D, I, J> {
152    type Item = TensorRank2<D, I, J>;
153    type IntoIter = std::vec::IntoIter<Self::Item>;
154    fn into_iter(self) -> Self::IntoIter {
155        self.0.into_iter()
156    }
157}
158
159impl<const D: usize, const I: usize, const J: usize> Add for TensorRank2Vec<D, I, J> {
160    type Output = Self;
161    fn add(mut self, tensor_rank_2_vec: Self) -> Self::Output {
162        self += tensor_rank_2_vec;
163        self
164    }
165}
166
167impl<const D: usize, const I: usize, const J: usize> Add<&Self> for TensorRank2Vec<D, I, J> {
168    type Output = Self;
169    fn add(mut self, tensor_rank_2_vec: &Self) -> Self::Output {
170        self += tensor_rank_2_vec;
171        self
172    }
173}
174
175impl<const D: usize, const I: usize, const J: usize> AddAssign for TensorRank2Vec<D, I, J> {
176    fn add_assign(&mut self, tensor_rank_2_vec: Self) {
177        self.iter_mut()
178            .zip(tensor_rank_2_vec.iter())
179            .for_each(|(self_entry, tensor_rank_2)| *self_entry += tensor_rank_2);
180    }
181}
182
183impl<const D: usize, const I: usize, const J: usize> AddAssign<&Self> for TensorRank2Vec<D, I, J> {
184    fn add_assign(&mut self, tensor_rank_2_vec: &Self) {
185        self.iter_mut()
186            .zip(tensor_rank_2_vec.iter())
187            .for_each(|(self_entry, tensor_rank_2)| *self_entry += tensor_rank_2);
188    }
189}
190
191impl<const D: usize, const I: usize, const J: usize> Div<TensorRank0> for TensorRank2Vec<D, I, J> {
192    type Output = Self;
193    fn div(mut self, tensor_rank_0: TensorRank0) -> Self::Output {
194        self /= &tensor_rank_0;
195        self
196    }
197}
198
199impl<const D: usize, const I: usize, const J: usize> Div<&TensorRank0> for TensorRank2Vec<D, I, J> {
200    type Output = Self;
201    fn div(mut self, tensor_rank_0: &TensorRank0) -> Self::Output {
202        self /= tensor_rank_0;
203        self
204    }
205}
206
207impl<const D: usize, const I: usize, const J: usize> DivAssign<TensorRank0>
208    for TensorRank2Vec<D, I, J>
209{
210    fn div_assign(&mut self, tensor_rank_0: TensorRank0) {
211        self.iter_mut().for_each(|entry| *entry /= &tensor_rank_0);
212    }
213}
214
215impl<const D: usize, const I: usize, const J: usize> DivAssign<&TensorRank0>
216    for TensorRank2Vec<D, I, J>
217{
218    fn div_assign(&mut self, tensor_rank_0: &TensorRank0) {
219        self.iter_mut().for_each(|entry| *entry /= tensor_rank_0);
220    }
221}
222
223impl<const D: usize, const I: usize, const J: usize> Mul<TensorRank0> for TensorRank2Vec<D, I, J> {
224    type Output = Self;
225    fn mul(mut self, tensor_rank_0: TensorRank0) -> Self::Output {
226        self *= &tensor_rank_0;
227        self
228    }
229}
230
231impl<const D: usize, const I: usize, const J: usize> Mul<&TensorRank0> for TensorRank2Vec<D, I, J> {
232    type Output = Self;
233    fn mul(mut self, tensor_rank_0: &TensorRank0) -> Self::Output {
234        self *= tensor_rank_0;
235        self
236    }
237}
238
239impl<const D: usize, const I: usize, const J: usize> MulAssign<TensorRank0>
240    for TensorRank2Vec<D, I, J>
241{
242    fn mul_assign(&mut self, tensor_rank_0: TensorRank0) {
243        self.iter_mut().for_each(|entry| *entry *= &tensor_rank_0);
244    }
245}
246
247impl<const D: usize, const I: usize, const J: usize> MulAssign<&TensorRank0>
248    for TensorRank2Vec<D, I, J>
249{
250    fn mul_assign(&mut self, tensor_rank_0: &TensorRank0) {
251        self.iter_mut().for_each(|entry| *entry *= tensor_rank_0);
252    }
253}
254
255impl<const D: usize, const I: usize, const J: usize> Sub for TensorRank2Vec<D, I, J> {
256    type Output = Self;
257    fn sub(mut self, tensor_rank_2_vec: Self) -> Self::Output {
258        self -= tensor_rank_2_vec;
259        self
260    }
261}
262
263impl<const D: usize, const I: usize, const J: usize> Sub<&Self> for TensorRank2Vec<D, I, J> {
264    type Output = Self;
265    fn sub(mut self, tensor_rank_2_vec: &Self) -> Self::Output {
266        self -= tensor_rank_2_vec;
267        self
268    }
269}
270
271impl<const D: usize, const I: usize, const J: usize> SubAssign for TensorRank2Vec<D, I, J> {
272    fn sub_assign(&mut self, tensor_rank_2_vec: Self) {
273        self.iter_mut()
274            .zip(tensor_rank_2_vec.iter())
275            .for_each(|(self_entry, tensor_rank_2)| *self_entry -= tensor_rank_2);
276    }
277}
278
279impl<const D: usize, const I: usize, const J: usize> SubAssign<&Self> for TensorRank2Vec<D, I, J> {
280    fn sub_assign(&mut self, tensor_rank_2_vec: &Self) {
281        self.iter_mut()
282            .zip(tensor_rank_2_vec.iter())
283            .for_each(|(self_entry, tensor_rank_2)| *self_entry -= tensor_rank_2);
284    }
285}