linearalgebra/vector/
vec_ops.rs

1use std::ops::{Mul, Add, Sub};
2
3use crate::numlib::Zero;
4
5use super::Vector;
6
7impl<T: Copy> Vector<T> {
8    pub fn apply<F: Fn(&T) -> T>(&mut self, f: F) {
9        for val in &mut self.data {
10            *val = f(val);
11        }
12    }
13}
14
15impl<T: Copy + Mul<T, Output = T>> Vector<T> {
16    pub fn scale(&self, scalar: T) -> Vector<T> {
17        let mut res = self.data.to_vec();
18
19        for val in &mut res {
20            *val = (*val) * scalar;
21        }
22
23        Vector::new(res)
24    }
25}
26
27impl<T: Copy + Add<T, Output = T>> Vector<T> {
28    pub fn add(&self, other: &Vector<T>) -> Result<Vector<T>, &'static str> {
29        let to_add = other.as_vec();
30        if other.size != self.size {
31            return Err("Vectors don't match in size");
32        }
33        let mut res = self.data.to_vec();
34        for index in 0..self.size {
35            if let Some(elem) = res.get_mut(index) {
36                // Unreachable since they have the same size and thus all indexes we loop through are
37                // Also present in to_add
38                *elem = *elem
39                    + match to_add.get(index) {
40                        Some(value) => *value,
41                        None => unreachable!(),
42                    };
43            }
44        }
45
46        Ok(Vector::new(res))
47    }
48}
49
50impl<T: Copy + Sub<T, Output = T>> Vector<T> {
51    pub fn sub(&self, other: &Vector<T>) -> Result<Vector<T>, &'static str> {
52        let to_add = other.as_vec();
53        if other.size != self.size {
54            return Err("Vectors don't match in size");
55        }
56        let mut res = self.data.to_vec();
57        for index in 0..self.size {
58            if let Some(elem) = res.get_mut(index) {
59                // None is unreachable since they have the same size and thus all indexes we loop through are
60                // Also present in to_add
61                *elem = *elem
62                    - match to_add.get(index) {
63                        Some(value) => *value,
64                        None => unreachable!(),
65                    };
66            }
67        }
68
69        Ok(Vector::new(res))
70    }
71}
72
73impl<T: Copy + Zero + Add<T, Output = T> + Mul<T, Output = T>> Vector<T> {
74    pub fn dot(&self, other: &Vector<T>) -> Result<T, &'static str> {
75        if self.size != other.size {
76            return Err("Vectors don't match in size");
77        }
78
79        let mut res = T::zero();
80
81        if self.size == 0 {
82            return Ok(res);
83        }
84
85        for index in 0..self.size {
86            if let Some(elem) = self.data.get(index) {
87                // None is unreachable since they have the same size and thus all indexes we loop through are
88                // Also present in to_add
89                res = res
90                    + (*elem
91                        * match other.data.get(index) {
92                            Some(value) => *value,
93                            None => unreachable!(),
94                        });
95            }
96        }
97
98        Ok(res)
99    }
100}
101
102impl Vector<f64> {
103    pub fn abs(&self) -> f64 {
104        self.dot(&self).unwrap().sqrt()
105    }
106}