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

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