Skip to main content

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

1#[cfg(test)]
2mod test;
3
4use crate::math::{Tensor, TensorRank0, TensorRank2, TensorRank2List, tensor::list::TensorList};
5use crate::units::{Dimensionless, UnitMul};
6use std::ops::Mul;
7
8use crate::math::assert::FiniteDifference;
9
10/// A list of lists of rank-2 tensors.
11pub type TensorRank2List2D<
12    const D: usize,
13    I,
14    J,
15    const M: usize,
16    const N: usize,
17    U = Dimensionless,
18> = TensorList<TensorRank2List<D, I, J, M, U>, N>;
19
20impl<const D: usize, I, J, const M: usize, const N: usize, U> From<[[[[TensorRank0; D]; D]; M]; N]>
21    for TensorRank2List2D<D, I, J, M, N, U>
22{
23    fn from(array: [[[[TensorRank0; D]; D]; M]; N]) -> Self {
24        array.into_iter().map(|entry| entry.into()).collect()
25    }
26}
27
28impl<const D: usize, I, J, K, const W: usize, const X: usize, U, V> Mul<TensorRank2<D, J, K, V>>
29    for TensorRank2List2D<D, I, J, W, X, U>
30where
31    U: UnitMul<V>,
32{
33    type Output = TensorRank2List2D<D, I, K, W, X, <U as UnitMul<V>>::Output>;
34    fn mul(self, tensor_rank_2: TensorRank2<D, J, K, V>) -> Self::Output {
35        self.iter()
36            .map(|self_entry| {
37                self_entry
38                    .iter()
39                    .map(|self_tensor_rank_2| self_tensor_rank_2 * &tensor_rank_2)
40                    .collect()
41            })
42            .collect()
43    }
44}
45
46impl<const D: usize, I, J, K, const W: usize, const X: usize, U, V> Mul<&TensorRank2<D, J, K, V>>
47    for TensorRank2List2D<D, I, J, W, X, U>
48where
49    U: UnitMul<V>,
50{
51    type Output = TensorRank2List2D<D, I, K, W, X, <U as UnitMul<V>>::Output>;
52    fn mul(self, tensor_rank_2: &TensorRank2<D, J, K, V>) -> Self::Output {
53        self.iter()
54            .map(|self_entry| {
55                self_entry
56                    .iter()
57                    .map(|self_tensor_rank_2| self_tensor_rank_2 * tensor_rank_2)
58                    .collect()
59            })
60            .collect()
61    }
62}
63
64impl<const D: usize, I, J, const W: usize, const X: usize, U> FiniteDifference
65    for TensorRank2List2D<D, I, J, W, X, U>
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.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}