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