diff --git a/src/lib.rs b/src/lib.rs index dacdf3f..8294a65 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 implement [`Add`], [`Sub`], [`Mul`], -//! [`Zero`] and [`Copy`]. Additional properties might be +//! [`Zero`], [`Neg`] and [`Copy`]. Additional properties might be //! needed for certain operations. //! I created it mostly to learn using generic types //! and traits. @@ -19,15 +19,38 @@ use std::{ mod tests; -/// A generic matrix struct (over any type with addition, substraction -/// and multiplication defined on it). +/// Trait a type must satisfy to be element of a matrix. This is +/// mostly to reduce writing trait bounds afterwards. +pub trait ToMatrix: + Mul + + Add + + Sub + + Zero + + Neg + + Copy +{ +} + +/// Blanket implementation for ToMatrix for any type that satisfies its bounds +impl ToMatrix for T where + T: Mul + + Add + + Sub + + Zero + + Neg + + Copy +{ +} + +/// A generic matrix struct (over any type with [`Add`], [`Sub`], [`Mul`], +/// [`Zero`], [`Neg`] and [`Copy`] implemented). /// Look at [`from`](Self::from()) to see examples. #[derive(PartialEq, Debug, Clone)] -pub struct Matrix + Add + Sub + Zero + Copy> { +pub struct Matrix { entries: Vec>, } -impl + Add + Sub + Zero + Copy> Matrix { +impl 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 @@ -379,17 +402,13 @@ impl + Add + Sub + Zero + Copy> Matri // TODO: Canonical forms, eigenvalues, eigenvectors etc. } -impl + Add + Sub + Zero + Copy> Display - for Matrix -{ +impl Display for Matrix { fn fmt(&self, f: &mut Formatter) -> fmt::Result { write!(f, "{:?}", self.entries) } } -impl + Add + Sub + Zero + Copy + Zero> Mul - for Matrix -{ +impl + ToMatrix> Mul for Matrix { // TODO: Implement a faster algorithm. type Output = Self; fn mul(self, other: Self) -> Self::Output { @@ -414,9 +433,7 @@ impl + Add + Sub + Zero + Copy + Zero } } -impl + Add + Sub + Zero + Copy + Zero> Add - for Matrix -{ +impl + ToMatrix> Add for Matrix { type Output = Self; fn add(self, other: Self) -> Self::Output { if self.height() == other.height() && self.width() == other.width() { @@ -433,9 +450,7 @@ impl + Add + Sub + Zero + Copy + Zero } } -impl + Add + Sub + Zero + Copy + Neg> Neg - for Matrix -{ +impl Neg for Matrix { type Output = Self; fn neg(self) -> Self::Output { let mut out = self; @@ -448,17 +463,7 @@ impl + Add + Sub + Zero + Copy + Neg< } } -impl< - T: Mul - + Add - + Sub - + Zero - + Copy - + Copy - + Zero - + Neg, - > Sub for Matrix -{ +impl Sub for Matrix { type Output = Self; fn sub(self, other: Self) -> Self::Output { if self.height() == other.height() && self.width() == other.width() { @@ -476,7 +481,7 @@ impl< /// 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 + Add + Sub + Zero + Copy> { +pub trait MatrixInto { /// Method for converting a matrix into a matrix of type `Matrix` fn matrix_into(self) -> Matrix; } @@ -494,11 +499,7 @@ pub trait MatrixInto + Add + Sub + Ze /// /// assert_eq!(c, b); /// ``` -impl< - T: Mul + Add + Sub + Zero + Copy, - S: Mul + Add + Sub + Zero + Copy + Into, - > MatrixInto for Matrix -{ +impl> MatrixInto for Matrix { fn matrix_into(self) -> Matrix { let mut out = Vec::new(); for row in self.entries {