mirror of
https://github.com/SinTan1729/matrix-basic.git
synced 2024-12-25 21:48:35 -06:00
Initial commit
This commit is contained in:
commit
f0c10ec7d0
4 changed files with 144 additions and 0 deletions
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
/target
|
||||||
|
/Cargo.lock
|
8
Cargo.toml
Normal file
8
Cargo.toml
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
[package]
|
||||||
|
name = "matrix"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
22
src/lib.rs
Normal file
22
src/lib.rs
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
pub mod matrix;
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
use matrix::Matrix;
|
||||||
|
#[test]
|
||||||
|
fn mul_test() {
|
||||||
|
let a = Matrix::from(vec![vec![1, 2, 4], vec![3, 4, 9]]).unwrap();
|
||||||
|
let b = Matrix::from(vec![vec![1, 2], vec![2, 3], vec![5, 1]]).unwrap();
|
||||||
|
let c = Matrix::from(vec![vec![25, 12], vec![56, 27]]).unwrap();
|
||||||
|
assert_eq!(a * b, c);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn add_test() {
|
||||||
|
let a = Matrix::from(vec![vec![1, 2, 3], vec![0, 1, 2]]).unwrap();
|
||||||
|
let b = Matrix::from(vec![vec![0, 0, 1], vec![2, 1, 3]]).unwrap();
|
||||||
|
let c = Matrix::from(vec![vec![1, 2, 4], vec![2, 2, 5]]).unwrap();
|
||||||
|
assert_eq!(a + b, c);
|
||||||
|
}
|
||||||
|
}
|
112
src/matrix.rs
Normal file
112
src/matrix.rs
Normal file
|
@ -0,0 +1,112 @@
|
||||||
|
use std::{
|
||||||
|
fmt::{self, Debug, Display, Formatter},
|
||||||
|
ops::{Add, Mul},
|
||||||
|
result::Result,
|
||||||
|
};
|
||||||
|
|
||||||
|
#[derive(PartialEq, Debug)]
|
||||||
|
pub struct Matrix<T: Mul + Add> {
|
||||||
|
entries: Vec<Vec<T>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Mul + Add> Matrix<T> {
|
||||||
|
pub fn from(entries: Vec<Vec<T>>) -> Result<Matrix<T>, &'static str> {
|
||||||
|
let mut equal_rows = true;
|
||||||
|
let row_len = entries[0].len();
|
||||||
|
for row in &entries {
|
||||||
|
if row_len != row.len() {
|
||||||
|
equal_rows = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if equal_rows {
|
||||||
|
Ok(Matrix { entries })
|
||||||
|
} else {
|
||||||
|
Err("Unequal rows.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn height(&self) -> usize {
|
||||||
|
self.entries.len()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn width(&self) -> usize {
|
||||||
|
self.entries[0].len()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn transpose(&self) -> Matrix<T>
|
||||||
|
where
|
||||||
|
T: Copy,
|
||||||
|
{
|
||||||
|
let mut out = Vec::new();
|
||||||
|
for i in 0..self.width() {
|
||||||
|
let mut column = Vec::new();
|
||||||
|
for row in &self.entries {
|
||||||
|
column.push(row[i]);
|
||||||
|
}
|
||||||
|
out.push(column)
|
||||||
|
}
|
||||||
|
Matrix { entries: out }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn rows(&self) -> Vec<Vec<T>>
|
||||||
|
where
|
||||||
|
T: Copy,
|
||||||
|
{
|
||||||
|
self.entries.clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn columns(&self) -> Vec<Vec<T>>
|
||||||
|
where
|
||||||
|
T: Copy,
|
||||||
|
{
|
||||||
|
self.transpose().entries
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Debug + Mul + Add> Display for Matrix<T> {
|
||||||
|
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
||||||
|
write!(f, "{:?}", self.entries)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Mul<Output = T> + Add<Output = T> + Copy> Mul for Matrix<T> {
|
||||||
|
type Output = Self;
|
||||||
|
fn mul(self, other: Self) -> Self {
|
||||||
|
let width = self.width();
|
||||||
|
if width != other.height() {
|
||||||
|
panic!("Row length of first matrix must be same as column length of second matrix.");
|
||||||
|
} else {
|
||||||
|
let mut out = Vec::new();
|
||||||
|
for row in self.rows() {
|
||||||
|
let mut new_row = Vec::new();
|
||||||
|
for col in other.columns() {
|
||||||
|
let mut prod = row[0] * col[0];
|
||||||
|
for i in 1..width {
|
||||||
|
prod = prod + (row[i] * col[i]);
|
||||||
|
}
|
||||||
|
new_row.push(prod)
|
||||||
|
}
|
||||||
|
out.push(new_row);
|
||||||
|
}
|
||||||
|
Matrix { entries: out }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Add<Output = T> + Mul + Copy> Add for Matrix<T> {
|
||||||
|
type Output = Self;
|
||||||
|
fn add(self, other: Self) -> Self {
|
||||||
|
if self.height() == other.height() && self.width() == other.width() {
|
||||||
|
let mut out = self.entries.clone();
|
||||||
|
for (i, row) in self.rows().iter().enumerate() {
|
||||||
|
for (j, entry) in other.rows()[i].iter().enumerate() {
|
||||||
|
out[i][j] = row[j] + *entry;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Matrix { entries: out }
|
||||||
|
} else {
|
||||||
|
panic!("Both matrices must be of same dimensions.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue