conspire/math/tensor/rank_2/list_2d/
mod.rs1#[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
10pub 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}