adtensor 0.0.3

Machine learning library with auto differentiation of arbitrary dimensional stack tensors.
Documentation
use std::marker::PhantomData;
use std::ops::{Deref, DerefMut, Mul, Div};
use std::fmt::{Debug, Formatter, Result};
use std::mem;
use generic_array::{GenericArray, ArrayLength};
use typenum::{Unsigned, Prod, Quot, Same};

pub struct RMaj;
pub struct CMaj;

pub struct Tensor<V, N, T, L>
  where N: ArrayLength<V> {
  a: GenericArray<V, N>,
  p: PhantomData<(T, L)>
}

#[macro_export]
macro_rules! tnsr {
  ($t:ty; $n:ty; $l:ty) => { Tensor<$t, $n, $t, $l> };
  ($t:ty; $n1:ty $(, $ntail:ty)*; RMaj) => { Tensor<tnsr![$t; $($ntail), *; RMaj], $n1, $t, RMaj> };
  ($t:ty; $n2:ty, $n1:ty; CMaj) => { Tensor<tnsr![$t; $n2; CMaj], $n1, $t, CMaj> };
  ($t:ty; $n2:ty, $n1:ty $(, $ntail:ty)*; CMaj) => { Tensor<tnsr![$t; $n1, $($ntail), *; CMaj], $n2, $t, CMaj> } 
} 

impl<V, N, T, L> Default for Tensor<V, N, T, L>
  where N: ArrayLength<V>,
        V: Default {
  fn default() -> Self {
    Self{a: GenericArray::<V, N>::default(), p: PhantomData::<(T, L)>::default()}
  }
}

impl<V, N, T, L> Clone for Tensor<V, N, T, L>
  where N: ArrayLength<V>,
        GenericArray<V, N>: Clone {
  fn clone(&self) -> Self {
    Self{a: self.a.clone(), p: PhantomData::<(T, L)>::default()}
  }
}

impl<V, N, T, L> Copy for Tensor<V, N, T, L> 
  where N: ArrayLength<V>,
        GenericArray<V, N>: Copy {}

impl<V, N, T, L> Deref for Tensor<V, N, T, L>
  where N: ArrayLength<V>,
        GenericArray<V, N>: Deref {
   type Target = [V];
  fn deref(&self) -> &Self::Target {
    &self.a.as_slice()
  }
}

impl<V, N, T, L> DerefMut for Tensor<V, N, T, L>
  where N: ArrayLength<V>,
        GenericArray<V, N>: DerefMut { 
  fn deref_mut(&mut self) -> &mut Self::Target {
    self.a.as_mut_slice()
  }
} 

impl<T, N> Debug for Tensor<T, N, T, RMaj>
  where N: ArrayLength<T>,
        T: Debug {
  fn fmt(&self, f: &mut Formatter) -> Result {
    let mut s = String::default();
    for (j, t) in self.iter().enumerate() {
      if j > 0 {
        s += &String::from(" ");
      }
      s += &format!("{:?}", t);
    }
    write!(f, "[{}]", s)
  }
}

impl<T, N> Debug for Tensor<T, N, T, CMaj>
  where N: ArrayLength<T>,
        T: Debug {
  fn fmt(&self, f: &mut Formatter) -> Result {
    let mut s = String::default();
    for (j, t) in self.iter().enumerate() {
      if j > 0 {
        s += &String::from("\n ");
      }
      s += &format!("{:?}", t);
    }
    write!(f, "[{}]", s)
  }
}

impl<M, N, T> Debug for Tensor<Tensor<T, N, T, RMaj>, M, T, RMaj>
  where M: ArrayLength<Tensor<T, N, T, RMaj>>,
        N: ArrayLength<T>,
        T: Debug {
  fn fmt(&self, f: &mut Formatter) -> Result {
    let mut s = String::default();
    for (i, r) in self.iter().enumerate() {
      if i > 0 {
        s += &String::from("\n ");
      }
      for (j, t) in r.iter().enumerate() {
        if j > 0 {
          s += &String::from(" ");
        }
        s += &format!("{:?}", t);
      }
    }
    write!(f, "[{}]", s)
  }
} 

impl<M, N, T> Debug for Tensor<Tensor<T, N, T, CMaj>, M, T, CMaj>
  where M: ArrayLength<Tensor<T, N, T, CMaj>> + Unsigned,
        N: ArrayLength<T> + Unsigned,
        T: Debug {
  fn fmt(&self, f: &mut Formatter) -> Result {
    let mut s = String::default();
    for i in 0..N::to_usize() {
      if i > 0 {
        s += &String::from("\n ");
      }
      for j in 0..M::to_usize() {
        if j > 0 {
          s += &String::from(" ");
        }
        s += &format!("{:?}", self[j][i]);
      }
    }
    write!(f, "[{}]", s)
  }
} 

