conspire/math/matrix/vector/
mod.rs

1#[cfg(test)]
2use crate::math::test::ErrorTensor;
3
4use crate::math::{
5    Jacobian, Matrix, Solution, Tensor, TensorRank0, TensorRank1Vec, TensorRank2, TensorVec,
6    write_tensor_rank_0,
7};
8use std::{
9    fmt::{Display, Formatter, Result},
10    ops::{
11        Add, AddAssign, Div, DivAssign, Index, IndexMut, Mul, MulAssign, RangeFrom, RangeTo, Sub,
12        SubAssign,
13    },
14    vec::IntoIter,
15};
16
17/// A vector.
18#[derive(Clone, Debug, PartialEq)]
19pub struct Vector(Vec<TensorRank0>);
20
21impl Vector {
22    pub fn as_slice(&self) -> &[TensorRank0] {
23        self.0.as_slice()
24    }
25    pub fn ones(len: usize) -> Self {
26        Self(vec![1.0; len])
27    }
28}
29
30#[cfg(test)]
31impl ErrorTensor for Vector {
32    fn error(
33        &self,
34        comparator: &Self,
35        tol_abs: &TensorRank0,
36        tol_rel: &TensorRank0,
37    ) -> Option<usize> {
38        let error_count = self
39            .iter()
40            .zip(comparator.iter())
41            .map(|(entry, comparator_entry)| {
42                entry
43                    .iter()
44                    .zip(comparator_entry.iter())
45                    .filter(|&(&entry_i, &comparator_entry_i)| {
46                        &(entry_i - comparator_entry_i).abs() >= tol_abs
47                            && &(entry_i / comparator_entry_i - 1.0).abs() >= tol_rel
48                    })
49                    .count()
50            })
51            .sum();
52        if error_count > 0 {
53            Some(error_count)
54        } else {
55            None
56        }
57    }
58    fn error_fd(&self, comparator: &Self, epsilon: &TensorRank0) -> Option<(bool, usize)> {
59        let error_count = self
60            .iter()
61            .zip(comparator.iter())
62            .map(|(entry, comparator_entry)| {
63                entry
64                    .iter()
65                    .zip(comparator_entry.iter())
66                    .filter(|&(&entry_i, &comparator_entry_i)| {
67                        &(entry_i / comparator_entry_i - 1.0).abs() >= epsilon
68                            && (&entry_i.abs() >= epsilon || &comparator_entry_i.abs() >= epsilon)
69                    })
70                    .count()
71            })
72            .sum();
73        if error_count > 0 {
74            let auxillary = self
75                .iter()
76                .zip(comparator.iter())
77                .map(|(entry, comparator_entry)| {
78                    entry
79                        .iter()
80                        .zip(comparator_entry.iter())
81                        .filter(|&(&entry_i, &comparator_entry_i)| {
82                            &(entry_i / comparator_entry_i - 1.0).abs() >= epsilon
83                                && &(entry_i - comparator_entry_i).abs() >= epsilon
84                                && (&entry_i.abs() >= epsilon
85                                    || &comparator_entry_i.abs() >= epsilon)
86                        })
87                        .count()
88                })
89                .sum::<usize>()
90                > 0;
91            Some((auxillary, error_count))
92        } else {
93            None
94        }
95    }
96}
97
98impl Display for Vector {
99    fn fmt(&self, f: &mut Formatter) -> Result {
100        write!(f, "\x1B[s")?;
101        write!(f, "[")?;
102        self.0.chunks(5).enumerate().try_for_each(|(i, chunk)| {
103            chunk
104                .iter()
105                .try_for_each(|entry| write_tensor_rank_0(f, entry))?;
106            if (i + 1) * 5 < self.len() {
107                writeln!(f, "\x1B[2D,")?;
108                write!(f, "\x1B[u")?;
109                write!(f, "\x1B[{}B ", i + 1)?;
110            }
111            Ok(())
112        })?;
113        write!(f, "\x1B[2D]")?;
114        Ok(())
115    }
116}
117
118impl<const D: usize, const I: usize> From<TensorRank1Vec<D, I>> for Vector {
119    fn from(tensor_rank_1_vec: TensorRank1Vec<D, I>) -> Self {
120        tensor_rank_1_vec.into_iter().flatten().collect()
121    }
122}
123
124impl<const D: usize, const I: usize, const J: usize> From<TensorRank2<D, I, J>> for Vector {
125    fn from(tensor_rank_2: TensorRank2<D, I, J>) -> Self {
126        tensor_rank_2.into_iter().flatten().collect()
127    }
128}
129
130impl FromIterator<TensorRank0> for Vector {
131    fn from_iter<Ii: IntoIterator<Item = TensorRank0>>(into_iterator: Ii) -> Self {
132        Self(Vec::from_iter(into_iterator))
133    }
134}
135
136impl Index<usize> for Vector {
137    type Output = TensorRank0;
138    fn index(&self, index: usize) -> &Self::Output {
139        &self.0[index]
140    }
141}
142
143impl Index<RangeTo<usize>> for Vector {
144    type Output = [TensorRank0];
145    fn index(&self, indices: RangeTo<usize>) -> &Self::Output {
146        &self.0[indices]
147    }
148}
149
150impl Index<RangeFrom<usize>> for Vector {
151    type Output = [TensorRank0];
152    fn index(&self, indices: RangeFrom<usize>) -> &Self::Output {
153        &self.0[indices]
154    }
155}
156
157impl IndexMut<usize> for Vector {
158    fn index_mut(&mut self, index: usize) -> &mut Self::Output {
159        &mut self.0[index]
160    }
161}
162
163impl Tensor for Vector {
164    type Item = TensorRank0;
165    fn iter(&self) -> impl Iterator<Item = &Self::Item> {
166        self.0.iter()
167    }
168    fn iter_mut(&mut self) -> impl Iterator<Item = &mut Self::Item> {
169        self.0.iter_mut()
170    }
171}
172
173impl Solution for Vector {
174    fn decrement_from_chained(&mut self, other: &mut Self, vector: Vector) {
175        self.iter_mut()
176            .chain(other.iter_mut())
177            .zip(vector)
178            .for_each(|(entry_i, vector_i)| *entry_i -= vector_i)
179    }
180}
181
182impl Jacobian for Vector {
183    fn fill_into(self, vector: &mut Vector) {
184        self.into_iter()
185            .zip(vector.iter_mut())
186            .for_each(|(self_i, vector_i)| *vector_i = self_i)
187    }
188    fn fill_into_chained(self, other: Self, vector: &mut Self) {
189        self.into_iter()
190            .chain(other)
191            .zip(vector.iter_mut())
192            .for_each(|(entry_i, vector_i)| *vector_i = entry_i)
193    }
194}
195
196impl IntoIterator for Vector {
197    type Item = TensorRank0;
198    type IntoIter = IntoIter<Self::Item>;
199    fn into_iter(self) -> Self::IntoIter {
200        self.0.into_iter()
201    }
202}
203
204impl TensorVec for Vector {
205    type Item = TensorRank0;
206    type Slice<'a> = &'a [TensorRank0];
207    fn append(&mut self, other: &mut Self) {
208        self.0.append(&mut other.0)
209    }
210    fn is_empty(&self) -> bool {
211        self.0.is_empty()
212    }
213    fn len(&self) -> usize {
214        self.0.len()
215    }
216    fn new(slice: Self::Slice<'_>) -> Self {
217        slice.iter().copied().collect()
218    }
219    fn push(&mut self, item: Self::Item) {
220        self.0.push(item)
221    }
222    fn zero(len: usize) -> Self {
223        Self(vec![0.0; len])
224    }
225}
226
227impl Div<TensorRank0> for Vector {
228    type Output = Self;
229    fn div(mut self, tensor_rank_0: TensorRank0) -> Self::Output {
230        self /= &tensor_rank_0;
231        self
232    }
233}
234
235impl Div<&TensorRank0> for Vector {
236    type Output = Self;
237    fn div(mut self, tensor_rank_0: &TensorRank0) -> Self::Output {
238        self /= tensor_rank_0;
239        self
240    }
241}
242
243impl DivAssign<TensorRank0> for Vector {
244    fn div_assign(&mut self, tensor_rank_0: TensorRank0) {
245        self.iter_mut().for_each(|entry| *entry /= &tensor_rank_0);
246    }
247}
248
249impl DivAssign<&TensorRank0> for Vector {
250    fn div_assign(&mut self, tensor_rank_0: &TensorRank0) {
251        self.iter_mut().for_each(|entry| *entry /= tensor_rank_0);
252    }
253}
254
255impl Mul<TensorRank0> for Vector {
256    type Output = Self;
257    fn mul(mut self, tensor_rank_0: TensorRank0) -> Self::Output {
258        self *= &tensor_rank_0;
259        self
260    }
261}
262
263impl Mul<&TensorRank0> for Vector {
264    type Output = Self;
265    fn mul(mut self, tensor_rank_0: &TensorRank0) -> Self::Output {
266        self *= tensor_rank_0;
267        self
268    }
269}
270
271impl Mul<&TensorRank0> for &Vector {
272    type Output = Vector;
273    fn mul(self, tensor_rank_0: &TensorRank0) -> Self::Output {
274        self.iter().map(|self_i| self_i * tensor_rank_0).collect()
275    }
276}
277
278impl MulAssign<TensorRank0> for Vector {
279    fn mul_assign(&mut self, tensor_rank_0: TensorRank0) {
280        self.iter_mut().for_each(|entry| *entry *= &tensor_rank_0);
281    }
282}
283
284impl MulAssign<&TensorRank0> for Vector {
285    fn mul_assign(&mut self, tensor_rank_0: &TensorRank0) {
286        self.iter_mut().for_each(|entry| *entry *= tensor_rank_0);
287    }
288}
289
290impl Add for Vector {
291    type Output = Self;
292    fn add(mut self, vector: Self) -> Self::Output {
293        self += vector;
294        self
295    }
296}
297
298impl Add<&Self> for Vector {
299    type Output = Self;
300    fn add(mut self, vector: &Self) -> Self::Output {
301        self += vector;
302        self
303    }
304}
305
306impl AddAssign for Vector {
307    fn add_assign(&mut self, vector: Self) {
308        self.iter_mut()
309            .zip(vector.iter())
310            .for_each(|(self_entry, tensor_rank_0)| *self_entry += tensor_rank_0);
311    }
312}
313
314impl AddAssign<&Self> for Vector {
315    fn add_assign(&mut self, vector: &Self) {
316        self.iter_mut()
317            .zip(vector.iter())
318            .for_each(|(self_entry, tensor_rank_0)| *self_entry += tensor_rank_0);
319    }
320}
321
322impl Mul for Vector {
323    type Output = TensorRank0;
324    fn mul(self, vector: Self) -> Self::Output {
325        self.iter()
326            .zip(vector.iter())
327            .map(|(self_i, vector_i)| self_i * vector_i)
328            .sum()
329    }
330}
331
332impl Mul<&Self> for Vector {
333    type Output = TensorRank0;
334    fn mul(self, vector: &Self) -> Self::Output {
335        self.iter()
336            .zip(vector.iter())
337            .map(|(self_i, vector_i)| self_i * vector_i)
338            .sum()
339    }
340}
341
342impl Mul for &Vector {
343    type Output = TensorRank0;
344    fn mul(self, vector: Self) -> Self::Output {
345        self.iter()
346            .zip(vector.iter())
347            .map(|(self_i, vector_i)| self_i * vector_i)
348            .sum()
349    }
350}
351
352impl Sub for Vector {
353    type Output = Self;
354    fn sub(mut self, vector: Self) -> Self::Output {
355        self -= vector;
356        self
357    }
358}
359
360impl Sub<&Self> for Vector {
361    type Output = Self;
362    fn sub(mut self, vector: &Self) -> Self::Output {
363        self -= vector;
364        self
365    }
366}
367
368impl Sub<Vector> for &Vector {
369    type Output = Vector;
370    fn sub(self, mut vector: Vector) -> Self::Output {
371        vector
372            .iter_mut()
373            .zip(self.iter())
374            .for_each(|(vector_i, self_i)| *vector_i = self_i - *vector_i);
375        vector
376    }
377}
378
379impl SubAssign for Vector {
380    fn sub_assign(&mut self, vector: Self) {
381        self.iter_mut()
382            .zip(vector.iter())
383            .for_each(|(self_entry, tensor_rank_1)| *self_entry -= tensor_rank_1);
384    }
385}
386
387impl SubAssign<&Self> for Vector {
388    fn sub_assign(&mut self, vector: &Self) {
389        self.iter_mut()
390            .zip(vector.iter())
391            .for_each(|(self_entry, tensor_rank_1)| *self_entry -= tensor_rank_1);
392    }
393}
394
395impl SubAssign<&[TensorRank0]> for Vector {
396    fn sub_assign(&mut self, slice: &[TensorRank0]) {
397        self.iter_mut()
398            .zip(slice.iter())
399            .for_each(|(self_entry, tensor_rank_1)| *self_entry -= tensor_rank_1);
400    }
401}
402
403impl Mul<&Matrix> for &Vector {
404    type Output = Vector;
405    fn mul(self, matrix: &Matrix) -> Self::Output {
406        let mut output = Vector::zero(matrix.width());
407        self.iter()
408            .zip(matrix.iter())
409            .for_each(|(self_i, matrix_i)| {
410                output
411                    .iter_mut()
412                    .zip(matrix_i.iter())
413                    .for_each(|(output_j, matrix_ij)| *output_j += self_i * matrix_ij)
414            });
415        output
416    }
417}
418
419impl<const D: usize, const I: usize> Mul<&TensorRank1Vec<D, I>> for &Vector {
420    type Output = TensorRank0;
421    fn mul(self, tensor_rank_1_vec: &TensorRank1Vec<D, I>) -> Self::Output {
422        tensor_rank_1_vec
423            .iter()
424            .enumerate()
425            .map(|(a, entry_a)| {
426                entry_a
427                    .iter()
428                    .enumerate()
429                    .map(|(i, entry_a_i)| self[D * a + i] * entry_a_i)
430                    .sum::<TensorRank0>()
431            })
432            .sum()
433    }
434}
435
436impl<const D: usize, const I: usize, const J: usize> Mul<&TensorRank2<D, I, J>> for &Vector {
437    type Output = TensorRank0;
438    fn mul(self, tensor_rank_2: &TensorRank2<D, I, J>) -> Self::Output {
439        tensor_rank_2
440            .iter()
441            .enumerate()
442            .map(|(i, entry_i)| {
443                entry_i
444                    .iter()
445                    .enumerate()
446                    .map(|(j, entry_ij)| self[D * i + j] * entry_ij)
447                    .sum::<TensorRank0>()
448            })
449            .sum()
450    }
451}