blob: 920fa0e9f179d120225b4f3909e84550fb634a0c [file] [log] [blame]
use std::ops::{Mul, Add, Div};
use libnum::{One, Zero, Float, FromPrimitive};
use std::fmt;
use std::vec::*;
use std::iter::FromIterator;
use std::slice::{Iter, IterMut};
use std::vec::IntoIter;
use norm::{VectorNorm, VectorMetric};
use utils;
use super::Vector;
impl<T> Vector<T> {
/// Constructor for Vector struct.
///
/// Requires the vector data.
///
/// # Examples
///
/// ```
/// use rulinalg::vector::Vector;
///
/// let vec = Vector::new(vec![1.0,2.0,3.0,4.0]);
/// ```
pub fn new<U: Into<Vec<T>>>(data: U) -> Vector<T> {
let our_data = data.into();
let size = our_data.len();
Vector {
size: size,
data: our_data,
}
}
/// Constructor for Vector struct that takes a function `f`
/// and constructs a new vector such that `V_i = f(i)`,
/// where `i` is the index.
///
/// # Examples
///
/// ```
/// # #[macro_use] extern crate rulinalg; fn main() {
/// use rulinalg::vector::Vector;
///
/// let v = Vector::from_fn(4, |x| x * 3);
/// assert_eq!(v, vector![0, 3, 6, 9]);
/// # }
/// ```
pub fn from_fn<F>(size: usize, mut f: F) -> Vector<T>
where F: FnMut(usize) -> T {
let data: Vec<T> = (0..size).into_iter().map(|x| f(x)).collect();
Vector {
size: size,
data: data,
}
}
/// Returns the size of the Vector.
pub fn size(&self) -> usize {
self.size
}
/// Returns a non-mutable reference to the underlying data.
pub fn data(&self) -> &Vec<T> {
&self.data
}
/// Returns a mutable slice of the underlying data.
pub fn mut_data(&mut self) -> &mut [T] {
&mut self.data
}
/// Consumes the Vector and returns the Vec of data.
pub fn into_vec(self) -> Vec<T> {
self.data
}
/// Returns an iterator over the Vector's data.
pub fn iter(&self) -> Iter<T> {
self.data.iter()
}
/// Returns an iterator over mutable references to the Vector's data.
pub fn iter_mut(&mut self) -> IterMut<T> {
self.mut_data().iter_mut()
}
/// Returns a pointer to the element at the given index, without doing
/// bounds checking.
pub unsafe fn get_unchecked(&self, index: usize) -> &T {
self.data.get_unchecked(index)
}
/// Returns an unsafe mutable pointer to the element at the given index,
/// without doing bounds checking.
pub unsafe fn get_unchecked_mut(&mut self, index: usize) -> &mut T {
self.data.get_unchecked_mut(index)
}
}
impl<T> Into<Vec<T>> for Vector<T> {
fn into(self) -> Vec<T> {
self.data
}
}
impl<T> IntoIterator for Vector<T> {
type Item = T;
type IntoIter = IntoIter<T>;
fn into_iter(self) -> Self::IntoIter {
self.data.into_iter()
}
}
impl<'a, T> IntoIterator for &'a Vector<T> {
type Item = &'a T;
type IntoIter = Iter<'a, T>;
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
impl<T> FromIterator<T> for Vector<T> {
fn from_iter<I>(iter: I) -> Self where I: IntoIterator<Item=T> {
let values: Vec<T> = iter.into_iter().collect();
Vector::new(values)
}
}
impl<T: fmt::Display> fmt::Display for Vector<T> {
/// Displays the Vector.
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
try!(write!(f, "["));
for (i, datum) in self.data.iter().enumerate() {
match f.precision() {
Some(places) => {
try!(write!(f, " {:.*}", places, datum));
}
None => {
try!(write!(f, " {}", datum));
}
}
if i < self.data.len() - 1 {
try!(write!(f, ","));
}
}
write!(f, "]")
}
}
impl<T: Clone> Clone for Vector<T> {
/// Clones the Vector.
fn clone(&self) -> Vector<T> {
Vector {
size: self.size,
data: self.data.clone(),
}
}
}
impl<T: Copy> Vector<T> {
/// Applies a function to each element in the vector.
///
/// # Examples
///
/// ```
/// # #[macro_use] extern crate rulinalg; fn main() {
/// use rulinalg::vector::Vector;
/// fn add_two(a: f64) -> f64 {
/// a + 2f64
/// }
///
/// let a = vector![0.; 4];
///
/// let b = a.apply(&add_two);
///
/// assert_eq!(b, vector![2.0; 4]);
/// # }
/// ```
pub fn apply(mut self, f: &Fn(T) -> T) -> Vector<T> {
for val in &mut self.data {
*val = f(*val);
}
self
}
}
impl<T: Copy + PartialOrd> Vector<T> {
/// Find the argmax of the Vector.
///
/// Returns the index of the largest value in the vector.
///
/// # Examples
///
/// ```
/// # #[macro_use] extern crate rulinalg; fn main() {
/// use rulinalg::vector::Vector;
///
/// let a = vector![1.0,2.0,0.0,5.0];
/// let b = a.argmax();
/// assert_eq!(b.0, 3);
/// assert_eq!(b.1, 5.0);
/// # }
/// ```
pub fn argmax(&self) -> (usize, T) {
utils::argmax(&self.data)
}
/// Find the argmin of the Vector.
///
/// Returns the index of the smallest value in the vector.
///
/// # Examples
///
/// ```
/// # #[macro_use] extern crate rulinalg; fn main() {
/// use rulinalg::vector::Vector;
///
/// let a = vector![1.0, 2.0, 0.0, 5.0];
/// let b = a.argmin();
/// assert_eq!(b.0, 2);
/// assert_eq!(b.1, 0.0);
/// # }
/// ```
pub fn argmin(&self) -> (usize, T) {
utils::argmin(&self.data)
}
/// Select elements from the Vector and form a new Vector from them.
///
/// # Examples
///
/// ```
/// # #[macro_use] extern crate rulinalg; fn main() {
/// use rulinalg::vector::Vector;
///
/// let a = vector![1.0, 2.0, 3.0, 4.0, 5.0];
///
/// let a_lower = a.select(&[2, 3, 4]);
///
/// // Prints [3,4,5]
/// assert_eq!(a_lower, vector![3.0, 4.0, 5.0]);
/// # }
/// ```
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: Clone + Zero> Vector<T> {
/// Constructs Vector of all zeros.
///
/// Requires the size of the vector.
///
/// # Examples
///
/// ```
/// use rulinalg::vector::Vector;
///
/// let vec = Vector::<f64>::zeros(10);
/// ```
pub fn zeros(size: usize) -> Vector<T> {
Vector {
size: size,
data: vec![T::zero(); size],
}
}
}
impl<T: Clone + One> Vector<T> {
/// Constructs Vector of all ones.
///
/// Requires the size of the vector.
///
/// # Examples
///
/// ```
/// use rulinalg::vector::Vector;
///
/// let vec = Vector::<f64>::ones(10);
/// ```
pub fn ones(size: usize) -> Vector<T> {
Vector {
size: size,
data: vec![T::one(); size],
}
}
}
impl<T: Copy + Zero + Mul<T, Output = T> + Add<T, Output = T>> Vector<T> {
/// Compute dot product with specified Vector.
///
/// # Examples
///
/// ```
/// # #[macro_use] extern crate rulinalg; fn main() {
/// use rulinalg::vector::Vector;
///
/// let a = vector![1.0, 2.0, 3.0, 4.0];
/// let b = vector![2.0; 4];
///
/// let c = a.dot(&b);
/// assert_eq!(c, 20.0);
/// # }
/// ```
pub fn dot(&self, v: &Vector<T>) -> T {
utils::dot(&self.data, &v.data)
}
}
impl<T: Copy + Zero + Add<T, Output = T>> Vector<T> {
/// The sum of the vector.
///
/// Returns the sum of all elements in the vector.
///
/// # Examples
///
/// ```
/// # #[macro_use] extern crate rulinalg; fn main() {
/// use rulinalg::vector::Vector;
///
/// let a = vector![1.0, 2.0, 3.0, 4.0];
///
/// let c = a.sum();
/// assert_eq!(c, 10.0);
/// # }
/// ```
pub fn sum(&self) -> T {
utils::unrolled_sum(&self.data[..])
}
}
impl<T: Copy + Mul<T, Output = T>> Vector<T> {
/// The elementwise product of two vectors.
///
/// # Examples
///
/// ```
/// # #[macro_use] extern crate rulinalg; fn main() {
/// use rulinalg::vector::Vector;
///
/// let a = vector![1.0, 2.0, 3.0, 4.0];
/// let b = vector![1.0, 2.0, 3.0, 4.0];
///
/// let c = &a.elemul(&b);
/// assert_eq!(c, &vector![1.0, 4.0, 9.0, 16.0]);
/// # }
/// ```
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 + Div<T, Output = T>> Vector<T> {
/// The elementwise division of two vectors.
///
/// # Examples
///
/// ```
/// # #[macro_use] extern crate rulinalg; fn main() {
/// use rulinalg::vector::Vector;
///
/// let a = vector![1.0, 2.0, 3.0, 4.0];
/// let b = vector![1.0, 2.0, 3.0, 4.0];
///
/// let c = &a.elediv(&b);
/// assert_eq!(c, &vector![1.0; 4]);
/// # }
/// ```
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: Float> Vector<T> {
/// Compute vector norm for vector.
///
/// # Examples
///
/// ```
/// # #[macro_use] extern crate rulinalg; fn main() {
/// use rulinalg::vector::Vector;
/// use rulinalg::norm::Euclidean;
///
/// let a = vector![3.0, 4.0];
/// let c = a.norm(Euclidean);
///
/// assert_eq!(c, 5.0);
/// # }
/// ```
pub fn norm<N: VectorNorm<T>>(&self, norm: N) -> T {
norm.norm(self)
}
/// Compute metric distance between two vectors.
///
/// # Examples
///
/// ```
/// # #[macro_use] extern crate rulinalg; fn main() {
/// use rulinalg::vector::Vector;
/// use rulinalg::norm::Euclidean;
///
/// let a = vector![3.0, 4.0];
/// let b = vector![0.0, 8.0];
///
/// // Compute the square root of the sum of
/// // elementwise squared-differences
/// let c = a.metric(&b, Euclidean);
/// assert_eq!(c, 5.0);
/// # }
/// ```
pub fn metric<M: VectorMetric<T>>(&self, v: &Vector<T>, m: M) -> T {
m.metric(self, v)
}
}
impl<T: Float + FromPrimitive> Vector<T> {
/// The mean of the vector.
///
/// Returns the arithmetic mean of the vector.
///
/// # Examples
///
/// ```
/// # #[macro_use] extern crate rulinalg; fn main() {
/// use rulinalg::vector::Vector;
///
/// let a = vector![1.0, 2.0, 3.0, 4.0];
///
/// let c = a.mean();
/// assert_eq!(c, 2.5);
/// # }
/// ```
pub fn mean(&self) -> T {
let sum = self.sum();
sum / FromPrimitive::from_usize(self.size()).unwrap()
}
/// The variance of the vector.
///
/// Returns the unbiased sample variance of the vector.
///
/// # Examples
///
/// ```
/// # #[macro_use] extern crate rulinalg; fn main() {
/// use rulinalg::vector::Vector;
///
/// let a = vector![1.0, 2.0, 3.0, 4.0];
///
/// let c = a.variance();
/// assert_eq!(c, 5.0 / 3.0);
/// # }
/// ```
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()
}
}
#[cfg(test)]
mod tests {
use super::super::Vector;
use norm::Euclidean;
#[test]
fn test_display() {
let v = vector![1, 2, 3, 4];
assert_eq!(format!("{}", v), "[ 1, 2, 3, 4]");
let v2 = vector![3.3, 4.0, 5.0, 6.0];
assert_eq!(format!("{}", v2), "[ 3.3, 4, 5, 6]");
assert_eq!(format!("{:.1}", v2), "[ 3.3, 4.0, 5.0, 6.0]");
}
#[test]
fn test_equality() {
let v = vector![1, 2, 3, 4];
let v_redux = v.clone();
assert_eq!(v, v_redux);
}
#[test]
fn create_vector_new() {
let a = vector![1.0; 12];
assert_eq!(a.size(), 12);
for i in 0..12 {
assert_eq!(a[i], 1.0);
}
}
#[test]
fn create_vector_new_from_slice() {
let data_vec: Vec<u32> = vec![1, 2, 3];
let data_slice: &[u32] = &data_vec[..];
let from_vec = Vector::new(data_vec.clone());
let from_slice = Vector::new(data_slice);
assert_eq!(from_vec, from_slice);
}
#[test]
fn create_vector_from_fn() {
let v1 = Vector::from_fn(3, |x| x + 1);
assert_eq!(v1, vector![1, 2, 3]);
let v2 = Vector::from_fn(3, |x| x as f64);
assert_eq!(v2, vector![0., 1., 2.]);
let mut z = 0;
let v3 = Vector::from_fn(3, |x| { z += 1; x + z });
assert_eq!(v3, vector![0 + 1, 1 + 2, 2 + 3]);
let v4 = Vector::from_fn(3, move |x| x + 1);
assert_eq!(v4, vector![1, 2, 3]);
let v5 = Vector::from_fn(0, |x| x);
assert_eq!(v5, Vector::new(vec![]));
}
#[test]
fn create_vector_zeros() {
let a = Vector::<f32>::zeros(7);
assert_eq!(a.size(), 7);
for i in 0..7 {
assert_eq!(a[i], 0.0);
}
}
#[test]
fn vector_dot_product() {
let a = vector![1.0, 2.0, 3.0, 4.0, 5.0, 6.0];
let b = vector![3.0; 6];
let c = a.dot(&b);
assert_eq!(c, 63.0);
}
#[test]
fn vector_euclidean_norm() {
let a = vector![1.0, 2.0, 3.0, 4.0, 5.0, 6.0];
let b = a.norm(Euclidean);
assert_eq!(b, (1. + 4. + 9. + 16. + 25. + 36. as f32).sqrt());
}
#[test]
fn vector_iteration() {
let our_vec = vec![2i32, 7, 1, 8, 2, 8];
let our_vector = Vector::new(our_vec.clone());
let our_vector_again = our_vector.clone();
// over Vector (consuming)
let mut our_recovered_vec = Vec::new();
for i in our_vector {
our_recovered_vec.push(i);
}
assert_eq!(our_recovered_vec, our_vec);
// over &Vector
let mut our_refcovered_vec = Vec::new();
for i in &our_vector_again {
our_refcovered_vec.push(*i);
}
assert_eq!(our_refcovered_vec, our_vec);
}
#[test]
fn vector_from_iter() {
let v1: Vector<usize> = (2..5).collect();
let exp1 = vector![2, 3, 4];
assert_eq!(v1, exp1);
let orig: Vec<f64> = vec![2., 3., 4.];
let v2: Vector<f64> = orig.iter().map(|x| x + 1.).collect();
let exp2 = vector![3., 4., 5.];
assert_eq!(v2, exp2);
}
#[test]
fn vector_get_unchecked() {
let v1 = vector![1, 2, 3];
unsafe {
assert_eq!(v1.get_unchecked(1), &2);
}
let mut v2 = vector![1, 2, 3];
unsafe {
let elem = v2.get_unchecked_mut(1);
*elem = 4;
}
assert_eq!(v2, vector![1, 4, 3]);
}
#[test]
fn vector_mul_f32_elemwise() {
let a = vector![1.0, 2.0, 3.0, 4.0, 5.0, 6.0];
let b = vector![2.0, 3.0, 4.0, 5.0, 6.0, 7.0];
let exp = vector![2.0, 6.0, 12.0, 20.0, 30.0, 42.0];
// Allocating new memory
let c = &a.elemul(&b);
assert_eq!(c, &exp);
// Allocating new memory
let c = a.elemul(&b);
assert_eq!(c, exp);
}
#[test]
fn vector_mul_int_elemwise() {
let a = vector![1, 2, 3, 4];
let b = vector![2, 4, 6, 8];
let exp = vector![2, 8, 18, 32];
// Allocating new memory
let c = &a.elemul(&b);
assert_eq!(c, &exp);
// Allocating new memory
let c = a.elemul(&b);
assert_eq!(c, exp);
}
#[test]
fn vector_div_f32_elemwise() {
let a = vector![1.0, 2.0, 3.0, 4.0, 5.0, 6.0];
let b = vector![2.0, 3.0, 4.0, 5.0, 6.0, 7.0];
let exp = vector![1. / 2., 2. / 3., 3. / 4., 4. / 5., 5. / 6., 6. / 7.];
// Allocating new memory
let c = &a.elediv(&b);
assert_eq!(c, &exp);
// Allocating new memory
let c = a.elediv(&b);
assert_eq!(c, exp);
}
#[test]
fn vector_div_int_elemwise() {
let a = vector![2, 4, 6, 8];
let b = vector![2, 2, 3, 3];
let exp = vector![1, 2, 2, 2];
// Allocating new memory
let c = &a.elediv(&b);
assert_eq!(c, &exp);
// Allocating new memory
let c = a.elediv(&b);
assert_eq!(c, exp);
}
}