<commit_before>use std::mem;
use std::ptr;
use std::ops;
use std::cmp;
use std::fmt;
use std::num::One;
use std::iter::Iterator;
use std::rt::heap::{allocate, deallocate};
use std::raw::Slice as RawSlice;

// The following is needed for destroying matrix.

#[doc = "
Represents a matrix of numbers.

The numbers are stored in column-major order.
This is the standard in Fortran and MATLAB.

Currently, the stride is same as the number
of rows. May be changed later on.

For a row vector, the stride  = 1.

"]
pub struct Mat<T:Ord+Copy> {
    rows : uint,
    cols : uint,
    ptr : *mut T
}

/// A matrix of 64-bit signed integers
pub type MatI64 = Mat<i64>;
/// A matrix of 64-bit floating point numbers.
pub type MatF64 = Mat<f64>;

/// Errors related to matrix operations
#[deriving(Show)]
pub enum MatErr{
    //EmptyMatrix,
    DimensionsMismatch,
}

/// Static functions for creating  a matrix
impl<T:Num+Ord+Copy> Mat<T> {

    pub fn new(rows: uint, cols : uint)-> Mat<T> {
        assert! (mem::size_of::<T>() != 0);
        let size = rows * cols;
        let bytes = size * mem::size_of::<T>();
        let raw = unsafe {
            allocate(bytes, mem::min_align_of::<T>())
        };
        let ptr = raw as *mut T;
        Mat { rows : rows, cols : cols, ptr : ptr}
    }

    /// Constructs a matrix of all zeros
    pub fn zeros(rows: uint, cols : uint)-> Mat<T> {
        let m : Mat<T> = Mat::new(rows, cols);
        // zero out the memory
        unsafe { ptr::zero_memory(m.ptr, m.capacity())};
        m
    }

    pub fn ones(rows: uint, cols : uint)-> Mat<T> {
        let m : Mat<T> = Mat::new(rows, cols);
        // fill with ones
        let ptr = m.ptr;
        let o : T = One::one();
        unsafe {
            for c in range(0, cols){
                for r in range (0, rows){
                    let offset = m.cell_to_offset(r, c);
                    let p  = ptr.offset(offset as int);
                    *p = o;
                }
            }
        }
        m
    }

    pub fn from_slice(rows: uint, cols : uint, values: &[T]) -> Mat<T>{
        let mut mat : Mat<T> = Mat::new(rows, cols);
        let n_cells = mat.num_cells();
        let stride = mat.stride();
        // get a mutable slice from m
        {
            let dst_slice = mat.as_mut_slice();
            let n_values = values.len();
            // The number of entries we can copy
            let n_fill = cmp::min(n_values, n_cells);
            let mut n = 0;
            let mut offset_src = 0;
            let mut offset_dst = 0;
            for _ in range(0, cols){
                for r in range(0, rows){
                    n+=1;
                    dst_slice[offset_dst + r] = values[offset_src + r];
                    if n == n_fill {
                        break;
                    }
                }
                if n == n_fill {
                    break;
                }
                offset_src += rows;
                offset_dst += stride;
            }
        }
        // return
        mat
    }

    pub fn from_iter< A : Iterator<T>>(rows: uint, cols : uint, mut iter: A) -> Mat<T>{
        let mut mat : Mat<T> = Mat::new(rows, cols);
        let stride = mat.stride();
        // get a mutable slice from m
        {
            let dst_slice = mat.as_mut_slice();
            let mut offset_dst = 0;
            'outer: for _ in range(0, cols){
                for r in range(0, rows){
                    let next_val = iter.next();
                    match next_val{
                        Some(val) => dst_slice[offset_dst + r] = val,
                        None => break 'outer
                    };
                }
                offset_dst += stride;
            }
        }
        // return
        mat
    }
}

/// Main methods of a matrix
impl<T:Num+Ord+Copy> Mat<T> {
    pub fn num_rows(&self) -> uint {
        self.rows
    }

    pub fn num_cols(&self) -> uint {
        self.cols
    }

    pub fn size (&self)-> (uint, uint){
        (self.rows, self.cols)
    }
    pub fn num_cells(&self)->uint {
        self.rows * self.cols
    }
    /// Returns the number of actual memory elements
    /// per column stored in the memory
    pub fn stride (&self)->uint {
        self.rows
    }

    pub fn capacity(&self)-> uint {
        self.stride() * self.cols
    }

    /// Returns an unsafe pointer to the matrix's
    /// buffer.
    #[inline]
    pub fn as_ptr(&self)-> *const T{
        self.ptr as *const T
    }

    /// Returns a mutable unsafe pointer to
    /// the matrix's underlying buffer
    #[inline]
    pub fn as_mut_ptr(&mut self) -> *mut T{
        self.ptr
    }

    #[inline]
    pub fn get(&self, r : uint, c : uint) -> T  {
        unsafe {
            *self.ptr.offset(self.cell_to_offset(r, c) as int)
        }
    }

    /// Converts an index to cell address (row, column)
    #[inline]
    pub fn index_to_cell(&self, index : uint) -> (uint, uint){
        let c = index / self.rows;
        let r = index - c*self.rows;
        (r, c)
    }

    /// Converts a cell address to an index (r, c) to index
    #[inline]
    pub fn cell_to_index(&self, r : uint,  c: uint) -> uint{
        c * self.rows + r
    }

    /// Converts the matrix to vector from standard library
    pub fn to_std_vec(&self) -> Vec<T> {
        let mut vec: Vec<T> = Vec::with_capacity(self.num_cells());
        // We iterate over elements in matrix and push in the vector
        let s = self.as_slice_();
        for c in range(0, self.cols){
            for r in range (0, self.rows){
                let offset = self.cell_to_offset(r, c);
                vec.push(s[offset]);
            }
        }
        vec
    }
}

impl<T:Num+Ord+Copy> Index<uint,T> for Mat<T> {
    #[inline]
    fn index<'a>(&'a self, index: &uint) -> &'a T {
        // The matrix is column major order
        let (r, c) = self.index_to_cell(*index);
        let offset = c * self.stride() + r;
        unsafe {
            &*self.ptr.offset(offset as int)
        }
    }
}

impl<T:Num+Ord+Copy> Mat<T>{
    /// This function is for internal use only.
    #[inline]
    fn as_mut_slice<'a>(&'a mut self) -> &'a mut [T] {
        unsafe {
            mem::transmute(RawSlice {
                data: self.as_mut_ptr() as *const T,
                len: self.capacity(),
            })
        }
    }
}

impl <T:Num+Ord+Copy> Clone for Mat<T> {

    fn clone(&self )-> Mat<T> {
        let m : Mat<T> = Mat::new(self.rows, self.cols);
        unsafe{
            ptr::copy_memory(m.ptr, self.ptr as *const T, self.capacity());
        }
        m
    }
}

impl <T:Num+Ord+Copy+fmt::Show> fmt::Show for Mat<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let s = self.as_slice_();
        try!(write!(f, "["));
        // Here we print row by row
        for r in range (0, self.rows) {
           try!(write!(f, "\n  "));
            for c in range (0, self.cols){
                let offset = c * self.stride() + r;
                try!(write!(f, "{} ", s[offset]));
            }
        }
        try!(write!(f, "\n]\n"));
        Ok(())
    }
}

/// Matrix addition support
impl<T:Num+Ord+Copy> ops::Add<Mat<T>, Mat<T>> for Mat<T> {
    fn add(&self, rhs: &Mat<T>) -> Mat<T> {
        // Validate dimensions are same.
        if self.size() != rhs.size(){
            fail!(DimensionsMismatch.to_string());
        }
        let result : Mat<T> = Mat::new(self.rows, self.cols);
        let pa = self.ptr;
        let pb = rhs.ptr;
        let pc = result.ptr;
        let n = self.capacity();
        unsafe{
            for i_ in range(0, n){
                let i = i_ as int;
                *pc.offset(i) = *pa.offset(i) + *pb.offset(i);
            }
        }
        result
    }
}

/// Matrix subtraction support
impl<T:Num+Ord+Copy> ops::Sub<Mat<T>, Mat<T>> for Mat<T>{
    fn sub(&self, rhs: &Mat<T>) -> Mat<T> {
        // Validate dimensions are same.
        if self.size() != rhs.size(){
            fail!(DimensionsMismatch.to_string());
        }
        let result : Mat<T> = Mat::new(self.rows, self.cols);
        let pa = self.ptr;
        let pb = rhs.ptr;
        let pc = result.ptr;
        let n = self.capacity();
        unsafe{
            for i_ in range(0, n){
                let i = i_ as int;
                *pc.offset(i) = *pa.offset(i) - *pb.offset(i);
            }
        }
        result
    }
}

#[unsafe_destructor]
impl<T:Num+Ord+Copy> Drop for Mat<T> {
    fn drop(&mut self) {
        if self.num_cells() != 0 {
            unsafe {
                dealloc(self.ptr, self.capacity())
            }
        }
    }
}

/******************************************************
 *
 *   Private implementation of Mat
 *
 *******************************************************/

impl<T:Num+Ord+Copy> Mat<T> {
    /// Returns a slice into `self`.
    #[inline]
    fn as_slice_<'a>(&'a self) -> &'a [T] {
        unsafe { mem::transmute(RawSlice { data: self.as_ptr(), len: self.capacity() }) }
    }

    /// Maps a cell index to actual offset in the internal buffer
    #[inline]
    fn cell_to_offset(&self, r : uint,  c: uint)-> uint {
        c * self.stride() + r
    }
}

/***
Private helper functions follow
*/

#[inline]
unsafe fn dealloc<T>(ptr: *mut T, len: uint) {
    if mem::size_of::<T>() != 0 {
        deallocate(ptr as *mut u8,
                   len * mem::size_of::<T>(),
                   mem::min_align_of::<T>())
    }
}

/******************************************************
 *
 *   Unit tests follow.
 *
 *******************************************************/

#[cfg(test)]
mod tests {

    use  super::{Mat, MatI64};

    #[test]
    fn  create_mat0(){
        let m : MatI64 = Mat::new(3, 4);
        assert_eq!(m.num_cells(), 12);
        assert_eq!(m.size(), (3, 4));
        let v : i64 = m.get(0, 0);
        assert_eq!(v, 0i64);
    }

    #[test]
    fn test_from_iter0(){
        let m : MatI64 = Mat::from_iter(4, 4, range(1, 20));
        let b: Vec<i64> = range(1, 17).collect();
        assert!(m.as_slice_() == b.as_slice_());
        let m : MatI64 = Mat::from_iter(4, 4, range(1, 16));
        assert_eq!(m.get(0, 0), 1);
        assert_eq!(m.get(2, 2), 11);
        let mut b: Vec<i64> = range(1, 16).collect();
        b.push(0);
        assert!(m.as_slice_() == b.as_slice_());
    }

    #[test]
    fn test_index0(){
        let m : MatI64 = Mat::from_iter(4, 4, range(1, 20));
        let x = m[4];
        assert_eq!(x, 5);
    }

    #[test]
    fn test_cell_index_mapping(){
        let rows = 20;
        let cols = 10;
        let m : MatI64 = Mat::new(rows, cols);
        assert_eq!(m.index_to_cell(3 + 2*rows), (3, 2));
        assert_eq!(m.cell_to_index(3, 2), 3 + 2*rows);
        assert_eq!(m.cell_to_index(5, 7), 145);
        assert_eq!(m.index_to_cell(145), (5, 7));
    }

    #[test]
    fn test_to_std_vec(){
        let m : MatI64 = Mat::from_iter(4, 3, range(0, 12));
        let v1 = m.to_std_vec();
        let v2 : Vec<i64> = range(0, 12).collect();
        assert_eq!(v1, v2);
    }

    #[test]
    fn test_ones(){
        let m : MatI64 = Mat::ones(4, 2);
        let v = vec![1i64, 1, 1, 1, 1, 1, 1, 1];
        assert_eq!(m.to_std_vec(), v);
    }

    #[test]
    fn test_sum(){
        let m : MatI64 = Mat::ones(4, 2);
        let m2 = m  + m;
        let v = vec![2i64, 2, 2, 2, 2, 2, 2, 2];
        assert_eq!(m2.to_std_vec(), v);
    }

    #[test]
    #[should_fail]
    fn test_sum_fail(){
        let m1 : MatI64 = Mat::ones(4, 2);
        let m2 : MatI64 = Mat::ones(3, 2);
        m1 + m2;
    }

    #[test]
    fn test_sub(){
        let m : MatI64 = Mat::ones(4, 2);
        let m3 = m  + m + m;
        let m2 = m3 - m;
        let v = vec![2i64, 2, 2, 2, 2, 2, 2, 2];
        assert_eq!(m2.to_std_vec(), v);
    }

