conspire/math/tensor/rank_2/vec_2d/
mod.rs1use 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
7pub 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}