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::{self, Display, Formatter},
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> Default for TensorRank2Vec<D, I, J> {
19    fn default() -> Self {
20        Self::zero(0)
21    }
22}
23
24impl<const D: usize, const I: usize, const J: usize> Display for TensorRank2Vec<D, I, J> {
25    fn fmt(&self, _f: &mut Formatter) -> fmt::Result {
26        Ok(())
27    }
28}
29
30#[cfg(test)]
31impl<const D: usize, const I: usize, const J: usize> ErrorTensor for TensorRank2Vec<D, I, J> {
32    fn error_fd(&self, comparator: &Self, epsilon: &TensorRank0) -> Option<(bool, usize)> {
33        let error_count = self
34            .iter()
35            .zip(comparator.iter())
36            .map(|(self_a, comparator_a)| {
37                self_a
38                    .iter()
39                    .zip(comparator_a.iter())
40                    .map(|(self_a_i, comparator_a_i)| {
41                        self_a_i
42                            .iter()
43                            .zip(comparator_a_i.iter())
44                            .filter(|&(&self_a_ij, &comparator_a_ij)| {
45                                &(self_a_ij / comparator_a_ij - 1.0).abs() >= epsilon
46                                    && (&self_a_ij.abs() >= epsilon
47                                        || &comparator_a_ij.abs() >= epsilon)
48                            })
49                            .count()
50                    })
51                    .sum::<usize>()
52            })
53            .sum();
54        if error_count > 0 {
55            Some((true, error_count))
56        } else {
57            None
58        }
59    }
60}
61
62impl<const D: usize, const I: usize, const J: usize> FromIterator<TensorRank2<D, I, J>>
63    for TensorRank2Vec<D, I, J>
64{
65    fn from_iter<Ii: IntoIterator<Item = TensorRank2<D, I, J>>>(into_iterator: Ii) -> Self {
66        Self(Vec::from_iter(into_iterator))
67    }
68}
69
70impl<const D: usize, const I: usize, const J: usize> Index<usize> for TensorRank2Vec<D, I, J> {
71    type Output = TensorRank2<D, I, J>;
72    fn index(&self, index: usize) -> &Self::Output {
73        &self.0[index]
74    }
75}
76
77impl<const D: usize, const I: usize, const J: usize> IndexMut<usize> for TensorRank2Vec<D, I, J> {
78    fn index_mut(&mut self, index: usize) -> &mut Self::Output {
79        &mut self.0[index]
80    }
81}
82
83impl<const D: usize, const I: usize, const J: usize> TensorVec for TensorRank2Vec<D, I, J> {
84    type Item = TensorRank2<D, I, J>;
85    type Slice<'a> = &'a [[[TensorRank0; D]; D]];
86    fn append(&mut self, other: &mut Self) {
87        self.0.append(&mut other.0)
88    }
89    fn capacity(&self) -> usize {
90        self.0.capacity()
91    }
92    fn is_empty(&self) -> bool {
93        self.0.is_empty()
94    }
95    fn len(&self) -> usize {
96        self.0.len()
97    }
98    fn new(slice: Self::Slice<'_>) -> Self {
99        slice
100            .iter()
101            .map(|slice_entry| Self::Item::new(*slice_entry))
102            .collect()
103    }
104    fn push(&mut self, item: Self::Item) {
105        self.0.push(item)
106    }
107    fn remove(&mut self, index: usize) -> Self::Item {
108        self.0.remove(index)
109    }
110    fn retain<F>(&mut self, f: F)
111    where
112        F: FnMut(&Self::Item) -> bool,
113    {
114        self.0.retain(f)
115    }
116    fn swap_remove(&mut self, index: usize) -> Self::Item {
117        self.0.swap_remove(index)
118    }
119    fn zero(len: usize) -> Self {
120        (0..len).map(|_| Self::Item::zero()).collect()
121    }
122}
123
124impl<const D: usize, const I: usize, const J: usize> Tensor for TensorRank2Vec<D, I, J> {
125    type Item = TensorRank2<D, I, J>;
126    fn iter(&self) -> impl Iterator<Item = &Self::Item> {
127        self.0.iter()
128    }
129    fn iter_mut(&mut self) -> impl Iterator<Item = &mut Self::Item> {
130        self.0.iter_mut()
131    }
132}
133
134impl<const D: usize, const I: usize, const J: usize> IntoIterator for TensorRank2Vec<D, I, J> {
135    type Item = TensorRank2<D, I, J>;
136    type IntoIter = std::vec::IntoIter<Self::Item>;
137    fn into_iter(self) -> Self::IntoIter {
138        self.0.into_iter()
139    }
140}
141
142impl<const D: usize, const I: usize, const J: usize> Add for TensorRank2Vec<D, I, J> {
143    type Output = Self;
144    fn add(mut self, tensor_rank_2_vec: Self) -> Self::Output {
145        self += tensor_rank_2_vec;
146        self
147    }
148}
149
150impl<const D: usize, const I: usize, const J: usize> Add<&Self> for TensorRank2Vec<D, I, J> {
151    type Output = Self;
152    fn add(mut self, tensor_rank_2_vec: &Self) -> Self::Output {
153        self += tensor_rank_2_vec;
154        self
155    }
156}
157
158impl<const D: usize, const I: usize, const J: usize> AddAssign for TensorRank2Vec<D, I, J> {
159    fn add_assign(&mut self, tensor_rank_2_vec: Self) {
160        self.iter_mut()
161            .zip(tensor_rank_2_vec.iter())
162            .for_each(|(self_entry, tensor_rank_2)| *self_entry += tensor_rank_2);
163    }
164}
165
166impl<const D: usize, const I: usize, const J: usize> AddAssign<&Self> for TensorRank2Vec<D, I, J> {
167    fn add_assign(&mut self, tensor_rank_2_vec: &Self) {
168        self.iter_mut()
169            .zip(tensor_rank_2_vec.iter())
170            .for_each(|(self_entry, tensor_rank_2)| *self_entry += tensor_rank_2);
171    }
172}
173
174impl<const D: usize, const I: usize, const J: usize> Div<TensorRank0> for TensorRank2Vec<D, I, J> {
175    type Output = Self;
176    fn div(mut self, tensor_rank_0: TensorRank0) -> Self::Output {
177        self /= &tensor_rank_0;
178        self
179    }
180}
181
182impl<const D: usize, const I: usize, const J: usize> Div<&TensorRank0> for TensorRank2Vec<D, I, J> {
183    type Output = Self;
184    fn div(mut self, tensor_rank_0: &TensorRank0) -> Self::Output {
185        self /= tensor_rank_0;
186        self
187    }
188}
189
190impl<const D: usize, const I: usize, const J: usize> DivAssign<TensorRank0>
191    for TensorRank2Vec<D, I, J>
192{
193    fn div_assign(&mut self, tensor_rank_0: TensorRank0) {
194        self.iter_mut().for_each(|entry| *entry /= &tensor_rank_0);
195    }
196}
197
198impl<const D: usize, const I: usize, const J: usize> DivAssign<&TensorRank0>
199    for TensorRank2Vec<D, I, J>
200{
201    fn div_assign(&mut self, tensor_rank_0: &TensorRank0) {
202        self.iter_mut().for_each(|entry| *entry /= tensor_rank_0);
203    }
204}
205
206impl<const D: usize, const I: usize, const J: usize> Mul<TensorRank0> for TensorRank2Vec<D, I, J> {
207    type Output = Self;
208    fn mul(mut self, tensor_rank_0: TensorRank0) -> Self::Output {
209        self *= &tensor_rank_0;
210        self
211    }
212}
213
214impl<const D: usize, const I: usize, const J: usize> Mul<&TensorRank0> for TensorRank2Vec<D, I, J> {
215    type Output = Self;
216    fn mul(mut self, tensor_rank_0: &TensorRank0) -> Self::Output {
217        self *= tensor_rank_0;
218        self
219    }
220}
221
222impl<const D: usize, const I: usize, const J: usize> MulAssign<TensorRank0>
223    for TensorRank2Vec<D, I, J>
224{
225    fn mul_assign(&mut self, tensor_rank_0: TensorRank0) {
226        self.iter_mut().for_each(|entry| *entry *= &tensor_rank_0);
227    }
228}
229
230impl<const D: usize, const I: usize, const J: usize> MulAssign<&TensorRank0>
231    for TensorRank2Vec<D, I, J>
232{
233    fn mul_assign(&mut self, tensor_rank_0: &TensorRank0) {
234        self.iter_mut().for_each(|entry| *entry *= tensor_rank_0);
235    }
236}
237
238impl<const D: usize, const I: usize, const J: usize> Sub for TensorRank2Vec<D, I, J> {
239    type Output = Self;
240    fn sub(mut self, tensor_rank_2_vec: Self) -> Self::Output {
241        self -= tensor_rank_2_vec;
242        self
243    }
244}
245
246impl<const D: usize, const I: usize, const J: usize> Sub<&Self> for TensorRank2Vec<D, I, J> {
247    type Output = Self;
248    fn sub(mut self, tensor_rank_2_vec: &Self) -> Self::Output {
249        self -= tensor_rank_2_vec;
250        self
251    }
252}
253
254impl<const D: usize, const I: usize, const J: usize> Sub for &TensorRank2Vec<D, I, J> {
255    type Output = TensorRank2Vec<D, I, J>;
256    fn sub(self, tensor_rank_2_vec: Self) -> Self::Output {
257        tensor_rank_2_vec
258            .iter()
259            .zip(self.iter())
260            .map(|(tensor_rank_2_vec_a, self_a)| self_a - tensor_rank_2_vec_a)
261            .collect()
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}