    #[test]
    #[should_fail]
    fn test_sub_fail(){
        let m1 : MatI64 = Mat::ones(4, 2);
        let m2 : MatI64 = Mat::ones(3, 2);
        m1 - m2;
    }
}
<commit_msg>Now the matrix type only assumes partial ordering on numbers. This is required since f64 and f32 types don't support total ordering due to NaN.<commit_after>// library imports
use std::mem;
use std::ptr;
use std::ops;
use std::cmp;
use std::fmt;
use std::num::One;
use std::iter::Iterator;
use std::rt::heap::{allocate, deallocate};
use std::raw::Slice as RawSlice;

// The following is needed for destroying matrix.

#[doc = "
Represents a matrix of numbers.

The numbers are stored in column-major order.
This is the standard in Fortran and MATLAB.

Currently, the stride is same as the number
of rows. May be changed later on.

For a row vector, the stride  = 1.

"]
pub struct Mat<T:MatElt> {
    rows : uint,
    cols : uint,
    ptr : *mut T
}

/// A matrix of 64-bit signed integers
pub type MatI64 = Mat<i64>;
/// A matrix of 64-bit floating point numbers.
pub type MatF64 = Mat<f64>;

/// Errors related to matrix operations
#[deriving(Show)]
pub enum MatErr{
    //EmptyMatrix,
    DimensionsMismatch,
}

/// Defines all the traits which a matrix element must support
pub trait MatElt : Num+PartialOrd+Copy {

}

/// Indicate that i64 fits all requirements for being a matrix element.
impl MatElt for i64 {

}

/// Indicate that f64 fits all requirements for being a matrix element.
impl MatElt for f64 {

}

/// Static functions for creating  a matrix
impl<T:MatElt> Mat<T> {

    pub fn new(rows: uint, cols : uint)-> Mat<T> {
        assert! (mem::size_of::<T>() != 0);
        let size = rows * cols;
        let bytes = size * mem::size_of::<T>();
        let raw = unsafe {
            allocate(bytes, mem::min_align_of::<T>())
        };
        let ptr = raw as *mut T;
        Mat { rows : rows, cols : cols, ptr : ptr}
    }

    /// Constructs a matrix of all zeros
    pub fn zeros(rows: uint, cols : uint)-> Mat<T> {
        let m : Mat<T> = Mat::new(rows, cols);
        // zero out the memory
        unsafe { ptr::zero_memory(m.ptr, m.capacity())};
        m
    }

    pub fn ones(rows: uint, cols : uint)-> Mat<T> {
        let m : Mat<T> = Mat::new(rows, cols);
        // fill with ones
        let ptr = m.ptr;
        let o : T = One::one();
        unsafe {
            for c in range(0, cols){
                for r in range (0, rows){
                    let offset = m.cell_to_offset(r, c);
                    let p  = ptr.offset(offset as int);
                    *p = o;
                }
            }
        }
        m
    }

    pub fn from_slice(rows: uint, cols : uint, values: &[T]) -> Mat<T>{
        let mut mat : Mat<T> = Mat::new(rows, cols);
        let n_cells = mat.num_cells();
        let stride = mat.stride();
        // get a mutable slice from m
        {
            let dst_slice = mat.as_mut_slice();
            let n_values = values.len();
            // The number of entries we can copy
            let n_fill = cmp::min(n_values, n_cells);
            let mut n = 0;
            let mut offset_src = 0;
            let mut offset_dst = 0;
            for _ in range(0, cols){
                for r in range(0, rows){
                    n+=1;
                    dst_slice[offset_dst + r] = values[offset_src + r];
                    if n == n_fill {
                        break;
                    }
                }
                if n == n_fill {
                    break;
                }
                offset_src += rows;
                offset_dst += stride;
            }
        }
        // return
        mat
    }

    pub fn from_iter< A : Iterator<T>>(rows: uint, cols : uint, mut iter: A) -> Mat<T>{
        let mut mat : Mat<T> = Mat::new(rows, cols);
        let stride = mat.stride();
        // get a mutable slice from m
        {
            let dst_slice = mat.as_mut_slice();
            let mut offset_dst = 0;
            'outer: for _ in range(0, cols){
                for r in range(0, rows){
                    let next_val = iter.next();
                    match next_val{
                        Some(val) => dst_slice[offset_dst + r] = val,
                        None => break 'outer
                    };
                }
                offset_dst += stride;
            }
        }
        // return
        mat
    }
}

/// Main methods of a matrix
impl<T:MatElt> Mat<T> {
    pub fn num_rows(&self) -> uint {
        self.rows
    }

    pub fn num_cols(&self) -> uint {
        self.cols
    }

    pub fn size (&self)-> (uint, uint){
        (self.rows, self.cols)
    }
    pub fn num_cells(&self)->uint {
        self.rows * self.cols
    }
    /// Returns the number of actual memory elements
    /// per column stored in the memory
    pub fn stride (&self)->uint {
        self.rows
    }

    pub fn capacity(&self)-> uint {
        self.stride() * self.cols
    }

    /// Returns an unsafe pointer to the matrix's
    /// buffer.
    #[inline]
    pub fn as_ptr(&self)-> *const T{
        self.ptr as *const T
    }

    /// Returns a mutable unsafe pointer to
    /// the matrix's underlying buffer
    #[inline]
    pub fn as_mut_ptr(&mut self) -> *mut T{
        self.ptr
    }

    #[inline]
    pub fn get(&self, r : uint, c : uint) -> T  {
        unsafe {
            *self.ptr.offset(self.cell_to_offset(r, c) as int)
        }
    }

    /// Converts an index to cell address (row, column)
    #[inline]
    pub fn index_to_cell(&self, index : uint) -> (uint, uint){
        let c = index / self.rows;
        let r = index - c*self.rows;
        (r, c)
    }

    /// Converts a cell address to an index (r, c) to index
    #[inline]
    pub fn cell_to_index(&self, r : uint,  c: uint) -> uint{
        c * self.rows + r
    }

    /// Converts the matrix to vector from standard library
    pub fn to_std_vec(&self) -> Vec<T> {
        let mut vec: Vec<T> = Vec::with_capacity(self.num_cells());
        // We iterate over elements in matrix and push in the vector
        let s = self.as_slice_();
        for c in range(0, self.cols){
            for r in range (0, self.rows){
                let offset = self.cell_to_offset(r, c);
                vec.push(s[offset]);
            }
        }
        vec
    }
}

impl<T:MatElt> Index<uint,T> for Mat<T> {
    #[inline]
    fn index<'a>(&'a self, index: &uint) -> &'a T {
        // The matrix is column major order
        let (r, c) = self.index_to_cell(*index);
        let offset = c * self.stride() + r;
        unsafe {
            &*self.ptr.offset(offset as int)
        }
    }
}

impl<T:MatElt> Mat<T>{
    /// This function is for internal use only.
    #[inline]
    fn as_mut_slice<'a>(&'a mut self) -> &'a mut [T] {
        unsafe {
            mem::transmute(RawSlice {
                data: self.as_mut_ptr() as *const T,
                len: self.capacity(),
            })
        }
    }
}

impl <T:MatElt> Clone for Mat<T> {

    fn clone(&self )-> Mat<T> {
        let m : Mat<T> = Mat::new(self.rows, self.cols);
        unsafe{
            ptr::copy_memory(m.ptr, self.ptr as *const T, self.capacity());
        }
        m
    }
}

impl <T:MatElt+fmt::Show> fmt::Show for Mat<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let s = self.as_slice_();
        try!(write!(f, "["));
        // Here we print row by row
        for r in range (0, self.rows) {
           try!(write!(f, "\n  "));
            for c in range (0, self.cols){
                let offset = c * self.stride() + r;
                try!(write!(f, "{} ", s[offset]));
            }
        }
        try!(write!(f, "\n]\n"));
        Ok(())
    }
}

/// Matrix addition support
impl<T:MatElt> ops::Add<Mat<T>, Mat<T>> for Mat<T> {
    fn add(&self, rhs: &Mat<T>) -> Mat<T> {
        // Validate dimensions are same.
        if self.size() != rhs.size(){
            fail!(DimensionsMismatch.to_string());
        }
        let result : Mat<T> = Mat::new(self.rows, self.cols);
        let pa = self.ptr;
        let pb = rhs.ptr;
        let pc = result.ptr;
        let n = self.capacity();
        unsafe{
            for i_ in range(0, n){
                let i = i_ as int;
                *pc.offset(i) = *pa.offset(i) + *pb.offset(i);
            }
        }
        result
    }
}

/// Matrix subtraction support
impl<T:MatElt> ops::Sub<Mat<T>, Mat<T>> for Mat<T>{
    fn sub(&self, rhs: &Mat<T>) -> Mat<T> {
        // Validate dimensions are same.
        if self.size() != rhs.size(){
            fail!(DimensionsMismatch.to_string());
        }
        let result : Mat<T> = Mat::new(self.rows, self.cols);
        let pa = self.ptr;
        let pb = rhs.ptr;
        let pc = result.ptr;
        let n = self.capacity();
        unsafe{
            for i_ in range(0, n){
                let i = i_ as int;
                *pc.offset(i) = *pa.offset(i) - *pb.offset(i);
            }
        }
        result
    }
}

#[unsafe_destructor]
impl<T:MatElt> Drop for Mat<T> {
    fn drop(&mut self) {
        if self.num_cells() != 0 {
            unsafe {
                dealloc(self.ptr, self.capacity())
            }
        }
    }
}

/******************************************************
 *
 *   Private implementation of Mat
 *
 *******************************************************/

impl<T:MatElt> Mat<T> {
    /// Returns a slice into `self`.
    #[inline]
    fn as_slice_<'a>(&'a self) -> &'a [T] {
        unsafe { mem::transmute(RawSlice { data: self.as_ptr(), len: self.capacity() }) }
    }

    /// Maps a cell index to actual offset in the internal buffer
    #[inline]
    fn cell_to_offset(&self, r : uint,  c: uint)-> uint {
        c * self.stride() + r
    }
}

/***
Private helper functions follow
*/

#[inline]
unsafe fn dealloc<T>(ptr: *mut T, len: uint) {
    if mem::size_of::<T>() != 0 {
        deallocate(ptr as *mut u8,
                   len * mem::size_of::<T>(),
                   mem::min_align_of::<T>())
    }
}

/******************************************************
 *
 *   Unit tests follow.
 *
 *******************************************************/

#[cfg(test)]
mod tests {

    use  super::{Mat, MatI64};

    #[test]
    fn  create_mat0(){
        let m : MatI64 = Mat::new(3, 4);
        assert_eq!(m.num_cells(), 12);
        assert_eq!(m.size(), (3, 4));
        let v : i64 = m.get(0, 0);
        assert_eq!(v, 0i64);
    }

    #[test]
    fn test_from_iter0(){
        let m : MatI64 = Mat::from_iter(4, 4, range(1, 20));
        let b: Vec<i64> = range(1, 17).collect();
        assert!(m.as_slice_() == b.as_slice_());
        let m : MatI64 = Mat::from_iter(4, 4, range(1, 16));
        assert_eq!(m.get(0, 0), 1);
        assert_eq!(m.get(2, 2), 11);
        let mut b: Vec<i64> = range(1, 16).collect();
        b.push(0);
        assert!(m.as_slice_() == b.as_slice_());
    }

    #[test]
    fn test_index0(){
        let m : MatI64 = Mat::from_iter(4, 4, range(1, 20));
        let x = m[4];
        assert_eq!(x, 5);
    }

    #[test]
    fn test_cell_index_mapping(){
        let rows = 20;
        let cols = 10;
        let m : MatI64 = Mat::new(rows, cols);
        assert_eq!(m.index_to_cell(3 + 2*rows), (3, 2));
        assert_eq!(m.cell_to_index(3, 2), 3 + 2*rows);
        assert_eq!(m.cell_to_index(5, 7), 145);
        assert_eq!(m.index_to_cell(145), (5, 7));
    }

    #[test]
    fn test_to_std_vec(){
        let m : MatI64 = Mat::from_iter(4, 3, range(0, 12));
        let v1 = m.to_std_vec();
        let v2 : Vec<i64> = range(0, 12).collect();
        assert_eq!(v1, v2);
    }

    #[test]
    fn test_ones(){
        let m : MatI64 = Mat::ones(4, 2);
        let v = vec![1i64, 1, 1, 1, 1, 1, 1, 1];
        assert_eq!(m.to_std_vec(), v);
    }

