use crate::vector::Vector;
use num_traits::{Float, Num};
use std::ops::{Add, Div, Mul, Rem, Sub};
pub trait VectorOps<T> {
fn add_vec(&self, other: &Vector<T>) -> Vector<T>;
fn sub_vec(&self, other: &Vector<T>) -> Vector<T>;
fn mul_vec(&self, other: &Vector<T>) -> Vector<T>;
fn div_vec(&self, other: &Vector<T>) -> Vector<T>;
fn rem_vec(&self, other: &Vector<T>) -> Vector<T>;
fn add_scalar(&self, scalar: T) -> Vector<T>;
fn sub_scalar(&self, scalar: T) -> Vector<T>;
fn mul_scalar(&self, scalar: T) -> Vector<T>;
fn div_scalar(&self, scalar: T) -> Vector<T>;
fn rem_scalar(&self, scalar: T) -> Vector<T>;
}
impl<T> VectorOps<T> for Vector<T>
where
T: Num + Copy + PartialOrd + Float,
{
fn add_vec(&self, other: &Vector<T>) -> Vector<T> {
assert_eq!(
self.len(),
other.len(),
"Vectors must be of the same length for addition."
);
let data = self
.iter()
.zip(other.iter())
.map(|(&a, &b)| a + b)
.collect();
Vector::new(data)
}
fn sub_vec(&self, other: &Vector<T>) -> Vector<T> {
assert_eq!(
self.len(),
other.len(),
"Vectors must be of the same length for subtraction."
);
let data = self
.iter()
.zip(other.iter())
.map(|(&a, &b)| a - b)
.collect();
Vector::new(data)
}
fn mul_vec(&self, other: &Vector<T>) -> Vector<T> {
assert_eq!(
self.len(),
other.len(),
"Vectors must be of the same length for multiplication."
);
let data = self
.iter()
.zip(other.iter())
.map(|(&a, &b)| a * b)
.collect();
Vector::new(data)
}
fn div_vec(&self, other: &Vector<T>) -> Vector<T> {
assert_eq!(
self.len(),
other.len(),
"Vectors must be of the same length for division."
);
let data = self
.iter()
.zip(other.iter())
.map(|(&a, &b)| a / b)
.collect();
Vector::new(data)
}
fn rem_vec(&self, other: &Vector<T>) -> Vector<T> {
assert_eq!(
self.len(),
other.len(),
"Vectors must be of the same length for modulus."
);
let data = self
.iter()
.zip(other.iter())
.map(|(&a, &b)| a % b)
.collect();
Vector::new(data)
}
fn add_scalar(&self, scalar: T) -> Vector<T> {
let data = self.iter().map(|&x| x + scalar).collect();
Vector::new(data)
}
fn sub_scalar(&self, scalar: T) -> Vector<T> {
let data = self.iter().map(|&x| x - scalar).collect();
Vector::new(data)
}
fn mul_scalar(&self, scalar: T) -> Vector<T> {
let data = self.iter().map(|&x| x * scalar).collect();
Vector::new(data)
}
fn div_scalar(&self, scalar: T) -> Vector<T> {
let data = self.iter().map(|&x| x / scalar).collect();
Vector::new(data)
}
fn rem_scalar(&self, scalar: T) -> Vector<T> {
let data = self.iter().map(|&x| x % scalar).collect();
Vector::new(data)
}
}
impl<T> Add for &Vector<T>
where
T: Num + Copy + PartialOrd + Float,
{
type Output = Vector<T>;
fn add(self, rhs: &Vector<T>) -> Vector<T> {
self.add_vec(rhs)
}
}
impl<T> Sub for &Vector<T>
where
T: Num + Copy + PartialOrd + Float,
{
type Output = Vector<T>;
fn sub(self, rhs: &Vector<T>) -> Vector<T> {
self.sub_vec(rhs)
}
}
impl<T> Mul for &Vector<T>
where
T: Num + Copy + PartialOrd + Float,
{
type Output = Vector<T>;
fn mul(self, rhs: &Vector<T>) -> Vector<T> {
self.mul_vec(rhs)
}
}
impl<T> Div for &Vector<T>
where
T: Num + Copy + PartialOrd + Float,
{
type Output = Vector<T>;
fn div(self, rhs: &Vector<T>) -> Vector<T> {
self.div_vec(rhs)
}
}
impl<T> Rem for &Vector<T>
where
T: Num + Copy + PartialOrd + Float,
{
type Output = Vector<T>;
fn rem(self, rhs: &Vector<T>) -> Vector<T> {
self.rem_vec(rhs)
}
}