flavio/math/tensor/rank_1/list_2d/
mod.rs

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