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

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