    #[test]
    fn test_sum(){
        let m : MatI64 = Mat::ones(4, 2);
        let m2 = m  + m;
        let v = vec![2i64, 2, 2, 2, 2, 2, 2, 2];
        assert_eq!(m2.to_std_vec(), v);
    }

    #[test]
    #[should_fail]
    fn test_sum_fail(){
        let m1 : MatI64 = Mat::ones(4, 2);
        let m2 : MatI64 = Mat::ones(3, 2);
        m1 + m2;
    }

    #[test]
    fn test_sub(){
        let m : MatI64 = Mat::ones(4, 2);
        let m3 = m  + m + m;
        let m2 = m3 - m;
        let v = vec![2i64, 2, 2, 2, 2, 2, 2, 2];
        assert_eq!(m2.to_std_vec(), v);
    }

    #[test]
    #[should_fail]
    fn test_sub_fail(){
        let m1 : MatI64 = Mat::ones(4, 2);
        let m2 : MatI64 = Mat::ones(3, 2);
        m1 - m2;
    }
}
<|endoftext|>


<commit_before>static MEMORY_SIZE: uint = 4096;

pub struct Memory {
	mem: [int, ..MEMORY_SIZE],
	memptr: uint
}

impl Memory {
	pub fn new() -> Memory {
		Memory { mem: [0, ..MEMORY_SIZE], memptr: 0 }
	}

	pub fn getptr(&self) -> uint {
		self.memptr
	}

	pub fn setptr(&mut self, loc: uint) {
		if loc < MEMORY_SIZE {
			self.memptr = loc;
		}
	}

	pub fn set(&mut self, val: int) {
		self.mem[self.memptr] = val
	}

	pub fn get(&self) -> int {
		self.mem[self.memptr]
	}

	pub fn fwd(&mut self) {
		self.memptr += 1;
		if self.memptr >= MEMORY_SIZE {
			self.memptr = 0;
		}
	}

	pub fn adv(&mut self, by: uint) {
		let mut cnt = 0u;
		while cnt < by {
			self.fwd();
			cnt += 1;
		}
	}

	pub fn bck(&mut self) {
		if self.memptr == 0 {
			self.memptr = MEMORY_SIZE - 1;
		}
		else {
			self.memptr -= 1;
		}
	}

	pub fn rwd(&mut self, by: uint) {
		let mut cnt = 0u;
		while cnt < by {
			self.bck();
			cnt += 1;
		}
	}

	pub fn inc(&mut self) {
		self.mem[self.memptr] += 1;
	}

	pub fn lft(&mut self, by: uint) {
		let mut cnt = 0u;
		while cnt < by {
			self.inc();
			cnt += 1;
		}
	}

	pub fn dcr(&mut self) {
		self.mem[self.memptr] -= 1;
	}

	pub fn dwn(&mut self, by: uint) {
		let mut cnt = 0u;
		while cnt < by {
			self.dcr();
			cnt += 1;
		}
	}
}

impl Iterator<int> for Memory {
	fn next(&mut self) -> Option<int> {
		let ret = if self.memptr < MEMORY_SIZE {
			// Get the memory at this location
			Some(self.mem[self.memptr])
		}
		else {
			// Reset the memory pointer
			self.memptr = 0;
			// You've went through all the memory
			None
		};
		self.memptr += 1;
		ret
	}
}<commit_msg>Pruned some code from Memory<commit_after>static MEMORY_SIZE: uint = 4096;

pub struct Memory {
	mem: [int, ..MEMORY_SIZE],
	memptr: uint
}

impl Memory {
	pub fn new() -> Memory {
		Memory { mem: [0, ..MEMORY_SIZE], memptr: 0 }
	}

	pub fn getptr(&self) -> uint {
		self.memptr
	}

	pub fn setptr(&mut self, loc: uint) {
		if loc < MEMORY_SIZE {
			self.memptr = loc;
		}
	}

	pub fn set(&mut self, val: int) {
		self.mem[self.memptr] = val
	}

	pub fn get(&self) -> int {
		self.mem[self.memptr]
	}

	pub fn fwd(&mut self) {
		self.memptr += 1;
		if self.memptr >= MEMORY_SIZE {
			self.memptr = 0;
		}
	}

	pub fn adv(&mut self, by: uint) {
		let mut cnt = 0u;
		while cnt < by {
			self.fwd();
			cnt += 1;
		}
	}

	pub fn bck(&mut self) {
		if self.memptr == 0 {
			self.memptr = MEMORY_SIZE - 1;
		}
		else {
			self.memptr -= 1;
		}
	}

	pub fn rwd(&mut self, by: uint) {
		let mut cnt = 0u;
		while cnt < by {
			self.bck();
			cnt += 1;
		}
	}

	pub fn inc(&mut self) {
		self.mem[self.memptr] += 1;
	}

	pub fn lft(&mut self, by: uint) {
		let mut cnt = 0u;
		while cnt < by {
			self.inc();
			cnt += 1;
		}
	}

	pub fn dcr(&mut self) {
		self.mem[self.memptr] -= 1;
	}

	pub fn dwn(&mut self, by: uint) {
		let mut cnt = 0u;
		while cnt < by {
			self.dcr();
			cnt += 1;
		}
	}
}<|endoftext|>


<commit_before>use syntax::abi::Abi;
use syntax::ast;
use syntax::codemap::{DUMMY_SP, Span};
use syntax::ptr::P;

use fn_decl::FnDeclBuilder;
use generics::GenericsBuilder;
use invoke::{Invoke, Identity};

//////////////////////////////////////////////////////////////////////////////

pub struct MethodSigBuilder<F=Identity> {
    callback: F,
    span: Span,
    abi: Abi,
    generics: ast::Generics,
    unsafety: ast::Unsafety,
    constness: ast::Constness,
}

impl MethodSigBuilder {
    pub fn new() -> Self {
        MethodSigBuilder::with_callback(Identity)
    }
}

impl<F> MethodSigBuilder<F>
    where F: Invoke<ast::MethodSig>,
{
    pub fn with_callback(callback: F) -> Self {
        MethodSigBuilder {
            callback: callback,
            span: DUMMY_SP,
            abi: Abi::Rust,
            generics: GenericsBuilder::new().build(),
            unsafety: ast::Unsafety::Normal,
            constness: ast::Constness::NotConst,
        }
    }

    pub fn span(mut self, span: Span) -> Self {
        self.span = span;
        self
    }

    pub fn unsafe_(mut self) -> Self {
        self.unsafety = ast::Unsafety::Normal;
        self
    }

    pub fn const_(mut self) -> Self {
        self.constness = ast::Constness::Const;
        self
    }

    pub fn abi(mut self, abi: Abi) -> Self {
        self.abi = abi;
        self
    }

    pub fn with_generics(mut self, generics: ast::Generics) -> Self {
        self.generics = generics;
        self
    }

    pub fn generics(self) -> GenericsBuilder<Self> {
        GenericsBuilder::with_callback(self)
    }

    pub fn build_fn_decl(self, fn_decl: P<ast::FnDecl>) -> F::Result {
        self.callback.invoke(ast::MethodSig {
            unsafety: self.unsafety,
            constness: self.constness,
            abi: self.abi,
            decl: fn_decl,
            generics: self.generics,
        })
    }

    pub fn fn_decl(self) -> FnDeclBuilder<Self> {
        FnDeclBuilder::with_callback(self)
    }
}

impl<F> Invoke<ast::Generics> for MethodSigBuilder<F>
    where F: Invoke<ast::MethodSig>,
{
    type Result = Self;

    fn invoke(self, generics: ast::Generics) -> Self {
        self.with_generics(generics)
    }
}

impl<F> Invoke<P<ast::FnDecl>> for MethodSigBuilder<F>
    where F: Invoke<ast::MethodSig>,
{
    type Result = F::Result;

    fn invoke(self, fn_decl: P<ast::FnDecl>) -> Self::Result {
        self.build_fn_decl(fn_decl)
    }
}
<commit_msg>Fix MethodSigBuilder::unsafe_()<commit_after>use syntax::abi::Abi;
use syntax::ast;
use syntax::codemap::{DUMMY_SP, Span};
use syntax::ptr::P;

use fn_decl::FnDeclBuilder;
use generics::GenericsBuilder;
use invoke::{Invoke, Identity};

//////////////////////////////////////////////////////////////////////////////

pub struct MethodSigBuilder<F=Identity> {
    callback: F,
    span: Span,
    abi: Abi,
    generics: ast::Generics,
    unsafety: ast::Unsafety,
    constness: ast::Constness,
}

impl MethodSigBuilder {
    pub fn new() -> Self {
        MethodSigBuilder::with_callback(Identity)
    }
}

impl<F> MethodSigBuilder<F>
    where F: Invoke<ast::MethodSig>,
{
    pub fn with_callback(callback: F) -> Self {
        MethodSigBuilder {
            callback: callback,
            span: DUMMY_SP,
            abi: Abi::Rust,
            generics: GenericsBuilder::new().build(),
            unsafety: ast::Unsafety::Normal,
            constness: ast::Constness::NotConst,
        }
    }

    pub fn span(mut self, span: Span) -> Self {
        self.span = span;
        self
    }

    pub fn unsafe_(mut self) -> Self {
        self.unsafety = ast::Unsafety::Unsafe;
        self
    }

    pub fn const_(mut self) -> Self {
        self.constness = ast::Constness::Const;
        self
    }

    pub fn abi(mut self, abi: Abi) -> Self {
        self.abi = abi;
        self
    }

    pub fn with_generics(mut self, generics: ast::Generics) -> Self {
        self.generics = generics;
        self
    }

    pub fn generics(self) -> GenericsBuilder<Self> {
        GenericsBuilder::with_callback(self)
    }

    pub fn build_fn_decl(self, fn_decl: P<ast::FnDecl>) -> F::Result {
        self.callback.invoke(ast::MethodSig {
            unsafety: self.unsafety,
            constness: self.constness,
            abi: self.abi,
            decl: fn_decl,
            generics: self.generics,
        })
    }

    pub fn fn_decl(self) -> FnDeclBuilder<Self> {
        FnDeclBuilder::with_callback(self)
    }
}

impl<F> Invoke<ast::Generics> for MethodSigBuilder<F>
    where F: Invoke<ast::MethodSig>,
{
    type Result = Self;

    fn invoke(self, generics: ast::Generics) -> Self {
        self.with_generics(generics)
    }
}

impl<F> Invoke<P<ast::FnDecl>> for MethodSigBuilder<F>
    where F: Invoke<ast::MethodSig>,
{
    type Result = F::Result;

    fn invoke(self, fn_decl: P<ast::FnDecl>) -> Self::Result {
        self.build_fn_decl(fn_decl)
    }
}
<|endoftext|>


<commit_before>use std::ops::{Mul, AddAssign};
use std::cmp;
use std::f32;
use std::fmt::Debug;

use na;
use num::{zero, Zero};

use ::Point2i;
use ::Point2f;
use ::lerp;
use blockedarray::BlockedArray;
use spectrum::Spectrum;

pub enum WrapMode {
    Repeat,
    Black,
    Clamp,
}

pub struct MIPMap<T> {
    do_trilinear: bool,
    max_anisotropy: f32,
    wrap_mode: WrapMode,
    resolution: Point2i,
    pyramid: Vec<BlockedArray<T>>,
    black: T,
}

impl<T> MIPMap<T>
    where T: Zero,
          T: Clone,
          T: Copy,
          T: Clampable,
          T: Debug,
          T: AddAssign<T>,
          T: Mul<f32, Output = T>
{
    pub fn new(res: &Point2i,
               img: &[T],
               do_trilinear: bool,
               max_anisotropy: f32,
               wrap_mode: WrapMode)
               -> MIPMap<T> {
        info!("Creating MIPMap for texture");
        let mut resolution = *res;
        let mut resampled_image = Vec::new();
        if !res.x.is_power_of_two() || !res.y.is_power_of_two() {
            info!("Texture dimensions are not powers of 2: re-sampling.");
            // resample image to power of two resolution
            let res_pow2 = Point2i::new(res.x.next_power_of_two(), res.y.next_power_of_two());
            // resample image in s direction
            resampled_image.resize(res_pow2.x as usize * res_pow2.y as usize, zero());
            let s_weights = MIPMap::<T>::resample_weights(res.x as usize, res_pow2.x as usize);
            // apply s_weights to zoom in s direction
            for t in 0..res.y as usize {
                for s in 0..res_pow2.x as usize {
                    // Compute texel (s,t) in s-zoomed image
                    resampled_image[t * res_pow2.x as usize + s] = zero();
                    for j in 0..4 {
                        let mut orig_s = s_weights[s].first_texel as usize + j;
                        orig_s = match wrap_mode {
                            WrapMode::Repeat => orig_s % res.x as usize,
                            WrapMode::Clamp => na::clamp(orig_s, 0, res.x as usize - 1),
                            WrapMode::Black => orig_s,
                        };
                        if orig_s < res.x as usize {
                            resampled_image[t * res_pow2.x as usize + s] +=
                                img[(t * res.x as usize + orig_s) as usize] *
                                s_weights[s].weights[j];
                        }
                    }

                }
            }
            // TODO use rayon to parallelize this loop?
            // resample image in t direction
            let t_weights = MIPMap::<T>::resample_weights(res.y as usize, res_pow2.y as usize);
            // apply t_weights to zoom in t direction
            for s in 0..res_pow2.x as usize {
                let mut work_data: Vec<T> = vec![zero(); res_pow2.y as usize];
                for t in 0..res_pow2.y as usize {
                    // work_data[t] = zero();
                    // Compute texel (s,t) in t-zoomed image
                    for j in 0..4 {
                        let mut offset = t_weights[t].first_texel as usize + j;
                        offset = match wrap_mode {
                            WrapMode::Repeat => offset % res.y as usize,
                            WrapMode::Clamp => na::clamp(offset, 0, res.y as usize - 1),
                            WrapMode::Black => offset,
                        };
                        if offset < res.y as usize {
                            work_data[t] += img[(offset * res_pow2.x as usize + s) as usize] *
                                            t_weights[t].weights[j];
                        }
                    }
                }
                for t in 0..res_pow2.y as usize {
                    resampled_image[t * res_pow2.x as usize + s] = work_data[t].clamp(0.0, 1.0);
                }
            }
            resolution = res_pow2;
        }

        let mut mipmap = MIPMap {
            do_trilinear: do_trilinear,
            max_anisotropy: max_anisotropy,
            wrap_mode: wrap_mode,
            resolution: resolution,
            pyramid: Vec::new(),
            black: zero(),
        };

        // initialize levels of MIPMap for image
        let n_levels = 1 + (cmp::max(resolution.x, resolution.y) as f32).log2() as usize;
        info!("mipmap will have {} levels", n_levels);
        // Initialize most detailed level of the pyramid
        let img_data = if resampled_image.is_empty() {
            img
        } else {
            &resampled_image[..]
        };
        // level 0
        mipmap.pyramid
            .push(BlockedArray::new_from(resolution.x as usize, resolution.y as usize, img_data));
        for i in 1..n_levels {
            // initialize ith level of the pyramid
            let s_res = cmp::max(1, mipmap.pyramid[i - 1].u_size() / 2);
            let t_res = cmp::max(1, mipmap.pyramid[i - 1].v_size() / 2);
            let mut ba = BlockedArray::new(s_res, t_res);
            // Filter 4 texels from finer level of pyramid
            for t in 0..t_res {
                for s in 0..s_res {
                    let (si, ti) = (s as isize, t as isize);
                    ba[(s, t)] = (*mipmap.texel(i - 1, 2 * si, 2 * ti) +
                                  *mipmap.texel(i - 1, 2 * si + 1, 2 * ti) +
                                  *mipmap.texel(i - 1, 2 * si, 2 * ti + 1) +
                                  *mipmap.texel(i - 1, 2 * si + 1, 2 * ti + 1)) *
                                 0.25;
                    debug!("l={}, ba[({}, {})]={:?}", i, s, t, ba[(s, t)]);
                }
            }
            mipmap.pyramid.push(ba);
        }
        // initialize EWA filter weights if needed

        mipmap
    }

    pub fn width(&self) -> usize {
        self.resolution.x as usize
    }

    pub fn height(&self) -> usize {
        self.resolution.y as usize
    }

    pub fn levels(&self) -> usize {
        self.pyramid.len()
    }

    pub fn texel(&self, level: usize, s: isize, t: isize) -> &T {
        let l = &self.pyramid[level];
        let (u_size, v_size) = (l.u_size() as isize, l.v_size() as isize);
        let (ss, tt): (usize, usize) = match self.wrap_mode {
            WrapMode::Repeat => (modulo(s, u_size), modulo(t, v_size)),
            WrapMode::Clamp => {
                (na::clamp(s, 0, u_size - 1) as usize, na::clamp(t, 0, v_size - 1) as usize)
            }
            WrapMode::Black => {
                if s < 0 || s >= u_size || t < 0 || t >= v_size {
                    return &self.black;
                }
                (s as usize, t as usize)
            }
        };
        &l[(ss, tt)]
    }

    pub fn lookup(&self, st: &Point2f, width: f32) -> T {
        // Compute MIPMap-level for trilinear filtering
        let level = self.levels() as f32 - 1.0 + width.max(1e-8).log2();
        // Perform trilinear interpolation at appropriate MIPMap level
        if level < 0.0 {
            self.triangle(0, st)
        } else if level >= self.levels() as f32 - 1.0 {
            *self.texel(self.levels() - 1, 0, 0)
        } else {
            let i_level = level.floor();
            let delta = level - i_level;
            lerp(delta,
                 self.triangle(i_level as usize, st),
                 self.triangle(i_level as usize + 1, st))
        }
    }

    pub fn triangle(&self, level: usize, st: &Point2f) -> T {
        let level = na::clamp(level, 0, self.levels() - 1);
        let s = st.x * self.pyramid[level].u_size() as f32 - 0.5;
        let t = st.y * self.pyramid[level].v_size() as f32 - 0.5;
        let s0 = s.floor() as isize;
        let t0 = t.floor() as isize;
        let ds = s - s0 as f32;
        let dt = t - t0 as f32;
        debug!("st={:?}, s={}, t={}, s0={}, t0={}, ds={}, dt={}",
               st,
               s,
               t,
               s0,
               t0,
               ds,
               dt);

        *self.texel(level, s0, t0) * (1.0 - ds) * (1.0 - dt) +
        *self.texel(level, s0, t0 + 1) * (1.0 - ds) * dt +
        *self.texel(level, s0 + 1, t0) * ds * (1.0 - dt) +
        *self.texel(level, s0 + 1, t0 + 1) * ds * dt
    }

    fn resample_weights(old_res: usize, new_res: usize) -> Vec<ResampleWeight> {
        assert!(new_res >= old_res);
        let mut wt = Vec::with_capacity(new_res);
        let filter_width = 2.0;
        let mut w = [0.0; 4];
        for i in 0..new_res {
            // compute image resampling weights for ith texel
            let center = (i as f32 + 0.5) * (old_res as f32 / new_res as f32);
            let first_texel = ((center - filter_width) + 0.5).floor() as u32;
            for j in 0..4 {
                let pos = first_texel as f32 + j as f32 + 0.5;
                w[j] = Self::lanczos((pos - center) / filter_width);
            }
            // Normalize filter weights for texel resampling
            let inv_sum_weights = 1.0 / (w[0] + w[1] + w[2] + w[3]);
            for j in 0..4 {
                w[j] *= inv_sum_weights;
                assert!(w[j] <= 1.0);
            }
            wt.push(ResampleWeight {
                first_texel: first_texel,
                weights: w,
            });
        }

        wt
    }

    fn lanczos(f: f32) -> f32 {
        let tau = 2.0;
        let mut x = f.abs();
        if x < 1e-5 {
            return 1.0;
        };
        if x > 1.0 {
            return 0.0;
        };
        x *= f32::consts::PI;
        let s = (x * tau).sin() / (x * tau);
        let lanczos = x.sin() / x;
        s * lanczos
    }
}

struct ResampleWeight {
    pub first_texel: u32,
    pub weights: [f32; 4],
}

pub trait Clampable {
    fn clamp(self, min: f32, max: f32) -> Self;
}

impl Clampable for f32 {
    fn clamp(self, min: f32, max: f32) -> f32 {
        na::clamp(self, min, max)
    }
}

impl Clampable for Spectrum {
    fn clamp(self, min: f32, max: f32) -> Spectrum {
        Spectrum::rgb(self.r.clamp(min, max),
                      self.g.clamp(min, max),
                      self.b.clamp(min, max))
    }
}

fn modulo(a: isize, b: isize) -> usize {
    let result = a % b;
    if result < 0 {
        (result + b) as usize
    } else {
        result as usize
    }
}
<commit_msg>Downgrade log in mipmap to trace level<commit_after>use std::ops::{Mul, AddAssign};
use std::cmp;
use std::f32;
use std::fmt::Debug;

use na;
use num::{zero, Zero};

use ::Point2i;
use ::Point2f;
use ::lerp;
use blockedarray::BlockedArray;
use spectrum::Spectrum;

pub enum WrapMode {
    Repeat,
    Black,
    Clamp,
}

pub struct MIPMap<T> {
    do_trilinear: bool,
    max_anisotropy: f32,
    wrap_mode: WrapMode,
    resolution: Point2i,
    pyramid: Vec<BlockedArray<T>>,
    black: T,
}

