2016-12-05 05:44:42 +08:00
|
|
|
// Non-convensional componentwise operators.
|
|
|
|
|
|
|
|
use num::Signed;
|
|
|
|
|
|
|
|
use alga::general::{ClosedMul, ClosedDiv};
|
|
|
|
|
2017-08-03 01:37:44 +08:00
|
|
|
use core::{DefaultAllocator, Scalar, Matrix, MatrixMN, MatrixSum};
|
2016-12-05 05:44:42 +08:00
|
|
|
use core::dimension::Dim;
|
|
|
|
use core::storage::{Storage, StorageMut};
|
2017-08-03 01:37:44 +08:00
|
|
|
use core::allocator::{Allocator, SameShapeAllocator};
|
2016-12-05 05:44:42 +08:00
|
|
|
use core::constraint::{ShapeConstraint, SameNumberOfRows, SameNumberOfColumns};
|
|
|
|
|
|
|
|
|
|
|
|
/// The type of the result of a matrix componentwise operation.
|
2017-08-03 01:37:44 +08:00
|
|
|
pub type MatrixComponentOp<N, R1, C1, R2, C2> = MatrixSum<N, R1, C1, R2, C2>;
|
2016-12-05 05:44:42 +08:00
|
|
|
|
|
|
|
impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
|
|
|
|
/// Computes the componentwise absolute value.
|
|
|
|
#[inline]
|
2017-08-03 01:37:44 +08:00
|
|
|
pub fn abs(&self) -> MatrixMN<N, R, C>
|
|
|
|
where N: Signed,
|
|
|
|
DefaultAllocator: Allocator<N, R, C> {
|
2016-12-05 05:44:42 +08:00
|
|
|
let mut res = self.clone_owned();
|
|
|
|
|
|
|
|
for e in res.iter_mut() {
|
|
|
|
*e = e.abs();
|
|
|
|
}
|
|
|
|
|
|
|
|
res
|
|
|
|
}
|
|
|
|
|
|
|
|
// FIXME: add other operators like component_ln, component_pow, etc. ?
|
|
|
|
}
|
|
|
|
|
|
|
|
macro_rules! component_binop_impl(
|
2017-08-14 01:53:04 +08:00
|
|
|
($($binop: ident, $binop_mut: ident, $binop_assign: ident, $Trait: ident . $op_assign: ident, $desc:expr, $desc_mut:expr);* $(;)*) => {$(
|
2017-08-03 01:37:44 +08:00
|
|
|
impl<N: Scalar, R1: Dim, C1: Dim, SA: Storage<N, R1, C1>> Matrix<N, R1, C1, SA> {
|
2017-04-07 05:58:44 +08:00
|
|
|
#[doc = $desc]
|
2016-12-05 05:44:42 +08:00
|
|
|
#[inline]
|
2017-08-03 01:37:44 +08:00
|
|
|
pub fn $binop<R2, C2, SB>(&self, rhs: &Matrix<N, R2, C2, SB>) -> MatrixComponentOp<N, R1, C1, R2, C2>
|
2016-12-05 05:44:42 +08:00
|
|
|
where N: $Trait,
|
|
|
|
R2: Dim, C2: Dim,
|
|
|
|
SB: Storage<N, R2, C2>,
|
2017-08-03 01:37:44 +08:00
|
|
|
DefaultAllocator: SameShapeAllocator<N, R1, C1, R2, C2>,
|
|
|
|
ShapeConstraint: SameNumberOfRows<R1, R2> + SameNumberOfColumns<C1, C2> {
|
2016-12-05 05:44:42 +08:00
|
|
|
|
2017-08-03 01:37:44 +08:00
|
|
|
assert_eq!(self.shape(), rhs.shape(), "Componentwise mul/div: mismatched matrix dimensions.");
|
2016-12-05 05:44:42 +08:00
|
|
|
let mut res = self.clone_owned_sum();
|
2017-08-03 01:37:44 +08:00
|
|
|
|
|
|
|
for j in 0 .. res.ncols() {
|
|
|
|
for i in 0 .. res.nrows() {
|
|
|
|
unsafe {
|
2017-08-14 01:53:04 +08:00
|
|
|
res.get_unchecked_mut(i, j).$op_assign(*rhs.get_unchecked(i, j));
|
2017-08-03 01:37:44 +08:00
|
|
|
}
|
|
|
|
}
|
2016-12-05 05:44:42 +08:00
|
|
|
}
|
2017-08-03 01:37:44 +08:00
|
|
|
|
2016-12-05 05:44:42 +08:00
|
|
|
res
|
|
|
|
}
|
|
|
|
}
|
2017-08-03 01:37:44 +08:00
|
|
|
|
|
|
|
impl<N: Scalar, R1: Dim, C1: Dim, SA: StorageMut<N, R1, C1>> Matrix<N, R1, C1, SA> {
|
2017-04-07 05:58:44 +08:00
|
|
|
#[doc = $desc_mut]
|
2016-12-05 05:44:42 +08:00
|
|
|
#[inline]
|
2017-08-14 01:53:04 +08:00
|
|
|
pub fn $binop_assign<R2, C2, SB>(&mut self, rhs: &Matrix<N, R2, C2, SB>)
|
2016-12-05 05:44:42 +08:00
|
|
|
where N: $Trait,
|
|
|
|
R2: Dim,
|
|
|
|
C2: Dim,
|
|
|
|
SB: Storage<N, R2, C2>,
|
2017-08-03 01:37:44 +08:00
|
|
|
ShapeConstraint: SameNumberOfRows<R1, R2> + SameNumberOfColumns<C1, C2> {
|
|
|
|
|
|
|
|
assert_eq!(self.shape(), rhs.shape(), "Componentwise mul/div: mismatched matrix dimensions.");
|
|
|
|
|
|
|
|
for j in 0 .. self.ncols() {
|
|
|
|
for i in 0 .. self.nrows() {
|
|
|
|
unsafe {
|
2017-08-14 01:53:04 +08:00
|
|
|
self.get_unchecked_mut(i, j).$op_assign(*rhs.get_unchecked(i, j));
|
2017-08-03 01:37:44 +08:00
|
|
|
}
|
|
|
|
}
|
2016-12-05 05:44:42 +08:00
|
|
|
}
|
|
|
|
}
|
2017-08-14 01:53:04 +08:00
|
|
|
|
|
|
|
#[doc = $desc_mut]
|
|
|
|
#[inline]
|
|
|
|
#[deprecated(note = "This is renamed using the `_assign` sufix instead of the `_mut` suffix.")]
|
|
|
|
pub fn $binop_mut<R2, C2, SB>(&mut self, rhs: &Matrix<N, R2, C2, SB>)
|
|
|
|
where N: $Trait,
|
|
|
|
R2: Dim,
|
|
|
|
C2: Dim,
|
|
|
|
SB: Storage<N, R2, C2>,
|
|
|
|
ShapeConstraint: SameNumberOfRows<R1, R2> + SameNumberOfColumns<C1, C2> {
|
|
|
|
self.$binop_assign(rhs)
|
|
|
|
}
|
2016-12-05 05:44:42 +08:00
|
|
|
}
|
|
|
|
)*}
|
|
|
|
);
|
|
|
|
|
|
|
|
component_binop_impl!(
|
2017-08-14 01:53:04 +08:00
|
|
|
component_mul, component_mul_mut, component_mul_assign, ClosedMul.mul_assign,
|
2017-04-07 05:58:44 +08:00
|
|
|
"Componentwise matrix multiplication.", "Mutable, componentwise matrix multiplication.";
|
2017-08-14 01:53:04 +08:00
|
|
|
component_div, component_div_mut, component_div_assign, ClosedDiv.div_assign,
|
2017-04-07 05:58:44 +08:00
|
|
|
"Componentwise matrix division.", "Mutable, componentwise matrix division.";
|
2016-12-05 05:44:42 +08:00
|
|
|
// FIXME: add other operators like bitshift, etc. ?
|
|
|
|
);
|