use num_traits::Signed;
use std::ops::{Index, IndexMut, Neg};
#[derive(Debug)]
pub struct SquareMatrix<C> {
pub size: usize,
data: Vec<C>,
}
impl<C: Clone> SquareMatrix<C> {
pub fn new(size: usize, value: C) -> SquareMatrix<C> {
let mut v = Vec::with_capacity(size * size);
v.resize(size * size, value);
SquareMatrix {
size: size,
data: v,
}
}
pub fn fill(&mut self, value: C) {
self.data.clear();
self.data.resize(self.size * self.size, value);
}
}
impl<C: Clone> Clone for SquareMatrix<C> {
fn clone(&self) -> SquareMatrix<C> {
SquareMatrix {
size: self.size,
data: self.data.clone(),
}
}
}
impl<C: Clone + Signed> Neg for SquareMatrix<C> {
type Output = SquareMatrix<C>;
fn neg(self) -> SquareMatrix<C> {
SquareMatrix {
size: self.size,
data: self.data.iter().map(|x| -x.clone()).collect::<Vec<_>>(),
}
}
}
impl<C> SquareMatrix<C> {
pub fn from_vec(values: Vec<C>) -> SquareMatrix<C> {
let size = (values.len() as f32).sqrt().round() as usize;
assert_eq!(
size * size,
values.len(),
"length of vector is not a square number"
);
SquareMatrix {
size: size,
data: values,
}
}
fn idx(&self, i: &(usize, usize)) -> usize {
i.0 * self.size + i.1
}
}
impl<'a, C> Index<&'a (usize, usize)> for SquareMatrix<C> {
type Output = C;
fn index(&self, index: &'a (usize, usize)) -> &C {
&self.data[self.idx(index)]
}
}
impl<'a, C> IndexMut<&'a (usize, usize)> for SquareMatrix<C> {
fn index_mut(&mut self, index: &'a (usize, usize)) -> &mut C {
let i = self.idx(index);
&mut self.data[i]
}
}