impl<T> MIPMap<T>
    where T: Zero,
          T: Clone,
          T: Copy,
          T: Clampable,
          T: Debug,
          T: AddAssign<T>,
          T: Mul<f32, Output = T>
{
    pub fn new(res: &Point2i,
               img: &[T],
               do_trilinear: bool,
               max_anisotropy: f32,
               wrap_mode: WrapMode)
               -> MIPMap<T> {
        info!("Creating MIPMap for texture");
        let mut resolution = *res;
        let mut resampled_image = Vec::new();
        if !res.x.is_power_of_two() || !res.y.is_power_of_two() {
            info!("Texture dimensions are not powers of 2: re-sampling.");
            // resample image to power of two resolution
            let res_pow2 = Point2i::new(res.x.next_power_of_two(), res.y.next_power_of_two());
            // resample image in s direction
            resampled_image.resize(res_pow2.x as usize * res_pow2.y as usize, zero());
            let s_weights = MIPMap::<T>::resample_weights(res.x as usize, res_pow2.x as usize);
            // apply s_weights to zoom in s direction
            for t in 0..res.y as usize {
                for s in 0..res_pow2.x as usize {
                    // Compute texel (s,t) in s-zoomed image
                    resampled_image[t * res_pow2.x as usize + s] = zero();
                    for j in 0..4 {
                        let mut orig_s = s_weights[s].first_texel as usize + j;
                        orig_s = match wrap_mode {
                            WrapMode::Repeat => orig_s % res.x as usize,
                            WrapMode::Clamp => na::clamp(orig_s, 0, res.x as usize - 1),
                            WrapMode::Black => orig_s,
                        };
                        if orig_s < res.x as usize {
                            resampled_image[t * res_pow2.x as usize + s] +=
                                img[(t * res.x as usize + orig_s) as usize] *
                                s_weights[s].weights[j];
                        }
                    }

                }
            }
            // TODO use rayon to parallelize this loop?
            // resample image in t direction
            let t_weights = MIPMap::<T>::resample_weights(res.y as usize, res_pow2.y as usize);
            // apply t_weights to zoom in t direction
            for s in 0..res_pow2.x as usize {
                let mut work_data: Vec<T> = vec![zero(); res_pow2.y as usize];
                for t in 0..res_pow2.y as usize {
                    // work_data[t] = zero();
                    // Compute texel (s,t) in t-zoomed image
                    for j in 0..4 {
                        let mut offset = t_weights[t].first_texel as usize + j;
                        offset = match wrap_mode {
                            WrapMode::Repeat => offset % res.y as usize,
                            WrapMode::Clamp => na::clamp(offset, 0, res.y as usize - 1),
                            WrapMode::Black => offset,
                        };
                        if offset < res.y as usize {
                            work_data[t] += img[(offset * res_pow2.x as usize + s) as usize] *
                                            t_weights[t].weights[j];
                        }
                    }
                }
                for t in 0..res_pow2.y as usize {
                    resampled_image[t * res_pow2.x as usize + s] = work_data[t].clamp(0.0, 1.0);
                }
            }
            resolution = res_pow2;
        }

        let mut mipmap = MIPMap {
            do_trilinear: do_trilinear,
            max_anisotropy: max_anisotropy,
            wrap_mode: wrap_mode,
            resolution: resolution,
            pyramid: Vec::new(),
            black: zero(),
        };

        // initialize levels of MIPMap for image
        let n_levels = 1 + (cmp::max(resolution.x, resolution.y) as f32).log2() as usize;
        info!("mipmap will have {} levels", n_levels);
        // Initialize most detailed level of the pyramid
        let img_data = if resampled_image.is_empty() {
            img
        } else {
            &resampled_image[..]
        };
        // level 0
        mipmap.pyramid
            .push(BlockedArray::new_from(resolution.x as usize, resolution.y as usize, img_data));
        for i in 1..n_levels {
            // initialize ith level of the pyramid
            let s_res = cmp::max(1, mipmap.pyramid[i - 1].u_size() / 2);
            let t_res = cmp::max(1, mipmap.pyramid[i - 1].v_size() / 2);
            let mut ba = BlockedArray::new(s_res, t_res);
            // Filter 4 texels from finer level of pyramid
            for t in 0..t_res {
                for s in 0..s_res {
                    let (si, ti) = (s as isize, t as isize);
                    ba[(s, t)] = (*mipmap.texel(i - 1, 2 * si, 2 * ti) +
                                  *mipmap.texel(i - 1, 2 * si + 1, 2 * ti) +
                                  *mipmap.texel(i - 1, 2 * si, 2 * ti + 1) +
                                  *mipmap.texel(i - 1, 2 * si + 1, 2 * ti + 1)) *
                                 0.25;
                    debug!("l={}, ba[({}, {})]={:?}", i, s, t, ba[(s, t)]);
                }
            }
            mipmap.pyramid.push(ba);
        }
        // initialize EWA filter weights if needed

        mipmap
    }

    pub fn width(&self) -> usize {
        self.resolution.x as usize
    }

    pub fn height(&self) -> usize {
        self.resolution.y as usize
    }

    pub fn levels(&self) -> usize {
        self.pyramid.len()
    }

    pub fn texel(&self, level: usize, s: isize, t: isize) -> &T {
        let l = &self.pyramid[level];
        let (u_size, v_size) = (l.u_size() as isize, l.v_size() as isize);
        let (ss, tt): (usize, usize) = match self.wrap_mode {
            WrapMode::Repeat => (modulo(s, u_size), modulo(t, v_size)),
            WrapMode::Clamp => {
                (na::clamp(s, 0, u_size - 1) as usize, na::clamp(t, 0, v_size - 1) as usize)
            }
            WrapMode::Black => {
                if s < 0 || s >= u_size || t < 0 || t >= v_size {
                    return &self.black;
                }
                (s as usize, t as usize)
            }
        };
        &l[(ss, tt)]
    }

    pub fn lookup(&self, st: &Point2f, width: f32) -> T {
        // Compute MIPMap-level for trilinear filtering
        let level = self.levels() as f32 - 1.0 + width.max(1e-8).log2();
        // Perform trilinear interpolation at appropriate MIPMap level
        if level < 0.0 {
            self.triangle(0, st)
        } else if level >= self.levels() as f32 - 1.0 {
            *self.texel(self.levels() - 1, 0, 0)
        } else {
            let i_level = level.floor();
            let delta = level - i_level;
            lerp(delta,
                 self.triangle(i_level as usize, st),
                 self.triangle(i_level as usize + 1, st))
        }
    }

    pub fn triangle(&self, level: usize, st: &Point2f) -> T {
        let level = na::clamp(level, 0, self.levels() - 1);
        let s = st.x * self.pyramid[level].u_size() as f32 - 0.5;
        let t = st.y * self.pyramid[level].v_size() as f32 - 0.5;
        let s0 = s.floor() as isize;
        let t0 = t.floor() as isize;
        let ds = s - s0 as f32;
        let dt = t - t0 as f32;
        trace!("st={:?}, s={}, t={}, s0={}, t0={}, ds={}, dt={}",
               st,
               s,
               t,
               s0,
               t0,
               ds,
               dt);

        *self.texel(level, s0, t0) * (1.0 - ds) * (1.0 - dt) +
        *self.texel(level, s0, t0 + 1) * (1.0 - ds) * dt +
        *self.texel(level, s0 + 1, t0) * ds * (1.0 - dt) +
        *self.texel(level, s0 + 1, t0 + 1) * ds * dt
    }

    fn resample_weights(old_res: usize, new_res: usize) -> Vec<ResampleWeight> {
        assert!(new_res >= old_res);
        let mut wt = Vec::with_capacity(new_res);
        let filter_width = 2.0;
        let mut w = [0.0; 4];
        for i in 0..new_res {
            // compute image resampling weights for ith texel
            let center = (i as f32 + 0.5) * (old_res as f32 / new_res as f32);
            let first_texel = ((center - filter_width) + 0.5).floor() as u32;
            for j in 0..4 {
                let pos = first_texel as f32 + j as f32 + 0.5;
                w[j] = Self::lanczos((pos - center) / filter_width);
            }
            // Normalize filter weights for texel resampling
            let inv_sum_weights = 1.0 / (w[0] + w[1] + w[2] + w[3]);
            for j in 0..4 {
                w[j] *= inv_sum_weights;
                assert!(w[j] <= 1.0);
            }
            wt.push(ResampleWeight {
                first_texel: first_texel,
                weights: w,
            });
        }

        wt
    }

    fn lanczos(f: f32) -> f32 {
        let tau = 2.0;
        let mut x = f.abs();
        if x < 1e-5 {
            return 1.0;
        };
        if x > 1.0 {
            return 0.0;
        };
        x *= f32::consts::PI;
        let s = (x * tau).sin() / (x * tau);
        let lanczos = x.sin() / x;
        s * lanczos
    }
}

struct ResampleWeight {
    pub first_texel: u32,
    pub weights: [f32; 4],
}

pub trait Clampable {
    fn clamp(self, min: f32, max: f32) -> Self;
}

impl Clampable for f32 {
    fn clamp(self, min: f32, max: f32) -> f32 {
        na::clamp(self, min, max)
    }
}

impl Clampable for Spectrum {
    fn clamp(self, min: f32, max: f32) -> Spectrum {
        Spectrum::rgb(self.r.clamp(min, max),
                      self.g.clamp(min, max),
                      self.b.clamp(min, max))
    }
}

fn modulo(a: isize, b: isize) -> usize {
    let result = a % b;
    if result < 0 {
        (result + b) as usize
    } else {
        result as usize
    }
}
<|endoftext|>


<commit_before>use std::str::FromStr;

pub enum BookCategory {
    Journal,
    Notepad,
    Scratchpad,
}

pub struct Entry {
    pub date: String, // TODO Proper date type
    pub content: String,
}

pub struct Book {
    pub title: String,
    category: BookCategory,
    pub entries: Vec<Entry>,
}

impl FromStr for BookCategory {
    type Err = ();

    fn from_str(s: &str) -> Result<BookCategory, ()> {
        match s {
            "journal" => Ok(BookCategory::Journal),
            "notepad" => Ok(BookCategory::Notepad),
            "scratchpad" => Ok(BookCategory::Scratchpad),
            _ => Err(()),
        }
    }
}

impl Book {
    pub fn new(title: &str, category: &str) -> Book {
        Book {
            title: String::from(title),
            category: category.parse::<BookCategory>().expect("Unknown book category"),
            entries: vec![],
        }
    }

    pub fn add_entry(&mut self, entry: Entry) {
        self.entries.push(entry)
    }
}

impl Entry {
    pub fn new() -> Entry {
        Entry {
            date: String::new(),
            content: String::new(),
        }
    }

    pub fn set_content(&mut self, content: &str) {
        self.content = String::from(content);
    }

    pub fn title(&self) -> &String {
        &self.content
    }
}
<commit_msg>Add ToString to BookCategory<commit_after>use std::str::FromStr;

const JOURNAL: &'static str = "journal";
const NOTEPAD: &'static str = "notepad";
const SCRATCHPAD: &'static str = "scratchpad";

pub enum BookCategory {
    Journal,
    Notepad,
    Scratchpad,
}

pub struct Entry {
    pub date: String, // TODO Proper date type
    pub content: String,
}

pub struct Book {
    pub title: String,
    category: BookCategory,
    pub entries: Vec<Entry>,
}

impl FromStr for BookCategory {
    type Err = ();

    fn from_str(s: &str) -> Result<BookCategory, ()> {
        match s {
            JOURNAL => Ok(BookCategory::Journal),
            NOTEPAD => Ok(BookCategory::Notepad),
            SCRATCHPAD => Ok(BookCategory::Scratchpad),
            _ => Err(()),
        }
    }
}

impl ToString for BookCategory {
    fn to_string(&self) -> String {
        let result = match *self {
            BookCategory::Journal => JOURNAL,
            BookCategory::Notepad => NOTEPAD,
            BookCategory::Scratchpad => SCRATCHPAD,
        };
        result.to_string()
    }
}

impl Book {
    pub fn new(title: &str, category: &str) -> Book {
        Book {
            title: String::from(title),
            category: category.parse::<BookCategory>().expect("Unknown book category"),
            entries: vec![],
        }
    }

    pub fn add_entry(&mut self, entry: Entry) {
        self.entries.push(entry)
    }
}

impl Entry {
    pub fn new() -> Entry {
        Entry {
            date: String::new(),
            content: String::new(),
        }
    }

    pub fn set_content(&mut self, content: &str) {
        self.content = String::from(content);
    }

    pub fn title(&self) -> &String {
        &self.content
    }
}
<|endoftext|>


<commit_before>use std::ops::{Add, Sub, Div};
use std::collections::HashMap;
use std::iter::FromIterator;
use std::iter::repeat;
use std::fmt::{Debug, Formatter, Error};
use std::cmp::Ordering::Equal;
use std::ops::Drop;
use std::cmp;
use std::path::Path;
use std::io::{BufWriter, Write, BufReader, Read, BufRead};
use std::fs::File;
use std::mem;

#[derive(Clone)]
pub struct WordVec {
    pub word: String,
    pub count: u64,
    vec: Vec<f32>,
}

impl PartialEq for WordVec {
    fn eq(&self, other: &WordVec) -> bool {
        self.vec == other.vec
    }
}

impl Debug for WordVec {
    fn fmt(&self, fmt: &mut Formatter) -> Result<(), Error> {
        try!(self.word.fmt(fmt));
        try!(fmt.write_str(": "));
        try!(self.count.fmt(fmt));
        try!(fmt.write_str(", "));
        self.vec.iter().take(5).collect::<Vec<_>>().fmt(fmt)
    }
}

impl WordVec {

    fn dot_prod(&self, other: &WordVec) -> f32 {
        self.vec.iter()
                .zip(other.vec.iter())
                .map(|(x, y)| x * y)
                .fold(0.0, |x, y| x + y)
    }

    fn magnitude(&self) -> f32 {
        self.vec.iter()
                .map(|x| x * x)
                .fold(0.0, |x, y| x + y)
                .sqrt()
    }

    pub fn distance(&self, other: &WordVec) -> f32 {
        self.vec.iter().zip(other.vec.iter())
                .map(|(x, y)| (x - y)*(x - y))
                .fold(0.0, |x, y| x + y)
                .sqrt()
    }

    fn new(word: String, num_words: usize) -> WordVec {
        WordVec {
            word: word,
            count: 0,
            vec: repeat(0.0).take(num_words).collect(),
        }
    }

    fn normalize(&mut self, cooccurences: f32) {
        for f in &mut self.vec {
            *f /= cooccurences;
        }
    }

    fn inc(&mut self, i: usize) {
        self.vec[i] += 1.0;
    }

}

impl Div<i32> for WordVec {
    type Output = WordVec;

    fn div(mut self, i: i32) -> WordVec {
        for f in &mut self.vec {
            *f /= i as f32;
        }

        self
    }
}

impl<'a> Add<&'a WordVec> for WordVec {
    type Output = WordVec;

    fn add(self, other: &WordVec) -> WordVec {
        debug_assert!(self.vec.len() == other.vec.len());
        let mut newvec = WordVec {
            word: format!("{} + {}", &self.word, &other.word),
            count: 0,
            vec: self.vec,
        };

        for i in 0..newvec.vec.len() {
            newvec.vec[i] += other.vec[i];
        }

        newvec
    }
}

impl<'a> Sub<&'a WordVec> for WordVec {
    type Output = WordVec;

    fn sub(self, other: &WordVec) -> WordVec {
        debug_assert!(self.vec.len() == other.vec.len());
        let mut newvec = WordVec {
            word: format!("{} - {}", &self.word, &other.word),
            count: 0,
            vec: self.vec,
        };

        for i in 0..(newvec.vec.len()) {
            newvec.vec[i] -= other.vec[i];
        }

        newvec
    }
}

#[derive(Clone, PartialEq, Debug)]
pub struct LanguageModel {
    words: HashMap<String, usize>,
    word_vecs: Vec<WordVec>,
}

