#![allow(dead_code)]
mod matrix_impl;
use std::ops::{
Add,
Sub,
Mul,
Div,
Rem,
};
use std::fmt;
use matrix_impl::*;
use super::super::{PolymathError, PolymathErrorKind};
#[derive(PartialEq, Eq, Clone)]
pub struct Matrix<T: Clone> {
pub rows: usize,
pub columns: usize,
data: Vec<T>,
}
impl<T: Clone> Matrix<T> {
pub fn new(shape: (usize, usize), element_default: T) -> Self {
let mut data: Vec<T> = Vec::with_capacity(shape.0 * shape.1);
data.resize(shape.0 * shape.1, element_default);
return Self::from_vec(shape, data).unwrap();
}
pub fn from_vec(shape: (usize, usize), data: Vec<T>) -> Option<Self> {
if data.len() != (shape.0 * shape.1) {
return None;
}
return Some(Self {
rows: shape.0,
columns: shape.1,
data,
});
}
pub fn from_2d_vec(data: Vec<Vec<T>>) -> Option<Self> {
if data.len() == 0 {
return None;
}
if data[0].len() == 0 {
return None;
}
for i in data.iter() {
if i.len() != data[0].len() {
return None;
}
}
let rows = data.len();
let columns = data[0].len();
let mut line_data: Vec<T> = Vec::new();
for i in data.into_iter() {
for j in i.into_iter() {
line_data.push(j);
}
}
return Self::from_vec((rows, columns), line_data);
}
pub fn vec_len(&self) -> usize {
return self.data.len();
}
pub fn len(&self) -> usize {
return self.rows * self.columns;
}
pub fn len_rc(&self) -> (usize, usize) {
return (self.rows, self.columns);
}
pub fn get_linear(&self, index: usize) -> Option<T> {
if self.data.len() <= index {
return None;
}
return Some(self.data[index].clone());
}
pub fn get(&self, pos: (usize, usize)) -> Option<T> {
return self.get_linear(self.linearize(pos));
}
pub fn set_linear(&mut self, index: usize, value: T) -> Result<(), PolymathError> {
if self.data.len() <= index {
return Err(PolymathError::new(PolymathErrorKind::OutOfBounds, "Index out of bounds!"));
}
self.data[index] = value;
return Ok(());
}
pub fn set(&mut self, pos: (usize, usize), value: T) -> Result<(), PolymathError> {
return self.set_linear(self.linearize(pos), value);
}
pub fn linearize(&self, pos: (usize, usize)) -> usize {
return pos.0 * self.columns + pos.1;
}
pub fn delinearize(&self, index: usize) -> (usize, usize) {
let row = index / self.columns;
let column = index % self.columns;
return (row, column);
}
}
impl_matrix_type!(usize);
impl_matrix_type!(u8);
impl_matrix_type!(u16);
impl_matrix_type!(u32);
impl_matrix_type!(u64);
impl_matrix_type!(isize);
impl_matrix_type!(i8);
impl_matrix_type!(i16);
impl_matrix_type!(i32);
impl_matrix_type!(i64);
impl_matrix_type!(f32);
impl_matrix_type!(f64);