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