pub struct LanguageModelBuilder {
    window_radius: usize,
    words: HashMap<String, usize>,
    word_vecs: Vec<WordVec>,
    sentence: Vec<Option<usize>>,
}

pub struct WordAcceptor<'a> {
    builder: &'a mut LanguageModelBuilder,
}

impl LanguageModelBuilder {
    pub fn new(window_radius: usize, words: Vec<String>) -> LanguageModelBuilder {

        let word_vecs = words.iter()
                             .map(|s| WordVec::new(s.clone(), words.len()))
                             .collect();

        let words = HashMap::from_iter(
                        words.into_iter()
                             .enumerate()
                             .map(|(a, b)| (b, a)));

        LanguageModelBuilder {
            window_radius: window_radius,
            words: words,
            word_vecs: word_vecs,
            sentence: vec![],
        }
    }

    pub fn build(mut self) -> LanguageModel {
        let mut cooccurences: Vec<f32> = repeat(0.0).take(self.word_vecs.len()).collect();
        for vec in &self.word_vecs {
            for (count, x) in cooccurences.iter_mut().zip(vec.vec.iter()) {
                *count += *x;
            }
        }

        for (vec, c) in self.word_vecs.iter_mut().zip(cooccurences.iter()) {
            vec.normalize(*c);
        }

        LanguageModel {
            words: self.words,
            word_vecs: self.word_vecs,
        }
    }

    pub fn new_sentence<'a>(&'a mut self) -> WordAcceptor<'a> {
        WordAcceptor {
            builder: self,
        }
    }

    fn word_seen(&mut self, word: usize) {
        self.word_vecs[word].count += 1;
    }

    pub fn save(&self, path: &Path) {
        let mut file = BufWriter::new(File::create(path).unwrap());

        write_raw(self.word_vecs.len(), &mut file);
        file.write(&[b'\n']).unwrap();

        for vec in &self.word_vecs {
            file.write(vec.word.as_bytes()).unwrap();
            file.write(&[b':']).unwrap();
            let count = vec.count;
            write_raw(count, &mut file);
            for f in &vec.vec {
                write_raw(*f, &mut file)
            }
            file.write(&[b'\n']).unwrap();
        }

    }

    pub fn load(path: &Path) -> LanguageModelBuilder {
        let mut file = BufReader::new(File::open(path).unwrap());
        let mut word_vecs = Vec::new();

        let size: u64 = unsafe { read_raw::<u64, _>(&mut file) };
        read_byte(b'\n', &mut file);

        for _ in 0..size {
            let mut word: Vec<u8> = Vec::new();
            file.read_until(b':', &mut word).unwrap();
            assert_eq!(Some(b':'), word.pop());
            let word = String::from_utf8(word).unwrap();
            let count: u64 = unsafe { read_raw::<u64, _>(&mut file) };

            let mut vec: Vec<f32> = repeat(0f32).take(size as usize).collect();
            for f in &mut vec {
                unsafe {
                    *f = read_raw::<f32, _>(&mut file);
                }
            }

            read_byte(b'\n', &mut file);

            word_vecs.push(WordVec {
                word: word,
                count: count,
                vec: vec,
            });
        }

        let words: HashMap<_, _> = word_vecs.iter()
                                            .map(|v| v.word.clone())
                                            .enumerate()
                                            .map(|(i, w)| (w, i))
                                            .collect();

        LanguageModelBuilder {
            window_radius: 0,
            words: words,
            word_vecs: word_vecs,
            sentence: Vec::new(),
        }
    }
}

impl<'a> WordAcceptor<'a> {
    pub fn add_word(&mut self, word: &str) {
        let idx_opt = self.builder.words.get(word).map(|w| *w);

        if let Some(next_idx) = idx_opt {
            self.builder.word_seen(next_idx);
            self.builder.sentence.push(Some(next_idx));
        }
        else {
            self.builder.sentence.push(None);
        }
    }
}

impl<'a> Drop for WordAcceptor<'a> {
    fn drop(&mut self) {
        let LanguageModelBuilder {
            ref mut sentence,
            ref mut word_vecs,
            window_radius,
            ..
        } = *self.builder;

        for (i, &word_idx) in sentence.iter().enumerate() {
            let start = cmp::max(0, i as isize - window_radius as isize) as usize;
            let end = cmp::min(sentence.len(), i + window_radius + 1);
            for &j in &sentence[start..end] {
                match (word_idx, j) {
                    (Some(w), Some(j)) if w != j =>
                        word_vecs[w].inc(j),
                    _ => {},
                }
            }
        }

        sentence.clear();
    }
}

impl LanguageModel {
    pub fn get(&self, word: &str) -> Option<&WordVec> {
        self.words.get(word).map(|i| &self.word_vecs[*i])
    }

    pub fn nearest_words(&self, word: &WordVec) -> Vec<&WordVec> {
        let mut vec_refs = self.word_vecs.iter().filter_map(|w| {
            let dist = w.distance(word);
            if w.word != word.word {
                Some((dist, w))
            } else {
                None
            }
        }).collect::<Vec<_>>();
        vec_refs.sort_by(|a, b| a.0.partial_cmp(&b.0).unwrap_or_else(|| {
            println!("bad vector: {:?}, {:?}", a, b);
            Equal
        }));
        vec_refs.into_iter().map(|x| x.1).collect()
    }

}

fn read_byte<R: Read>(b: u8, read: &mut R) {
    let buf = &mut [0];
    while read.read(buf).unwrap() == 0 {}
    assert_eq!(&[b], buf);
}

unsafe fn read_raw<T: Copy, R: Read>(reader: &mut BufReader<R>) -> T {
    let mut buffer = [0u8; 64];
    let t_size = mem::size_of::<T>();
    assert!(t_size <= buffer.len());

    let mut remainder = t_size;
    while remainder > 0 {
        let bytes_read = reader.read(&mut buffer[(t_size-remainder)..t_size]).unwrap();
        remainder -= bytes_read;
    }

    let bptr: *mut T = mem::transmute(buffer.as_ptr());
    *bptr
}

fn write_raw<T: Copy, F: Write>(t: T, writer: &mut BufWriter<F>) {
    let mut buffer = [0u8; 64];
    let t_size = mem::size_of::<T>();
    assert!(t_size <= buffer.len());
    unsafe {
        let bptr: *mut T = mem::transmute(buffer.as_ptr());
        *bptr = t;
    }

    writer.write(&buffer[0..t_size]);
}

#[cfg(test)]
mod test {
    use super::{WordVec, LanguageModel, LanguageModelBuilder};
    use std::path::Path;

    fn get_builder() -> LanguageModelBuilder {
        let words = "foo bar baz blort".split(" ").map(|w| w.to_string()).collect::<Vec<_>>();
        let mut builder = LanguageModelBuilder::new(1, words);

        let input = "x foo bar baz x x x x x x x blort".split(" ");

        {
            let mut acc = builder.new_sentence();
            for word in input {
                acc.add_word(word);
            }
        }

        builder
    }

    #[test]
    fn test_accept_sentences() {
        let model = get_builder().build();
        let foo = model.get("foo").unwrap();
        let baz = model.get("baz").unwrap();
        let bar = model.get("bar").unwrap();
        let blort = model.get("blort").unwrap();

        assert!(foo.distance(baz) < foo.distance(blort));
        assert!(foo.distance(bar) == bar.distance(baz));
    }

    #[test]
    fn test_serialization() {
        let builder = get_builder();
        let path = Path::new("/tmp/model.data");
        builder.save(&path);

        let loaded_model = LanguageModelBuilder::load(path).build();
        assert_eq!(builder.build(), loaded_model);
    }
}
<commit_msg>Fix case where a word has no cooccurences.<commit_after>use std::ops::{Add, Sub, Div};
use std::collections::HashMap;
use std::iter::FromIterator;
use std::iter::repeat;
use std::fmt::{Debug, Formatter, Error};
use std::cmp::Ordering::Equal;
use std::ops::Drop;
use std::cmp;
use std::path::Path;
use std::io::{BufWriter, Write, BufReader, Read, BufRead};
use std::fs::File;
use std::mem;

#[derive(Clone)]
pub struct WordVec {
    pub word: String,
    pub count: u64,
    vec: Vec<f32>,
}

impl PartialEq for WordVec {
    fn eq(&self, other: &WordVec) -> bool {
        self.vec == other.vec
    }
}

impl Debug for WordVec {
    fn fmt(&self, fmt: &mut Formatter) -> Result<(), Error> {
        try!(self.word.fmt(fmt));
        try!(fmt.write_str(": "));
        try!(self.count.fmt(fmt));
        try!(fmt.write_str(", "));
        self.vec.iter().take(5).collect::<Vec<_>>().fmt(fmt)
    }
}

impl WordVec {

    fn dot_prod(&self, other: &WordVec) -> f32 {
        self.vec.iter()
                .zip(other.vec.iter())
                .map(|(x, y)| x * y)
                .fold(0.0, |x, y| x + y)
    }

    fn magnitude(&self) -> f32 {
        self.vec.iter()
                .map(|x| x * x)
                .fold(0.0, |x, y| x + y)
                .sqrt()
    }

    pub fn distance(&self, other: &WordVec) -> f32 {
        self.vec.iter().zip(other.vec.iter())
                .map(|(x, y)| (x - y)*(x - y))
                .fold(0.0, |x, y| x + y)
                .sqrt()
    }

    fn new(word: String, num_words: usize) -> WordVec {
        WordVec {
            word: word,
            count: 0,
            vec: repeat(0.0).take(num_words).collect(),
        }
    }

    fn normalize(&mut self, cooccurences: f32) {
        for f in &mut self.vec {
            *f /= cooccurences;
        }
    }

    fn inc(&mut self, i: usize) {
        self.vec[i] += 1.0;
    }

}

impl Div<i32> for WordVec {
    type Output = WordVec;

    fn div(mut self, i: i32) -> WordVec {
        for f in &mut self.vec {
            *f /= i as f32;
        }

        self
    }
}

impl<'a> Add<&'a WordVec> for WordVec {
    type Output = WordVec;

    fn add(self, other: &WordVec) -> WordVec {
        debug_assert!(self.vec.len() == other.vec.len());
        let mut newvec = WordVec {
            word: format!("{} + {}", &self.word, &other.word),
            count: 0,
            vec: self.vec,
        };

        for i in 0..newvec.vec.len() {
            newvec.vec[i] += other.vec[i];
        }

        newvec
    }
}

impl<'a> Sub<&'a WordVec> for WordVec {
    type Output = WordVec;

    fn sub(self, other: &WordVec) -> WordVec {
        debug_assert!(self.vec.len() == other.vec.len());
        let mut newvec = WordVec {
            word: format!("{} - {}", &self.word, &other.word),
            count: 0,
            vec: self.vec,
        };

        for i in 0..(newvec.vec.len()) {
            newvec.vec[i] -= other.vec[i];
        }

        newvec
    }
}

#[derive(Clone, PartialEq, Debug)]
pub struct LanguageModel {
    words: HashMap<String, usize>,
    word_vecs: Vec<WordVec>,
}

pub struct LanguageModelBuilder {
    window_radius: usize,
    words: HashMap<String, usize>,
    word_vecs: Vec<WordVec>,
    sentence: Vec<Option<usize>>,
}

pub struct WordAcceptor<'a> {
    builder: &'a mut LanguageModelBuilder,
}

impl LanguageModelBuilder {
    pub fn new(window_radius: usize, words: Vec<String>) -> LanguageModelBuilder {

        let word_vecs = words.iter()
                             .map(|s| WordVec::new(s.clone(), words.len()))
                             .collect();

        let words = HashMap::from_iter(
                        words.into_iter()
                             .enumerate()
                             .map(|(a, b)| (b, a)));

        LanguageModelBuilder {
            window_radius: window_radius,
            words: words,
            word_vecs: word_vecs,
            sentence: vec![],
        }
    }

    pub fn build(mut self) -> LanguageModel {
        let mut cooccurences: Vec<f32> = repeat(0.0).take(self.word_vecs.len()).collect();
        for vec in &self.word_vecs {
            for (count, x) in cooccurences.iter_mut().zip(vec.vec.iter()) {
                *count += *x;
            }
        }

        for (vec, c) in self.word_vecs.iter_mut().zip(cooccurences.iter()) {
            vec.normalize(c.max(1.0));
        }

        LanguageModel {
            words: self.words,
            word_vecs: self.word_vecs,
        }
    }

