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::{
14 super::{Tensor, TensorArray},
15 TensorRank0, TensorRank2,
16 list::TensorRank2List,
17};
18
19#[derive(Clone, Debug)]
23pub struct TensorRank2List2D<
24 const D: usize,
25 const I: usize,
26 const J: usize,
27 const W: usize,
28 const X: usize,
29>([TensorRank2List<D, I, J, W>; X]);
30
31impl<const D: usize, const I: usize, const J: usize, const W: usize, const X: usize> Display
32 for TensorRank2List2D<D, I, J, W, X>
33{
34 fn fmt(&self, f: &mut Formatter) -> Result {
35 write!(f, "[")?;
36 self.iter()
37 .enumerate()
38 .try_for_each(|(i, entry)| write!(f, "{entry},\n\x1B[u\x1B[{}B\x1B[2D", i + 1))?;
39 write!(f, "\x1B[u\x1B[1A\x1B[{}C]", 16 * D + 2)
40 }
41}
42
43#[cfg(test)]
44impl<const D: usize, const I: usize, const J: usize, const W: usize, const X: usize> ErrorTensor
45 for TensorRank2List2D<D, I, J, W, X>
46{
47 fn error_fd(&self, comparator: &Self, epsilon: &TensorRank0) -> Option<(bool, usize)> {
48 let error_count = self
49 .iter()
50 .zip(comparator.iter())
51 .map(|(self_a, comparator_a)| {
52 self_a
53 .iter()
54 .zip(comparator_a.iter())
55 .map(|(self_ab, comparator_ab)| {
56 self_ab
57 .iter()
58 .zip(comparator_ab.iter())
59 .map(|(self_ab_i, comparator_ab_i)| {
60 self_ab_i
61 .iter()
62 .zip(comparator_ab_i.iter())
63 .filter(|&(&self_ab_ij, &comparator_ab_ij)| {
64 &(self_ab_ij / comparator_ab_ij - 1.0).abs() >= epsilon
65 && (&self_ab_ij.abs() >= epsilon
66 || &comparator_ab_ij.abs() >= epsilon)
67 })
68 .count()
69 })
70 .sum::<usize>()
71 })
72 .sum::<usize>()
73 })
74 .sum();
75 if error_count > 0 {
76 let auxiliary = self
77 .iter()
78 .zip(comparator.iter())
79 .map(|(self_a, comparator_a)| {
80 self_a
81 .iter()
82 .zip(comparator_a.iter())
83 .map(|(self_ab, comparator_ab)| {
84 self_ab
85 .iter()
86 .zip(comparator_ab.iter())
87 .map(|(self_ab_i, comparator_ab_i)| {
88 self_ab_i
89 .iter()
90 .zip(comparator_ab_i.iter())
91 .filter(|&(&self_ab_ij, &comparator_ab_ij)| {
92 &(self_ab_ij / comparator_ab_ij - 1.0).abs() >= epsilon
93 && &(self_ab_ij - comparator_ab_ij).abs() >= epsilon
94 && (&self_ab_ij.abs() >= epsilon
95 || &comparator_ab_ij.abs() >= epsilon)
96 })
97 .count()
98 })
99 .sum::<usize>()
100 })
101 .sum::<usize>()
102 })
103 .sum::<usize>()
104 > 0;
105 Some((auxiliary, error_count))
106 } else {
107 None
108 }
109 }
110}
111
112impl<const D: usize, const I: usize, const J: usize, const W: usize, const X: usize> Tensor
113 for TensorRank2List2D<D, I, J, W, X>
114{
115 type Item = TensorRank2List<D, I, J, W>;
116 fn iter(&self) -> impl Iterator<Item = &Self::Item> {
117 self.0.iter()
118 }
119 fn iter_mut(&mut self) -> impl Iterator<Item = &mut Self::Item> {
120 self.0.iter_mut()
121 }
122}
123
124impl<const D: usize, const I: usize, const J: usize, const W: usize, const X: usize> TensorArray
125 for TensorRank2List2D<D, I, J, W, X>
126{
127 type Array = [[[[TensorRank0; D]; D]; W]; X];
128 type Item = TensorRank2List<D, I, J, W>;
129 fn as_array(&self) -> Self::Array {
130 let mut array = [[[[0.0; D]; D]; W]; X];
131 array
132 .iter_mut()
133 .zip(self.iter())
134 .for_each(|(entry_rank_2_list, tensor_rank_2_list)| {
135 *entry_rank_2_list = tensor_rank_2_list.as_array()
136 });
137 array
138 }
139 fn identity() -> Self {
140 Self(from_fn(|_| Self::Item::identity()))
141 }
142 fn new(array: Self::Array) -> Self {
143 array.into_iter().map(Self::Item::new).collect()
144 }
145 fn zero() -> Self {
146 Self(from_fn(|_| Self::Item::zero()))
147 }
148}
149
150impl<const D: usize, const I: usize, const J: usize, const W: usize, const X: usize>
151 FromIterator<TensorRank2List<D, I, J, W>> for TensorRank2List2D<D, I, J, W, X>
152{
153 fn from_iter<Ii: IntoIterator<Item = TensorRank2List<D, I, J, W>>>(into_iterator: Ii) -> Self {
154 let mut tensor_rank_2_list_2d = Self::zero();
155 tensor_rank_2_list_2d
156 .iter_mut()
157 .zip(into_iterator)
158 .for_each(|(tensor_rank_2_list, entry)| *tensor_rank_2_list = entry);
159 tensor_rank_2_list_2d
160 }
161}
162
163impl<const D: usize, const I: usize, const J: usize, const W: usize, const X: usize> Index<usize>
164 for TensorRank2List2D<D, I, J, W, X>
165{
166 type Output = TensorRank2List<D, I, J, W>;
167 fn index(&self, index: usize) -> &Self::Output {
168 &self.0[index]
169 }
170}
171
172impl<const D: usize, const I: usize, const J: usize, const W: usize, const X: usize> IndexMut<usize>
173 for TensorRank2List2D<D, I, J, W, X>
174{
175 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
176 &mut self.0[index]
177 }
178}
179
180impl<const D: usize, const I: usize, const J: usize, const W: usize, const X: usize> std::iter::Sum
181 for TensorRank2List2D<D, I, J, W, X>
182{
183 fn sum<Ii>(iter: Ii) -> Self
184 where
185 Ii: Iterator<Item = Self>,
186 {
187 let mut output = TensorRank2List2D::zero();
188 iter.for_each(|item| output += item);
189 output
190 }
191}
192
193impl<const D: usize, const I: usize, const J: usize, const K: usize, const W: usize, const X: usize>
194 Mul<TensorRank2<D, J, K>> for TensorRank2List2D<D, I, J, W, X>
195{
196 type Output = TensorRank2List2D<D, I, K, W, X>;
197 fn mul(self, tensor_rank_2: TensorRank2<D, J, K>) -> Self::Output {
198 self.iter()
199 .map(|self_entry| {
200 self_entry
201 .iter()
202 .map(|self_tensor_rank_2| self_tensor_rank_2 * &tensor_rank_2)
203 .collect()
204 })
205 .collect()
206 }
207}
208
209impl<const D: usize, const I: usize, const J: usize, const K: usize, const W: usize, const X: usize>
210 Mul<&TensorRank2<D, J, K>> for TensorRank2List2D<D, I, J, W, X>
211{
212 type Output = TensorRank2List2D<D, I, K, W, X>;
213 fn mul(self, tensor_rank_2: &TensorRank2<D, J, K>) -> Self::Output {
214 self.iter()
215 .map(|self_entry| {
216 self_entry
217 .iter()
218 .map(|self_tensor_rank_2| self_tensor_rank_2 * tensor_rank_2)
219 .collect()
220 })
221 .collect()
222 }
223}
224
225impl<const D: usize, const I: usize, const J: usize, const W: usize, const X: usize> Add
226 for TensorRank2List2D<D, I, J, W, X>
227{
228 type Output = Self;
229 fn add(mut self, tensor_rank_2_list_2d: Self) -> Self::Output {
230 self += tensor_rank_2_list_2d;
231 self
232 }
233}
234
235impl<const D: usize, const I: usize, const J: usize, const W: usize, const X: usize> Add<&Self>
236 for TensorRank2List2D<D, I, J, W, X>
237{
238 type Output = Self;
239 fn add(mut self, tensor_rank_2_list_2d: &Self) -> Self::Output {
240 self += tensor_rank_2_list_2d;
241 self
242 }
243}
244
245impl<const D: usize, const I: usize, const J: usize, const W: usize, const X: usize> AddAssign
246 for TensorRank2List2D<D, I, J, W, X>
247{
248 fn add_assign(&mut self, tensor_rank_2_list_2d: Self) {
249 self.iter_mut()
250 .zip(tensor_rank_2_list_2d.iter())
251 .for_each(|(self_entry, tensor_rank_2_list)| *self_entry += tensor_rank_2_list);
252 }
253}
254
255impl<const D: usize, const I: usize, const J: usize, const W: usize, const X: usize>
256 AddAssign<&Self> for TensorRank2List2D<D, I, J, W, X>
257{
258 fn add_assign(&mut self, tensor_rank_2_list_2d: &Self) {
259 self.iter_mut()
260 .zip(tensor_rank_2_list_2d.iter())
261 .for_each(|(self_entry, tensor_rank_2_list)| *self_entry += tensor_rank_2_list);
262 }
263}
264
265impl<const D: usize, const I: usize, const J: usize, const W: usize, const X: usize>
266 Div<TensorRank0> for TensorRank2List2D<D, I, J, W, X>
267{
268 type Output = Self;
269 fn div(mut self, tensor_rank_0: TensorRank0) -> Self::Output {
270 self /= &tensor_rank_0;
271 self
272 }
273}
274
275impl<const D: usize, const I: usize, const J: usize, const W: usize, const X: usize>
276 Div<&TensorRank0> for TensorRank2List2D<D, I, J, W, X>
277{
278 type Output = Self;
279 fn div(mut self, tensor_rank_0: &TensorRank0) -> Self::Output {
280 self /= tensor_rank_0;
281 self
282 }
283}
284
285impl<const D: usize, const I: usize, const J: usize, const W: usize, const X: usize>
286 DivAssign<TensorRank0> for TensorRank2List2D<D, I, J, W, X>
287{
288 fn div_assign(&mut self, tensor_rank_0: TensorRank0) {
289 self.iter_mut().for_each(|entry| *entry /= &tensor_rank_0);
290 }
291}
292
293impl<const D: usize, const I: usize, const J: usize, const W: usize, const X: usize>
294 DivAssign<&TensorRank0> for TensorRank2List2D<D, I, J, W, X>
295{
296 fn div_assign(&mut self, tensor_rank_0: &TensorRank0) {
297 self.iter_mut().for_each(|entry| *entry /= tensor_rank_0);
298 }
299}
300
301impl<const D: usize, const I: usize, const J: usize, const W: usize, const X: usize>
302 Mul<TensorRank0> for TensorRank2List2D<D, I, J, W, X>
303{
304 type Output = Self;
305 fn mul(mut self, tensor_rank_0: TensorRank0) -> Self::Output {
306 self *= &tensor_rank_0;
307 self
308 }
309}
310
311impl<const D: usize, const I: usize, const J: usize, const W: usize, const X: usize>
312 Mul<&TensorRank0> for TensorRank2List2D<D, I, J, W, X>
313{
314 type Output = Self;
315 fn mul(mut self, tensor_rank_0: &TensorRank0) -> Self::Output {
316 self *= tensor_rank_0;
317 self
318 }
319}
320
321impl<const D: usize, const I: usize, const J: usize, const W: usize, const X: usize>
322 MulAssign<TensorRank0> for TensorRank2List2D<D, I, J, W, X>
323{
324 fn mul_assign(&mut self, tensor_rank_0: TensorRank0) {
325 self.iter_mut().for_each(|entry| *entry *= &tensor_rank_0);
326 }
327}
328
329impl<const D: usize, const I: usize, const J: usize, const W: usize, const X: usize>
330 MulAssign<&TensorRank0> for TensorRank2List2D<D, I, J, W, X>
331{
332 fn mul_assign(&mut self, tensor_rank_0: &TensorRank0) {
333 self.iter_mut().for_each(|entry| *entry *= tensor_rank_0);
334 }
335}
336
337impl<const D: usize, const I: usize, const J: usize, const W: usize, const X: usize> Sub
338 for TensorRank2List2D<D, I, J, W, X>
339{
340 type Output = Self;
341 fn sub(mut self, tensor_rank_2_list_2d: Self) -> Self::Output {
342 self -= tensor_rank_2_list_2d;
343 self
344 }
345}
346
347impl<const D: usize, const I: usize, const J: usize, const W: usize, const X: usize> Sub<&Self>
348 for TensorRank2List2D<D, I, J, W, X>
349{
350 type Output = Self;
351 fn sub(mut self, tensor_rank_2_list_2d: &Self) -> Self::Output {
352 self -= tensor_rank_2_list_2d;
353 self
354 }
355}
356
357impl<const D: usize, const I: usize, const J: usize, const W: usize, const X: usize> Sub
358 for &TensorRank2List2D<D, I, J, W, X>
359{
360 type Output = TensorRank2List2D<D, I, J, W, X>;
361 fn sub(self, tensor_rank_2_list_2d: Self) -> Self::Output {
362 tensor_rank_2_list_2d
363 .iter()
364 .zip(self.iter())
365 .map(|(tensor_rank_2_list_2d_a, self_a)| self_a - tensor_rank_2_list_2d_a)
366 .collect()
367 }
368}
369
370impl<const D: usize, const I: usize, const J: usize, const W: usize, const X: usize> SubAssign
371 for TensorRank2List2D<D, I, J, W, X>
372{
373 fn sub_assign(&mut self, tensor_rank_2_list_2d: Self) {
374 self.iter_mut()
375 .zip(tensor_rank_2_list_2d.iter())
376 .for_each(|(self_entry, tensor_rank_2_list)| *self_entry -= tensor_rank_2_list);
377 }
378}
379
380impl<const D: usize, const I: usize, const J: usize, const W: usize, const X: usize>
381 SubAssign<&Self> for TensorRank2List2D<D, I, J, W, X>
382{
383 fn sub_assign(&mut self, tensor_rank_2_list_2d: &Self) {
384 self.iter_mut()
385 .zip(tensor_rank_2_list_2d.iter())
386 .for_each(|(self_entry, tensor_rank_2_list)| *self_entry -= tensor_rank_2_list);
387 }
388}