dsalgo 0.3.7

A package for Datastructures and Algorithms.
Documentation
use crate::tensor_property::{Shape, Size, Strides};

// TODO: define macro for initialization.
// accept scalar, 1d vec, 2d vec, ... n-d vec.
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct Tensor<P, T> {
    _phantom: std::marker::PhantomData<P>,
    data: Vec<T>,
}

impl<P, T> Shape for Tensor<P, T>
where
    P: Shape,
{
    fn shape() -> &'static [usize] { P::shape() }
}

impl<P, T> Default for Tensor<P, T>
where
    P: Size,
    T: Default,
{
    fn default() -> Self {
        Self {
            _phantom: std::marker::PhantomData,
            data: (0..P::size()).map(|_| T::default()).collect(),
        }
    }
}

impl<P, T> Tensor<P, T>
where
    P: Size,
    T: Default,
{
    pub fn new() -> Self { Self::default() }
}

impl<P, T> From<Vec<T>> for Tensor<P, T>
where
    P: Size,
{
    fn from(v: Vec<T>) -> Self {
        assert_eq!(v.len(), P::size());
        Self {
            _phantom: std::marker::PhantomData,
            data: v,
        }
    }
}

impl<P, T> Tensor<P, T>
where
    P: Strides,
{
    fn flatten_index(&self, index: &[usize]) -> usize {
        let mut idx = 0;
        let strides = P::strides();
        assert!(index.len() == strides.len());
        for i in 0..index.len() {
            idx += index[i] * strides[i];
        }
        idx
    }
}

impl<P, T> std::ops::Index<&[usize]> for Tensor<P, T>
where
    P: Strides,
{
    type Output = T;

    fn index(&self, index: &[usize]) -> &Self::Output {
        let idx = self.flatten_index(index);
        &self.data[idx]
    }
}

impl<P, T> std::ops::IndexMut<&[usize]> for Tensor<P, T>
where
    P: Strides,
{
    fn index_mut(&mut self, index: &[usize]) -> &mut Self::Output {
        let idx = self.flatten_index(index);
        &mut self.data[idx]
    }
}

// TODO
#[cfg(test)]
mod tests {
    #[test]
    fn test() {}
}