    pub fn new_sentence<'a>(&'a mut self) -> WordAcceptor<'a> {
        WordAcceptor {
            builder: self,
        }
    }

    fn word_seen(&mut self, word: usize) {
        self.word_vecs[word].count += 1;
    }

    pub fn save(&self, path: &Path) {
        let mut file = BufWriter::new(File::create(path).unwrap());

        write_raw(self.word_vecs.len(), &mut file);
        file.write(&[b'\n']).unwrap();

        for vec in &self.word_vecs {
            file.write(vec.word.as_bytes()).unwrap();
            file.write(&[b':']).unwrap();
            let count = vec.count;
            write_raw(count, &mut file);
            for f in &vec.vec {
                write_raw(*f, &mut file)
            }
            file.write(&[b'\n']).unwrap();
        }

    }

    pub fn load(path: &Path) -> LanguageModelBuilder {
        let mut file = BufReader::new(File::open(path).unwrap());
        let mut word_vecs = Vec::new();

        let size: u64 = unsafe { read_raw::<u64, _>(&mut file) };
        read_byte(b'\n', &mut file);

        for _ in 0..size {
            let mut word: Vec<u8> = Vec::new();
            file.read_until(b':', &mut word).unwrap();
            assert_eq!(Some(b':'), word.pop());
            let word = String::from_utf8(word).unwrap();
            let count: u64 = unsafe { read_raw::<u64, _>(&mut file) };

            let mut vec: Vec<f32> = repeat(0f32).take(size as usize).collect();
            for f in &mut vec {
                unsafe {
                    *f = read_raw::<f32, _>(&mut file);
                }
            }

            read_byte(b'\n', &mut file);

            word_vecs.push(WordVec {
                word: word,
                count: count,
                vec: vec,
            });
        }

        let words: HashMap<_, _> = word_vecs.iter()
                                            .map(|v| v.word.clone())
                                            .enumerate()
                                            .map(|(i, w)| (w, i))
                                            .collect();

        LanguageModelBuilder {
            window_radius: 0,
            words: words,
            word_vecs: word_vecs,
            sentence: Vec::new(),
        }
    }
}

impl<'a> WordAcceptor<'a> {
    pub fn add_word(&mut self, word: &str) {
        let idx_opt = self.builder.words.get(word).map(|w| *w);

        if let Some(next_idx) = idx_opt {
            self.builder.word_seen(next_idx);
            self.builder.sentence.push(Some(next_idx));
        }
        else {
            self.builder.sentence.push(None);
        }
    }
}

impl<'a> Drop for WordAcceptor<'a> {
    fn drop(&mut self) {
        let LanguageModelBuilder {
            ref mut sentence,
            ref mut word_vecs,
            window_radius,
            ..
        } = *self.builder;

        for (i, &word_idx) in sentence.iter().enumerate() {
            let start = cmp::max(0, i as isize - window_radius as isize) as usize;
            let end = cmp::min(sentence.len(), i + window_radius + 1);
            for &j in &sentence[start..end] {
                match (word_idx, j) {
                    (Some(w), Some(j)) if w != j =>
                        word_vecs[w].inc(j),
                    _ => {},
                }
            }
        }

        sentence.clear();
    }
}

impl LanguageModel {
    pub fn get(&self, word: &str) -> Option<&WordVec> {
        self.words.get(word).map(|i| &self.word_vecs[*i])
    }

    pub fn nearest_words(&self, word: &WordVec) -> Vec<&WordVec> {
        let mut vec_refs = self.word_vecs.iter().filter_map(|w| {
            let dist = w.distance(word);
            if w.word != word.word {
                Some((dist, w))
            } else {
                None
            }
        }).collect::<Vec<_>>();
        vec_refs.sort_by(|a, b| a.0.partial_cmp(&b.0).unwrap_or_else(|| {
            println!("bad vector: {:?}, {:?}", a, b);
            Equal
        }));
        vec_refs.into_iter().map(|x| x.1).collect()
    }

}

fn read_byte<R: Read>(b: u8, read: &mut R) {
    let buf = &mut [0];
    while read.read(buf).unwrap() == 0 {}
    assert_eq!(&[b], buf);
}

unsafe fn read_raw<T: Copy, R: Read>(reader: &mut BufReader<R>) -> T {
    let mut buffer = [0u8; 64];
    let t_size = mem::size_of::<T>();
    assert!(t_size <= buffer.len());

    let mut remainder = t_size;
    while remainder > 0 {
        let bytes_read = reader.read(&mut buffer[(t_size-remainder)..t_size]).unwrap();
        remainder -= bytes_read;
    }

    let bptr: *mut T = mem::transmute(buffer.as_ptr());
    *bptr
}

fn write_raw<T: Copy, F: Write>(t: T, writer: &mut BufWriter<F>) {
    let mut buffer = [0u8; 64];
    let t_size = mem::size_of::<T>();
    assert!(t_size <= buffer.len());
    unsafe {
        let bptr: *mut T = mem::transmute(buffer.as_ptr());
        *bptr = t;
    }

    writer.write(&buffer[0..t_size]);
}

#[cfg(test)]
mod test {
    use super::{WordVec, LanguageModel, LanguageModelBuilder};
    use std::path::Path;

    fn get_builder() -> LanguageModelBuilder {
        let words = "foo bar baz blort".split(" ").map(|w| w.to_string()).collect::<Vec<_>>();
        let mut builder = LanguageModelBuilder::new(1, words);

        let input = "x foo bar baz x x x x x x x blort".split(" ");

        {
            let mut acc = builder.new_sentence();
            for word in input {
                acc.add_word(word);
            }
        }

        builder
    }

    #[test]
    fn test_accept_sentences() {
        let model = get_builder().build();
        let foo = model.get("foo").unwrap();
        let baz = model.get("baz").unwrap();
        let bar = model.get("bar").unwrap();
        let blort = model.get("blort").unwrap();

        assert!(foo.distance(baz) < foo.distance(blort));
        assert!(foo.distance(bar) == bar.distance(baz));
    }

    #[test]
    fn test_serialization() {
        let builder = get_builder();
        let path = Path::new("/tmp/model.data");
        builder.save(&path);

        let loaded_model = LanguageModelBuilder::load(path).build();
        assert_eq!(builder.build(), loaded_model);
    }
}
<|endoftext|>


<commit_before>use sqlite::{Connection, Statement, State};
use std::mem;

use streamer::{Config, Result};
use streamer::platform::{self, Platform, Profile};
use streamer::system::Event;

pub struct Output {
    #[allow(dead_code)]
    connection: Connection,
    statement: Statement<'static>,
    buffer: (usize, usize, Vec<f64>, Vec<f64>),
}

