use std::ops::{
Add,
Sub,
Mul,
Index,
IndexMut,
};
use crate::error::*;
#[derive(Clone, Debug)]
pub struct Matrix {
rows: usize,
cols: usize,
vals: Vec<f64>,
}
impl Matrix {
pub fn new(rows: usize, cols: usize, vals: Vec<f64>) -> Self {
Self {
rows,
cols,
vals,
}
}
pub fn scalar_multiply(&self, scalar: f64) -> Self {
let vals = self.vals.iter().map(|x| scalar*x).collect::<Vec<f64>>();
Self {
vals,
..*self
}
}
pub fn rows(&self) -> usize {
self.rows
}
pub fn cols(&self) -> usize {
self.cols
}
pub fn copy_vals(&self) -> Vec<f64> {
self.vals.to_owned()
}
pub fn vals(&self) -> &Vec<f64> {
&self.vals
}
pub fn vals_mut(&mut self) -> &mut Vec<f64> {
&mut self.vals
}
pub fn empty() -> Self {
Self {
rows: 0,
cols: 0,
vals: Vec::new(),
}
}
}
impl Add for Matrix {
type Output = Self;
fn add(self, other: Self) -> Self {
if self.rows() != other.rows() || self.cols() != other.cols() {
throw(ImproperDimensions);
Self::new(0, 0, Vec::new());
}
let mut output_vals = Vec::new();
for (i, j) in self.vals().iter().zip(other.vals().iter()) {
output_vals.push(i + j);
}
Self {
vals: output_vals,
..self
}
}
}
impl Sub for Matrix {
type Output = Self;
fn sub(self, other: Self) -> Self {
if self.rows() != other.rows() || self.cols() != other.cols() {
throw(ImproperDimensions);
Self::new(0, 0, Vec::new());
}
let mut output_vals = Vec::new();
for (i, j) in self.vals().iter().zip(other.vals().iter()) {
output_vals.push(i - j);
}
Self {
vals: output_vals,
..self
}
}
}
impl Mul for Matrix {
type Output = Self;
#[allow(unused_variables)]
fn mul(self, other: Self) -> Self {
Self::new(0, 0, Vec::new())
}
}
impl Index<[usize; 2]> for Matrix {
type Output = f64;
fn index(&self, index: [usize; 2]) -> &Self::Output {
let i = index[0];
let j = index[1];
&self.vals()[i*self.cols() + j]
}
}
impl IndexMut<[usize; 2]> for Matrix {
fn index_mut(&mut self, index: [usize; 2]) -> &mut Self::Output {
let i = index[0];
let j = index[1];
let cols = self.cols();
&mut self.vals_mut()[i*cols + j]
}
}