devela/num/geom/linear/vector/vec/
ops.rs

1// devela::num::geom::linear::vector::vec::ops
2//
3//! implement overloadable operators
4//
5
6#![allow(clippy::needless_range_loop)]
7
8use crate::{
9    data::Vec,
10    num::{NumError::MismatchedSizes, NumResult as Result, VecVector},
11};
12use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Sub, SubAssign};
13
14/* ops between vectors */
15
16impl<T: Clone + Add<Output = T>> VecVector<T> {
17    /// Adds two vectors together
18    /// # Errors
19    /// Returns [`MismatchedSizes`] if `self and `other` don't have the same length.
20    pub fn clone_add(&self, other: &Self) -> Result<Self> {
21        if self.coords.len() != other.coords.len() {
22            Err(MismatchedSizes)
23        } else {
24            let mut coords = Vec::with_capacity(self.coords.len());
25            for i in 0..self.coords.len() {
26                coords.push(self.coords[i].clone() + other.coords[i].clone());
27            }
28            Ok(VecVector { coords })
29        }
30    }
31}
32impl<T: Clone + Add<Output = T>> Add for VecVector<T> {
33    type Output = Result<Self>;
34    fn add(self, other: Self) -> Self::Output {
35        Self::clone_add(&self, &other)
36    }
37}
38impl<T: Clone + Add<Output = T>> AddAssign<&Self> for VecVector<T> {
39    /// # Panics
40    /// Panics if `self` and `other` don't have the same size.
41    fn add_assign(&mut self, other: &Self) {
42        *self = Self::clone_add(self, other).unwrap();
43    }
44}
45
46impl<T: Clone + Sub<Output = T>> VecVector<T> {
47    /// Subtracts two vectors together.
48    /// # Errors
49    /// Returns [`MismatchedSizes`] if `self and `other` don't have the same length.
50    pub fn clone_sub(&self, other: &Self) -> Result<Self> {
51        if self.coords.len() != other.coords.len() {
52            Err(MismatchedSizes)
53        } else {
54            let mut coords = Vec::with_capacity(self.coords.len());
55            for i in 0..self.coords.len() {
56                coords.push(self.coords[i].clone() - other.coords[i].clone());
57            }
58            Ok(VecVector { coords })
59        }
60    }
61}
62impl<T: Clone + Sub<Output = T>> Sub for VecVector<T> {
63    type Output = Result<Self>;
64    fn sub(self, other: Self) -> Self::Output {
65        Self::clone_sub(&self, &other)
66    }
67}
68impl<T: Clone + Sub<Output = T>> SubAssign<&Self> for VecVector<T> {
69    /// # Panics
70    /// Panics if `self` and `other` don't have the same size.
71    fn sub_assign(&mut self, other: &Self) {
72        *self = Self::clone_sub(self, other).unwrap();
73    }
74}
75
76/* ops between vectors and scalars */
77
78impl<T: Clone + Mul<Output = T>> VecVector<T> {
79    /// Multiplies a vector by a scalar.
80    pub fn clone_mul_scalar(&self, scalar: &T) -> Self {
81        let mut coords = Vec::with_capacity(self.coords.len());
82        for item in &self.coords {
83            coords.push(item.clone() * scalar.clone());
84        }
85        VecVector { coords }
86    }
87}
88impl<T: Clone + Mul<Output = T>> Mul<T> for VecVector<T> {
89    type Output = Self;
90    fn mul(self, scalar: T) -> Self::Output {
91        Self::clone_mul_scalar(&self, &scalar)
92    }
93}
94impl<T: Clone + Mul<Output = T>> MulAssign<T> for VecVector<T> {
95    fn mul_assign(&mut self, scalar: T) {
96        *self = Self::clone_mul_scalar(self, &scalar);
97    }
98}
99impl<T: Clone + Mul<Output = T>> Mul<&T> for VecVector<T> {
100    type Output = Self;
101    fn mul(self, scalar: &T) -> Self::Output {
102        Self::clone_mul_scalar(&self, scalar)
103    }
104}
105impl<T: Clone + Mul<Output = T>> MulAssign<&T> for VecVector<T> {
106    fn mul_assign(&mut self, scalar: &T) {
107        *self = Self::clone_mul_scalar(self, scalar);
108    }
109}
110
111impl<T: Clone + Div<Output = T>> VecVector<T> {
112    /// Divides a vector by a scalar.
113    pub fn clone_div_scalar(&self, scalar: &T) -> Self {
114        let mut coords = Vec::with_capacity(self.coords.len());
115        for item in &self.coords {
116            coords.push(item.clone() / scalar.clone());
117        }
118        VecVector { coords }
119    }
120}
121impl<T: Clone + Div<Output = T>> Div<T> for VecVector<T> {
122    type Output = Self;
123    fn div(self, scalar: T) -> Self::Output {
124        Self::clone_div_scalar(&self, &scalar)
125    }
126}
127impl<T: Clone + Div<Output = T>> DivAssign<T> for VecVector<T> {
128    fn div_assign(&mut self, scalar: T) {
129        *self = Self::clone_div_scalar(self, &scalar);
130    }
131}
132impl<T: Clone + Div<Output = T>> Div<&T> for VecVector<T> {
133    type Output = Self;
134    fn div(self, scalar: &T) -> Self::Output {
135        Self::clone_div_scalar(&self, scalar)
136    }
137}
138impl<T: Clone + Div<Output = T>> DivAssign<&T> for VecVector<T> {
139    fn div_assign(&mut self, scalar: &T) {
140        *self = Self::clone_div_scalar(self, scalar);
141    }
142}