1use crate::math::{Tensor, TensorArray, TensorRank0, TensorRank1, TensorRank2};
2use std::{
3 array::{IntoIter, from_fn},
4 fmt::{Display, Formatter, Result},
5 iter::Sum,
6 ops::{Add, AddAssign, Div, DivAssign, Index, IndexMut, Mul, MulAssign, Sub, SubAssign},
7};
8
9#[repr(transparent)]
10#[derive(Clone, Debug)]
11pub struct TensorList<T, const N: usize>([T; N])
12where
13 T: Tensor;
14
15macro_rules! const_from_impl_tensor_rank_0_list {
16 ($len:literal, $($i:literal),*) => {
17 impl TensorList<TensorRank0, $len> {
18 pub const fn const_from(array: [TensorRank0; $len]) -> Self {
20 Self([
21 $(array[$i]),*
22 ])
23 }
24 }
25 }
26}
27const_from_impl_tensor_rank_0_list!(1, 0);
28const_from_impl_tensor_rank_0_list!(5, 0, 1, 2, 3, 4);
29const_from_impl_tensor_rank_0_list!(6, 0, 1, 2, 3, 4, 5);
30const_from_impl_tensor_rank_0_list!(8, 0, 1, 2, 3, 4, 5, 6, 7);
31
32macro_rules! const_from_impl_tensor_rank_1_list {
33 ($dim:literal, $len:literal, $($i:literal),*) => {
34 impl<const I: usize> TensorList<TensorRank1<$dim, I>, $len> {
35 pub const fn const_from(array: [[TensorRank0; $dim]; $len]) -> Self {
37 Self([
38 $(TensorRank1::const_from(array[$i])),*
39 ])
40 }
41 }
42 }
43}
44const_from_impl_tensor_rank_1_list!(2, 3, 0, 1, 2);
45const_from_impl_tensor_rank_1_list!(3, 4, 0, 1, 2, 3);
46const_from_impl_tensor_rank_1_list!(3, 5, 0, 1, 2, 3, 4);
47const_from_impl_tensor_rank_1_list!(3, 6, 0, 1, 2, 3, 4, 5);
48const_from_impl_tensor_rank_1_list!(3, 8, 0, 1, 2, 3, 4, 5, 6, 7);
49const_from_impl_tensor_rank_1_list!(3, 10, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
50const_from_impl_tensor_rank_1_list!(3, 12, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11);
51const_from_impl_tensor_rank_1_list!(3, 1, 0);
52const_from_impl_tensor_rank_1_list!(4, 1, 0);
53const_from_impl_tensor_rank_1_list!(4, 4, 0, 1, 2, 3);
54const_from_impl_tensor_rank_1_list!(4, 12, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11);
55const_from_impl_tensor_rank_1_list!(5, 5, 0, 1, 2, 3, 4);
56const_from_impl_tensor_rank_1_list!(6, 6, 0, 1, 2, 3, 4, 5);
57const_from_impl_tensor_rank_1_list!(8, 8, 0, 1, 2, 3, 4, 5, 6, 7);
58
59macro_rules! const_from_impl_tensor_rank_1_list_2d {
60 ($dim:literal, $len_1:literal, $len_2:literal, $($i:literal),*) => {
61 impl<const I: usize> TensorList<TensorList<TensorRank1<$dim, I>, $len_1>, $len_2> {
62 pub const fn const_from(array: [[[TensorRank0; $dim]; $len_1]; $len_2]) -> Self {
64 Self([
65 $(TensorList::<TensorRank1<$dim, I>, $len_1>::const_from(array[$i])),*
66 ])
67 }
68 }
69 }
70}
71const_from_impl_tensor_rank_1_list_2d!(2, 3, 1, 0);
72const_from_impl_tensor_rank_1_list_2d!(3, 4, 1, 0);
73const_from_impl_tensor_rank_1_list_2d!(3, 5, 5, 0, 1, 2, 3, 4);
74const_from_impl_tensor_rank_1_list_2d!(3, 6, 6, 0, 1, 2, 3, 4, 5);
75const_from_impl_tensor_rank_1_list_2d!(3, 8, 8, 0, 1, 2, 3, 4, 5, 6, 7);
76const_from_impl_tensor_rank_1_list_2d!(3, 10, 12, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11);
77const_from_impl_tensor_rank_1_list_2d!(3, 12, 10, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
78
79macro_rules! const_from_impl_tensor_rank_2_list {
80 ($dim:literal, $len:literal, $($i:literal),*) => {
81 impl<const I: usize, const J: usize> TensorList<TensorRank2<$dim, I, J>, $len> {
82 pub const fn const_from(array: [[[TensorRank0; $dim]; $dim]; $len]) -> Self {
84 Self([
85 $(TensorRank2::<$dim, I, J>::const_from(array[$i])),*
86 ])
87 }
88 }
89 }
90}
91const_from_impl_tensor_rank_2_list!(4, 12, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11);
92
93impl<T, const N: usize> Default for TensorList<T, N>
94where
95 T: Tensor,
96{
97 fn default() -> Self {
98 Self(from_fn(|_| T::default()))
99 }
100}
101
102impl<T, const N: usize> From<[T; N]> for TensorList<T, N>
103where
104 T: Tensor,
105{
106 fn from(tensor_array: [T; N]) -> Self {
107 Self(tensor_array)
108 }
109}
110
111impl<T, const N: usize> Display for TensorList<T, N>
112where
113 T: Tensor,
114{
115 fn fmt(&self, f: &mut Formatter) -> Result {
116 write!(f, "Need to implement Display")
117 }
132}
133
134impl<T, const N: usize> Index<usize> for TensorList<T, N>
135where
136 T: Tensor,
137{
138 type Output = T;
139 fn index(&self, index: usize) -> &Self::Output {
140 &self.0[index]
141 }
142}
143
144impl<T, const N: usize> IndexMut<usize> for TensorList<T, N>
145where
146 T: Tensor,
147{
148 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
149 &mut self.0[index]
150 }
151}
152
153impl<T, const N: usize> Tensor for TensorList<T, N>
154where
155 T: Tensor,
156{
157 type Item = T;
158 fn iter(&self) -> impl Iterator<Item = &Self::Item> {
159 self.0.iter()
160 }
161 fn iter_mut(&mut self) -> impl Iterator<Item = &mut Self::Item> {
162 self.0.iter_mut()
163 }
164 fn len(&self) -> usize {
165 N
166 }
167 fn size(&self) -> usize {
168 N * self[0].size() }
170}
171
172impl<T, const N: usize> FromIterator<T> for TensorList<T, N>
173where
174 T: Tensor,
175{
176 fn from_iter<Ii: IntoIterator<Item = T>>(into_iterator: Ii) -> Self {
177 let mut tensor_list = Self::default();
178 tensor_list
179 .iter_mut()
180 .zip(into_iterator)
181 .for_each(|(tensor_list_entry, entry)| *tensor_list_entry = entry);
182 tensor_list
183 }
184}
185
186impl<T, const N: usize> IntoIterator for TensorList<T, N>
187where
188 T: Tensor,
189{
190 type Item = T;
191 type IntoIter = IntoIter<Self::Item, N>;
192 fn into_iter(self) -> Self::IntoIter {
193 self.0.into_iter()
194 }
195}
196
197impl<T, const N: usize> Sum for TensorList<T, N>
198where
199 T: Tensor,
200{
201 fn sum<Ii>(iter: Ii) -> Self
202 where
203 Ii: Iterator<Item = Self>,
204 {
205 iter.reduce(|mut acc, item| {
206 acc += item;
207 acc
208 })
209 .unwrap_or_else(Self::default)
210 }
211}
212
213impl<T, const N: usize> TensorArray for TensorList<T, N>
214where
215 T: Tensor + TensorArray,
216{
217 type Array = [T::Array; N];
218 type Item = T;
219 fn as_array(&self) -> Self::Array {
220 from_fn(|i| self[i].as_array())
221 }
222 fn identity() -> Self {
223 Self(from_fn(|_| Self::Item::identity()))
224 }
225 fn new(array: Self::Array) -> Self {
226 array.into_iter().map(Self::Item::new).collect()
227 }
228 fn zero() -> Self {
229 Self(from_fn(|_| Self::Item::zero()))
230 }
231}
232
233impl<T, const N: usize> Div<TensorRank0> for TensorList<T, N>
234where
235 T: Tensor,
236{
237 type Output = Self;
238 fn div(mut self, tensor_rank_0: TensorRank0) -> Self::Output {
239 self /= tensor_rank_0;
240 self
241 }
242}
243
244impl<T, const N: usize> Div<&TensorRank0> for TensorList<T, N>
245where
246 T: Tensor,
247{
248 type Output = Self;
249 fn div(mut self, tensor_rank_0: &TensorRank0) -> Self::Output {
250 self /= tensor_rank_0;
251 self
252 }
253}
254
255impl<T, const N: usize> DivAssign<TensorRank0> for TensorList<T, N>
256where
257 T: Tensor,
258{
259 fn div_assign(&mut self, tensor_rank_0: TensorRank0) {
260 self.iter_mut().for_each(|entry| *entry /= &tensor_rank_0);
261 }
262}
263
264impl<T, const N: usize> DivAssign<&TensorRank0> for TensorList<T, N>
265where
266 T: Tensor,
267{
268 fn div_assign(&mut self, tensor_rank_0: &TensorRank0) {
269 self.iter_mut().for_each(|entry| *entry /= tensor_rank_0);
270 }
271}
272
273impl<T, const N: usize> Mul<TensorRank0> for TensorList<T, N>
274where
275 T: Tensor,
276{
277 type Output = Self;
278 fn mul(mut self, tensor_rank_0: TensorRank0) -> Self::Output {
279 self *= tensor_rank_0;
280 self
281 }
282}
283
284impl<T, const N: usize> Mul<&TensorRank0> for TensorList<T, N>
285where
286 T: Tensor,
287{
288 type Output = Self;
289 fn mul(mut self, tensor_rank_0: &TensorRank0) -> Self::Output {
290 self *= tensor_rank_0;
291 self
292 }
293}
294
295impl<T, const N: usize> Mul<TensorRank0> for &TensorList<T, N>
296where
297 T: Tensor,
298 for<'a> &'a T: Mul<&'a TensorRank0, Output = T>,
299{
300 type Output = TensorList<T, N>;
301 fn mul(self, tensor_rank_0: TensorRank0) -> Self::Output {
302 self.iter().map(|self_i| self_i * &tensor_rank_0).collect()
303 }
304}
305
306impl<T, const N: usize> Mul<&TensorRank0> for &TensorList<T, N>
307where
308 T: Tensor,
309{
310 type Output = TensorList<T, N>;
311 fn mul(self, tensor_rank_0: &TensorRank0) -> Self::Output {
312 self.clone() * tensor_rank_0
316 }
317}
318
319impl<T, const N: usize> MulAssign<TensorRank0> for TensorList<T, N>
320where
321 T: Tensor,
322{
323 fn mul_assign(&mut self, tensor_rank_0: TensorRank0) {
324 self.iter_mut().for_each(|entry| *entry *= &tensor_rank_0);
325 }
326}
327
328impl<T, const N: usize> MulAssign<&TensorRank0> for TensorList<T, N>
329where
330 T: Tensor,
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<T, const N: usize> Add for TensorList<T, N>
338where
339 T: Tensor,
340{
341 type Output = Self;
342 fn add(mut self, tensor_list: Self) -> Self::Output {
343 self += tensor_list;
344 self
345 }
346}
347
348impl<T, const N: usize> Add<&Self> for TensorList<T, N>
349where
350 T: Tensor,
351{
352 type Output = Self;
353 fn add(mut self, tensor_list: &Self) -> Self::Output {
354 self += tensor_list;
355 self
356 }
357}
358
359impl<T, const N: usize> AddAssign for TensorList<T, N>
360where
361 T: Tensor,
362{
363 fn add_assign(&mut self, tensor_list: Self) {
364 self.iter_mut()
365 .zip(tensor_list)
366 .for_each(|(self_entry, entry)| *self_entry += entry);
367 }
368}
369
370impl<T, const N: usize> AddAssign<&Self> for TensorList<T, N>
371where
372 T: Tensor,
373{
374 fn add_assign(&mut self, tensor_list: &Self) {
375 self.iter_mut()
376 .zip(tensor_list.iter())
377 .for_each(|(self_entry, entry)| *self_entry += entry);
378 }
379}
380
381impl<T, const N: usize> Sub for TensorList<T, N>
382where
383 T: Tensor,
384{
385 type Output = Self;
386 fn sub(mut self, tensor_list: Self) -> Self::Output {
387 self -= tensor_list;
388 self
389 }
390}
391
392impl<T, const N: usize> Sub<&Self> for TensorList<T, N>
393where
394 T: Tensor,
395{
396 type Output = Self;
397 fn sub(mut self, tensor_list: &Self) -> Self::Output {
398 self -= tensor_list;
399 self
400 }
401}
402
403impl<T, const N: usize> SubAssign for TensorList<T, N>
404where
405 T: Tensor,
406{
407 fn sub_assign(&mut self, tensor_list: Self) {
408 self.iter_mut()
409 .zip(tensor_list)
410 .for_each(|(self_entry, entry)| *self_entry -= entry);
411 }
412}
413
414impl<T, const N: usize> SubAssign<&Self> for TensorList<T, N>
415where
416 T: Tensor,
417{
418 fn sub_assign(&mut self, tensor_list: &Self) {
419 self.iter_mut()
420 .zip(tensor_list.iter())
421 .for_each(|(self_entry, entry)| *self_entry -= entry);
422 }
423}