use matrix::{Matrix, MatrixSlice, MatrixSliceMut};
use std::marker::PhantomData;
impl<'a, T> MatrixSlice<'a, T> {
pub fn from_matrix(mat: &'a Matrix<T>,
start: [usize; 2],
rows: usize,
cols: usize)
-> MatrixSlice<T> {
assert!(start[0] + rows <= mat.rows,
"View dimensions exceed matrix dimensions.");
assert!(start[1] + cols <= mat.cols,
"View dimensions exceed matrix dimensions.");
unsafe {
MatrixSlice {
ptr: mat.data().get_unchecked(start[0] * mat.cols + start[1]) as *const T,
rows: rows,
cols: cols,
row_stride: mat.cols,
marker: PhantomData::<&'a T>,
}
}
}
pub unsafe fn from_raw_parts(ptr: *const T,
rows: usize,
cols: usize,
row_stride: usize)
-> MatrixSlice<'a, T> {
MatrixSlice {
ptr: ptr,
rows: rows,
cols: cols,
row_stride: row_stride,
marker: PhantomData::<&'a T>,
}
}
}
impl<'a, T> MatrixSliceMut<'a, T> {
pub fn from_matrix(mat: &'a mut Matrix<T>,
start: [usize; 2],
rows: usize,
cols: usize)
-> MatrixSliceMut<T> {
assert!(start[0] + rows <= mat.rows,
"View dimensions exceed matrix dimensions.");
assert!(start[1] + cols <= mat.cols,
"View dimensions exceed matrix dimensions.");
let mat_cols = mat.cols;
unsafe {
MatrixSliceMut {
ptr: mat.mut_data().get_unchecked_mut(start[0] * mat_cols + start[1]) as *mut T,
rows: rows,
cols: cols,
row_stride: mat_cols,
marker: PhantomData::<&'a mut T>,
}
}
}
pub unsafe fn from_raw_parts(ptr: *mut T,
rows: usize,
cols: usize,
row_stride: usize)
-> MatrixSliceMut<'a, T> {
MatrixSliceMut {
ptr: ptr,
rows: rows,
cols: cols,
row_stride: row_stride,
marker: PhantomData::<&'a mut T>,
}
}
}
#[cfg(test)]
mod tests {
use matrix::{Matrix, MatrixSlice, MatrixSliceMut, BaseMatrix, Axes};
#[test]
#[should_panic]
fn make_slice_bad_dim() {
let a = Matrix::ones(3, 3) * 2.0;
let _ = MatrixSlice::from_matrix(&a, [1, 1], 3, 2);
}
#[test]
fn make_slice() {
let a = Matrix::ones(3, 3) * 2.0;
let b = MatrixSlice::from_matrix(&a, [1, 1], 2, 2);
assert_eq!(b.rows(), 2);
assert_eq!(b.cols(), 2);
}
#[test]
fn make_slice_mut() {
let mut a = Matrix::ones(3, 3) * 2.0;
{
let mut b = MatrixSliceMut::from_matrix(&mut a, [1, 1], 2, 2);
assert_eq!(b.rows(), 2);
assert_eq!(b.cols(), 2);
b += 2.0;
}
let exp = matrix![2.0, 2.0, 2.0;
2.0, 4.0, 4.0;
2.0, 4.0, 4.0];
assert_matrix_eq!(a, exp);
}
#[test]
fn matrix_min_max() {
let a = matrix![1., 3., 5., 4.;
2., 4., 7., 1.;
1., 1., 0., 0.];
assert_eq!(a.min(Axes::Col), vector![1., 1., 0.]);
assert_eq!(a.min(Axes::Row), vector![1., 1., 0., 0.]);
assert_eq!(a.max(Axes::Col), vector![5., 7., 1.]);
assert_eq!(a.max(Axes::Row), vector![2., 4., 7., 4.]);
let r = matrix![1., 3., 5., 4.];
assert_eq!(r.min(Axes::Col), vector![1.]);
assert_eq!(r.min(Axes::Row), vector![1., 3., 5., 4.]);
assert_eq!(r.max(Axes::Col), vector![5.]);
assert_eq!(r.max(Axes::Row), vector![1., 3., 5., 4.]);
let c = matrix![1.; 2.; 3.];
assert_eq!(c.min(Axes::Col), vector![1., 2., 3.]);
assert_eq!(c.min(Axes::Row), vector![1.]);
assert_eq!(c.max(Axes::Col), vector![1., 2., 3.]);
assert_eq!(c.max(Axes::Row), vector![3.]);
let t = matrix![1., 2.; 0., 1.];
assert_eq!(t.min(Axes::Col), vector![1., 0.]);
assert_eq!(t.min(Axes::Row), vector![0., 1.]);
assert_eq!(t.max(Axes::Col), vector![2., 1.]);
assert_eq!(t.max(Axes::Row), vector![1., 2.]);
}
}