impl Output {
    pub fn new(platform: &platform::Thermal, config: &Config) -> Result<Self> {
        use sql::prelude::*;

        let connection = ok!(Connection::open(path!(@unchecked config,
                                                    "an output file is required")));
        ok!(connection.execute("
            PRAGMA journal_mode = MEMORY;
            PRAGMA synchronous = OFF;
        "));
        ok!(connection.execute(
            ok!(create_table("profiles").if_not_exists().columns(&[
                "time".float().not_null(), "component_id".integer().not_null(),
                "power".float().not_null(), "temperature".float().not_null(),
            ]).compile())
        ));
        ok!(connection.execute(ok!(delete_from("profiles").compile())));
        let units = platform.elements().len();
        let statement = {
            let statement = ok!(connection.prepare(
                ok!(insert_into("profiles").columns(&[
                    "time", "component_id", "power", "temperature",
                ]).batch(units).compile())
            ));
            unsafe { mem::transmute(statement) }
        };
        let subsample = *config.get::<i64>("subsample").unwrap_or(&1);
        if subsample <= 0 {
            raise!("the subsample size should be greater than zero");
        }
        Ok(Output {
            connection: connection,
            statement: statement,
            buffer: (subsample as usize, 0, vec![0.0; units], vec![0.0; units]),
        })
    }

    pub fn next(&mut self, _: &Event, profiles: &(Profile, Profile)) -> Result<()> {
        ok!(self.connection.execute("BEGIN TRANSACTION"));
        ok!(self.write_profiles(profiles));
        ok!(self.connection.execute("END TRANSACTION"));
        Ok(())
    }

    fn write_profiles(&mut self, profiles: &(Profile, Profile)) -> Result<()> {
        let &Profile { units, steps, time, time_step, data: ref new_power } = &profiles.0;
        let &Profile { data: ref new_temperature, .. } = &profiles.1;
        let &mut Output { ref mut statement, ref mut buffer, .. } = self;
        let &mut (subsample, ref mut position, ref mut power, ref mut temperature) = buffer;
        for i in 0..steps {
            for j in 0..units {
                power[j] += new_power[i * units + j];
                temperature[j] += new_temperature[i * units + j];
            }
            *position = (*position + 1) % subsample;
            if *position > 0 {
                continue;
            }
            let time = time + (i as f64) * time_step;
            ok!(statement.reset());
            let mut k = 0;
            for j in 0..units {
                power[j] /= subsample as f64;
                temperature[j] /= subsample as f64;
                ok!(statement.bind(k + 1, time));
                ok!(statement.bind(k + 2, j as i64));
                ok!(statement.bind(k + 3, power[j]));
                ok!(statement.bind(k + 4, temperature[j]));
                power[j] = 0.0;
                temperature[j] = 0.0;
                k += 4;
            }
            if State::Done != ok!(statement.next()) {
                raise!("failed to write into the database");
            }
        }
        Ok(())
    }
}
<commit_msg>Make a cosmetic adjustment<commit_after>use sqlite::{Connection, Statement, State};
use std::mem;

use streamer::{Config, Result};
use streamer::platform::{self, Platform, Profile};
use streamer::system::Event;

pub struct Output {
    #[allow(dead_code)]
    connection: Connection,
    profiles: Statement<'static>,
    buffer: (usize, usize, Vec<f64>, Vec<f64>),
}

impl Output {
    pub fn new(platform: &platform::Thermal, config: &Config) -> Result<Self> {
        use sql::prelude::*;

        let connection = ok!(Connection::open(path!(@unchecked config,
                                                    "an output file is required")));
        ok!(connection.execute("
            PRAGMA journal_mode = MEMORY;
            PRAGMA synchronous = OFF;
        "));
        ok!(connection.execute(
            ok!(create_table("profiles").if_not_exists().columns(&[
                "time".float().not_null(), "component_id".integer().not_null(),
                "power".float().not_null(), "temperature".float().not_null(),
            ]).compile())
        ));
        ok!(connection.execute(ok!(delete_from("profiles").compile())));
        let units = platform.elements().len();
        let profiles = {
            let statement = ok!(connection.prepare(
                ok!(insert_into("profiles").columns(&[
                    "time", "component_id", "power", "temperature",
                ]).batch(units).compile())
            ));
            unsafe { mem::transmute(statement) }
        };
        let subsample = *config.get::<i64>("subsample").unwrap_or(&1);
        if subsample <= 0 {
            raise!("the subsample size should be greater than zero");
        }
        Ok(Output {
            connection: connection,
            profiles: profiles,
            buffer: (subsample as usize, 0, vec![0.0; units], vec![0.0; units]),
        })
    }

    pub fn next(&mut self, _: &Event, profiles: &(Profile, Profile)) -> Result<()> {
        ok!(self.connection.execute("BEGIN TRANSACTION"));
        ok!(self.write_profiles(profiles));
        ok!(self.connection.execute("END TRANSACTION"));
        Ok(())
    }

    fn write_profiles(&mut self, profiles: &(Profile, Profile)) -> Result<()> {
        let &Profile { units, steps, time, time_step, data: ref new_power } = &profiles.0;
        let &Profile { data: ref new_temperature, .. } = &profiles.1;
        let &mut Output { profiles: ref mut statement, ref mut buffer, .. } = self;
        let &mut (subsample, ref mut position, ref mut power, ref mut temperature) = buffer;
        for i in 0..steps {
            for j in 0..units {
                power[j] += new_power[i * units + j];
                temperature[j] += new_temperature[i * units + j];
            }
            *position = (*position + 1) % subsample;
            if *position > 0 {
                continue;
            }
            let time = time + (i as f64) * time_step;
            ok!(statement.reset());
            let mut k = 0;
            for j in 0..units {
                power[j] /= subsample as f64;
                temperature[j] /= subsample as f64;
                ok!(statement.bind(k + 1, time));
                ok!(statement.bind(k + 2, j as i64));
                ok!(statement.bind(k + 3, power[j]));
                ok!(statement.bind(k + 4, temperature[j]));
                power[j] = 0.0;
                temperature[j] = 0.0;
                k += 4;
            }
            if State::Done != ok!(statement.next()) {
                raise!("failed to write into the database");
            }
        }
        Ok(())
    }
}
<|endoftext|>


<commit_before>use ast::AST;
use helpers::operator_precedence;
use std::collections::VecDeque;

/// Parses string into AST
pub struct Parser {
    var_stack: VecDeque<AST>,
    op_stack: VecDeque<String>,
    err: Result<bool, String>,
}

impl Parser {
    pub fn new() -> Self {
        Parser {
            var_stack: VecDeque::new(),
            op_stack: VecDeque::new(),
            err: Ok(true),
        }
    }

    /// collapse_stacks combines the current variable and operator stacks into an AST
    /// and pushes the result back onto the variable stack
    fn collapse_stacks(&mut self) {
        let mut paren_count = 0;
        while !self.op_stack.is_empty() {
            let operator = self.op_stack.pop_front().unwrap();

            match operator.as_str() {
                ")" => paren_count += 1,
                "(" => paren_count -= 1,

                "!" => {
                    let var = self.var_stack.pop_front().unwrap();
                    self.var_stack.push_front(AST::Not(Box::new(var)));
                },

                // Double parameter operators
                _ => {
                    let var1 = self.var_stack.pop_front().unwrap();
                    let var2 = self.var_stack.pop_front().unwrap();

                    let ast_node = match operator.as_str() {
                        "=" => AST::Assign(Box::new(var1), Box::new(var2)),
                        "+" => AST::Plus(Box::new(var1), Box::new(var2)),
                        "-" => AST::Minus(Box::new(var1), Box::new(var2)),
                        "*" => AST::Times(Box::new(var1), Box::new(var2)),
                        "/" => AST::Divide(Box::new(var1), Box::new(var2)),
                        "%" => AST::Modulo(Box::new(var1), Box::new(var2)),
                        "^" => AST::Exponent(Box::new(var1), Box::new(var2)),
                        "&&" => AST::And(Box::new(var1), Box::new(var2)),
                        "||" => AST::Or(Box::new(var1), Box::new(var2)),
                        _ => AST::None,
                    };

                    self.var_stack.push_front(ast_node);
                }
            }
        }

        if paren_count != 0 {
            self.err = Err("Parentheses do not match".to_string());
        }
    }

    /// Takes in two deques for the variables and operators
    /// and returns the parsed AST value
    pub fn parse_to_ast(&mut self,
                        variables: &mut VecDeque<AST>,
                        operators: &mut VecDeque<String>)
                        -> Option<AST> {
        while !operators.is_empty() {
            if !variables.is_empty() {
                self.var_stack.push_front(variables.pop_back().unwrap());
            }

            let mut lower_precedence = false;

            // check if the next operator has greater precedence than the
            // current operator on the stack
            // an operator with precedence -1 ignores precedence rules
            let operator = operators.pop_back().unwrap();

            if self.op_stack.len() > 0 {
                let front_operator = self.op_stack.front().unwrap();
                if operator_precedence(operator.as_str()) <
                   operator_precedence(front_operator.as_str()) &&
                   operator_precedence(operator.as_str()) != -1 {
                    lower_precedence = true;
                }
            }

            if lower_precedence {
                self.collapse_stacks();
            }

            self.op_stack.push_front(operator);
        }

        self.collapse_stacks();

        self.var_stack.pop_front()
    }
}

#[test]
fn test_collapse_stacks() {
    // test ast generation for `1 * (2 + 3)`

    let mut parser = Parser::new();

    parser.var_stack.push_front(AST::Number("1".to_string()));
    parser.var_stack.push_front(AST::Number("2".to_string()));
    parser.var_stack.push_front(AST::Number("3".to_string()));

    parser.op_stack.push_front("*".to_string());
    parser.op_stack.push_front("(".to_string());
    parser.op_stack.push_front("+".to_string());
    parser.op_stack.push_front(")".to_string());

    parser.collapse_stacks();

    assert_eq!(parser.var_stack.len(), 1);

    match parser.var_stack.pop_front().take() {
        Some(root) => {
            match root {
                AST::Times(box leaf1, box leaf2) => {
                    match leaf1 {
                        AST::Plus(box leaf1, box leaf2) => {
                            assert_eq!(leaf1, AST::Number("3".to_string()));
                            assert_eq!(leaf2, AST::Number("2".to_string()));
                        }
                        _ => {
                            println!("Left child node is not a plus operator");
                            assert!(false);
                        }
                    }

                    assert_eq!(leaf2, AST::Number("1".to_string()));
                }
                _ => {
                    println!("Root node is not a times operator");
                    assert!(false);
                }
            }
        }
        None => {
            println!("Failed to unparse the first element");
            assert!(false);
        }
    }
}

#[test]
fn test_parse_to_ast() {
    // test ast generation for `1 + !5 ^ (2 && 6) * 2`
    let mut parser = Parser::new();

    let mut variables = VecDeque::new();
    let mut operators = VecDeque::new();

    variables.push_front(AST::Number("1".to_string()));
    variables.push_front(AST::Number("5".to_string()));
    variables.push_front(AST::Number("2".to_string()));
    variables.push_front(AST::Number("6".to_string()));
    variables.push_front(AST::Number("2".to_string()));

    operators.push_front("+".to_string());
    operators.push_front("!".to_string());
    operators.push_front("^".to_string());
    operators.push_front("(".to_string());
    operators.push_front("&&".to_string());
    operators.push_front(")".to_string());
    operators.push_front("*".to_string());

    let result = parser.parse_to_ast(&mut variables, &mut operators);

    println!("{:?}", result);
}
<commit_msg>Fixed parser and added test case<commit_after>use ast::AST;
use helpers::operator_precedence;
use std::collections::VecDeque;

/// Parses string into AST
pub struct Parser {
    var_stack: VecDeque<AST>,
    op_stack: VecDeque<String>,
    err: Result<bool, String>,
}

impl Parser {
    pub fn new() -> Self {
        Parser {
            var_stack: VecDeque::new(),
            op_stack: VecDeque::new(),
            err: Ok(true),
        }
    }

    /// collapse_stacks combines the current variable and operator stacks into an AST
    /// and pushes the result back onto the variable stack
    fn collapse_stacks(&mut self, add_op_precedence: i32) {
        let mut paren_count = 0;
        while !self.op_stack.is_empty() &&
              (add_op_precedence < operator_precedence(self.op_stack.front().unwrap()) ||
               paren_count > 0) {
            let operator = self.op_stack.pop_front().unwrap();

            match operator.as_str() {
                ")" => paren_count += 1,
                "(" => paren_count -= 1,

                "!" => {
                    let var = self.var_stack.pop_front().unwrap();
                    self.var_stack.push_front(AST::Not(Box::new(var)));
                }

                // Double parameter operators
                _ => {
                    let var1 = self.var_stack.pop_front().unwrap();
                    let var2 = self.var_stack.pop_front().unwrap();

                    let ast_node = match operator.as_str() {
                        "=" => AST::Assign(Box::new(var2), Box::new(var1)),
                        "+" => AST::Plus(Box::new(var2), Box::new(var1)),
                        "-" => AST::Minus(Box::new(var2), Box::new(var1)),
                        "*" => AST::Times(Box::new(var2), Box::new(var1)),
                        "/" => AST::Divide(Box::new(var2), Box::new(var1)),
                        "%" => AST::Modulo(Box::new(var2), Box::new(var1)),
                        "^" => AST::Exponent(Box::new(var2), Box::new(var1)),
                        "&&" => AST::And(Box::new(var2), Box::new(var1)),
                        "||" => AST::Or(Box::new(var2), Box::new(var1)),
                        _ => AST::None,
                    };

                    self.var_stack.push_front(ast_node);
                }
            }
        }

        if paren_count != 0 {
            self.err = Err("Parentheses do not match".to_string());
        }
    }

    /// Takes in two deques for the variables and operators
    /// and returns the parsed AST value
    pub fn parse_to_ast(&mut self,
                        variables: &mut VecDeque<AST>,
                        operators: &mut VecDeque<String>)
                        -> Option<AST> {
        while !operators.is_empty() {
            let mut lower_precedence = false;
            let mut op_precedence = -2;

            // check if the next operator has greater precedence than the
            // current operator on the stack
            // an operator with precedence -1 ignores precedence rules
            let operator = operators.pop_back().unwrap();

            if self.op_stack.len() > 0 {
                let front_operator = self.op_stack.front().unwrap();
                if operator_precedence(operator.as_str()) <
                   operator_precedence(front_operator.as_str()) &&
                   operator_precedence(operator.as_str()) != -1 {
                    lower_precedence = true;
                    op_precedence = operator_precedence(operator.as_str());
                }
            }

            if lower_precedence {
                self.collapse_stacks(op_precedence);
            }

            if !variables.is_empty() && operator != "(" && operator != ")" {
                self.var_stack.push_front(variables.pop_back().unwrap());
            }

            self.op_stack.push_front(operator);
        }

        self.collapse_stacks(-2);

        self.var_stack.pop_front()
    }
}

#[test]
fn test_collapse_stacks() {
    // test ast generation for `1 * (2 + 3)`
    // expected result:
    //      *
    //    /   \
    //   1     +
    //        / \
    //       2   3

    let mut parser = Parser::new();

    parser.var_stack.push_front(AST::Number("1".to_string()));
    parser.var_stack.push_front(AST::Number("2".to_string()));
    parser.var_stack.push_front(AST::Number("3".to_string()));

    parser.op_stack.push_front("*".to_string());
    parser.op_stack.push_front("(".to_string());
    parser.op_stack.push_front("+".to_string());
    parser.op_stack.push_front(")".to_string());

    parser.collapse_stacks(-2);

    assert_eq!(parser.var_stack.len(), 1);

    match parser.var_stack.pop_front().take() {
        Some(root) => {
            match root {
                AST::Times(box leaf1, box leaf2) => {
                    assert_eq!(leaf1, AST::Number("1".to_string()));

                    match leaf2 {
                        AST::Plus(box leaf1, box leaf2) => {
                            assert_eq!(leaf1, AST::Number("2".to_string()));
                            assert_eq!(leaf2, AST::Number("3".to_string()));
                        }
                        _ => {
                            println!("Right child node is not a plus operator");
                            assert!(false);
                        }
                    }
                }
                _ => {
                    println!("Root node is not a times operator");
                    assert!(false);
                }
            }
        }
        None => {
            println!("Failed to unparse the first element");
            assert!(false);
        }
    }
}

#[test]
fn test_parse_to_ast() {
    // test ast generation for `1 + !5 ^ (2 && 6) * 2`
    // expected result:
    //     +
    //   /   \
    //  1     *
    //      /   \
    //    ^       2
    //  /   \
    // !     &&
    // |    /  \
    // 5   2    6
    let mut parser = Parser::new();

    let mut variables = VecDeque::new();
    let mut operators = VecDeque::new();

    variables.push_front(AST::Number("1".to_string()));
    variables.push_front(AST::Number("5".to_string()));
    variables.push_front(AST::Number("2".to_string()));
    variables.push_front(AST::Number("6".to_string()));
    variables.push_front(AST::Number("2".to_string()));

    operators.push_front("+".to_string());
    operators.push_front("!".to_string());
    operators.push_front("^".to_string());
    operators.push_front("(".to_string());
    operators.push_front("&&".to_string());
    operators.push_front(")".to_string());
    operators.push_front("*".to_string());

    let result = parser.parse_to_ast(&mut variables, &mut operators);

    match result.unwrap() {
        AST::Plus(box leaf1, box leaf2) => {
            assert_eq!(leaf1, AST::Number("1".to_string()));

            match leaf2 {
                AST::Times(box leaf1, box leaf2) => {
                    assert_eq!(leaf2, AST::Number("2".to_string()));

                    match leaf1 {
                        AST::Exponent(box leaf1, box leaf2) => {
                            match leaf1 {
                                AST::Not(box leaf) => {
                                    assert_eq!(leaf, AST::Number("5".to_string()));
                                }
                                _ => {
                                    println!("Left grand-grand child is not the not operator");
                                    assert!(false);
                                }
                            }

                            match leaf2 {
                                AST::And(box leaf1, box leaf2) => {
                                    assert_eq!(leaf1, AST::Number("2".to_string()));
                                    assert_eq!(leaf2, AST::Number("6".to_string()));
                                }
                                _ => {
                                    println!("Right grand-grand child is not the and operator");
                                    assert!(false);
                                }
                            }
                        }
                        _ => {
                            println!("Left grandchild is not the exponent operator");
                            assert!(false);
                        }
                    }
                }
                _ => {
                    println!("Right child is not the times operator");
                    assert!(false);
                }
            }
        }
        _ => {
            println!("Leaf node is not the plus operator");
            assert!(false);
        }
    }
}
<|endoftext|>