lin_algebra 0.5.0

A linear algebra package to compute image, kernel and rank of linear applications.
Documentation
use num_traits::{One, Zero};
use std::ops::{BitAnd, BitXor, Shl, Shr};

pub trait Number:
    Copy
    + Eq
    + Ord
    + BitXor<Output = Self>
    + BitAnd<Output = Self>
    + Shr<usize, Output = Self>
    + Shl<usize, Output = Self>
    + Zero
    + One
{
    fn into_usize(self) -> usize;
}

impl Number for u8 {
    fn into_usize(self) -> usize {
        self as usize
    }
}
impl Number for u16 {
    fn into_usize(self) -> usize {
        self as usize
    }
}
impl Number for u32 {
    fn into_usize(self) -> usize {
        self as usize
    }
}
impl Number for u64 {
    fn into_usize(self) -> usize {
        self as usize
    }
}

pub trait MatrixTrait<T: Number>: MatrixCommon<T> {
    fn rank(&self) -> usize;
    fn kernel(&self) -> Vec<Vec<T>>;
    fn echelon_form(&self) -> (Self, Vec<(usize, usize)>)
    where
        Self: Sized;
    fn image(&self) -> Vec<Vec<T>>;
    fn is_reduced_echelon(&self) -> bool;
}

#[derive(Clone, Debug)]
pub struct Matrix<T: Number> {
    pub elements: Vec<Vec<T>>,
}

impl<T: Number> Matrix<T> {
    pub fn new(elements: Vec<Vec<T>>) -> Self {
        Self { elements }
    }
}

impl<T: Number> MatrixCommon<T> for Matrix<T> {
    fn nrows(&self) -> usize {
        self.elements.len()
    }
    fn ncols(&self) -> usize {
        self.elements.first().map_or(0, |r| r.len())
    }
    fn row(&self, r: usize) -> &[T] {
        &self.elements[r]
    }
}

pub trait MatrixCommon<T: Number> {
    fn nrows(&self) -> usize;
    fn ncols(&self) -> usize;
    fn row(&self, r: usize) -> &[T];
    fn get_pivot(row: &[T]) -> Option<usize> {
        row.iter().position(|&x| !x.is_zero())
    }
}