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

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