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

1#[cfg(test)]
2use super::super::test::ErrorTensor;
3
4use crate::math::{
5    Jacobian, Solution, Tensor, TensorArray, TensorRank0, TensorRank1, TensorRank2,
6    TensorRank2Vec2D, TensorVec, Vector, write_tensor_rank_0,
7};
8use std::{
9    fmt::{self, Display, Formatter},
10    mem::transmute,
11    ops::{Add, AddAssign, Div, DivAssign, Index, IndexMut, Mul, MulAssign, Sub, SubAssign},
12};
13
14/// A vector of *d*-dimensional tensors of rank 1.
15///
16/// `D` is the dimension, `I` is the configuration.
17#[derive(Clone, Debug)]
18pub struct TensorRank1Vec<const D: usize, const I: usize>(Vec<TensorRank1<D, I>>);
19
20impl<const D: usize, const I: usize> Display for TensorRank1Vec<D, I> {
21    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
22        write!(f, "\x1B[s")?;
23        write!(f, "[[")?;
24        self.iter().enumerate().try_for_each(|(i, tensor_rank_1)| {
25            tensor_rank_1
26                .iter()
27                .try_for_each(|entry| write_tensor_rank_0(f, entry))?;
28            if i + 1 < self.len() {
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    }
37}
38
39#[cfg(test)]
40impl<const D: usize, const I: usize> ErrorTensor for TensorRank1Vec<D, I> {
41    fn error_fd(&self, comparator: &Self, epsilon: &TensorRank0) -> Option<(bool, usize)> {
42        let error_count = self
43            .iter()
44            .zip(comparator.iter())
45            .map(|(entry, comparator_entry)| {
46                entry
47                    .iter()
48                    .zip(comparator_entry.iter())
49                    .filter(|&(&entry_i, &comparator_entry_i)| {
50                        &(entry_i / comparator_entry_i - 1.0).abs() >= epsilon
51                            && (&entry_i.abs() >= epsilon || &comparator_entry_i.abs() >= epsilon)
52                    })
53                    .count()
54            })
55            .sum();
56        if error_count > 0 {
57            let auxiliary = self
58                .iter()
59                .zip(comparator.iter())
60                .map(|(entry, comparator_entry)| {
61                    entry
62                        .iter()
63                        .zip(comparator_entry.iter())
64                        .filter(|&(&entry_i, &comparator_entry_i)| {
65                            &(entry_i / comparator_entry_i - 1.0).abs() >= epsilon
66                                && &(entry_i - comparator_entry_i).abs() >= epsilon
67                                && (&entry_i.abs() >= epsilon
68                                    || &comparator_entry_i.abs() >= epsilon)
69                        })
70                        .count()
71                })
72                .sum::<usize>()
73                > 0;
74            Some((auxiliary, error_count))
75        } else {
76            None
77        }
78    }
79}
80
81impl<const D: usize, const I: usize> From<Vec<[TensorRank0; D]>> for TensorRank1Vec<D, I> {
82    fn from(vec: Vec<[TensorRank0; D]>) -> Self {
83        vec.into_iter()
84            .map(|tensor_rank_1| tensor_rank_1.into())
85            .collect()
86    }
87}
88
89impl<const D: usize, const I: usize> From<Vec<Vec<TensorRank0>>> for TensorRank1Vec<D, I> {
90    fn from(vec: Vec<Vec<TensorRank0>>) -> Self {
91        vec.into_iter()
92            .map(|tensor_rank_1| tensor_rank_1.into())
93            .collect()
94    }
95}
96
97impl<const D: usize, const I: usize> From<TensorRank1Vec<D, I>> for Vec<[TensorRank0; D]> {
98    fn from(tensor_rank_1_vec: TensorRank1Vec<D, I>) -> Self {
99        tensor_rank_1_vec
100            .iter()
101            .map(|tensor_rank_1| tensor_rank_1.clone().into())
102            .collect()
103    }
104}
105
106impl<const D: usize, const I: usize> From<TensorRank1Vec<D, I>> for Vec<Vec<TensorRank0>> {
107    fn from(tensor_rank_1_vec: TensorRank1Vec<D, I>) -> Self {
108        tensor_rank_1_vec
109            .iter()
110            .map(|tensor_rank_1| tensor_rank_1.clone().into())
111            .collect()
112    }
113}
114
115impl From<TensorRank1Vec<3, 0>> for TensorRank1Vec<3, 1> {
116    fn from(tensor_rank_1_vec: TensorRank1Vec<3, 0>) -> Self {
117        unsafe { transmute::<TensorRank1Vec<3, 0>, TensorRank1Vec<3, 1>>(tensor_rank_1_vec) }
118    }
119}
120
121impl From<TensorRank1Vec<3, 1>> for TensorRank1Vec<3, 0> {
122    fn from(tensor_rank_1_vec: TensorRank1Vec<3, 1>) -> Self {
123        unsafe { transmute::<TensorRank1Vec<3, 1>, TensorRank1Vec<3, 0>>(tensor_rank_1_vec) }
124    }
125}
126
127impl<const D: usize, const I: usize> From<Vector> for TensorRank1Vec<D, I> {
128    fn from(vector: Vector) -> Self {
129        let n = vector.len();
130        if n % D != 0 {
131            panic!("Vector length mismatch.")
132        } else {
133            (0..n / D)
134                .map(|a| (0..D).map(|i| vector[D * a + i]).collect())
135                .collect()
136        }
137    }
138}
139
140impl<const D: usize, const I: usize> From<&Vector> for TensorRank1Vec<D, I> {
141    fn from(vector: &Vector) -> Self {
142        let n = vector.len();
143        if n % D != 0 {
144            panic!("Vector length mismatch.")
145        } else {
146            (0..n / D)
147                .map(|a| (0..D).map(|i| vector[D * a + i]).collect())
148                .collect()
149        }
150    }
151}
152
153impl<const D: usize, const I: usize> FromIterator<TensorRank1<D, I>> for TensorRank1Vec<D, I> {
154    fn from_iter<Ii: IntoIterator<Item = TensorRank1<D, I>>>(into_iterator: Ii) -> Self {
155        Self(Vec::from_iter(into_iterator))
156    }
157}
158
159impl<const D: usize, const I: usize> Index<usize> for TensorRank1Vec<D, I> {
160    type Output = TensorRank1<D, I>;
161    fn index(&self, index: usize) -> &Self::Output {
162        &self.0[index]
163    }
164}
165
166impl<const D: usize, const I: usize> IndexMut<usize> for TensorRank1Vec<D, I> {
167    fn index_mut(&mut self, index: usize) -> &mut Self::Output {
168        &mut self.0[index]
169    }
170}
171
172impl<const D: usize, const I: usize> TensorRank1Vec<D, I> {
173    /// Returns the sum of the full dot product of each tensor in each vector.
174    pub fn dot(&self, tensors: &Self) -> TensorRank0 {
175        self.iter()
176            .zip(tensors.iter())
177            .map(|(entry, tensor)| entry * tensor)
178            .sum()
179    }
180}
181
182impl<const D: usize, const I: usize> TensorVec for TensorRank1Vec<D, I> {
183    type Item = TensorRank1<D, I>;
184    type Slice<'a> = &'a [[TensorRank0; D]];
185    fn append(&mut self, other: &mut Self) {
186        self.0.append(&mut other.0)
187    }
188    fn is_empty(&self) -> bool {
189        self.0.is_empty()
190    }
191    fn len(&self) -> usize {
192        self.0.len()
193    }
194    fn new(slice: Self::Slice<'_>) -> Self {
195        slice
196            .iter()
197            .map(|slice_entry| Self::Item::new(*slice_entry))
198            .collect()
199    }
200    fn push(&mut self, item: Self::Item) {
201        self.0.push(item)
202    }
203    fn remove(&mut self, index: usize) -> Self::Item {
204        self.0.remove(index)
205    }
206    fn retain<F>(&mut self, f: F)
207    where
208        F: FnMut(&Self::Item) -> bool,
209    {
210        self.0.retain(f)
211    }
212    fn swap_remove(&mut self, index: usize) -> Self::Item {
213        self.0.swap_remove(index)
214    }
215    fn zero(len: usize) -> Self {
216        (0..len).map(|_| super::zero()).collect()
217    }
218}
219
220impl<const D: usize, const I: usize> Tensor for TensorRank1Vec<D, I> {
221    type Item = TensorRank1<D, I>;
222    fn iter(&self) -> impl Iterator<Item = &Self::Item> {
223        self.0.iter()
224    }
225    fn iter_mut(&mut self) -> impl Iterator<Item = &mut Self::Item> {
226        self.0.iter_mut()
227    }
228    fn norm_inf(&self) -> TensorRank0 {
229        self.iter()
230            .map(|tensor_rank_1| {
231                tensor_rank_1
232                    .iter()
233                    .fold(0.0, |acc, entry| entry.abs().max(acc))
234            })
235            .reduce(TensorRank0::max)
236            .unwrap()
237    }
238    fn num_entries(&self) -> usize {
239        D * self.len()
240    }
241}
242
243impl<const D: usize, const I: usize> IntoIterator for TensorRank1Vec<D, I> {
244    type Item = TensorRank1<D, I>;
245    type IntoIter = std::vec::IntoIter<Self::Item>;
246    fn into_iter(self) -> Self::IntoIter {
247        self.0.into_iter()
248    }
249}
250
251impl<const D: usize, const I: usize> Solution for TensorRank1Vec<D, I> {
252    fn decrement_from_chained(&mut self, other: &mut Vector, vector: Vector) {
253        self.iter_mut()
254            .flat_map(|x| x.iter_mut())
255            .chain(other.iter_mut())
256            .zip(vector)
257            .for_each(|(entry_i, vector_i)| *entry_i -= vector_i)
258    }
259}
260
261impl<const D: usize, const I: usize> Jacobian for TensorRank1Vec<D, I> {
262    fn fill_into(self, vector: &mut Vector) {
263        self.into_iter()
264            .flatten()
265            .zip(vector.iter_mut())
266            .for_each(|(self_i, vector_i)| *vector_i = self_i)
267    }
268    fn fill_into_chained(self, other: Vector, vector: &mut Vector) {
269        self.into_iter()
270            .flatten()
271            .chain(other)
272            .zip(vector.iter_mut())
273            .for_each(|(self_i, vector_i)| *vector_i = self_i)
274    }
275}
276
277impl<const D: usize, const I: usize, const J: usize> Div<TensorRank2Vec2D<D, I, J>>
278    for &TensorRank1Vec<D, I>
279{
280    type Output = TensorRank1Vec<D, J>;
281    fn div(self, _tensor_rank_2_vec_2d: TensorRank2Vec2D<D, I, J>) -> Self::Output {
282        todo!()
283    }
284}
285
286impl<const D: usize, const I: usize> Sub<Vector> for TensorRank1Vec<D, I> {
287    type Output = Self;
288    fn sub(mut self, vector: Vector) -> Self::Output {
289        self.iter_mut().enumerate().for_each(|(a, self_a)| {
290            self_a
291                .iter_mut()
292                .enumerate()
293                .for_each(|(i, self_a_i)| *self_a_i -= vector[D * a + i])
294        });
295        self
296    }
297}
298
299impl<const D: usize, const I: usize> Sub<&Vector> for TensorRank1Vec<D, I> {
300    type Output = Self;
301    fn sub(mut self, vector: &Vector) -> Self::Output {
302        self.iter_mut().enumerate().for_each(|(a, self_a)| {
303            self_a
304                .iter_mut()
305                .enumerate()
306                .for_each(|(i, self_a_i)| *self_a_i -= vector[D * a + i])
307        });
308        self
309    }
310}
311
312impl<const D: usize, const I: usize> Div<TensorRank0> for TensorRank1Vec<D, I> {
313    type Output = Self;
314    fn div(mut self, tensor_rank_0: TensorRank0) -> Self::Output {
315        self /= &tensor_rank_0;
316        self
317    }
318}
319
320impl<const D: usize, const I: usize> Div<&TensorRank0> for TensorRank1Vec<D, I> {
321    type Output = Self;
322    fn div(mut self, tensor_rank_0: &TensorRank0) -> Self::Output {
323        self /= tensor_rank_0;
324        self
325    }
326}
327
328impl<const D: usize, const I: usize> DivAssign<TensorRank0> for TensorRank1Vec<D, I> {
329    fn div_assign(&mut self, tensor_rank_0: TensorRank0) {
330        self.iter_mut().for_each(|entry| *entry /= &tensor_rank_0);
331    }
332}
333
334impl<const D: usize, const I: usize> DivAssign<&TensorRank0> for TensorRank1Vec<D, I> {
335    fn div_assign(&mut self, tensor_rank_0: &TensorRank0) {
336        self.iter_mut().for_each(|entry| *entry /= tensor_rank_0);
337    }
338}
339
340impl<const D: usize, const I: usize> Mul<TensorRank0> for TensorRank1Vec<D, I> {
341    type Output = Self;
342    fn mul(mut self, tensor_rank_0: TensorRank0) -> Self::Output {
343        self *= &tensor_rank_0;
344        self
345    }
346}
347
348impl<const D: usize, const I: usize> Mul<&TensorRank0> for TensorRank1Vec<D, I> {
349    type Output = Self;
350    fn mul(mut self, tensor_rank_0: &TensorRank0) -> Self::Output {
351        self *= tensor_rank_0;
352        self
353    }
354}
355
356impl<const D: usize, const I: usize> Mul<TensorRank0> for &TensorRank1Vec<D, I> {
357    type Output = TensorRank1Vec<D, I>;
358    fn mul(self, tensor_rank_0: TensorRank0) -> Self::Output {
359        self.iter().map(|self_i| self_i * tensor_rank_0).collect()
360    }
361}
362
363impl<const D: usize, const I: usize> Mul<&TensorRank0> for &TensorRank1Vec<D, I> {
364    type Output = TensorRank1Vec<D, I>;
365    fn mul(self, tensor_rank_0: &TensorRank0) -> Self::Output {
366        self.iter().map(|self_i| self_i * tensor_rank_0).collect()
367    }
368}
369
370impl<const D: usize, const I: usize> MulAssign<TensorRank0> for TensorRank1Vec<D, I> {
371    fn mul_assign(&mut self, tensor_rank_0: TensorRank0) {
372        self.iter_mut().for_each(|entry| *entry *= &tensor_rank_0);
373    }
374}
375
376impl<const D: usize, const I: usize> MulAssign<&TensorRank0> for TensorRank1Vec<D, I> {
377    fn mul_assign(&mut self, tensor_rank_0: &TensorRank0) {
378        self.iter_mut().for_each(|entry| *entry *= tensor_rank_0);
379    }
380}
381
382impl<const D: usize, const I: usize> Add for TensorRank1Vec<D, I> {
383    type Output = Self;
384    fn add(mut self, tensor_rank_1_vec: Self) -> Self::Output {
385        self += tensor_rank_1_vec;
386        self
387    }
388}
389
390impl<const D: usize, const I: usize> Add<&Self> for TensorRank1Vec<D, I> {
391    type Output = Self;
392    fn add(mut self, tensor_rank_1_vec: &Self) -> Self::Output {
393        self += tensor_rank_1_vec;
394        self
395    }
396}
397
398impl<const D: usize, const I: usize> AddAssign for TensorRank1Vec<D, I> {
399    fn add_assign(&mut self, tensor_rank_1_vec: Self) {
400        self.iter_mut()
401            .zip(tensor_rank_1_vec.iter())
402            .for_each(|(self_entry, tensor_rank_1)| *self_entry += tensor_rank_1);
403    }
404}
405
406impl<const D: usize, const I: usize> AddAssign<&Self> for TensorRank1Vec<D, I> {
407    fn add_assign(&mut self, tensor_rank_1_vec: &Self) {
408        self.iter_mut()
409            .zip(tensor_rank_1_vec.iter())
410            .for_each(|(self_entry, tensor_rank_1)| *self_entry += tensor_rank_1);
411    }
412}
413
414impl<const D: usize, const I: usize, const J: usize> Mul<TensorRank1Vec<D, J>>
415    for TensorRank1Vec<D, I>
416{
417    type Output = TensorRank2<D, I, J>;
418    fn mul(self, tensor_rank_1_vec: TensorRank1Vec<D, J>) -> Self::Output {
419        self.iter()
420            .zip(tensor_rank_1_vec.iter())
421            .map(|(self_entry, tensor_rank_1_vec_entry)| {
422                TensorRank2::dyad(self_entry, tensor_rank_1_vec_entry)
423            })
424            .sum()
425    }
426}
427
428impl<const D: usize, const I: usize, const J: usize> Mul<&TensorRank1Vec<D, J>>
429    for TensorRank1Vec<D, I>
430{
431    type Output = TensorRank2<D, I, J>;
432    fn mul(self, tensor_rank_1_vec: &TensorRank1Vec<D, J>) -> Self::Output {
433        self.iter()
434            .zip(tensor_rank_1_vec.iter())
435            .map(|(self_entry, tensor_rank_1_vec_entry)| {
436                TensorRank2::dyad(self_entry, tensor_rank_1_vec_entry)
437            })
438            .sum()
439    }
440}
441
442impl<const D: usize, const I: usize, const J: usize> Mul<TensorRank1Vec<D, J>>
443    for &TensorRank1Vec<D, I>
444{
445    type Output = TensorRank2<D, I, J>;
446    fn mul(self, tensor_rank_1_vec: TensorRank1Vec<D, J>) -> Self::Output {
447        self.iter()
448            .zip(tensor_rank_1_vec.iter())
449            .map(|(self_entry, tensor_rank_1_vec_entry)| {
450                TensorRank2::dyad(self_entry, tensor_rank_1_vec_entry)
451            })
452            .sum()
453    }
454}
455
456impl<const D: usize, const I: usize, const J: usize> Mul<&TensorRank1Vec<D, J>>
457    for &TensorRank1Vec<D, I>
458{
459    type Output = TensorRank2<D, I, J>;
460    fn mul(self, tensor_rank_1_vec: &TensorRank1Vec<D, J>) -> Self::Output {
461        self.iter()
462            .zip(tensor_rank_1_vec.iter())
463            .map(|(self_entry, tensor_rank_1_vec_entry)| {
464                TensorRank2::dyad(self_entry, tensor_rank_1_vec_entry)
465            })
466            .sum()
467    }
468}
469
470impl<const D: usize, const I: usize> Sub for TensorRank1Vec<D, I> {
471    type Output = Self;
472    fn sub(mut self, tensor_rank_1_vec: Self) -> Self::Output {
473        self -= tensor_rank_1_vec;
474        self
475    }
476}
477
478impl<const D: usize, const I: usize> Sub<&Self> for TensorRank1Vec<D, I> {
479    type Output = Self;
480    fn sub(mut self, tensor_rank_1_vec: &Self) -> Self::Output {
481        self -= tensor_rank_1_vec;
482        self
483    }
484}
485
486impl<const D: usize, const I: usize> Sub for &TensorRank1Vec<D, I> {
487    type Output = TensorRank1Vec<D, I>;
488    fn sub(self, tensor_rank_1_vec: Self) -> Self::Output {
489        tensor_rank_1_vec
490            .iter()
491            .zip(self.iter())
492            .map(|(tensor_rank_1_vec_a, self_a)| {
493                tensor_rank_1_vec_a
494                    .iter()
495                    .zip(self_a.iter())
496                    .map(|(tensor_rank_1_vec_a_i, self_a_i)| self_a_i - *tensor_rank_1_vec_a_i)
497                    .collect()
498            })
499            .collect()
500    }
501}
502
503impl<const D: usize, const I: usize> SubAssign for TensorRank1Vec<D, I> {
504    fn sub_assign(&mut self, tensor_rank_1_vec: Self) {
505        self.iter_mut()
506            .zip(tensor_rank_1_vec.iter())
507            .for_each(|(self_entry, tensor_rank_1)| *self_entry -= tensor_rank_1);
508    }
509}
510
511impl<const D: usize, const I: usize> SubAssign<&Self> for TensorRank1Vec<D, I> {
512    fn sub_assign(&mut self, tensor_rank_1_vec: &Self) {
513        self.iter_mut()
514            .zip(tensor_rank_1_vec.iter())
515            .for_each(|(self_entry, tensor_rank_1)| *self_entry -= tensor_rank_1);
516    }
517}