extern crate num;
use matrix::Matrix;
use vectors::zero;
use ops_inplace::VectorVectorOpsInPlace;
use math::Dimension;
pub trait SumVec<T> {
fn sum(&self) -> T;
}
macro_rules! vec_sum_impl {
($($t:ty)*) => ($(
impl SumVec<$t> for Vec<$t> {
fn sum(&self) -> $t {
(&self[..]).sum()
}
}
impl SumVec<$t> for [$t] {
fn sum(&self) -> $t {
self.iter().fold(0 as $t, |init, &val| init + val)
}
}
)*)
}
vec_sum_impl!{ usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 }
pub trait Sum<T> {
fn sum(&self, dim: Dimension) -> T;
}
macro_rules! sum_impl {
($($t:ty)*) => ($(
impl Sum<Vec<$t>> for Matrix<$t> {
fn sum(&self, dim: Dimension) -> Vec<$t> {
match dim {
Dimension:: Column => {
let mut v = zero::<$t>(self.cols());
for row in self.row_iter() {
v.iadd(row);
}
v
}
Dimension::Row => {
self.row_iter().map(|row| row.sum()).collect()
}
}
}
}
)*)
}
sum_impl!{ f32 f64 }
#[cfg(test)]
mod tests {
use super::*;
use matrix::*;
use math::Dimension;
#[test]
fn test_sum_matrix_f32() {
let m = mat![
1.0f32, 2.0;
5.0, 10.0
];
assert_eq!(m.sum(Dimension::Column), vec![6.0, 12.0]);
assert_eq!(m.sum(Dimension::Row), vec![3.0, 15.0]);
let a = Matrix::<f32>::new();
assert_eq!(a.sum(Dimension::Column), vec![]);
assert_eq!(a.sum(Dimension::Row), vec![]);
}
#[test]
fn test_sum_vec_f32() {
let x: Vec<f32> = vec![1.0, 2.0, 3.0, 4.0];
assert_eq!(x.sum(), 10.0);
let a: Vec<f32> = Vec::new();
assert_eq!(a.sum(), 0.0);
}
}