use std::ops::{Range, RangeFrom, RangeTo, RangeFull};
#[derive(RustcEncodable, RustcDecodable)]
#[derive(Clone, Debug)]
pub enum MatrixOrder {
RowMajor,
ColumnMajor
}
pub trait IndexableMatrix {
fn rows(&self) -> usize;
fn cols(&self) -> usize;
unsafe fn get_unchecked(&self, row: usize, column: usize) -> f32;
unsafe fn get_unchecked_mut(&mut self, row: usize, column: usize) -> &mut f32;
fn get(&self, row: usize, column: usize) -> f32 {
assert!(row < self.rows());
assert!(column < self.cols());
unsafe {
self.get_unchecked(row, column)
}
}
fn get_mut(&mut self, row: usize, column: usize) -> &mut f32 {
assert!(row < self.rows());
assert!(column < self.cols());
unsafe {
self.get_unchecked_mut(row, column)
}
}
fn set(&mut self, row: usize, column: usize, value: f32) {
assert!(row < self.rows());
assert!(column < self.cols());
unsafe {
self.set_unchecked(row, column, value);
}
}
unsafe fn set_unchecked(&mut self, row: usize, column: usize, value: f32) {
*self.get_unchecked_mut(row, column) = value;
}
}
pub trait RowIterable<T: NonzeroIterable> {
type Output: Iterator<Item=T>;
fn iter_rows(self) -> Self::Output;
fn view_row(self, idx: usize) -> T;
}
pub trait ColumnIterable<T: NonzeroIterable> {
type Output: Iterator<Item=T>;
fn iter_columns(self) -> Self::Output;
fn view_column(self, idx: usize) -> T;
}
pub trait NonzeroIterable {
type Output: Iterator<Item = (usize, f32)>;
fn iter_nonzero(self) -> Self::Output;
}
pub trait RowIndex<Rhs> {
type Output;
fn get_rows<'a>(&self, index: &'a Rhs) -> Self::Output;
}
impl<T> RowIndex<usize> for T where T: RowIndex<Vec<usize>> {
type Output = T::Output;
fn get_rows(&self, index: &usize) -> Self::Output {
self.get_rows(&vec![*index])
}
}
impl<T> RowIndex<Range<usize>> for T where T: RowIndex<Vec<usize>> {
type Output = T::Output;
fn get_rows(&self, index: &Range<usize>) -> Self::Output {
self.get_rows(&(index.start..index.end).collect::<Vec<usize>>())
}
}
impl<T> RowIndex<RangeFrom<usize>> for T where T: RowIndex<Range<usize>> + IndexableMatrix {
type Output = T::Output;
fn get_rows(&self, index: &RangeFrom<usize>) -> Self::Output {
self.get_rows(&(index.start..self.rows()))
}
}
impl<T> RowIndex<RangeTo<usize>> for T where T: RowIndex<Range<usize>> + IndexableMatrix {
type Output = T::Output;
fn get_rows(&self, index: &RangeTo<usize>) -> Self::Output {
self.get_rows(&(0..index.end))
}
}
impl<T> RowIndex<RangeFull> for T where T: RowIndex<Range<usize>> + IndexableMatrix {
type Output = T::Output;
fn get_rows(&self, _: &RangeFull) -> Self::Output {
self.get_rows(&(0..self.rows()))
}
}
pub trait ElementwiseArrayOps<Rhs> {
type Output;
fn add(&self, rhs: Rhs) -> Self::Output;
fn add_inplace(&mut self, rhs: Rhs);
fn sub(&self, rhs: Rhs) -> Self::Output;
fn sub_inplace(&mut self, rhs: Rhs);
fn times(&self, rhs: Rhs) -> Self::Output;
fn times_inplace(&mut self, rhs: Rhs);
fn div(&self, rhs: Rhs) -> Self::Output;
fn div_inplace(&mut self, rhs: Rhs);
}
pub trait Dot<Rhs> {
type Output;
fn dot(&self, rhs: Rhs) -> Self::Output;
}