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 std::ops::Mul;
6
7use crate::math::assert::FiniteDifference;
8
9pub type TensorRank2List2D<
11 const D: usize,
12 const I: usize,
13 const J: usize,
14 const M: usize,
15 const N: usize,
16> = TensorList<TensorRank2List<D, I, J, M>, N>;
17
18impl<const D: usize, const I: usize, const J: usize, const M: usize, const N: usize>
19 From<[[[[TensorRank0; D]; D]; M]; N]> for TensorRank2List2D<D, I, J, M, N>
20{
21 fn from(array: [[[[TensorRank0; D]; D]; M]; N]) -> Self {
22 array.into_iter().map(|entry| entry.into()).collect()
23 }
24}
25
26impl<const D: usize, const I: usize, const J: usize, const K: usize, const W: usize, const X: usize>
27 Mul<TensorRank2<D, J, K>> for TensorRank2List2D<D, I, J, W, X>
28{
29 type Output = TensorRank2List2D<D, I, K, W, X>;
30 fn mul(self, tensor_rank_2: TensorRank2<D, J, K>) -> Self::Output {
31 self.iter()
32 .map(|self_entry| {
33 self_entry
34 .iter()
35 .map(|self_tensor_rank_2| self_tensor_rank_2 * &tensor_rank_2)
36 .collect()
37 })
38 .collect()
39 }
40}
41
42impl<const D: usize, const I: usize, const J: usize, const K: usize, const W: usize, const X: usize>
43 Mul<&TensorRank2<D, J, K>> for TensorRank2List2D<D, I, J, W, X>
44{
45 type Output = TensorRank2List2D<D, I, K, W, X>;
46 fn mul(self, tensor_rank_2: &TensorRank2<D, J, K>) -> Self::Output {
47 self.iter()
48 .map(|self_entry| {
49 self_entry
50 .iter()
51 .map(|self_tensor_rank_2| self_tensor_rank_2 * tensor_rank_2)
52 .collect()
53 })
54 .collect()
55 }
56}
57
58impl<const D: usize, const I: usize, const J: usize, const W: usize, const X: usize>
59 FiniteDifference for TensorRank2List2D<D, I, J, W, X>
60{
61 fn error_fd(&self, comparator: &Self, epsilon: TensorRank0) -> Option<(bool, usize)> {
62 let error_count = self
63 .iter()
64 .zip(comparator.iter())
65 .map(|(self_a, comparator_a)| {
66 self_a
67 .iter()
68 .zip(comparator_a.iter())
69 .map(|(self_ab, comparator_ab)| {
70 self_ab
71 .iter()
72 .zip(comparator_ab.iter())
73 .map(|(self_ab_i, comparator_ab_i)| {
74 self_ab_i
75 .iter()
76 .zip(comparator_ab_i.iter())
77 .filter(|&(&self_ab_ij, &comparator_ab_ij)| {
78 ((self_ab_ij / comparator_ab_ij - 1.0).abs() >= epsilon
79 && (self_ab_ij.abs() >= epsilon
80 || comparator_ab_ij.abs() >= epsilon))
81 || self_ab_ij.is_nan()
82 || comparator_ab_ij.is_nan()
83 })
84 .count()
85 })
86 .sum::<usize>()
87 })
88 .sum::<usize>()
89 })
90 .sum();
91 if error_count > 0 {
92 let auxiliary = self
93 .iter()
94 .zip(comparator.iter())
95 .map(|(self_a, comparator_a)| {
96 self_a
97 .iter()
98 .zip(comparator_a.iter())
99 .map(|(self_ab, comparator_ab)| {
100 self_ab
101 .iter()
102 .zip(comparator_ab.iter())
103 .map(|(self_ab_i, comparator_ab_i)| {
104 self_ab_i
105 .iter()
106 .zip(comparator_ab_i.iter())
107 .filter(|&(&self_ab_ij, &comparator_ab_ij)| {
108 ((self_ab_ij / comparator_ab_ij - 1.0).abs() >= epsilon
109 && (self_ab_ij - comparator_ab_ij).abs() >= epsilon
110 && (self_ab_ij.abs() >= epsilon
111 || comparator_ab_ij.abs() >= epsilon))
112 || self_ab_ij.is_nan()
113 || comparator_ab_ij.is_nan()
114 })
115 .count()
116 })
117 .sum::<usize>()
118 })
119 .sum::<usize>()
120 })
121 .sum::<usize>()
122 > 0;
123 Some((auxiliary, error_count))
124 } else {
125 None
126 }
127 }
128}