From ae8abfa8335edf856f423e7a60c5bb830a79d5a7 Mon Sep 17 00:00:00 2001 From: hachem Date: Sun, 22 Sep 2024 14:24:27 +0200 Subject: Refactor and implement other gates --- libpsi/src/maths/complex.rs | 183 +++++-------------------------------- libpsi/src/maths/complex_ops.rs | 147 +++++++++++++++++++++++++++++ libpsi/src/maths/matrix.rs | 60 ------------ libpsi/src/maths/matrix_ops.rs | 62 +++++++++++++ libpsi/src/maths/mod.rs | 12 ++- libpsi/src/maths/numeric_float.rs | 65 +++++++++++++ libpsi/src/maths/numeric_int.rs | 44 +++++++++ libpsi/src/maths/numeric_traits.rs | 24 +++++ libpsi/src/maths/numeric_types.rs | 152 ------------------------------ libpsi/src/maths/vector.rs | 144 ++++------------------------- libpsi/src/maths/vector_ops.rs | 107 ++++++++++++++++++++++ 11 files changed, 502 insertions(+), 498 deletions(-) create mode 100644 libpsi/src/maths/complex_ops.rs create mode 100644 libpsi/src/maths/matrix_ops.rs create mode 100644 libpsi/src/maths/numeric_float.rs create mode 100644 libpsi/src/maths/numeric_int.rs create mode 100644 libpsi/src/maths/numeric_traits.rs delete mode 100644 libpsi/src/maths/numeric_types.rs create mode 100644 libpsi/src/maths/vector_ops.rs (limited to 'libpsi/src/maths') diff --git a/libpsi/src/maths/complex.rs b/libpsi/src/maths/complex.rs index 28a3121..bb19510 100644 --- a/libpsi/src/maths/complex.rs +++ b/libpsi/src/maths/complex.rs @@ -1,5 +1,7 @@ use crate::Float; -use core::{fmt, ops}; +use core::fmt; + +use super::Numeric; #[macro_export] macro_rules! complex { @@ -30,6 +32,26 @@ impl fmt::Display for Complex { } } +impl Numeric for Complex { + fn zero() -> Self { + Complex::new(0.0, 0.0) + } + + fn one() -> Self { + Complex::new(1.0, 0.0) + } +} + +impl Numeric for Complex { + fn zero() -> Self { + Complex::new(0.0, 0.0) + } + + fn one() -> Self { + Complex::new(1.0, 0.0) + } +} + impl Complex { pub fn new(real: T, imaginary: T) -> Complex { Complex { real, imaginary } @@ -58,162 +80,3 @@ impl Complex { T::sqrt(self.norm()) } } - -impl ops::Neg for Complex { - type Output = Complex; - - fn neg(self) -> Complex { - Complex { - real: -self.real, - imaginary: -self.imaginary, - } - } -} - -impl ops::Add for Complex { - type Output = Complex; - - fn add(self, other: Complex) -> Complex { - Complex { - real: self.real + other.real, - imaginary: self.imaginary + other.imaginary, - } - } -} - -impl ops::Sub for Complex { - type Output = Complex; - - fn sub(self, other: Complex) -> Complex { - Complex { - real: self.real - other.real, - imaginary: self.imaginary - other.imaginary, - } - } -} - -impl ops::Mul for Complex { - type Output = Complex; - - fn mul(self, other: Complex) -> Complex { - Complex { - real: self.real * other.real - self.imaginary * other.imaginary, - imaginary: self.real * other.imaginary + self.imaginary * other.real, - } - } -} - -impl ops::Div for Complex { - type Output = Complex; - - fn div(self, other: Complex) -> Complex { - let denom = other.real * other.real + other.imaginary * other.imaginary; - Complex { - real: (self.real * other.real + self.imaginary * other.imaginary) / denom, - imaginary: (self.imaginary * other.real - self.real * other.imaginary) / denom, - } - } -} - -impl ops::Add for Complex { - type Output = Complex; - - fn add(self, other: T) -> Complex { - Complex { - real: self.real + other, - imaginary: self.imaginary, - } - } -} - -impl ops::Sub for Complex { - type Output = Complex; - - fn sub(self, other: T) -> Complex { - Complex { - real: self.real - other, - imaginary: self.imaginary, - } - } -} - -impl ops::Mul for Complex { - type Output = Complex; - - fn mul(self, other: T) -> Complex { - Complex { - real: self.real * other, - imaginary: self.imaginary * other, - } - } -} - -impl ops::Div for Complex { - type Output = Complex; - - fn div(self, other: T) -> Complex { - Complex { - real: self.real / other, - imaginary: self.imaginary / other, - } - } -} - -impl ops::AddAssign for Complex { - fn add_assign(&mut self, other: Complex) { - self.real += other.real; - self.imaginary += other.imaginary; - } -} - -impl ops::SubAssign for Complex { - fn sub_assign(&mut self, other: Complex) { - self.real -= other.real; - self.imaginary -= other.imaginary; - } -} - -impl ops::MulAssign for Complex { - fn mul_assign(&mut self, other: Complex) { - let new_real = self.real * other.real - self.imaginary * other.imaginary; - let new_imaginary = self.real * other.imaginary + self.imaginary * other.real; - self.real = new_real; - self.imaginary = new_imaginary; - } -} - -impl ops::DivAssign for Complex { - fn div_assign(&mut self, other: Complex) { - let denom = other.real * other.real + other.imaginary * other.imaginary; - let new_real = (self.real * other.real + self.imaginary * other.imaginary) / denom; - let new_imaginary = (self.imaginary * other.real - self.real * other.imaginary) / denom; - self.real = new_real; - self.imaginary = new_imaginary; - } -} - -impl ops::AddAssign for Complex { - fn add_assign(&mut self, other: T) { - self.real += other; - } -} - -impl ops::SubAssign for Complex { - fn sub_assign(&mut self, other: T) { - self.real -= other; - } -} - -impl ops::MulAssign for Complex { - fn mul_assign(&mut self, other: T) { - self.real *= other; - self.imaginary *= other; - } -} - -impl ops::DivAssign for Complex { - fn div_assign(&mut self, other: T) { - self.real /= other; - self.imaginary /= other; - } -} diff --git a/libpsi/src/maths/complex_ops.rs b/libpsi/src/maths/complex_ops.rs new file mode 100644 index 0000000..bfcf920 --- /dev/null +++ b/libpsi/src/maths/complex_ops.rs @@ -0,0 +1,147 @@ +use super::{Complex, Float}; +use core::ops; + +impl ops::Neg for Complex { + type Output = Complex; + + fn neg(self) -> Complex { + Complex { + real: -self.real, + imaginary: -self.imaginary, + } + } +} + +impl From for Complex { + fn from(real: T) -> Complex { + Complex { + real, + imaginary: T::zero(), + } + } +} + +// Complex-Complex +impl ops::Add for Complex { + type Output = Complex; + + fn add(self, other: Complex) -> Complex { + Complex { + real: self.real - other.real, + imaginary: self.imaginary - other.imaginary, + } + } +} + +impl ops::Sub for Complex { + type Output = Complex; + + fn sub(self, other: Complex) -> Complex { + Complex { + real: self.real - other.real, + imaginary: self.imaginary - other.imaginary, + } + } +} + +impl ops::Mul for Complex { + type Output = Complex; + + fn mul(self, other: Complex) -> Complex { + Complex { + real: self.real * other.real - self.imaginary * other.imaginary, + imaginary: self.real * other.imaginary + self.imaginary * other.real, + } + } +} + +impl ops::Div for Complex { + type Output = Complex; + + fn div(self, other: Complex) -> Complex { + let denom = other.real * other.real + other.imaginary * other.imaginary; + Complex { + real: (self.real * other.real + self.imaginary * other.imaginary) / denom, + imaginary: (self.imaginary * other.real - self.real * other.imaginary) / denom, + } + } +} + +// Complex-Complex, Assign +impl ops::AddAssign for Complex { + fn add_assign(&mut self, other: Complex) { + self.real += other.real; + self.imaginary += other.imaginary; + } +} + +impl ops::SubAssign for Complex { + fn sub_assign(&mut self, other: Complex) { + self.real -= other.real; + self.imaginary -= other.imaginary; + } +} + +impl ops::MulAssign for Complex { + fn mul_assign(&mut self, other: Complex) { + let new_real = self.real * other.real - self.imaginary * other.imaginary; + let new_imaginary = self.real * other.imaginary + self.imaginary * other.real; + self.real = new_real; + self.imaginary = new_imaginary; + } +} + +impl ops::DivAssign for Complex { + fn div_assign(&mut self, other: Complex) { + let denom = other.real * other.real + other.imaginary * other.imaginary; + let new_real = (self.real * other.real + self.imaginary * other.imaginary) / denom; + let new_imaginary = (self.imaginary * other.real - self.real * other.imaginary) / denom; + self.real = new_real; + self.imaginary = new_imaginary; + } +} + +// Real-Complex +impl ops::Add for Complex { + type Output = Complex; + + fn add(self, other: T) -> Complex { + Complex { + real: self.real + other, + imaginary: self.imaginary, + } + } +} + +impl ops::Sub for Complex { + type Output = Complex; + + fn sub(self, other: T) -> Complex { + Complex { + real: self.real - other, + imaginary: self.imaginary, + } + } +} + +impl ops::Mul for Complex { + type Output = Complex; + + fn mul(self, other: T) -> Complex { + Complex { + real: self.real * other, + imaginary: self.imaginary * other, + } + } +} + +impl ops::Div for Complex { + type Output = Complex; + + fn div(self, other: T) -> Complex { + Complex { + real: self.real / other, + imaginary: self.imaginary / other, + } + } +} diff --git a/libpsi/src/maths/matrix.rs b/libpsi/src/maths/matrix.rs index 388f858..795b37f 100644 --- a/libpsi/src/maths/matrix.rs +++ b/libpsi/src/maths/matrix.rs @@ -183,63 +183,3 @@ impl fmt::Display for Matrix { Ok(()) } } - -impl ops::Add<&Matrix> for Matrix { - type Output = Option>; - - fn add(self, other: &Matrix) -> Self::Output { - self.add_to(other) - } -} - -impl ops::Sub<&Matrix> for Matrix { - type Output = Option>; - - fn sub(self, other: &Matrix) -> Self::Output { - self.subtract(other) - } -} - -impl ops::Mul for Matrix { - type Output = Matrix; - - fn mul(self, scalar: T) -> Self::Output { - self.scale(scalar) - } -} - -impl ops::Div for Matrix { - type Output = Matrix; - - fn div(self, scalar: T) -> Self::Output { - self.scale(T::one() / scalar) - } -} - -impl ops::AddAssign<&Matrix> for Matrix { - fn add_assign(&mut self, other: &Matrix) { - if let Some(result) = self.add_to(other) { - *self = result; - } - } -} - -impl ops::SubAssign<&Matrix> for Matrix { - fn sub_assign(&mut self, other: &Matrix) { - if let Some(result) = self.subtract(other) { - *self = result; - } - } -} - -impl ops::MulAssign for Matrix { - fn mul_assign(&mut self, scalar: T) { - *self = self.scale(scalar); - } -} - -impl ops::DivAssign for Matrix { - fn div_assign(&mut self, scalar: T) { - *self = self.scale(T::one() / scalar); - } -} diff --git a/libpsi/src/maths/matrix_ops.rs b/libpsi/src/maths/matrix_ops.rs new file mode 100644 index 0000000..15ab28b --- /dev/null +++ b/libpsi/src/maths/matrix_ops.rs @@ -0,0 +1,62 @@ +use super::{Float, Matrix}; +use core::ops; + +impl ops::Add<&Matrix> for Matrix { + type Output = Option>; + + fn add(self, other: &Matrix) -> Self::Output { + self.add_to(other) + } +} + +impl ops::Sub<&Matrix> for Matrix { + type Output = Option>; + + fn sub(self, other: &Matrix) -> Self::Output { + self.subtract(other) + } +} + +impl ops::Mul for Matrix { + type Output = Matrix; + + fn mul(self, scalar: T) -> Self::Output { + self.scale(scalar) + } +} + +impl ops::Div for Matrix { + type Output = Matrix; + + fn div(self, scalar: T) -> Self::Output { + self.scale(T::one() / scalar) + } +} + +impl ops::AddAssign<&Matrix> for Matrix { + fn add_assign(&mut self, other: &Matrix) { + if let Some(result) = self.add_to(other) { + *self = result; + } + } +} + +impl ops::SubAssign<&Matrix> for Matrix { + fn sub_assign(&mut self, other: &Matrix) { + if let Some(result) = self.subtract(other) { + *self = result; + } + } +} + +impl ops::MulAssign for Matrix { + fn mul_assign(&mut self, scalar: T) { + *self = self.scale(scalar); + } +} + +impl ops::DivAssign for Matrix { + fn div_assign(&mut self, scalar: T) { + *self = self.scale(T::one() / scalar); + } +} diff --git a/libpsi/src/maths/mod.rs b/libpsi/src/maths/mod.rs index 734cfb4..a2b9b84 100644 --- a/libpsi/src/maths/mod.rs +++ b/libpsi/src/maths/mod.rs @@ -1,8 +1,16 @@ pub mod complex; +pub mod complex_ops; + pub mod matrix; -pub mod numeric_types; +pub mod matrix_ops; + +pub mod numeric_float; +pub mod numeric_int; +pub mod numeric_traits; + pub mod vector; +pub mod vector_ops; pub use complex::*; pub use matrix::*; -pub use numeric_types::*; +pub use numeric_traits::*; diff --git a/libpsi/src/maths/numeric_float.rs b/libpsi/src/maths/numeric_float.rs new file mode 100644 index 0000000..3591f24 --- /dev/null +++ b/libpsi/src/maths/numeric_float.rs @@ -0,0 +1,65 @@ +use super::{Complex, Float}; + +impl Float for f32 { + fn sqrt(self) -> Self { + libm::sqrtf(self) + } + + fn atan2(y: Self, x: Self) -> Self { + libm::atan2f(y, x) + } +} + +impl Float for f64 { + fn sqrt(self) -> Self { + libm::sqrt(self) + } + + fn atan2(y: Self, x: Self) -> Self { + libm::atan2(y, x) + } +} + +impl Float for Complex { + fn sqrt(self) -> Self { + let r = self.abs(); + let theta = self.phase(); + + let sqrt_r = libm::sqrtf(r); + let sqrt_theta = theta / 2.0; + + Complex::new( + sqrt_r * libm::cosf(sqrt_theta), + sqrt_r * libm::sinf(sqrt_theta), + ) + } + + fn atan2(y: Self, x: Self) -> Self { + Complex::new( + libm::atan2f(y.real, x.real), + libm::atan2f(y.imaginary, x.imaginary), + ) + } +} + +impl Float for Complex { + fn sqrt(self) -> Self { + let r = self.abs(); + let theta = self.phase(); + + let sqrt_r = libm::sqrt(r); + let sqrt_theta = theta / 2.0; + + Complex::new( + sqrt_r * libm::cos(sqrt_theta), + sqrt_r * libm::sin(sqrt_theta), + ) + } + + fn atan2(y: Self, x: Self) -> Self { + Complex::new( + libm::atan2(y.real, x.real), + libm::atan2(y.imaginary, x.imaginary), + ) + } +} diff --git a/libpsi/src/maths/numeric_int.rs b/libpsi/src/maths/numeric_int.rs new file mode 100644 index 0000000..a9ecec7 --- /dev/null +++ b/libpsi/src/maths/numeric_int.rs @@ -0,0 +1,44 @@ +use super::{Integer, Numeric}; + +impl Integer for i64 {} +impl Integer for i32 {} + +impl Numeric for i32 { + fn zero() -> Self { + 0 + } + + fn one() -> Self { + 1 + } +} + +impl Numeric for i64 { + fn zero() -> Self { + 0 + } + + fn one() -> Self { + 1 + } +} + +impl Numeric for f32 { + fn zero() -> Self { + 0.0 + } + + fn one() -> Self { + 1.0 + } +} + +impl Numeric for f64 { + fn zero() -> Self { + 0.0 + } + + fn one() -> Self { + 1.0 + } +} diff --git a/libpsi/src/maths/numeric_traits.rs b/libpsi/src/maths/numeric_traits.rs new file mode 100644 index 0000000..dd7fdec --- /dev/null +++ b/libpsi/src/maths/numeric_traits.rs @@ -0,0 +1,24 @@ +use core::ops; + +pub trait Numeric: + Copy + + PartialOrd + + ops::Add + + ops::Mul + + ops::Sub + + ops::Div + + ops::Neg + + ops::AddAssign + + ops::SubAssign + + ops::MulAssign + + ops::DivAssign +{ + fn zero() -> Self; + fn one() -> Self; +} + +pub trait Integer: Numeric {} +pub trait Float: Numeric { + fn sqrt(self) -> Self; + fn atan2(y: Self, x: Self) -> Self; +} diff --git a/libpsi/src/maths/numeric_types.rs b/libpsi/src/maths/numeric_types.rs deleted file mode 100644 index f1355de..0000000 --- a/libpsi/src/maths/numeric_types.rs +++ /dev/null @@ -1,152 +0,0 @@ -use super::Complex; -use core::ops; - -pub trait Numeric: - Copy - + PartialOrd - + ops::Add - + ops::Mul - + ops::Sub - + ops::Div - + ops::Neg - + ops::AddAssign - + ops::SubAssign - + ops::MulAssign - + ops::DivAssign -{ - fn zero() -> Self; - fn one() -> Self; -} - -pub trait Integer: Numeric {} -pub trait Float: Numeric { - fn sqrt(self) -> Self; - fn atan2(y: Self, x: Self) -> Self; -} - -impl Float for f32 { - fn sqrt(self) -> Self { - libm::sqrtf(self) - } - - fn atan2(y: Self, x: Self) -> Self { - libm::atan2f(y, x) - } -} - -impl Float for f64 { - fn sqrt(self) -> Self { - libm::sqrt(self) - } - - fn atan2(y: Self, x: Self) -> Self { - libm::atan2(y, x) - } -} - -impl Float for Complex { - fn sqrt(self) -> Self { - let r = self.abs(); - let theta = self.phase(); - - let sqrt_r = libm::sqrtf(r); - let sqrt_theta = theta / 2.0; - - Complex::new( - sqrt_r * libm::cosf(sqrt_theta), - sqrt_r * libm::sinf(sqrt_theta), - ) - } - - fn atan2(y: Self, x: Self) -> Self { - Complex::new( - libm::atan2f(y.real, x.real), - libm::atan2f(y.imaginary, x.imaginary), - ) - } -} - -impl Float for Complex { - fn sqrt(self) -> Self { - let r = self.abs(); - let theta = self.phase(); - - let sqrt_r = libm::sqrt(r); - let sqrt_theta = theta / 2.0; - - Complex::new( - sqrt_r * libm::cos(sqrt_theta), - sqrt_r * libm::sin(sqrt_theta), - ) - } - - fn atan2(y: Self, x: Self) -> Self { - Complex::new( - libm::atan2(y.real, x.real), - libm::atan2(y.imaginary, x.imaginary), - ) - } -} - -impl Integer for i64 {} -impl Integer for i32 {} - -impl Numeric for i32 { - fn zero() -> Self { - 0 - } - - fn one() -> Self { - 1 - } -} - -impl Numeric for i64 { - fn zero() -> Self { - 0 - } - - fn one() -> Self { - 1 - } -} - -impl Numeric for f32 { - fn zero() -> Self { - 0.0 - } - - fn one() -> Self { - 1.0 - } -} - -impl Numeric for f64 { - fn zero() -> Self { - 0.0 - } - - fn one() -> Self { - 1.0 - } -} - -impl Numeric for Complex { - fn zero() -> Self { - Complex::new(0.0, 0.0) - } - - fn one() -> Self { - Complex::new(1.0, 0.0) - } -} - -impl Numeric for Complex { - fn zero() -> Self { - Complex::new(0.0, 0.0) - } - - fn one() -> Self { - Complex::new(1.0, 0.0) - } -} diff --git a/libpsi/src/maths/vector.rs b/libpsi/src/maths/vector.rs index 243061d..a21cf36 100644 --- a/libpsi/src/maths/vector.rs +++ b/libpsi/src/maths/vector.rs @@ -96,6 +96,26 @@ impl RowVector { } } +impl VectorMatrix for RowVector { + fn to_matrix(&self) -> Matrix { + Matrix::new(1, self.size(), self.0.clone()) + } + + fn from_matrix(matrix: &Matrix) -> Self { + Self::new(matrix.data.clone()) + } +} + +impl VectorMatrix for ColumnVector { + fn to_matrix(&self) -> Matrix { + Matrix::new(self.size(), 1, self.0.clone()) + } + + fn from_matrix(matrix: &Matrix) -> Self { + Self::new(matrix.data.clone()) + } +} + impl Vector for VectorImpl { fn new(data: Vec) -> Self { Self(data) @@ -211,130 +231,6 @@ impl ops::IndexMut } } -impl ops::Add<&VectorImpl> - for VectorImpl -{ - type Output = Option>; - - fn add(self, other: &VectorImpl) -> Self::Output { - self.add_to(other) - } -} - -impl ops::Sub<&VectorImpl> - for VectorImpl -{ - type Output = Option>; - - fn sub(self, other: &VectorImpl) -> Self::Output { - self.subtract(other) - } -} - -impl ops::Mul for VectorImpl { - type Output = VectorImpl; - - fn mul(self, scalar: T) -> Self::Output { - self.scale(scalar) - } -} - -impl ops::Div for VectorImpl { - type Output = VectorImpl; - - fn div(self, scalar: T) -> Self::Output { - self.scale(T::one() / scalar) - } -} - -impl ops::AddAssign> - for VectorImpl -{ - fn add_assign(&mut self, other: VectorImpl) { - if let Some(result) = self.add_to(&other) { - *self = result; - } - } -} - -impl ops::SubAssign> - for VectorImpl -{ - fn sub_assign(&mut self, other: VectorImpl) { - if let Some(result) = self.subtract(&other) { - *self = result; - } - } -} - -impl ops::MulAssign - for VectorImpl -{ - fn mul_assign(&mut self, scalar: T) { - *self = self.scale(scalar); - } -} - -impl ops::DivAssign - for VectorImpl -{ - fn div_assign(&mut self, scalar: T) { - *self = self.scale(T::one() / scalar); - } -} - -impl VectorMatrix for RowVector { - fn to_matrix(&self) -> Matrix { - Matrix::new(1, self.size(), self.0.clone()) - } - - fn from_matrix(matrix: &Matrix) -> Self { - Self::new(matrix.data.clone()) - } -} - -impl VectorMatrix for ColumnVector { - fn to_matrix(&self) -> Matrix { - Matrix::new(self.size(), 1, self.0.clone()) - } - - fn from_matrix(matrix: &Matrix) -> Self { - Self::new(matrix.data.clone()) - } -} - -impl ops::Mul<&Matrix> for RowVector { - type Output = Option>; - - fn mul(self, matrix: &Matrix) -> Self::Output { - self.mul_matrix(matrix) - } -} - -impl ops::Mul<&Matrix> for ColumnVector { - type Output = Option>; - - fn mul(self, matrix: &Matrix) -> Self::Output { - self.mul_matrix(matrix) - } -} - -impl ops::MulAssign<&Matrix> for RowVector { - fn mul_assign(&mut self, matrix: &Matrix) { - if let Some(result) = self.mul_matrix(matrix) { - *self = result; - } - } -} - -impl ops::MulAssign<&Matrix> for ColumnVector { - fn mul_assign(&mut self, matrix: &Matrix) { - if let Some(result) = self.mul_matrix(matrix) { - *self = result; - } - } -} - impl fmt::Debug for RowVector { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "RowVector({:?})", self.0) diff --git a/libpsi/src/maths/vector_ops.rs b/libpsi/src/maths/vector_ops.rs new file mode 100644 index 0000000..1e7148c --- /dev/null +++ b/libpsi/src/maths/vector_ops.rs @@ -0,0 +1,107 @@ +use super::{Float, Matrix}; +use crate::{ColumnVector, RowVector, VectorImpl}; +use core::ops; + +impl ops::Add<&VectorImpl> + for VectorImpl +{ + type Output = Option>; + + fn add(self, other: &VectorImpl) -> Self::Output { + self.add_to(other) + } +} + +impl ops::Sub<&VectorImpl> + for VectorImpl +{ + type Output = Option>; + + fn sub(self, other: &VectorImpl) -> Self::Output { + self.subtract(other) + } +} + +impl ops::Mul for VectorImpl { + type Output = VectorImpl; + + fn mul(self, scalar: T) -> Self::Output { + self.scale(scalar) + } +} + +impl ops::Div for VectorImpl { + type Output = VectorImpl; + + fn div(self, scalar: T) -> Self::Output { + self.scale(T::one() / scalar) + } +} + +impl ops::AddAssign> + for VectorImpl +{ + fn add_assign(&mut self, other: VectorImpl) { + if let Some(result) = self.add_to(&other) { + *self = result; + } + } +} + +impl ops::SubAssign> + for VectorImpl +{ + fn sub_assign(&mut self, other: VectorImpl) { + if let Some(result) = self.subtract(&other) { + *self = result; + } + } +} + +impl ops::MulAssign + for VectorImpl +{ + fn mul_assign(&mut self, scalar: T) { + *self = self.scale(scalar); + } +} + +impl ops::DivAssign + for VectorImpl +{ + fn div_assign(&mut self, scalar: T) { + *self = self.scale(T::one() / scalar); + } +} + +impl ops::Mul<&Matrix> for RowVector { + type Output = Option>; + + fn mul(self, matrix: &Matrix) -> Self::Output { + self.mul_matrix(matrix) + } +} + +impl ops::Mul<&Matrix> for ColumnVector { + type Output = Option>; + + fn mul(self, matrix: &Matrix) -> Self::Output { + self.mul_matrix(matrix) + } +} + +impl ops::MulAssign<&Matrix> for RowVector { + fn mul_assign(&mut self, matrix: &Matrix) { + if let Some(result) = self.mul_matrix(matrix) { + *self = result; + } + } +} + +impl ops::MulAssign<&Matrix> for ColumnVector { + fn mul_assign(&mut self, matrix: &Matrix) { + if let Some(result) = self.mul_matrix(matrix) { + *self = result; + } + } +} -- cgit v1.3