adtensor 0.0.3

Machine learning library with auto differentiation of arbitrary dimensional stack tensors.
Documentation
use crate::vector::Vector;
use std::ops::{Deref, DerefMut, Add, AddAssign, Mul};
use std::iter::{FromIterator};
use std::fmt::{Display, Debug, Formatter, Result};
use generic_array::{GenericArray, ArrayLength};
use typenum::{Unsigned};

#[derive(Debug)]
pub struct Matrix<T, R, C>
  where C: ArrayLength<T>,
        R: ArrayLength<Vector<T, C>> {
  a: GenericArray<Vector<T, C>, R>
}

impl<T, R, C> Display for Matrix<T, R, C> 
  where T: Debug,
        C: ArrayLength<T>,
        R: ArrayLength<Vector<T, C>> {
  fn fmt(&self, f: &mut Formatter) -> Result {
    write!(f , "[{}]", self.a.iter()
                             .map(|v| format!("{}", v))
                             .collect::<Vec<String>>()
                             .join(", "))
  }
} 

impl<T, R, C> Deref for Matrix<T, R, C>
  where C: ArrayLength<T>,
        R: ArrayLength<Vector<T, C>> {
  type Target = GenericArray<Vector<T, C>, R>;
  #[inline]
  fn deref(&self) -> &Self::Target {
    &self.a
  }
}

impl<T, R, C> DerefMut for Matrix<T, R, C>
  where C: ArrayLength<T>,
        R: ArrayLength<Vector<T, C>>  {
  #[inline]
  fn deref_mut(&mut self) -> &mut Self::Target {
    &mut self.a
  }
}

impl<T, R, C> FromIterator<T> for Matrix<T, R, C>
  where C: ArrayLength<T>,
        R: ArrayLength<Vector<T, C>> {
  fn from_iter<I>(i: I) -> Self
    where I: IntoIterator<Item=T> {
    let mut m: Self = unsafe { std::mem::uninitialized() };
    let mut i = i.into_iter();
    for v in &mut m[..] {
      for p in &mut v[..] {
        unsafe { std::ptr::write(p, i.next().unwrap()) };
      }
    }
    m
  }
}

impl<T, M, K> Matrix<T, M, K>
  where K: ArrayLength<T> + Unsigned,
        M: ArrayLength<Vector<T, K>> + Unsigned {
  pub fn matmul<'b, N>(&self, cmat: &'b Matrix<T, N, K>) -> Matrix<T, M, N>
    where T: Default + Copy + Add<T, Output=T> + AddAssign<T> + Mul<T, Output=T>,
          N: ArrayLength<Vector<T, K>> + ArrayLength<T> + Unsigned,
          M: ArrayLength<Vector<T, N>> {
    let mut out: Matrix<T, M, N> = unsafe { std::mem::uninitialized() };
    for (r, row) in self.iter().enumerate() {
      for (c, col) in cmat.iter().enumerate() {
        out[r][c] = row.dot(&col);
      }
    }
    out
  }
}