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    fn is_positive_definite(&self) -> bool {
233        todo!()
234    }
235}
236
237impl<const D: usize, const I: usize, const J: usize, const K: usize> Mul<TensorRank2<D, J, K>>
238    for TensorRank2Vec2D<D, I, J>
239{
240    type Output = TensorRank2Vec2D<D, I, K>;
241    fn mul(self, tensor_rank_2: TensorRank2<D, J, K>) -> Self::Output {
242        self.iter()
243            .map(|self_entry| {
244                self_entry
245                    .iter()
246                    .map(|self_tensor_rank_2| self_tensor_rank_2 * &tensor_rank_2)
247                    .collect()
248            })
249            .collect()
250    }
251}
252
253impl<const D: usize, const I: usize, const J: usize, const K: usize> Mul<&TensorRank2<D, J, K>>
254    for TensorRank2Vec2D<D, I, J>
255{
256    type Output = TensorRank2Vec2D<D, I, K>;
257    fn mul(self, tensor_rank_2: &TensorRank2<D, J, K>) -> Self::Output {
258        self.iter()
259            .map(|self_entry| {
260                self_entry
261                    .iter()
262                    .map(|self_tensor_rank_2| self_tensor_rank_2 * tensor_rank_2)
263                    .collect()
264            })
265            .collect()
266    }
267}
268
269impl<const D: usize, const I: usize, const J: usize> Add for TensorRank2Vec2D<D, I, J> {
270    type Output = Self;
271    fn add(mut self, tensor_rank_2_vec_2d: Self) -> Self::Output {
272        self += tensor_rank_2_vec_2d;
273        self
274    }
275}
276
277impl<const D: usize, const I: usize, const J: usize> Add<&Self> for TensorRank2Vec2D<D, I, J> {
278    type Output = Self;
279    fn add(mut self, tensor_rank_2_vec_2d: &Self) -> Self::Output {
280        self += tensor_rank_2_vec_2d;
281        self
282    }
283}
284
285impl<const D: usize, const I: usize, const J: usize> AddAssign for TensorRank2Vec2D<D, I, J> {
286    fn add_assign(&mut self, tensor_rank_2_vec_2d: Self) {
287        self.iter_mut()
288            .zip(tensor_rank_2_vec_2d.iter())
289            .for_each(|(self_entry, tensor_rank_2_vec)| *self_entry += tensor_rank_2_vec);
290    }
291}
292
293impl<const D: usize, const I: usize, const J: usize> AddAssign<&Self>
294    for TensorRank2Vec2D<D, I, J>
295{
296    fn add_assign(&mut self, tensor_rank_2_vec_2d: &Self) {
297        self.iter_mut()
298            .zip(tensor_rank_2_vec_2d.iter())
299            .for_each(|(self_entry, tensor_rank_2_vec)| *self_entry += tensor_rank_2_vec);
300    }
301}
302
303impl<const D: usize, const I: usize, const J: usize> Div<TensorRank0>
304    for TensorRank2Vec2D<D, I, J>
305{
306    type Output = Self;
307    fn div(mut self, tensor_rank_0: TensorRank0) -> Self::Output {
308        self /= &tensor_rank_0;
309        self
310    }
311}
312
313impl<const D: usize, const I: usize, const J: usize> Div<&TensorRank0>
314    for TensorRank2Vec2D<D, I, J>
315{
316    type Output = Self;
317    fn div(mut self, tensor_rank_0: &TensorRank0) -> Self::Output {
318        self /= tensor_rank_0;
319        self
320    }
321}
322
323impl<const D: usize, const I: usize, const J: usize> DivAssign<TensorRank0>
324    for TensorRank2Vec2D<D, I, J>
325{
326    fn div_assign(&mut self, tensor_rank_0: TensorRank0) {
327        self.iter_mut().for_each(|entry| *entry /= &tensor_rank_0);
328    }
329}
330
331impl<const D: usize, const I: usize, const J: usize> DivAssign<&TensorRank0>
332    for TensorRank2Vec2D<D, I, J>
333{
334    fn div_assign(&mut self, tensor_rank_0: &TensorRank0) {
335        self.iter_mut().for_each(|entry| *entry /= tensor_rank_0);
336    }
337}
338
339impl<const D: usize, const I: usize, const J: usize> Mul<TensorRank0>
340    for TensorRank2Vec2D<D, I, J>
341{
342    type Output = Self;
343    fn mul(mut self, tensor_rank_0: TensorRank0) -> Self::Output {
344        self *= &tensor_rank_0;
345        self
346    }
347}
348
349impl<const D: usize, const I: usize, const J: usize> Mul<&TensorRank0>
350    for TensorRank2Vec2D<D, I, J>
351{
352    type Output = Self;
353    fn mul(mut self, tensor_rank_0: &TensorRank0) -> Self::Output {
354        self *= tensor_rank_0;
355        self
356    }
357}
358
359impl<const D: usize, const I: usize, const J: usize> MulAssign<TensorRank0>
360    for TensorRank2Vec2D<D, I, J>
361{
362    fn mul_assign(&mut self, tensor_rank_0: TensorRank0) {
363        self.iter_mut().for_each(|entry| *entry *= &tensor_rank_0);
364    }
365}
366
367impl<const D: usize, const I: usize, const J: usize> MulAssign<&TensorRank0>
368    for TensorRank2Vec2D<D, I, J>
369{
370    fn mul_assign(&mut self, tensor_rank_0: &TensorRank0) {
371        self.iter_mut().for_each(|entry| *entry *= tensor_rank_0);
372    }
373}
374
375impl<const D: usize, const I: usize, const J: usize> Sub for TensorRank2Vec2D<D, I, J> {
376    type Output = Self;
377    fn sub(mut self, tensor_rank_2_vec_2d: Self) -> Self::Output {
378        self -= tensor_rank_2_vec_2d;
379        self
380    }
381}
382
383impl<const D: usize, const I: usize, const J: usize> Sub<&Self> for TensorRank2Vec2D<D, I, J> {
384    type Output = Self;
385    fn sub(mut self, tensor_rank_2_vec_2d: &Self) -> Self::Output {
386        self -= tensor_rank_2_vec_2d;
387        self
388    }
389}
390
391impl<const D: usize, const I: usize, const J: usize> SubAssign for TensorRank2Vec2D<D, I, J> {
392    fn sub_assign(&mut self, tensor_rank_2_vec_2d: Self) {
393        self.iter_mut()
394            .zip(tensor_rank_2_vec_2d.iter())
395            .for_each(|(self_entry, tensor_rank_2_vec)| *self_entry -= tensor_rank_2_vec);
396    }
397}
398
399impl<const D: usize, const I: usize, const J: usize> SubAssign<&Self>
400    for TensorRank2Vec2D<D, I, J>
401{
402    fn sub_assign(&mut self, tensor_rank_2_vec_2d: &Self) {
403        self.iter_mut()
404            .zip(tensor_rank_2_vec_2d.iter())
405            .for_each(|(self_entry, tensor_rank_2_vec)| *self_entry -= tensor_rank_2_vec);
406    }
407}