Skip to main content

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

1use crate::math::{Tensor, TensorRank0, TensorRank2, TensorRank2Vec, tensor::vec::TensorVector};
2use crate::units::{Dimensionless, UnitMul};
3use std::ops::Mul;
4
5use crate::math::assert::FiniteDifference;
6
7/// A vector of vectors of rank-2 tensors.
8pub type TensorRank2Vec2D<const D: usize, I, J, U = Dimensionless> =
9    TensorVector<TensorRank2Vec<D, I, J, U>>;
10
11impl<const D: usize, I, J, U> TensorRank2Vec2D<D, I, J, U> {
12    pub fn zero(len: usize) -> Self {
13        (0..len).map(|_| TensorRank2Vec::zero(len)).collect()
14    }
15}
16
17impl<const D: usize, I, J, U> From<TensorRank2Vec2D<D, I, J, U>> for Vec<TensorRank0> {
18    fn from(tensor_rank_2_vec_2d: TensorRank2Vec2D<D, I, J, U>) -> Self {
19        tensor_rank_2_vec_2d
20            .into_iter()
21            .flat_map(|tensor_rank_2_vec_1d| {
22                tensor_rank_2_vec_1d.into_iter().flat_map(|tensor_rank_2| {
23                    tensor_rank_2.into_iter().flat_map(|tensor_rank_1| {
24                        tensor_rank_1.into_iter().map(|entry| entry.value())
25                    })
26                })
27            })
28            .collect()
29    }
30}
31
32impl<const D: usize, I, J, K, U, V> Mul<TensorRank2<D, J, K, V>> for TensorRank2Vec2D<D, I, J, U>
33where
34    U: UnitMul<V>,
35{
36    type Output = TensorRank2Vec2D<D, I, K, <U as UnitMul<V>>::Output>;
37    fn mul(self, tensor_rank_2: TensorRank2<D, J, K, V>) -> Self::Output {
38        self.iter()
39            .map(|self_entry| {
40                self_entry
41                    .iter()
42                    .map(|self_tensor_rank_2| self_tensor_rank_2 * &tensor_rank_2)
43                    .collect()
44            })
45            .collect()
46    }
47}
48
49impl<const D: usize, I, J, K, U, V> Mul<&TensorRank2<D, J, K, V>> for TensorRank2Vec2D<D, I, J, U>
50where
51    U: UnitMul<V>,
52{
53    type Output = TensorRank2Vec2D<D, I, K, <U as UnitMul<V>>::Output>;
54    fn mul(self, tensor_rank_2: &TensorRank2<D, J, K, V>) -> Self::Output {
55        self.iter()
56            .map(|self_entry| {
57                self_entry
58                    .iter()
59                    .map(|self_tensor_rank_2| self_tensor_rank_2 * tensor_rank_2)
60                    .collect()
61            })
62            .collect()
63    }
64}
65
66impl<const D: usize, I, J, U> FiniteDifference for TensorRank2Vec2D<D, I, J, U> {
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.differs(comparator_ab_ij, epsilon)
85                                    })
86                                    .count()
87                            })
88                            .sum::<usize>()
89                    })
90                    .sum::<usize>()
91            })
92            .sum();
93        if error_count > 0 {
94            let auxiliary = self
95                .iter()
96                .zip(comparator.iter())
97                .map(|(self_a, comparator_a)| {
98                    self_a
99                        .iter()
100                        .zip(comparator_a.iter())
101                        .map(|(self_ab, comparator_ab)| {
102                            self_ab
103                                .iter()
104                                .zip(comparator_ab.iter())
105                                .map(|(self_ab_i, comparator_ab_i)| {
106                                    self_ab_i
107                                        .iter()
108                                        .zip(comparator_ab_i.iter())
109                                        .filter(|&(&self_ab_ij, &comparator_ab_ij)| {
110                                            self_ab_ij.differs_severely(comparator_ab_ij, epsilon)
111                                        })
112                                        .count()
113                                })
114                                .sum::<usize>()
115                        })
116                        .sum::<usize>()
117                })
118                .sum::<usize>()
119                > 0;
120            Some((auxiliary, error_count))
121        } else {
122            None
123        }
124    }
125}