diff --git a/src/lib.rs b/src/lib.rs index a827db4..8d53e57 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,6 +1,6 @@ //! This is a crate for very basic matrix operations -//! with any type that supports addition, substraction, -//! and multiplication. Additional properties might be +//! with any type that implement [`Add`], [`Sub`], [`Mul`], +//! [`Zero`] and [`Copy`]. Additional properties might be //! needed for certain operations. //! I created it mostly to learn using generic types //! and traits. @@ -23,11 +23,11 @@ mod tests; /// and multiplication defined on it). /// Look at [`from`](Self::from()) to see examples. #[derive(PartialEq, Debug, Clone)] -pub struct Matrix { +pub struct Matrix + Add + Sub + Zero + Copy> { entries: Vec>, } -impl Matrix { +impl + Add + Sub + Zero + Copy> Matrix { /// Creates a matrix from given 2D "array" in a `Vec>` form. /// It'll throw an error if all the given rows aren't of the same size. /// # Example @@ -65,10 +65,7 @@ impl Matrix { } /// Returns the transpose of a matrix. - pub fn transpose(&self) -> Self - where - T: Copy, - { + pub fn transpose(&self) -> Self { let mut out = Vec::new(); for i in 0..self.width() { let mut column = Vec::new(); @@ -86,10 +83,7 @@ impl Matrix { } /// Return the columns of a matrix as `Vec>`. - pub fn columns(&self) -> Vec> - where - T: Copy, - { + pub fn columns(&self) -> Vec> { self.transpose().entries } @@ -107,10 +101,7 @@ impl Matrix { /// let n = Matrix::from(vec![vec![5,6]]).unwrap(); /// assert_eq!(m.submatrix(0,0),n); /// ``` - pub fn submatrix(&self, row: usize, col: usize) -> Self - where - T: Copy, - { + pub fn submatrix(&self, row: usize, col: usize) -> Self { let mut out = Vec::new(); for (m, row_iter) in self.entries.iter().enumerate() { if m == row { @@ -138,13 +129,7 @@ impl Matrix { /// let m = Matrix::from(vec![vec![1,2],vec![3,4]]).unwrap(); /// assert_eq!(m.det(),Ok(-2)); /// ``` - pub fn det(&self) -> Result - where - T: Copy, - T: Mul, - T: Sub, - T: Zero, - { + pub fn det(&self) -> Result { if self.is_square() { // It's a recursive algorithm using minors. // TODO: Implement a faster algorithm. @@ -181,10 +166,6 @@ impl Matrix { /// ``` pub fn det_in_field(&self) -> Result where - T: Copy, - T: Mul, - T: Sub, - T: Zero, T: One, T: PartialEq, T: Div, @@ -237,10 +218,6 @@ impl Matrix { /// ``` pub fn row_echelon(&self) -> Self where - T: Copy, - T: Mul, - T: Sub, - T: Zero, T: One, T: PartialEq, T: Div, @@ -284,10 +261,6 @@ impl Matrix { /// See [`row_echelon`](Self::row_echelon()) and [`transpose`](Self::transpose()). pub fn column_echelon(&self) -> Self where - T: Copy, - T: Mul, - T: Sub, - T: Zero, T: One, T: PartialEq, T: Div, @@ -305,10 +278,6 @@ impl Matrix { /// ``` pub fn reduced_row_echelon(&self) -> Self where - T: Copy, - T: Mul, - T: Sub, - T: Zero, T: One, T: PartialEq, T: Div, @@ -329,10 +298,7 @@ impl Matrix { } /// Creates a zero matrix of a given size. - pub fn zero(height: usize, width: usize) -> Self - where - T: Zero, - { + pub fn zero(height: usize, width: usize) -> Self { let mut out = Vec::new(); for _ in 0..height { let mut new_row = Vec::new(); @@ -347,7 +313,6 @@ impl Matrix { /// Creates an identity matrix of a given size. pub fn identity(size: usize) -> Self where - T: Zero, T: One, { let mut out = Vec::new(); @@ -368,13 +333,17 @@ impl Matrix { // TODO: Canonical forms, eigenvalues, eigenvectors etc. } -impl Display for Matrix { +impl + Add + Sub + Zero + Copy> Display + for Matrix +{ fn fmt(&self, f: &mut Formatter) -> fmt::Result { write!(f, "{:?}", self.entries) } } -impl + Add + Sub + Copy + Zero> Mul for Matrix { +impl + Add + Sub + Zero + Copy + Copy + Zero> Mul + for Matrix +{ // TODO: Implement a faster algorithm. type Output = Self; fn mul(self, other: Self) -> Self::Output { @@ -399,7 +368,9 @@ impl + Add + Sub + Copy + Zero> Mul for Matrix { } } -impl + Sub + Mul + Copy + Zero> Add for Matrix { +impl + Add + Sub + Zero + Copy + Copy + Zero> Add + for Matrix +{ type Output = Self; fn add(self, other: Self) -> Self::Output { if self.height() == other.height() && self.width() == other.width() { @@ -416,7 +387,10 @@ impl + Sub + Mul + Copy + Zero> Add for Matrix { } } -impl + Mul + Copy + Neg> Neg for Matrix { +impl< + T: Mul + Add + Sub + Zero + Copy + Copy + Neg, + > Neg for Matrix +{ type Output = Self; fn neg(self) -> Self::Output { let mut out = self; @@ -429,7 +403,17 @@ impl + Mul + Copy + Neg> Neg for Matrix } } -impl + Mul + Copy + Zero + Neg> Sub for Matrix { +impl< + T: Mul + + Add + + Sub + + Zero + + Copy + + Copy + + Zero + + Neg, + > Sub for Matrix +{ type Output = Self; fn sub(self, other: Self) -> Self::Output { if self.height() == other.height() && self.width() == other.width() { @@ -447,7 +431,7 @@ impl + Mul + Copy + Zero + Neg> Sub for Mat /// I plan to change this to the default From trait as soon as some sort /// of specialization system is implemented. /// You can track this issue [here](https://github.com/rust-lang/rust/issues/42721). -pub trait MatrixInto { +pub trait MatrixInto + Add + Sub + Zero + Copy> { /// Method for converting a matrix into a matrix of type `Matrix` fn matrix_into(self) -> Matrix; } @@ -465,7 +449,11 @@ pub trait MatrixInto { /// /// assert_eq!(c, b); /// ``` -impl> MatrixInto for Matrix { +impl< + T: Mul + Add + Sub + Zero + Copy, + S: Mul + Add + Sub + Zero + Copy + Into, + > MatrixInto for Matrix +{ fn matrix_into(self) -> Matrix { let mut out = Vec::new(); for row in self.entries {