conspire/math/tensor/rank_0/list/
mod.rs

1#[cfg(test)]
2mod test;
3
4use super::{super::super::write_tensor_rank_0, Tensor, TensorArray, TensorRank0};
5use std::{
6    fmt::{Display, Formatter, Result},
7    ops::{Add, AddAssign, Div, DivAssign, Index, IndexMut, Mul, MulAssign, Sub, SubAssign},
8};
9
10/// A list of tensors of rank 0 (a list of scalars).
11///
12/// `W` is the list length.
13#[derive(Clone, Debug)]
14pub struct TensorRank0List<const W: usize>([TensorRank0; W]);
15
16pub const fn tensor_rank_0_list<const W: usize>(array: [TensorRank0; W]) -> TensorRank0List<W> {
17    TensorRank0List(array)
18}
19
20impl<const W: usize> Display for TensorRank0List<W> {
21    fn fmt(&self, f: &mut Formatter) -> Result {
22        write!(f, "\x1B[s")?;
23        write!(f, "[")?;
24        self.0.chunks(5).enumerate().try_for_each(|(i, chunk)| {
25            chunk
26                .iter()
27                .try_for_each(|entry| write_tensor_rank_0(f, entry))?;
28            if (i + 1) * 5 < W {
29                writeln!(f, "\x1B[2D,")?;
30                write!(f, "\x1B[u")?;
31                write!(f, "\x1B[{}B ", i + 1)?;
32            }
33            Ok(())
34        })?;
35        write!(f, "\x1B[2D]")?;
36        Ok(())
37    }
38}
39
40impl<const W: usize> Tensor for TensorRank0List<W> {
41    type Item = TensorRank0;
42    fn full_contraction(&self, tensor_rank_0_list: &Self) -> TensorRank0 {
43        self.iter()
44            .zip(tensor_rank_0_list.iter())
45            .map(|(self_entry, tensor_rank_0)| self_entry * tensor_rank_0)
46            .sum()
47    }
48    fn iter(&self) -> impl Iterator<Item = &TensorRank0> {
49        self.0.iter()
50    }
51    fn iter_mut(&mut self) -> impl Iterator<Item = &mut Self::Item> {
52        self.0.iter_mut()
53    }
54}
55
56impl<const W: usize> TensorArray for TensorRank0List<W> {
57    type Array = [TensorRank0; W];
58    type Item = TensorRank0;
59    fn as_array(&self) -> Self::Array {
60        self.0
61    }
62    fn identity() -> Self {
63        Self([1.0; W])
64    }
65    fn new(array: Self::Array) -> Self {
66        Self(array)
67    }
68    fn zero() -> Self {
69        Self([0.0; W])
70    }
71}
72
73impl<const W: usize> FromIterator<TensorRank0> for TensorRank0List<W> {
74    fn from_iter<Ii: IntoIterator<Item = TensorRank0>>(into_iterator: Ii) -> Self {
75        let mut tensor_rank_0_list = Self::zero();
76        tensor_rank_0_list
77            .iter_mut()
78            .zip(into_iterator)
79            .for_each(|(tensor_rank_0, entry)| *tensor_rank_0 = entry);
80        tensor_rank_0_list
81    }
82}
83
84impl<const W: usize> Index<usize> for TensorRank0List<W> {
85    type Output = TensorRank0;
86    fn index(&self, index: usize) -> &Self::Output {
87        &self.0[index]
88    }
89}
90
91impl<const W: usize> IndexMut<usize> for TensorRank0List<W> {
92    fn index_mut(&mut self, index: usize) -> &mut Self::Output {
93        &mut self.0[index]
94    }
95}
96
97impl<const W: usize> Add for TensorRank0List<W> {
98    type Output = Self;
99    fn add(mut self, tensor_rank_0_list: Self) -> Self::Output {
100        self += tensor_rank_0_list;
101        self
102    }
103}
104
105impl<const W: usize> Add<&Self> for TensorRank0List<W> {
106    type Output = Self;
107    fn add(mut self, tensor_rank_0_list: &Self) -> Self::Output {
108        self += tensor_rank_0_list;
109        self
110    }
111}
112
113impl<const W: usize> AddAssign for TensorRank0List<W> {
114    fn add_assign(&mut self, tensor_rank_0_list: Self) {
115        self.iter_mut()
116            .zip(tensor_rank_0_list.iter())
117            .for_each(|(self_entry, tensor_rank_0)| *self_entry += tensor_rank_0);
118    }
119}
120
121impl<const W: usize> AddAssign<&Self> for TensorRank0List<W> {
122    fn add_assign(&mut self, tensor_rank_0_list: &Self) {
123        self.iter_mut()
124            .zip(tensor_rank_0_list.iter())
125            .for_each(|(self_entry, tensor_rank_0)| *self_entry += tensor_rank_0);
126    }
127}
128
129impl<const W: usize> Div<TensorRank0> for TensorRank0List<W> {
130    type Output = Self;
131    fn div(mut self, tensor_rank_0: TensorRank0) -> Self::Output {
132        self /= tensor_rank_0;
133        self
134    }
135}
136
137impl<const W: usize> Div<&TensorRank0> for TensorRank0List<W> {
138    type Output = Self;
139    fn div(mut self, tensor_rank_0: &TensorRank0) -> Self::Output {
140        self /= tensor_rank_0;
141        self
142    }
143}
144
145impl<const W: usize> DivAssign<TensorRank0> for TensorRank0List<W> {
146    fn div_assign(&mut self, tensor_rank_0: TensorRank0) {
147        self.iter_mut().for_each(|self_i| *self_i /= &tensor_rank_0);
148    }
149}
150
151impl<const W: usize> DivAssign<&TensorRank0> for TensorRank0List<W> {
152    fn div_assign(&mut self, tensor_rank_0: &TensorRank0) {
153        self.iter_mut().for_each(|self_i| *self_i /= tensor_rank_0);
154    }
155}
156
157impl<const W: usize> Mul<TensorRank0> for TensorRank0List<W> {
158    type Output = Self;
159    fn mul(mut self, tensor_rank_0: TensorRank0) -> Self::Output {
160        self *= tensor_rank_0;
161        self
162    }
163}
164
165// impl<const W: usize> Mul<TensorRank0> for &TensorRank0List<W> {
166//     type Output = TensorRank0List<W>;
167//     fn mul(self, tensor_rank_0: TensorRank0) -> Self::Output {
168//         self.iter().map(|self_i| self_i * tensor_rank_0).collect()
169//     }
170// }
171
172impl<const W: usize> Mul<&TensorRank0> for TensorRank0List<W> {
173    type Output = Self;
174    fn mul(mut self, tensor_rank_0: &TensorRank0) -> Self::Output {
175        self *= tensor_rank_0;
176        self
177    }
178}
179
180impl<const W: usize> Mul<&TensorRank0> for &TensorRank0List<W> {
181    type Output = TensorRank0List<W>;
182    fn mul(self, tensor_rank_0: &TensorRank0) -> Self::Output {
183        self.iter().map(|self_i| self_i * tensor_rank_0).collect()
184    }
185}
186
187impl<const W: usize> MulAssign<TensorRank0> for TensorRank0List<W> {
188    fn mul_assign(&mut self, tensor_rank_0: TensorRank0) {
189        self.iter_mut().for_each(|self_i| *self_i *= &tensor_rank_0);
190    }
191}
192
193impl<const W: usize> MulAssign<&TensorRank0> for TensorRank0List<W> {
194    fn mul_assign(&mut self, tensor_rank_0: &TensorRank0) {
195        self.iter_mut().for_each(|self_i| *self_i *= tensor_rank_0);
196    }
197}
198
199impl<const W: usize> Mul for TensorRank0List<W> {
200    type Output = TensorRank0;
201    fn mul(self, tensor_rank_0_list: Self) -> Self::Output {
202        self.iter()
203            .zip(tensor_rank_0_list.iter())
204            .map(|(self_entry, tensor_rank_0_list_entry)| self_entry * tensor_rank_0_list_entry)
205            .sum()
206    }
207}
208
209impl<const W: usize> Mul<&Self> for TensorRank0List<W> {
210    type Output = TensorRank0;
211    fn mul(self, tensor_rank_0_list: &Self) -> Self::Output {
212        self.iter()
213            .zip(tensor_rank_0_list.iter())
214            .map(|(self_entry, tensor_rank_0_list_entry)| self_entry * tensor_rank_0_list_entry)
215            .sum()
216    }
217}
218
219impl<const W: usize> Mul<TensorRank0List<W>> for &TensorRank0List<W> {
220    type Output = TensorRank0;
221    fn mul(self, tensor_rank_0_list: TensorRank0List<W>) -> Self::Output {
222        self.iter()
223            .zip(tensor_rank_0_list.iter())
224            .map(|(self_entry, tensor_rank_0_list_entry)| self_entry * tensor_rank_0_list_entry)
225            .sum()
226    }
227}
228
229impl<const W: usize> Mul for &TensorRank0List<W> {
230    type Output = TensorRank0;
231    fn mul(self, tensor_rank_0_list: Self) -> Self::Output {
232        self.iter()
233            .zip(tensor_rank_0_list.iter())
234            .map(|(self_entry, tensor_rank_0_list_entry)| self_entry * tensor_rank_0_list_entry)
235            .sum()
236    }
237}
238
239impl<const W: usize> Sub for TensorRank0List<W> {
240    type Output = Self;
241    fn sub(mut self, tensor_rank_0_list: Self) -> Self::Output {
242        self -= tensor_rank_0_list;
243        self
244    }
245}
246
247impl<const W: usize> Sub<&Self> for TensorRank0List<W> {
248    type Output = Self;
249    fn sub(mut self, tensor_rank_0_list: &Self) -> Self::Output {
250        self -= tensor_rank_0_list;
251        self
252    }
253}
254
255impl<const W: usize> SubAssign for TensorRank0List<W> {
256    fn sub_assign(&mut self, tensor_rank_0_list: Self) {
257        self.iter_mut()
258            .zip(tensor_rank_0_list.iter())
259            .for_each(|(self_entry, tensor_rank_0)| *self_entry -= tensor_rank_0);
260    }
261}
262
263impl<const W: usize> SubAssign<&Self> for TensorRank0List<W> {
264    fn sub_assign(&mut self, tensor_rank_0_list: &Self) {
265        self.iter_mut()
266            .zip(tensor_rank_0_list.iter())
267            .for_each(|(self_entry, tensor_rank_0)| *self_entry -= tensor_rank_0);
268    }
269}