use core::ops::{Neg, Add, Sub, Mul, Div};
use core::ops::{AddAssign, SubAssign, MulAssign, DivAssign};
pub use crate::vector::{Vector, Vec64};
pub use crate::matrix::{Matrix, Mat64};
pub use crate::traits::{Number, Signed, Zero, One};
impl<T: Copy + Neg<Output = T> + Signed> Neg for &Matrix<T> {
type Output = Matrix<T>;
#[inline]
fn neg(self) -> Self::Output {
let mut result = Matrix::<T>::new( self.rows(), self.cols(), T::zero() );
for i in 0..result.rows() {
for j in 0..result.cols() {
result[(i,j)] = -self[(i,j)];
}
}
result
}
}
impl<T: Copy + Neg<Output = T> + Signed> Neg for Matrix<T> {
type Output = Self;
#[inline]
fn neg(self) -> Self::Output {
-&self
}
}
impl<T: Copy + Number> Add<&Matrix<T>> for &Matrix<T> {
type Output = Matrix<T>;
#[inline]
fn add(self, plus: &Matrix<T>) -> Self::Output {
if self.rows != plus.rows { panic!( "Matrix row dimensions do not agree (+)." ); }
if self.cols != plus.cols { panic!( "Matrix col dimensions do not agree (+)." ); }
let mut result = Matrix::<T>::new( self.rows(), self.cols(), T::zero() );
for i in 0..result.rows() {
for j in 0..result.cols() {
result[(i,j)] = self[(i,j)] + plus[(i,j)];
}
}
result
}
}
impl<T: Copy + Number> Add<Matrix<T>> for Matrix<T> {
type Output = Self;
#[inline]
fn add(self, plus: Self) -> Self::Output {
&self + &plus
}
}
impl<T: Copy + Number> Sub<&Matrix<T>> for &Matrix<T> {
type Output = Matrix<T>;
#[inline]
fn sub(self, minus: &Matrix<T>) -> Self::Output {
if self.rows != minus.rows { panic!( "Matrix row dimensions do not agree (-)." ); }
if self.cols != minus.cols { panic!( "Matrix col dimensions do not agree (-)." ); }
let mut result = Matrix::<T>::new( self.rows(), self.cols(), T::zero() );
for i in 0..result.rows() {
for j in 0..result.cols() {
result[(i,j)] = self[(i,j)] - minus[(i,j)];
}
}
result
}
}
impl<T: Copy + Number> Sub<Matrix<T>> for Matrix<T> {
type Output = Self;
#[inline]
fn sub(self, minus: Self) -> Self::Output {
&self - &minus
}
}
impl<T: Copy + Number> Mul<T> for &Matrix<T> {
type Output = Matrix<T>;
#[inline]
fn mul(self, scalar: T) -> Self::Output {
let mut result = Matrix::<T>::new( self.rows(), self.cols(), T::zero() );
for i in 0..result.rows() {
for j in 0..result.cols() {
result[(i,j)] = self[(i,j)] * scalar;
}
}
result
}
}
impl<T: Copy + Number> Mul<T> for Matrix<T> {
type Output = Self;
#[inline]
fn mul(self, scalar: T) -> Self::Output {
&self * scalar
}
}
impl Mul<Matrix<f64>> for f64 {
type Output = Matrix<f64>;
#[inline]
fn mul(self, matrix: Matrix<f64>) -> Self::Output {
let mut result = Matrix::<f64>::new( matrix.rows(), matrix.cols(), 0.0 );
for i in 0..result.rows() {
for j in 0..result.cols() {
result[(i,j)] = matrix[(i,j)] * self.clone();
}
}
result
}
}
impl<T: Copy + Number> Div<T> for &Matrix<T> {
type Output = Matrix<T>;
fn div(self, scalar: T) -> Self::Output {
let mut result = Matrix::<T>::new( self.rows(), self.cols(), T::zero() );
for i in 0..result.rows() {
for j in 0..result.cols() {
result[(i,j)] = self[(i,j)] / scalar;
}
}
result
}
}
impl<T: Copy + Number> Div<T> for Matrix<T> {
type Output = Self;
fn div(self, scalar: T) -> Self::Output {
&self / scalar
}
}
impl<T: Copy + Number> AddAssign<&Matrix<T>> for Matrix<T> {
fn add_assign(&mut self, rhs: &Self) {
if self.rows != rhs.rows { panic!( "Matrix row dimensions do not agree (+=)." ); }
if self.cols != rhs.cols { panic!( "Matrix col dimensions do not agree (+=)." ); }
for i in 0..self.rows {
for j in 0..self.cols {
self[(i,j)] += rhs[(i,j)];
}
}
}
}
impl<T: Copy + Number> AddAssign for Matrix<T> {
fn add_assign(&mut self, rhs: Self) {
*self += &rhs
}
}
impl<T: Copy + Number> SubAssign<&Matrix<T>> for Matrix<T> {
fn sub_assign(&mut self, rhs: &Self) {
if self.rows != rhs.rows { panic!( "Matrix row dimensions do not agree (-=)." ); }
if self.cols != rhs.cols { panic!( "Matrix col dimensions do not agree (-=)." ); }
for i in 0..self.rows {
for j in 0..self.cols {
self[(i,j)] -= rhs[(i,j)];
}
}
}
}
impl<T: Copy + Number> SubAssign for Matrix<T> {
fn sub_assign(&mut self, rhs: Self) {
*self -= &rhs
}
}
impl<T: Copy + Number> MulAssign<T> for Matrix<T> {
fn mul_assign(&mut self, rhs: T) {
for i in 0..self.rows {
for j in 0..self.cols {
self[(i,j)] *= rhs;
}
}
}
}
impl<T: Copy + Number> DivAssign<T> for Matrix<T> {
fn div_assign(&mut self, rhs: T) {
for i in 0..self.rows {
for j in 0..self.cols {
self[(i,j)] /= rhs;
}
}
}
}
impl<T: Copy + Number> AddAssign<T> for Matrix<T> {
fn add_assign(&mut self, rhs: T) {
for i in 0..self.rows {
for j in 0..self.cols {
self[(i,j)] += rhs;
}
}
}
}
impl<T: Copy + Number> SubAssign<T> for Matrix<T> {
fn sub_assign(&mut self, rhs: T) {
for i in 0..self.rows {
for j in 0..self.cols {
self[(i,j)] -= rhs;
}
}
}
}
impl<T: Clone + Copy + Number> Mul<Matrix<T>> for Matrix<T> {
type Output = Self;
#[inline]
fn mul(self, mul: Self) -> Self::Output {
&self * &mul
}
}
impl<T: Clone + Copy + Number> Mul<&Matrix<T>> for &Matrix<T> {
type Output = Matrix<T>;
#[inline]
fn mul(self, mul: &Matrix<T> ) -> Matrix<T> {
if self.cols != mul.rows { panic!( "Matrix dimensions do not agree (*)." ); }
let mut result = Matrix::<T>::new( self.rows(), mul.cols(), T::zero() );
for col in 0..mul.cols() {
result.set_col( col, self.multiply( &mul.get_col( col ) ) );
}
result
}
}
impl<T: Clone + Copy + Number> Mul<Vector<T>> for Matrix<T> {
type Output = Vector<T>;
#[inline]
fn mul(self, vec: Vector<T> ) -> Vector<T> {
self.multiply( &vec )
}
}
impl<T: Clone + Copy + Number> Mul<&Vector<T>> for &Matrix<T> {
type Output = Vector<T>;
#[inline]
fn mul(self, vec: &Vector<T> ) -> Vector<T> {
self.multiply( vec )
}
}