matreex 0.44.1

A simple matrix implementation.
Documentation
use super::super::Matrix;
use super::super::order::{Order, OrderKind};
use crate::convert::IntoRows;
use crate::index::Index;
use alloc::boxed::Box;
use alloc::vec::Vec;
use core::mem::MaybeUninit;

impl<T, O> IntoRows<Box<[Box<[T]>]>> for Matrix<T, O>
where
    O: Order,
{
    fn into_rows(self) -> Box<[Box<[T]>]> {
        let shape = self.shape();

        match O::KIND {
            OrderKind::RowMajor => {
                let mut iter = self.data.into_iter();
                (0..shape.nrows)
                    .map(|_| iter.by_ref().take(shape.ncols).collect())
                    .collect()
            }

            OrderKind::ColMajor => {
                let mut output: Box<[Box<[MaybeUninit<T>]>]> = (0..shape.nrows)
                    .map(|_| Box::new_uninit_slice(shape.ncols))
                    .collect();
                let mut index = Index::new(0, 0);
                for element in self.data {
                    if index.row == shape.nrows {
                        index.row = 0;
                        index.col += 1;
                    }
                    unsafe {
                        output
                            .get_unchecked_mut(index.row)
                            .get_unchecked_mut(index.col)
                            .write(element);
                    }
                    index.row += 1;
                }
                output
                    .into_iter()
                    .map(|row| unsafe { row.assume_init() })
                    .collect()
            }
        }
    }
}

impl<T, O> IntoRows<Vec<Box<[T]>>> for Matrix<T, O>
where
    O: Order,
{
    fn into_rows(self) -> Vec<Box<[T]>> {
        IntoRows::<Box<[Box<[T]>]>>::into_rows(self).into_vec()
    }
}

impl<T, O> IntoRows<Box<[Vec<T>]>> for Matrix<T, O>
where
    O: Order,
{
    fn into_rows(self) -> Box<[Vec<T>]> {
        let shape = self.shape();

        match O::KIND {
            OrderKind::RowMajor => {
                let mut iter = self.data.into_iter();
                (0..shape.nrows)
                    .map(|_| iter.by_ref().take(shape.ncols).collect())
                    .collect()
            }

            OrderKind::ColMajor => {
                let mut output: Box<[Vec<T>]> = (0..shape.nrows)
                    .map(|_| Vec::with_capacity(shape.ncols))
                    .collect();
                let mut index = Index::new(0, 0);
                for element in self.data {
                    if index.row == shape.nrows {
                        index.row = 0;
                        index.col += 1;
                    }
                    unsafe {
                        output
                            .get_unchecked_mut(index.row)
                            .spare_capacity_mut()
                            .get_unchecked_mut(index.col)
                            .write(element);
                    }
                    index.row += 1;
                }
                for row in &mut output {
                    unsafe {
                        row.set_len(shape.ncols);
                    }
                }
                output
            }
        }
    }
}

impl<T, O> IntoRows<Vec<Vec<T>>> for Matrix<T, O>
where
    O: Order,
{
    fn into_rows(self) -> Vec<Vec<T>> {
        IntoRows::<Box<[Vec<T>]>>::into_rows(self).into_vec()
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use crate::convert::TryFromRows;
    use crate::dispatch_unary;
    use crate::error::Result;
    use alloc::vec;

    #[test]
    fn test_into_rows() -> Result<()> {
        dispatch_unary! {{
            let matrix = Matrix::<i32, O>::try_from_rows([[1, 2, 3], [4, 5, 6]])?;
            let output: Box<[Box<[i32]>]> = matrix.into_rows();
            let expected: Box<[Box<[i32]>]> = Box::new([Box::new([1, 2, 3]), Box::new([4, 5, 6])]);
            assert_eq!(output, expected);

            let matrix = Matrix::<i32, O>::try_from_rows([[1, 2, 3], [4, 5, 6]])?;
            let output: Vec<Box<[i32]>> = matrix.into_rows();
            let expected: Vec<Box<[i32]>> = vec![Box::new([1, 2, 3]), Box::new([4, 5, 6])];
            assert_eq!(output, expected);

            let matrix = Matrix::<i32, O>::try_from_rows([[1, 2, 3], [4, 5, 6]])?;
            let output: Box<[Vec<i32>]> = matrix.into_rows();
            let expected: Box<[Vec<i32>]> = Box::new([vec![1, 2, 3], vec![4, 5, 6]]);
            assert_eq!(output, expected);

            let matrix = Matrix::<i32, O>::try_from_rows([[1, 2, 3], [4, 5, 6]])?;
            let output: Vec<Vec<i32>> = matrix.into_rows();
            let expected: Vec<Vec<i32>> = vec![vec![1, 2, 3], vec![4, 5, 6]];
            assert_eq!(output, expected);
        }}

        Ok(())
    }
}