conspire/math/tensor/list/
mod.rs

1use crate::math::{Tensor, TensorArray, TensorRank0};
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
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> Display for TensorList<T, N>
44where
45    T: Tensor,
46{
47    fn fmt(&self, f: &mut Formatter) -> Result {
48        write!(f, "Need to implement Display")
49        // write!(f, "\x1B[s")?;
50        // write!(f, "[[")?;
51        // self.iter().enumerate().try_for_each(|(i, tensor_rank_1)| {
52        //     tensor_rank_1
53        //         .iter()
54        //         .try_for_each(|entry| write_tensor_rank_0(f, entry))?;
55        //     if i + 1 < W {
56        //         writeln!(f, "\x1B[2D],")?;
57        //         write!(f, "\x1B[u")?;
58        //         write!(f, "\x1B[{}B [", i + 1)?;
59        //     }
60        //     Ok(())
61        // })?;
62        // write!(f, "\x1B[2D]]")
63    }
64}
65
66impl<T, const N: usize> Index<usize> for TensorList<T, N>
67where
68    T: Tensor,
69{
70    type Output = T;
71    fn index(&self, index: usize) -> &Self::Output {
72        &self.0[index]
73    }
74}
75
76impl<T, const N: usize> IndexMut<usize> for TensorList<T, N>
77where
78    T: Tensor,
79{
80    fn index_mut(&mut self, index: usize) -> &mut Self::Output {
81        &mut self.0[index]
82    }
83}
84
85impl<T, const N: usize> Tensor for TensorList<T, N>
86where
87    T: Tensor,
88{
89    type Item = T;
90    fn iter(&self) -> impl Iterator<Item = &Self::Item> {
91        self.0.iter()
92    }
93    fn iter_mut(&mut self) -> impl Iterator<Item = &mut Self::Item> {
94        self.0.iter_mut()
95    }
96    fn len(&self) -> usize {
97        N
98    }
99    fn size(&self) -> usize {
100        N * self[0].size() // fine if T is TensorArray
101    }
102}
103
104impl<T, const N: usize> FromIterator<T> for TensorList<T, N>
105where
106    T: Tensor,
107{
108    fn from_iter<Ii: IntoIterator<Item = T>>(into_iterator: Ii) -> Self {
109        let mut tensor_list = Self::default();
110        tensor_list
111            .iter_mut()
112            .zip(into_iterator)
113            .for_each(|(tensor_list_entry, entry)| *tensor_list_entry = entry);
114        tensor_list
115    }
116}
117
118impl<T, const N: usize> IntoIterator for TensorList<T, N>
119where
120    T: Tensor,
121{
122    type Item = T;
123    type IntoIter = IntoIter<Self::Item, N>;
124    fn into_iter(self) -> Self::IntoIter {
125        self.0.into_iter()
126    }
127}
128
129impl<T, const N: usize> Sum for TensorList<T, N>
130where
131    T: Tensor,
132{
133    fn sum<Ii>(iter: Ii) -> Self
134    where
135        Ii: Iterator<Item = Self>,
136    {
137        iter.reduce(|mut acc, item| {
138            acc += item;
139            acc
140        })
141        .unwrap_or_else(Self::default)
142    }
143}
144
145impl<T, const N: usize> TensorArray for TensorList<T, N>
146where
147    T: Tensor + TensorArray,
148{
149    type Array = [T::Array; N];
150    type Item = T;
151    fn as_array(&self) -> Self::Array {
152        from_fn(|i| self[i].as_array())
153    }
154    fn identity() -> Self {
155        Self(from_fn(|_| Self::Item::identity()))
156    }
157    fn new(array: Self::Array) -> Self {
158        array.into_iter().map(Self::Item::new).collect()
159    }
160    fn zero() -> Self {
161        Self(from_fn(|_| Self::Item::zero()))
162    }
163}
164
165impl<T, const N: usize> Div<TensorRank0> for TensorList<T, N>
166where
167    T: Tensor,
168{
169    type Output = Self;
170    fn div(mut self, tensor_rank_0: TensorRank0) -> Self::Output {
171        self /= tensor_rank_0;
172        self
173    }
174}
175
176impl<T, const N: usize> Div<&TensorRank0> for TensorList<T, N>
177where
178    T: Tensor,
179{
180    type Output = Self;
181    fn div(mut self, tensor_rank_0: &TensorRank0) -> Self::Output {
182        self /= tensor_rank_0;
183        self
184    }
185}
186
187impl<T, const N: usize> DivAssign<TensorRank0> for TensorList<T, N>
188where
189    T: Tensor,
190{
191    fn div_assign(&mut self, tensor_rank_0: TensorRank0) {
192        self.iter_mut().for_each(|entry| *entry /= &tensor_rank_0);
193    }
194}
195
196impl<T, const N: usize> DivAssign<&TensorRank0> for TensorList<T, N>
197where
198    T: Tensor,
199{
200    fn div_assign(&mut self, tensor_rank_0: &TensorRank0) {
201        self.iter_mut().for_each(|entry| *entry /= tensor_rank_0);
202    }
203}
204
205impl<T, const N: usize> Mul<TensorRank0> for TensorList<T, N>
206where
207    T: Tensor,
208{
209    type Output = Self;
210    fn mul(mut self, tensor_rank_0: TensorRank0) -> Self::Output {
211        self *= tensor_rank_0;
212        self
213    }
214}
215
216impl<T, const N: usize> Mul<&TensorRank0> for TensorList<T, N>
217where
218    T: Tensor,
219{
220    type Output = Self;
221    fn mul(mut self, tensor_rank_0: &TensorRank0) -> Self::Output {
222        self *= tensor_rank_0;
223        self
224    }
225}
226
227impl<T, const N: usize> MulAssign<TensorRank0> for TensorList<T, N>
228where
229    T: Tensor,
230{
231    fn mul_assign(&mut self, tensor_rank_0: TensorRank0) {
232        self.iter_mut().for_each(|entry| *entry *= &tensor_rank_0);
233    }
234}
235
236impl<T, const N: usize> MulAssign<&TensorRank0> for TensorList<T, N>
237where
238    T: Tensor,
239{
240    fn mul_assign(&mut self, tensor_rank_0: &TensorRank0) {
241        self.iter_mut().for_each(|entry| *entry *= tensor_rank_0);
242    }
243}
244
245impl<T, const N: usize> Add for TensorList<T, N>
246where
247    T: Tensor,
248{
249    type Output = Self;
250    fn add(mut self, tensor_list: Self) -> Self::Output {
251        self += tensor_list;
252        self
253    }
254}
255
256impl<T, const N: usize> Add<&Self> for TensorList<T, N>
257where
258    T: Tensor,
259{
260    type Output = Self;
261    fn add(mut self, tensor_list: &Self) -> Self::Output {
262        self += tensor_list;
263        self
264    }
265}
266
267impl<T, const N: usize> AddAssign for TensorList<T, N>
268where
269    T: Tensor,
270{
271    fn add_assign(&mut self, tensor_list: Self) {
272        self.iter_mut()
273            .zip(tensor_list.iter())
274            .for_each(|(self_entry, entry)| *self_entry += entry);
275    }
276}
277
278impl<T, const N: usize> AddAssign<&Self> for TensorList<T, N>
279where
280    T: Tensor,
281{
282    fn add_assign(&mut self, tensor_list: &Self) {
283        self.iter_mut()
284            .zip(tensor_list.iter())
285            .for_each(|(self_entry, entry)| *self_entry += entry);
286    }
287}
288
289impl<T, const N: usize> Sub for TensorList<T, N>
290where
291    T: Tensor,
292{
293    type Output = Self;
294    fn sub(mut self, tensor_list: Self) -> Self::Output {
295        self -= tensor_list;
296        self
297    }
298}
299
300impl<T, const N: usize> Sub<&Self> for TensorList<T, N>
301where
302    T: Tensor,
303{
304    type Output = Self;
305    fn sub(mut self, tensor_list: &Self) -> Self::Output {
306        self -= tensor_list;
307        self
308    }
309}
310
311impl<T, const N: usize> SubAssign for TensorList<T, N>
312where
313    T: Tensor,
314{
315    fn sub_assign(&mut self, tensor_list: Self) {
316        self.iter_mut()
317            .zip(tensor_list.iter())
318            .for_each(|(self_entry, entry)| *self_entry -= entry);
319    }
320}
321
322impl<T, const N: usize> SubAssign<&Self> for TensorList<T, N>
323where
324    T: Tensor,
325{
326    fn sub_assign(&mut self, tensor_list: &Self) {
327        self.iter_mut()
328            .zip(tensor_list.iter())
329            .for_each(|(self_entry, entry)| *self_entry -= entry);
330    }
331}