use crate::mat::{Matrix, Vector};
use num_traits::identities::{One, Zero};
use std::convert::From;
use std::ops::{Add, AddAssign, Div, Index, IndexMut, Mul, Neg, Sub, SubAssign};
impl<T> Add for &Vector<T>
where
T: Add<Output = T> + Clone + Copy,
{
type Output = Vector<T>;
fn add(self, vector: &Vector<T>) -> Self::Output {
if self.dims != vector.dims {
panic!("The Vectors need to have the same dimensions.");
} else {
let mut e = self.clone().entries;
for i in 0..self.entries.len() {
e[i] = e[i] + vector[i];
}
Vector::<T> {
dims: self.dims,
entries: e,
}
}
}
}
impl<T> AddAssign<&Vector<T>> for Vector<T>
where
T: Add<Output = T> + Clone + Copy,
{
fn add_assign(&mut self, vector: &Vector<T>) {
let v = &self.clone() + vector;
self.entries = v.entries;
}
}
impl<T> Sub for &Vector<T>
where
T: Sub<Output = T> + Zero + One + Copy + Clone,
{
type Output = Vector<T>;
fn sub(self, vector: &Vector<T>) -> Self::Output {
self + &(vector * (T::zero() - T::one()))
}
}
impl<T> SubAssign<&Vector<T>> for Vector<T>
where
T: Sub<Output = T> + Zero + One + Copy + Clone,
{
fn sub_assign(&mut self, vector: &Vector<T>) {
let v = &self.clone() - vector;
self.entries = v.entries;
}
}
impl<T> Neg for &Vector<T>
where
T: Sub<Output = T> + One + Zero + Clone + Copy,
{
type Output = Vector<T>;
fn neg(self) -> Self::Output {
&Vector::new(self.get_size(), T::zero()) - &self.clone()
}
}
impl<T> Mul for &Vector<T>
where
T: Mul<Output = T> + Clone + Copy + Zero,
{
type Output = T;
fn mul(self, vec: &Vector<T>) -> Self::Output {
if self.entries.len() != vec.entries.len() {
panic!("Vectors need to be the same length.");
}
let mut sum: T = T::zero();
for i in 0..self.entries.len() {
sum = sum + (self[i] * vec[i]);
}
sum
}
}
impl<T> Mul<&Matrix<T>> for &Vector<T>
where
T: One + Zero + Copy + Clone,
{
type Output = Vector<T>;
fn mul(self, mat: &Matrix<T>) -> Self::Output {
let vec: Vector<T> = self.clone();
let mat_v: Matrix<T> = vec.into();
let res = &mat_v * mat;
res.into()
}
}
impl<T> Mul<T> for &Vector<T>
where
T: Mul<Output = T> + Clone + Zero + Copy,
{
type Output = Vector<T>;
fn mul(self, scalar: T) -> Self::Output {
let mut vec = Vec::<T>::new();
for i in 0..self.entries.len() {
vec.push(self[i] * scalar);
}
Vector::from(vec)
}
}
impl<T> Div<T> for &Vector<T>
where
T: Div<Output = T> + Mul<Output = T> + Clone + Zero + Copy + One,
{
type Output = Vector<T>;
fn div(self, divisor: T) -> Self::Output {
self * (T::one() / divisor)
}
}
impl<T> Index<usize> for Vector<T> {
type Output = T;
fn index(&self, idx: usize) -> &Self::Output {
&self.entries[idx]
}
}
impl<T> IndexMut<usize> for Vector<T> {
fn index_mut(&mut self, idx: usize) -> &mut Self::Output {
&mut self.entries[idx]
}
}