2023-05-22 05:52:47 +00:00
|
|
|
use crate::Matrix;
|
2023-05-18 05:44:02 +00:00
|
|
|
use num_traits::Num;
|
|
|
|
|
2022-08-01 07:33:43 +00:00
|
|
|
// borrowed from the auto_ops crate
|
|
|
|
#[doc(hidden)]
|
|
|
|
macro_rules! impl_matrix_op {
|
2022-08-19 04:07:05 +00:00
|
|
|
(neg) => {
|
2023-06-14 07:04:24 +00:00
|
|
|
_impl_op_unary_ex!(Neg::neg);
|
2022-08-19 04:07:05 +00:00
|
|
|
};
|
|
|
|
(!) => {
|
2023-06-14 07:04:24 +00:00
|
|
|
_impl_op_unary_ex!(Not::not);
|
2022-08-19 04:07:05 +00:00
|
|
|
};
|
|
|
|
(+) => {
|
2023-06-14 07:04:24 +00:00
|
|
|
_impl_op_binary_ex!(Add::add, AddAssign::add_assign);
|
2022-08-19 04:07:05 +00:00
|
|
|
};
|
|
|
|
(-) => {
|
2023-06-14 07:04:24 +00:00
|
|
|
_impl_op_binary_ex!(Sub::sub, SubAssign::sub_assign);
|
2022-08-19 04:07:05 +00:00
|
|
|
};
|
|
|
|
(*) => {
|
2023-06-14 07:04:24 +00:00
|
|
|
_impl_op_binary_ex!(Mul::mul, MulAssign::mul_assign);
|
2022-08-19 04:07:05 +00:00
|
|
|
};
|
|
|
|
(/) => {
|
2023-06-14 07:04:24 +00:00
|
|
|
_impl_op_binary_ex!(Div::div, DivAssign::div_assign);
|
2022-08-19 04:07:05 +00:00
|
|
|
};
|
|
|
|
(%) => {
|
2023-06-14 07:04:24 +00:00
|
|
|
_impl_op_binary_ex!(Rem::rem, RemAssign::rem_assign);
|
2022-08-19 04:07:05 +00:00
|
|
|
};
|
|
|
|
(&) => {
|
2023-06-14 07:04:24 +00:00
|
|
|
_impl_op_binary_ex!(BitAnd::bitand, BitAndAssign::bitand_assign);
|
2022-08-19 04:07:05 +00:00
|
|
|
};
|
|
|
|
(|) => {
|
2023-06-14 07:04:24 +00:00
|
|
|
_impl_op_binary_ex!(BitOr::bitor, BitOrAssign::bitor_assign);
|
2022-08-19 04:07:05 +00:00
|
|
|
};
|
|
|
|
(^) => {
|
2023-06-14 07:04:24 +00:00
|
|
|
_impl_op_binary_ex!(BitXor::bitxor, BitXorAssign::bitxor_assign);
|
2022-08-19 04:07:05 +00:00
|
|
|
};
|
|
|
|
(<<) => {
|
2023-06-14 07:04:24 +00:00
|
|
|
_impl_op_binary_ex!(Shl::shl, ShlAssign::shl_assign);
|
2022-08-19 04:07:05 +00:00
|
|
|
};
|
|
|
|
(>>) => {
|
2023-06-14 07:04:24 +00:00
|
|
|
_impl_op_binary_ex!(Shr::shr, ShrAssign::shr_assign);
|
2022-08-01 07:33:43 +00:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2022-11-27 22:59:36 +00:00
|
|
|
#[doc(hidden)]
|
2022-08-01 07:33:43 +00:00
|
|
|
#[macro_export]
|
2023-06-14 07:04:24 +00:00
|
|
|
macro_rules! _impl_op_unary_ex {
|
|
|
|
($op_trait:ident::$op_fn:ident) => {
|
|
|
|
_impl_op_m_internal!($op_trait, $op_fn, Matrix<L,M,N>, Matrix<L,M,N>);
|
|
|
|
_impl_op_m_internal!($op_trait, $op_fn, &Matrix<L,M,N>, Matrix<L,M,N>);
|
2022-08-01 07:33:43 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-11-27 22:59:36 +00:00
|
|
|
#[doc(hidden)]
|
2022-08-01 07:33:43 +00:00
|
|
|
#[macro_export]
|
2023-06-14 07:04:24 +00:00
|
|
|
macro_rules! _impl_op_binary_ex {
|
|
|
|
($op_trait:ident::$op_fn:ident, $op_assign_trait:ident::$op_assign_fn:ident) => {
|
|
|
|
_impl_op_mm_internal!($op_trait, $op_fn, Matrix<L,M,N>, Matrix<R,M,N>, Matrix<L,M,N>);
|
|
|
|
_impl_op_mm_internal!($op_trait, $op_fn, &Matrix<L,M,N>, Matrix<R,M,N>, Matrix<L,M,N>);
|
|
|
|
_impl_op_mm_internal!($op_trait, $op_fn, Matrix<L,M,N>, &Matrix<R,M,N>, Matrix<L,M,N>);
|
|
|
|
_impl_op_mm_internal!($op_trait, $op_fn, &Matrix<L,M,N>, &Matrix<R,M,N>, Matrix<L,M,N>);
|
2022-08-01 07:33:43 +00:00
|
|
|
|
2023-06-14 07:04:24 +00:00
|
|
|
_impl_op_ms_internal!($op_trait, $op_fn, Matrix<L,M,N>, R, Matrix<L,M,N>);
|
|
|
|
_impl_op_ms_internal!($op_trait, $op_fn, &Matrix<L,M,N>, R, Matrix<L,M,N>);
|
2022-08-01 07:33:43 +00:00
|
|
|
|
2023-06-14 07:04:24 +00:00
|
|
|
_impl_opassign_mm_internal!($op_assign_trait, $op_assign_fn, Matrix<L,M,N>, Matrix<R,M,N>, Matrix<L,M,N>);
|
|
|
|
_impl_opassign_mm_internal!($op_assign_trait, $op_assign_fn, Matrix<L,M,N>, &Matrix<R,M,N>, Matrix<L,M,N>);
|
|
|
|
|
|
|
|
_impl_opassign_ms_internal!($op_assign_trait, $op_assign_fn, Matrix<L,M,N>, R, Matrix<L,M,N>);
|
2022-08-01 07:33:43 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-11-27 22:59:36 +00:00
|
|
|
#[doc(hidden)]
|
2022-08-19 04:07:05 +00:00
|
|
|
macro_rules! _impl_op_m_internal {
|
2023-06-14 07:04:24 +00:00
|
|
|
($op_trait:ident, $op_fn:ident, $lhs:ty, $out:ty) => {
|
|
|
|
impl<L, const M: usize, const N: usize> ::std::ops::$op_trait for $lhs
|
2022-08-01 07:33:43 +00:00
|
|
|
where
|
2023-06-14 07:04:24 +00:00
|
|
|
L: ::std::ops::$op_trait<Output = L> + Copy,
|
2022-08-01 07:33:43 +00:00
|
|
|
{
|
|
|
|
type Output = $out;
|
|
|
|
|
2022-08-19 04:07:05 +00:00
|
|
|
#[inline(always)]
|
2023-06-14 07:04:24 +00:00
|
|
|
fn $op_fn(self) -> Self::Output {
|
2022-08-01 07:33:43 +00:00
|
|
|
let mut result = self.clone();
|
2023-06-14 07:04:24 +00:00
|
|
|
// we arnt using iterators because they dont seem to always vectorize correctly
|
2022-08-19 04:07:05 +00:00
|
|
|
for m in 0..M {
|
|
|
|
for n in 0..N {
|
2023-06-14 07:04:24 +00:00
|
|
|
result.data[m][n] = self.data[m][n].$op_fn();
|
2022-08-19 04:07:05 +00:00
|
|
|
}
|
2022-08-01 07:33:43 +00:00
|
|
|
}
|
|
|
|
result
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2022-11-27 22:59:36 +00:00
|
|
|
#[doc(hidden)]
|
2022-08-19 04:07:05 +00:00
|
|
|
macro_rules! _impl_op_mm_internal {
|
2023-06-14 07:04:24 +00:00
|
|
|
($op_trait:ident, $op_fn:ident, $lhs:ty, $rhs:ty, $out:ty) => {
|
|
|
|
impl<L, R, const M: usize, const N: usize> ::std::ops::$op_trait<$rhs> for $lhs
|
2022-08-01 07:33:43 +00:00
|
|
|
where
|
2023-06-14 07:04:24 +00:00
|
|
|
L: ::std::ops::$op_trait<R, Output = L> + Copy,
|
2022-11-15 05:23:15 +00:00
|
|
|
R: Copy,
|
2022-08-01 07:33:43 +00:00
|
|
|
{
|
2022-08-19 04:07:05 +00:00
|
|
|
type Output = $out;
|
|
|
|
|
|
|
|
#[inline(always)]
|
2023-06-14 07:04:24 +00:00
|
|
|
fn $op_fn(self, other: $rhs) -> Self::Output {
|
2022-08-19 04:07:05 +00:00
|
|
|
let mut result = self.clone();
|
|
|
|
for m in 0..M {
|
|
|
|
for n in 0..N {
|
2023-06-14 07:04:24 +00:00
|
|
|
result.data[m][n] = self.data[m][n].$op_fn(other.data[m][n]);
|
2022-08-19 04:07:05 +00:00
|
|
|
}
|
2022-08-01 07:33:43 +00:00
|
|
|
}
|
2022-08-19 04:07:05 +00:00
|
|
|
result
|
2022-08-01 07:33:43 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2022-11-27 22:59:36 +00:00
|
|
|
#[doc(hidden)]
|
2022-08-19 04:07:05 +00:00
|
|
|
macro_rules! _impl_opassign_mm_internal {
|
2023-06-14 07:04:24 +00:00
|
|
|
($op_trait:ident, $op_fn:ident, $lhs:ty, $rhs:ty, $out:ty) => {
|
|
|
|
impl<L, R, const M: usize, const N: usize> ::std::ops::$op_trait<$rhs> for $lhs
|
2022-08-01 07:33:43 +00:00
|
|
|
where
|
2023-06-14 07:04:24 +00:00
|
|
|
L: ::std::ops::$op_trait<R> + Copy,
|
2022-11-15 05:23:15 +00:00
|
|
|
R: Copy,
|
2022-08-01 07:33:43 +00:00
|
|
|
{
|
2022-08-19 04:07:05 +00:00
|
|
|
#[inline(always)]
|
2023-06-14 07:04:24 +00:00
|
|
|
fn $op_fn(&mut self, other: $rhs) {
|
2022-08-19 04:07:05 +00:00
|
|
|
for m in 0..M {
|
|
|
|
for n in 0..N {
|
2023-06-14 07:04:24 +00:00
|
|
|
self.data[m][n].$op_fn(other.data[m][n]);
|
2022-08-19 04:07:05 +00:00
|
|
|
}
|
2022-08-01 07:33:43 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2022-11-27 22:59:36 +00:00
|
|
|
#[doc(hidden)]
|
2022-08-01 07:33:43 +00:00
|
|
|
macro_rules! _impl_op_ms_internal {
|
2023-06-14 07:04:24 +00:00
|
|
|
($op_trait:ident, $op_fn:ident, $lhs:ty, $rhs:ty, $out:ty) => {
|
|
|
|
impl<L, R, const M: usize, const N: usize> ::std::ops::$op_trait<$rhs> for $lhs
|
2022-08-01 07:33:43 +00:00
|
|
|
where
|
2023-06-14 07:04:24 +00:00
|
|
|
L: ::std::ops::$op_trait<R, Output = L> + Copy,
|
2022-11-15 05:23:15 +00:00
|
|
|
R: Copy + Num,
|
2022-08-01 07:33:43 +00:00
|
|
|
{
|
|
|
|
type Output = $out;
|
|
|
|
|
2022-08-19 04:07:05 +00:00
|
|
|
#[inline(always)]
|
2023-06-14 07:04:24 +00:00
|
|
|
fn $op_fn(self, other: $rhs) -> Self::Output {
|
2022-08-01 07:33:43 +00:00
|
|
|
let mut result = self.clone();
|
2022-08-19 04:07:05 +00:00
|
|
|
for m in 0..M {
|
|
|
|
for n in 0..N {
|
2023-06-14 07:04:24 +00:00
|
|
|
result.data[m][n] = self.data[m][n].$op_fn(other);
|
2022-08-19 04:07:05 +00:00
|
|
|
}
|
2022-08-01 07:33:43 +00:00
|
|
|
}
|
|
|
|
result
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2022-11-27 22:59:36 +00:00
|
|
|
#[doc(hidden)]
|
2022-08-01 07:33:43 +00:00
|
|
|
macro_rules! _impl_opassign_ms_internal {
|
2023-06-14 07:04:24 +00:00
|
|
|
($op_trait:ident, $op_fn:ident, $lhs:ty, $rhs:ty, $out:ty) => {
|
|
|
|
impl<L, R, const M: usize, const N: usize> ::std::ops::$op_trait<$rhs> for $lhs
|
2022-08-01 07:33:43 +00:00
|
|
|
where
|
2023-06-14 07:04:24 +00:00
|
|
|
L: ::std::ops::$op_trait<R> + Copy,
|
2022-11-15 05:23:15 +00:00
|
|
|
R: Copy + Num,
|
2022-08-01 07:33:43 +00:00
|
|
|
{
|
2022-08-19 04:07:05 +00:00
|
|
|
#[inline(always)]
|
2023-06-14 07:04:24 +00:00
|
|
|
fn $op_fn(&mut self, r: $rhs) {
|
2022-08-19 04:07:05 +00:00
|
|
|
for m in 0..M {
|
|
|
|
for n in 0..N {
|
2023-06-14 07:04:24 +00:00
|
|
|
self.data[m][n].$op_fn(r);
|
2022-08-19 04:07:05 +00:00
|
|
|
}
|
2022-08-01 07:33:43 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
2023-05-18 05:44:02 +00:00
|
|
|
|
|
|
|
impl_matrix_op!(neg);
|
|
|
|
impl_matrix_op!(!);
|
|
|
|
impl_matrix_op!(+);
|
|
|
|
impl_matrix_op!(-);
|
|
|
|
impl_matrix_op!(*);
|
|
|
|
impl_matrix_op!(/);
|
|
|
|
impl_matrix_op!(%);
|
|
|
|
impl_matrix_op!(&);
|
|
|
|
impl_matrix_op!(|);
|
|
|
|
impl_matrix_op!(^);
|
|
|
|
impl_matrix_op!(<<);
|
|
|
|
impl_matrix_op!(>>);
|