use std::ops::{Mul, Add, Div, Sub, Index, Neg};
use libnum::{One, Zero, Float, FromPrimitive};
use std::cmp::PartialEq;
use linalg::Metric;
use linalg::utils;
pub struct Vector<T> {
size: usize,
data: Vec<T>,
}
impl<T> Vector<T> {
pub fn new(data: Vec<T>) -> Vector<T> {
let size = data.len();
Vector {
size: size,
data: data,
}
}
pub fn size(&self) -> usize {
self.size
}
pub fn data(&self) -> &Vec<T> {
&self.data
}
pub fn into_vec(self) -> Vec<T> {
self.data
}
pub fn any<F>(&self, f: F) -> bool
where F: FnMut(&T) -> bool
{
self.data.iter().any(f)
}
}
impl<T: Clone> Clone for Vector<T> {
fn clone(&self) -> Vector<T> {
Vector {
size: self.size,
data: self.data.clone(),
}
}
}
impl<T: Copy> Vector<T> {
pub fn apply(self, f: &Fn(T) -> T) -> Vector<T> {
let new_data = self.data.into_iter().map(f).collect();
Vector {
size: self.size,
data: new_data,
}
}
}
impl<T: Copy + PartialOrd> Vector<T> {
pub fn argmax(&self) -> (usize, T) {
utils::argmax(&self.data)
}
pub fn argmin(&self) -> (usize, T) {
utils::argmin(&self.data)
}
pub fn select(&self, idxs: &[usize]) -> Vector<T> {
let mut new_data = Vec::with_capacity(idxs.len());
for idx in idxs.into_iter() {
new_data.push(self[*idx]);
}
Vector::new(new_data)
}
}
impl<T: Zero + One + Copy> Vector<T> {
pub fn zeros(size: usize) -> Vector<T> {
Vector {
size: size,
data: vec![T::zero(); size],
}
}
pub fn ones(size: usize) -> Vector<T> {
Vector {
size: size,
data: vec![T::one(); size],
}
}
}
impl<T: Copy + One + Zero + Mul<T, Output = T> + Add<T, Output = T>> Vector<T> {
pub fn dot(&self, v: &Vector<T>) -> T {
utils::dot(&self.data, &v.data)
}
}
impl<T: Copy + Zero + Add<T, Output = T>> Vector<T> {
pub fn sum(&self) -> T {
utils::unrolled_sum(&self.data[..])
}
}
impl<T: Copy + Zero + Mul<T, Output = T>> Vector<T> {
pub fn elemul(&self, v: &Vector<T>) -> Vector<T> {
assert_eq!(self.size, v.size);
Vector::new(utils::ele_mul(&self.data, &v.data))
}
}
impl<T: Copy + Zero + Div<T, Output = T>> Vector<T> {
pub fn elediv(&self, v: &Vector<T>) -> Vector<T> {
assert_eq!(self.size, v.size);
Vector::new(utils::ele_div(&self.data, &v.data))
}
}
impl<T: Copy + Zero + Float + FromPrimitive> Vector<T> {
pub fn mean(&self) -> T {
let sum = self.sum();
sum / FromPrimitive::from_usize(self.size()).unwrap()
}
pub fn variance(&self) -> T {
let m = self.mean();
let mut var = T::zero();
for u in &self.data {
var = var + (*u - m) * (*u - m);
}
var / FromPrimitive::from_usize(self.size() - 1).unwrap()
}
}
impl<T: Copy + One + Zero + Mul<T, Output = T>> Mul<T> for Vector<T> {
type Output = Vector<T>;
fn mul(self, f: T) -> Vector<T> {
(&self) * (&f)
}
}
impl<'a, T: Copy + One + Zero + Mul<T, Output = T>> Mul<T> for &'a Vector<T> {
type Output = Vector<T>;
fn mul(self, f: T) -> Vector<T> {
self * (&f)
}
}
impl<'a, T: Copy + One + Zero + Mul<T, Output = T>> Mul<&'a T> for Vector<T> {
type Output = Vector<T>;
fn mul(self, f: &T) -> Vector<T> {
(&self) * f
}
}
impl<'a, 'b, T: Copy + One + Zero + Mul<T, Output = T>> Mul<&'b T> for &'a Vector<T> {
type Output = Vector<T>;
fn mul(self, f: &T) -> Vector<T> {
let new_data = self.data.iter().map(|v| (*v) * (*f)).collect();
Vector {
size: self.size,
data: new_data,
}
}
}
impl<T: Copy + One + Zero + PartialEq + Div<T, Output = T>> Div<T> for Vector<T> {
type Output = Vector<T>;
fn div(self, f: T) -> Vector<T> {
(&self) / (&f)
}
}
impl<'a, T: Copy + One + Zero + PartialEq + Div<T, Output = T>> Div<T> for &'a Vector<T> {
type Output = Vector<T>;
fn div(self, f: T) -> Vector<T> {
self / (&f)
}
}
impl<'a, T: Copy + One + Zero + PartialEq + Div<T, Output = T>> Div<&'a T> for Vector<T> {
type Output = Vector<T>;
fn div(self, f: &T) -> Vector<T> {
(&self) / f
}
}
impl<'a, 'b, T: Copy + One + Zero + PartialEq + Div<T, Output = T>> Div<&'b T> for &'a Vector<T> {
type Output = Vector<T>;
fn div(self, f: &T) -> Vector<T> {
assert!(*f != T::zero());
let new_data = self.data.iter().map(|v| *v / *f).collect();
Vector {
size: self.size,
data: new_data,
}
}
}
impl<T: Copy + One + Zero + Add<T, Output = T>> Add<T> for Vector<T> {
type Output = Vector<T>;
fn add(self, f: T) -> Vector<T> {
(&self) + (&f)
}
}
impl<'a, T: Copy + One + Zero + Add<T, Output = T>> Add<T> for &'a Vector<T> {
type Output = Vector<T>;
fn add(self, f: T) -> Vector<T> {
self + (&f)
}
}
impl<'a, T: Copy + One + Zero + Add<T, Output = T>> Add<&'a T> for Vector<T> {
type Output = Vector<T>;
fn add(self, f: &T) -> Vector<T> {
(&self) + f
}
}
impl<'a, 'b, T: Copy + One + Zero + Add<T, Output = T>> Add<&'b T> for &'a Vector<T> {
type Output = Vector<T>;
fn add(self, f: &T) -> Vector<T> {
let new_data = self.data.iter().map(|v| *v + *f).collect();
Vector {
size: self.size,
data: new_data,
}
}
}
impl<T: Copy + One + Zero + Add<T, Output = T>> Add<Vector<T>> for Vector<T> {
type Output = Vector<T>;
fn add(self, v: Vector<T>) -> Vector<T> {
(&self) + (&v)
}
}
impl<'a, T: Copy + One + Zero + Add<T, Output = T>> Add<Vector<T>> for &'a Vector<T> {
type Output = Vector<T>;
fn add(self, v: Vector<T>) -> Vector<T> {
self + (&v)
}
}
impl<'a, T: Copy + One + Zero + Add<T, Output = T>> Add<&'a Vector<T>> for Vector<T> {
type Output = Vector<T>;
fn add(self, v: &Vector<T>) -> Vector<T> {
(&self) + v
}
}
impl<'a, 'b, T: Copy + One + Zero + Add<T, Output = T>> Add<&'b Vector<T>> for &'a Vector<T> {
type Output = Vector<T>;
fn add(self, v: &Vector<T>) -> Vector<T> {
assert!(self.size == v.size);
let new_data = utils::vec_sum(&self.data, &v.data);
Vector {
size: self.size,
data: new_data,
}
}
}
impl<T: Copy + One + Zero + Sub<T, Output = T>> Sub<T> for Vector<T> {
type Output = Vector<T>;
fn sub(self, f: T) -> Vector<T> {
(&self) - (&f)
}
}
impl<'a, T: Copy + One + Zero + Sub<T, Output = T>> Sub<T> for &'a Vector<T> {
type Output = Vector<T>;
fn sub(self, f: T) -> Vector<T> {
self - (&f)
}
}
impl<'a, T: Copy + One + Zero + Sub<T, Output = T>> Sub<&'a T> for Vector<T> {
type Output = Vector<T>;
fn sub(self, f: &T) -> Vector<T> {
(&self) - f
}
}
impl<'a, 'b, T: Copy + One + Zero + Sub<T, Output = T>> Sub<&'b T> for &'a Vector<T> {
type Output = Vector<T>;
fn sub(self, f: &T) -> Vector<T> {
let new_data = self.data.iter().map(|v| *v - *f).collect();
Vector {
size: self.size,
data: new_data,
}
}
}
impl<T: Copy + One + Zero + Sub<T, Output = T>> Sub<Vector<T>> for Vector<T> {
type Output = Vector<T>;
fn sub(self, v: Vector<T>) -> Vector<T> {
(&self) - (&v)
}
}
impl<'a, T: Copy + One + Zero + Sub<T, Output = T>> Sub<Vector<T>> for &'a Vector<T> {
type Output = Vector<T>;
fn sub(self, v: Vector<T>) -> Vector<T> {
self - (&v)
}
}
impl<'a, T: Copy + One + Zero + Sub<T, Output = T>> Sub<&'a Vector<T>> for Vector<T> {
type Output = Vector<T>;
fn sub(self, v: &Vector<T>) -> Vector<T> {
(&self) - v
}
}
impl<'a, 'b, T: Copy + One + Zero + Sub<T, Output = T>> Sub<&'b Vector<T>> for &'a Vector<T> {
type Output = Vector<T>;
fn sub(self, v: &Vector<T>) -> Vector<T> {
assert!(self.size == v.size);
let new_data = utils::vec_sub(&self.data, &v.data);
Vector {
size: self.size,
data: new_data,
}
}
}
impl<T: Neg<Output = T> + Copy> Neg for Vector<T> {
type Output = Vector<T>;
fn neg(self) -> Vector<T> {
let new_data = self.data.iter().map(|v| -*v).collect();
Vector::new(new_data)
}
}
impl<'a, T: Neg<Output = T> + Copy> Neg for &'a Vector<T> {
type Output = Vector<T>;
fn neg(self) -> Vector<T> {
let new_data = self.data.iter().map(|v| -*v).collect();
Vector::new(new_data)
}
}
impl<T> Index<usize> for Vector<T> {
type Output = T;
fn index(&self, idx: usize) -> &T {
assert!(idx < self.size);
unsafe { &self.data.get_unchecked(idx) }
}
}
impl<T: Float> Metric<T> for Vector<T> {
fn norm(&self) -> T {
let mut s = T::zero();
for u in &self.data {
s = s + (*u) * (*u);
}
s.sqrt()
}
}