1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
use crate::{Vector, Matrix, traits::Broadcast};
use num_traits::Float;
impl<T, const M: usize, const N: usize> Broadcast<Matrix<T, M, N>> for Matrix<T, M, N> {
fn broadcast(self) -> Self { self }
}
impl<T: Copy, const M: usize, const N: usize> Broadcast<Matrix<T, M, N>> for Vector<T, N> {
fn broadcast(self) -> Matrix<T, M, N> { Matrix::from_vector_of_vectors(Vector::fill(self)) }
}
impl<T: Copy, const M: usize, const N: usize> Broadcast<Matrix<T, M, N>> for T {
fn broadcast(self) -> Matrix<T, M, N> { Matrix::fill(self) }
}
impl<T: Float, const M: usize, const N: usize> Matrix<T, M, N> {
pub fn abs(self) -> Self { self.map(T::abs) }
pub fn abs_sub<B: Broadcast<Self>>(self, other: B) -> Self { self.zip(other.broadcast()).map(|(s, o)| T::abs_sub(s, o)) }
pub fn signum(self) -> Self { self.map(T::signum) }
pub fn cbrt(self) -> Self { self.map(T::cbrt) }
pub fn sqrt(self) -> Self { self.map(T::sqrt) }
pub fn vmin<B: Broadcast<Self>>(self, other: B) -> Self { self.zip(other.broadcast()).map(|(s, o)| T::min(s, o)) }
pub fn vmax<B: Broadcast<Self>>(self, other: B) -> Self { self.zip(other.broadcast()).map(|(s, o)| T::max(s, o)) }
pub fn clamp<A: Broadcast<Self>, B: Broadcast<Self>>(self, a: A, b: B) -> Self { self.zip(a.broadcast().zip(b.broadcast())).map(|(s, (a, b))| T::min(T::max(s, a), b)) }
pub fn acos(self) -> Self { self.map(T::acos) }
pub fn asin(self) -> Self { self.map(T::asin) }
pub fn atan(self) -> Self { self.map(T::atan) }
pub fn atan2<B: Broadcast<Self>>(self, other: B) -> Self { self.zip(other.broadcast()).map(|(s, o)| T::atan2(s, o)) }
pub fn cosh(self) -> Self { self.map(T::cosh) }
pub fn hypot<B: Broadcast<Self>>(self, other: B) -> Self { self.zip(other.broadcast()).map(|(s, o)| T::hypot(s, o)) }
pub fn sinh(self) -> Self { self.map(T::sinh) }
pub fn tan(self) -> Self { self.map(T::tan) }
pub fn tanh(self) -> Self { self.map(T::tanh) }
pub fn log2(self) -> Self { self.map(T::log2) }
pub fn mul_add<A: Broadcast<Self>, B: Broadcast<Self>>(self, a: A, b: B) -> Self { self.zip(a.broadcast().zip(b.broadcast())).map(|(s, (a, b))| T::mul_add(s, a, b)) }
pub fn exp(self) -> Self { self.map(T::exp) }
pub fn powi<B: Broadcast<Matrix<i32, M, N>>>(self, other: B) -> Self { self.zip(other.broadcast()).map(|(s, o)| T::powi(s, o)) }
pub fn ln(self) -> Self { self.map(T::ln) }
pub fn powf<B: Broadcast<Self>>(self, other: B) -> Self { self.zip(other.broadcast()).map(|(s, o)| T::powf(s, o)) }
pub fn log<B: Broadcast<Self>>(self, other: B) -> Self { self.zip(other.broadcast()).map(|(s, o)| T::log(s, o)) }
pub fn sin(self) -> Self { self.map(T::sin) }
pub fn cos(self) -> Self { self.map(T::cos) }
pub fn asinh(self) -> Self { self.map(T::asinh) }
pub fn acosh(self) -> Self { self.map(T::acosh) }
pub fn atanh(self) -> Self { self.map(T::atanh) }
pub fn floor(self) -> Self { self.map(T::floor) }
pub fn ceil(self) -> Self { self.map(T::ceil) }
pub fn round(self) -> Self { self.map(T::round) }
pub fn trunc(self) -> Self { self.map(T::trunc) }
pub fn fract(self) -> Self { self.map(T::fract) }
pub fn recip(self) -> Self { self.map(T::recip) }
pub fn exp2(self) -> Self { self.map(T::exp2) }
pub fn log10(self) -> Self { self.map(T::log10) }
pub fn sin_cos(self) -> (Self, Self) { self.map(T::sin_cos).unzip() }
pub fn exp_m1(self) -> Self { self.map(T::exp_m1) }
pub fn ln_1p(self) -> Self { self.map(T::ln_1p) }
}