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 {
type Item: NonzeroIterable;
type Output: Iterator<Item = Self::Item>;
fn iter_rows(self) -> Self::Output;
fn iter_rows_range(self, range: Range<usize>) -> Self::Output;
fn view_row(self, idx: usize) -> Self::Item;
}
pub trait ColumnIterable {
type Item: NonzeroIterable;
type Output: Iterator<Item = Self::Item>;
fn iter_columns(self) -> Self::Output;
fn iter_columns_range(self, range: Range<usize>) -> Self::Output;
fn view_column(self, idx: usize) -> Self::Item;
}
pub trait NonzeroIterable {
type Output: Iterator<Item = (usize, f32)>;
fn iter_nonzero(&self) -> Self::Output;
}
pub trait RowIndex<Rhs> {
type Output;
fn get_rows(&self, index: &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;
}