Skip to main content

conspire/math/tensor/list/
mod.rs

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