impl<V, K, M, N, T, L> Debug for Tensor<Tensor<Tensor<V, N, T, L>, M, T, L>, K, T, L>
  where K: ArrayLength<Tensor<Tensor<V, N, T, L>, M, T, L>>,
        M: ArrayLength<Tensor<V, N, T, L>>,
        N: ArrayLength<V>,
        Tensor<Tensor<V, N, T, L>, M, T, L>: Debug {
  fn fmt(&self, f: &mut Formatter) -> Result {
    let mut s = String::default();
    for (i, r) in self.iter().enumerate() {
      if i > 0 {
        s += &String::from("\n ");
      }
      s += &format!("{:?}", r).replace("\n", "\n ");
    }
    write!(f, "[{}]", s)
  }
} 

pub trait NItems {
  fn nitems() -> usize;
}

impl<T, N, L> NItems for Tensor<T, N, T, L>
  where N: ArrayLength<T> + Unsigned {
  fn nitems() -> usize { N::to_usize() }
}

impl<V, M, N, T, L> NItems for Tensor<Tensor<V, N, T, L>, M, T, L>
  where N: ArrayLength<V>,
        Tensor<V, N, T, L>: NItems,
        M: ArrayLength<Tensor<V, N, T, L>> + Unsigned {
  fn nitems() -> usize { M::to_usize() * Tensor::<V, N, T, L>::nitems() }
}


impl<T, N, L> From<GenericArray<T, N>> for Tensor<T, N, T, L>
  where N: ArrayLength<T> {
  fn from(a: GenericArray<T, N>) -> Self {
    Self{a, p: PhantomData::<(T, L)>::default()}
  }
}

impl<T, M, N, S> From<GenericArray<T, S>> for Tensor<Tensor<T, N, T, RMaj>, M, T, RMaj>
  where M: ArrayLength<Tensor<T, N, T, RMaj>> + Mul<N>,
        N: ArrayLength<T> + Unsigned,
        S: ArrayLength<T> + Same<Prod<M, N>>,
        T: Copy {
  fn from(a: GenericArray<T, S>) -> Self {
    let mut tn =  Self{a: unsafe { mem::uninitialized() }, 
                       p: PhantomData::<(T, RMaj)>::default()};
    let mut s = &a[..];
    let n = N::to_usize();
    for r in tn.iter_mut() {
       r[..].copy_from_slice(&s[..n]);
       s = &s[n..];
    }
    tn
  }
}

impl<T, M, N, S> From<GenericArray<T, S>> for Tensor<Tensor<T, M, T, CMaj>, N, T, CMaj>
  where M: ArrayLength<T> + Mul<N> + Unsigned,
        N: ArrayLength<Tensor<T, M, T, CMaj>> + Unsigned,
        S: ArrayLength<T> + Same<Prod<M, N>>,
        T: Copy {
  fn from(a: GenericArray<T, S>) -> Self {
    let mut tn =  Self{a: unsafe { mem::uninitialized() }, 
                       p: PhantomData::<(T, CMaj)>::default()};
    let n = N::to_usize();
    let m = M::to_usize();
    let mut u = 0;
    for j in 0..n {
      for i in 0..m {
        tn[j][i] = a[u];
        u += 1;
      }
    }
    tn
  }
}

impl<V, T, K, M, N, L, S> From<GenericArray<T, S>> for Tensor<Tensor<Tensor<V, N, T, L>, M, T, L>, K, T, L>
  where K: ArrayLength<Tensor<Tensor<V, N, T, L>, M, T, L>> + Unsigned, 
        M: ArrayLength<Tensor<V, N, T, L>>,
        N: ArrayLength<V>,
        S: ArrayLength<T> + Div<K>,
        Quot<S, K>: ArrayLength<T>,
        Tensor<Tensor<V, N, T, L>, M, T, L>: From<GenericArray<T, Quot<S, K>>>,
        Tensor<V, N, T, L>: NItems,
        T: Copy,
        GenericArray<T, Quot<S, K>>: Copy {
  fn from(a: GenericArray<T, S>) -> Self {
    let mut tn: Self =  unsafe { mem::uninitialized() };
    let mut s = &a[..];
    let mut ra: GenericArray<T, Quot<S, K>> = unsafe { mem::uninitialized() };
    let q = Tensor::<Tensor<V, N, T, L>, M, T, L>::nitems();
    let k = K::to_usize();
    for i in 0..k {
      ra[..].copy_from_slice(&s[..q]);
      tn[i] = Tensor::<Tensor<V, N, T, L>, M, T, L>::from(ra);
      s = &s[q..];
    }
    tn
  }
}