1#[cfg(test)]
2mod test;
3
4#[cfg(test)]
5use super::super::test::ErrorTensor;
6
7use std::{
8 array::from_fn,
9 fmt::{Display, Formatter, Result},
10 ops::{Add, AddAssign, Div, DivAssign, Index, IndexMut, Mul, MulAssign, Sub, SubAssign},
11};
12
13use super::{Tensor, TensorArray, TensorRank0, TensorRank2};
14
15#[derive(Clone, Debug)]
19pub struct TensorRank2List<const D: usize, const I: usize, const J: usize, const W: usize>(
20 [TensorRank2<D, I, J>; W],
21);
22
23pub const fn tensor_rank_2_list<const D: usize, const I: usize, const J: usize, const W: usize>(
24 array: [TensorRank2<D, I, J>; W],
25) -> TensorRank2List<D, I, J, W> {
26 TensorRank2List(array)
27}
28
29impl<const D: usize, const I: usize, const J: usize, const W: usize> Display
30 for TensorRank2List<D, I, J, W>
31{
32 fn fmt(&self, _f: &mut Formatter) -> Result {
33 Ok(())
34 }
35}
36
37#[cfg(test)]
38impl<const D: usize, const I: usize, const J: usize, const W: usize> ErrorTensor
39 for TensorRank2List<D, I, J, W>
40{
41 fn error(
42 &self,
43 comparator: &Self,
44 tol_abs: &TensorRank0,
45 tol_rel: &TensorRank0,
46 ) -> Option<usize> {
47 let error_count = self
48 .iter()
49 .zip(comparator.iter())
50 .map(|(self_a, comparator_a)| {
51 self_a
52 .iter()
53 .zip(comparator_a.iter())
54 .map(|(self_a_i, comparator_a_i)| {
55 self_a_i
56 .iter()
57 .zip(comparator_a_i.iter())
58 .filter(|&(&self_a_ij, &comparator_a_ij)| {
59 &(self_a_ij - comparator_a_ij).abs() >= tol_abs
60 && &(self_a_ij / comparator_a_ij - 1.0).abs() >= tol_rel
61 })
62 .count()
63 })
64 .sum::<usize>()
65 })
66 .sum();
67 if error_count > 0 {
68 Some(error_count)
69 } else {
70 None
71 }
72 }
73 fn error_fd(&self, comparator: &Self, epsilon: &TensorRank0) -> Option<(bool, usize)> {
74 let error_count = self
75 .iter()
76 .zip(comparator.iter())
77 .map(|(self_a, comparator_a)| {
78 self_a
79 .iter()
80 .zip(comparator_a.iter())
81 .map(|(self_a_i, comparator_a_i)| {
82 self_a_i
83 .iter()
84 .zip(comparator_a_i.iter())
85 .filter(|&(&self_a_ij, &comparator_a_ij)| {
86 &(self_a_ij / comparator_a_ij - 1.0).abs() >= epsilon
87 && (&self_a_ij.abs() >= epsilon
88 || &comparator_a_ij.abs() >= epsilon)
89 })
90 .count()
91 })
92 .sum::<usize>()
93 })
94 .sum();
95 if error_count > 0 {
96 Some((true, error_count))
97 } else {
98 None
99 }
100 }
101}
102
103impl<const D: usize, const I: usize, const J: usize, const W: usize> Tensor
104 for TensorRank2List<D, I, J, W>
105{
106 type Item = TensorRank2<D, I, J>;
107 fn iter(&self) -> impl Iterator<Item = &Self::Item> {
108 self.0.iter()
109 }
110 fn iter_mut(&mut self) -> impl Iterator<Item = &mut Self::Item> {
111 self.0.iter_mut()
112 }
113}
114
115impl<const D: usize, const I: usize, const J: usize, const W: usize> TensorArray
116 for TensorRank2List<D, I, J, W>
117{
118 type Array = [[[TensorRank0; D]; D]; W];
119 type Item = TensorRank2<D, I, J>;
120 fn as_array(&self) -> Self::Array {
121 let mut array = [[[0.0; D]; D]; W];
122 array
123 .iter_mut()
124 .zip(self.iter())
125 .for_each(|(entry_rank_2, tensor_rank_2)| *entry_rank_2 = tensor_rank_2.as_array());
126 array
127 }
128 fn identity() -> Self {
129 Self(from_fn(|_| Self::Item::identity()))
130 }
131 fn new(array: Self::Array) -> Self {
132 array.into_iter().map(TensorRank2::new).collect()
133 }
134 fn zero() -> Self {
135 Self(from_fn(|_| TensorRank2::zero()))
136 }
137}
138
139impl<const D: usize, const I: usize, const J: usize, const W: usize>
140 FromIterator<TensorRank2<D, I, J>> for TensorRank2List<D, I, J, W>
141{
142 fn from_iter<Ii: IntoIterator<Item = TensorRank2<D, I, J>>>(into_iterator: Ii) -> Self {
143 let mut tensor_rank_2_list = Self::zero();
144 tensor_rank_2_list
145 .iter_mut()
146 .zip(into_iterator)
147 .for_each(|(tensor_rank_2_list_entry, entry)| *tensor_rank_2_list_entry = entry);
148 tensor_rank_2_list
149 }
150}
151
152impl<const D: usize, const I: usize, const J: usize, const W: usize> Index<usize>
153 for TensorRank2List<D, I, J, W>
154{
155 type Output = TensorRank2<D, I, J>;
156 fn index(&self, index: usize) -> &Self::Output {
157 &self.0[index]
158 }
159}
160
161impl<const D: usize, const I: usize, const J: usize, const W: usize> IndexMut<usize>
162 for TensorRank2List<D, I, J, W>
163{
164 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
165 &mut self.0[index]
166 }
167}
168
169impl<const D: usize, const I: usize, const J: usize, const W: usize> Add
170 for TensorRank2List<D, I, J, W>
171{
172 type Output = Self;
173 fn add(mut self, tensor_rank_2_list: Self) -> Self::Output {
174 self += tensor_rank_2_list;
175 self
176 }
177}
178
179impl<const D: usize, const I: usize, const J: usize, const W: usize> Add<&Self>
180 for TensorRank2List<D, I, J, W>
181{
182 type Output = Self;
183 fn add(mut self, tensor_rank_2_list: &Self) -> Self::Output {
184 self += tensor_rank_2_list;
185 self
186 }
187}
188
189impl<const D: usize, const I: usize, const J: usize, const W: usize> AddAssign
190 for TensorRank2List<D, I, J, W>
191{
192 fn add_assign(&mut self, tensor_rank_2_list: Self) {
193 self.iter_mut()
194 .zip(tensor_rank_2_list.iter())
195 .for_each(|(self_entry, tensor_rank_2)| *self_entry += tensor_rank_2);
196 }
197}
198
199impl<const D: usize, const I: usize, const J: usize, const W: usize> AddAssign<&Self>
200 for TensorRank2List<D, I, J, W>
201{
202 fn add_assign(&mut self, tensor_rank_2_list: &Self) {
203 self.iter_mut()
204 .zip(tensor_rank_2_list.iter())
205 .for_each(|(self_entry, tensor_rank_2)| *self_entry += tensor_rank_2);
206 }
207}
208
209impl<const D: usize, const I: usize, const J: usize, const W: usize> Div<TensorRank0>
210 for TensorRank2List<D, I, J, W>
211{
212 type Output = Self;
213 fn div(mut self, tensor_rank_0: TensorRank0) -> Self::Output {
214 self /= &tensor_rank_0;
215 self
216 }
217}
218
219impl<const D: usize, const I: usize, const J: usize, const W: usize> Div<&TensorRank0>
220 for TensorRank2List<D, I, J, W>
221{
222 type Output = Self;
223 fn div(mut self, tensor_rank_0: &TensorRank0) -> Self::Output {
224 self /= tensor_rank_0;
225 self
226 }
227}
228
229impl<const D: usize, const I: usize, const J: usize, const W: usize> DivAssign<TensorRank0>
230 for TensorRank2List<D, I, J, W>
231{
232 fn div_assign(&mut self, tensor_rank_0: TensorRank0) {
233 self.iter_mut().for_each(|entry| *entry /= &tensor_rank_0);
234 }
235}
236
237impl<const D: usize, const I: usize, const J: usize, const W: usize> DivAssign<&TensorRank0>
238 for TensorRank2List<D, I, J, W>
239{
240 fn div_assign(&mut self, tensor_rank_0: &TensorRank0) {
241 self.iter_mut().for_each(|entry| *entry /= tensor_rank_0);
242 }
243}
244
245impl<const D: usize, const I: usize, const J: usize, const W: usize> Mul<TensorRank0>
246 for TensorRank2List<D, I, J, W>
247{
248 type Output = Self;
249 fn mul(mut self, tensor_rank_0: TensorRank0) -> Self::Output {
250 self *= &tensor_rank_0;
251 self
252 }
253}
254
255impl<const D: usize, const I: usize, const J: usize, const W: usize> Mul<&TensorRank0>
256 for TensorRank2List<D, I, J, W>
257{
258 type Output = Self;
259 fn mul(mut self, tensor_rank_0: &TensorRank0) -> Self::Output {
260 self *= tensor_rank_0;
261 self
262 }
263}
264
265impl<const D: usize, const I: usize, const J: usize, const W: usize> MulAssign<TensorRank0>
266 for TensorRank2List<D, I, J, W>
267{
268 fn mul_assign(&mut self, tensor_rank_0: TensorRank0) {
269 self.iter_mut().for_each(|entry| *entry *= &tensor_rank_0);
270 }
271}
272
273impl<const D: usize, const I: usize, const J: usize, const W: usize> MulAssign<&TensorRank0>
274 for TensorRank2List<D, I, J, W>
275{
276 fn mul_assign(&mut self, tensor_rank_0: &TensorRank0) {
277 self.iter_mut().for_each(|entry| *entry *= tensor_rank_0);
278 }
279}
280
281impl<const D: usize, const I: usize, const J: usize, const W: usize> Sub
282 for TensorRank2List<D, I, J, W>
283{
284 type Output = Self;
285 fn sub(mut self, tensor_rank_2_list: Self) -> Self::Output {
286 self -= tensor_rank_2_list;
287 self
288 }
289}
290
291impl<const D: usize, const I: usize, const J: usize, const W: usize> Sub<&Self>
292 for TensorRank2List<D, I, J, W>
293{
294 type Output = Self;
295 fn sub(mut self, tensor_rank_2_list: &Self) -> Self::Output {
296 self -= tensor_rank_2_list;
297 self
298 }
299}
300
301impl<const D: usize, const I: usize, const J: usize, const W: usize> SubAssign
302 for TensorRank2List<D, I, J, W>
303{
304 fn sub_assign(&mut self, tensor_rank_2_list: Self) {
305 self.iter_mut()
306 .zip(tensor_rank_2_list.iter())
307 .for_each(|(self_entry, tensor_rank_2)| *self_entry -= tensor_rank_2);
308 }
309}
310
311impl<const D: usize, const I: usize, const J: usize, const W: usize> SubAssign<&Self>
312 for TensorRank2List<D, I, J, W>
313{
314 fn sub_assign(&mut self, tensor_rank_2_list: &Self) {
315 self.iter_mut()
316 .zip(tensor_rank_2_list.iter())
317 .for_each(|(self_entry, tensor_rank_2)| *self_entry -= tensor_rank_2);
318 }
319}