use crate::{Dot};
use crate::Init;
use crate::matrix::Matrix;
use impl_ops::*;
use std::ops;
pub struct Vector {
array : Vec<f64>,
}
impl Vector {
#[inline]
pub fn from(array: Vec<f64>) -> Vector {
Vector { array }
}
#[inline]
pub fn empty() -> Vector {
Vector { array : Vec::new() }
}
#[inline]
pub fn iter(&self) -> std::slice::Iter<'_, f64> {
self.array.iter()
}
#[inline]
pub fn iter_mut(&mut self) -> std::slice::IterMut<'_,f64> {
self.array.iter_mut()
}
#[inline]
pub fn len(&self) -> usize {
self.array.len()
}
pub fn into_vec(&self) -> Vec<f64> {
self.array.clone()
}
pub fn to_vec(&self) -> &Vec<f64> {
&self.array
}
}
impl Init for Vector {
type Output = Vector;
type Size = usize;
fn init(value: f64, size: Self::Size) -> Self::Output {
Vector { array : vec![value; size] }
}
fn init_func<F>(func: F, size: Self::Size) -> Self::Output
where F: Fn(Self::Size) -> f64 {
Vector {
array : (0..size).map(func).collect(),
}
}
}
impl std::clone::Clone for Vector {
fn clone(&self) -> Self {
Vector { array : self.array.clone() }
}
}
impl Dot<Vector> for Vector {
type Output = f64;
fn dot(&self, rhs: &Vector) -> Self::Output {
assert_eq!(self.len(), rhs.len());
self.array.iter()
.zip(rhs.array.iter())
.map(|(x,y)| x*y)
.sum()
}
}
impl Dot<Matrix> for Vector {
type Output = Vector;
fn dot(&self, rhs: &Matrix) -> Self::Output {
rhs.transpose().dot(self)
}
}
impl std::ops::Index<usize> for Vector {
type Output = f64;
#[inline]
fn index(&self, index: usize) -> &Self::Output {
&self.array[index]
}
}
impl std::ops::IndexMut<usize> for Vector {
#[inline]
fn index_mut(&mut self, index: usize) -> &mut Self::Output {
&mut self.array[index]
}
}
impl std::ops::Neg for Vector {
type Output = Vector;
fn neg(self) -> Self::Output {
Vector::from(self.iter().map(|x| -x).collect())
}
}
impl std::ops::Neg for &Vector {
type Output = Vector;
fn neg(self) -> Self::Output {
Vector::from(self.iter().map(|x| -x).collect())
}
}
macro_rules! impl_operator {
( $($op:tt),* ) => {
$(
impl_op_ex!($op |a: &Vector, b: &Vector| -> Vector {
Vector::from(a.iter()
.zip(b.iter())
.map(|(x,y)| x $op y)
.collect()
)
});
impl_op_ex!($op |a: &Vector, k: &f64| -> Vector {
Vector::from(a.iter()
.map(|x| x $op k)
.collect()
)
});
)*
}
}
macro_rules! impl_operator_assign {
( $($op:tt),* ) => {
$(
impl_op_ex!($op |a: &mut Vector, b: &Vector| {
a.iter_mut().zip(b.iter())
.for_each(|(x,y)| *x $op y);
});
impl_op_ex!($op |a: &mut Vector, k: &f64| {
a.iter_mut().for_each(|x| *x $op k);
});
)*
}
}
impl_operator![+, -, *, /];
impl_operator_assign![+=, -=, *=, /=];