use std::ops::{Index, IndexMut, Add, Sub, Mul};
use std::cmp::{PartialEq};
use std::fmt::{self, Display};
use std::marker::Copy;
#[derive(Clone)]
pub struct Matrix {
m_data: Vec<f64>,
m_rows: usize,
m_cols: usize,
}
impl Matrix {
pub fn new(rows: usize, cols: usize) -> Matrix {
let c: usize = rows * cols;
let mut m : Matrix = Matrix {
m_data: Vec::with_capacity(c),
m_rows: rows,
m_cols: cols,
};
m.m_data.resize(rows * cols, 0.0);
return m;
}
pub fn get_row(&self, row: usize) -> &[f64] {
&self.m_data[row * self.m_cols .. (row + 1) * self.m_cols]
}
pub fn eye(rows: usize) -> Matrix {
let mut m : Matrix = Matrix::new(rows, rows);
for i in 0..rows {
m[i][i] = 1.0;
}
m
}
pub fn shape(&self) -> (usize, usize) {
return (self.m_rows, self.m_cols);
}
pub fn swap_row(&mut self, row1: usize, row2: usize) {
for i in 0..self.m_cols {
self.m_data.swap(row1 * self.m_cols + i, row2 * self.m_cols + i);
}
}
pub fn get_col(&self, col:usize) -> Matrix {
let mut v = Matrix::new(self.m_rows, 1);
for i in 0..self.m_rows {
v[(i, 0)] = self[(i, col)];
}
return v;
}
}
impl Index<usize> for Matrix {
type Output = [f64];
fn index(&self, indx: usize) -> &Self::Output {
&self.m_data[indx * self.m_cols .. (indx + 1) * self.m_cols]
}
}
impl IndexMut<usize> for Matrix {
fn index_mut(&mut self, indx: usize) -> &mut Self::Output {
&mut self.m_data[indx * self.m_cols .. (indx + 1) * self.m_cols]
}
}
impl Index<(usize, usize)> for Matrix {
type Output = f64;
fn index(&self, indx: (usize, usize)) -> &Self::Output {
&self.m_data[self.m_cols * indx.0 + indx.1]
}
}
impl IndexMut<(usize, usize)> for Matrix {
fn index_mut(&mut self, indx: (usize, usize)) -> &mut Self::Output {
&mut self.m_data[self.m_cols * indx.0 + indx.1]
}
}
impl fmt::Display for Matrix {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
for row in 0..self.m_rows {
write!(f, "{:?}\n", self.get_row(row))?;
}
Ok(())
}
}
impl PartialEq for Matrix {
fn eq(&self, other: &Matrix) -> bool {
return self.m_data == other.m_data;
}
}
impl Mul<f64> for &Matrix {
type Output = Matrix;
fn mul(self, rhs: f64) -> Self::Output {
let mut m: Matrix = Matrix::new(self.m_rows, self.m_cols);
for i in 0..self.m_rows * self.m_cols {
m.m_data[i] = self.m_data[i] * rhs;
}
return m;
}
}
impl Mul<&Matrix> for f64 {
type Output = Matrix;
fn mul(self, rhs: &Matrix) -> Self::Output {
let mut m: Matrix = Matrix::new(rhs.m_rows, rhs.m_cols);
for i in 0..rhs.m_rows * rhs.m_cols {
m.m_data[i] = rhs.m_data[i] * self;
}
return m;
}
}
impl Mul<&Matrix> for &Matrix {
type Output = Matrix;
fn mul(self, rhs: &Matrix) -> Self::Output {
let mut m: Matrix = Matrix::new(self.m_rows, rhs.m_cols);
for i in 0..self.m_rows {
for j in 0..rhs.m_cols {
let mut sum = 0.0;
for n in 0..self.m_cols {
sum += self[(i, n)] * rhs[(n, j)];
}
m[(i, j)] = sum;
}
}
return m;
}
}
impl Add for &Matrix {
type Output = Matrix;
fn add(self, other: &Matrix) -> Matrix {
let mut m: Matrix = Matrix::new(self.m_rows, self.m_cols);
for i in 0..self.m_rows * self.m_cols {
m.m_data[i] = self.m_data[i] + other.m_data[i];
}
return m;
}
}
impl Sub for &Matrix {
type Output = Matrix;
fn sub(self, other: &Matrix) -> Matrix {
let mut m: Matrix = Matrix::new(self.m_rows, self.m_cols);
m = self + &(-1.0f64 * other);
return m;
}
}