#[cfg(feature = "std")]
use num_traits::Float;
use crate::imp_prelude::*;
#[cfg(feature = "std")]
macro_rules! boolean_ops {
($(#[$meta1:meta])* fn $func:ident
$(#[$meta2:meta])* fn $all:ident
$(#[$meta3:meta])* fn $any:ident) => {
$(#[$meta1])*
#[must_use = "method returns a new array and does not mutate the original value"]
pub fn $func(&self) -> Array<bool, D> {
self.mapv(A::$func)
}
$(#[$meta2])*
#[must_use = "method returns a new boolean value and does not mutate the original value"]
pub fn $all(&self) -> bool {
$crate::Zip::from(self).all(|&elt| !elt.$func())
}
$(#[$meta3])*
#[must_use = "method returns a new boolean value and does not mutate the original value"]
pub fn $any(&self) -> bool {
!self.$all()
}
};
}
#[cfg(feature = "std")]
macro_rules! unary_ops {
($($(#[$meta:meta])* fn $id:ident)+) => {
$($(#[$meta])*
#[must_use = "method returns a new array and does not mutate the original value"]
pub fn $id(&self) -> Array<A, D> {
self.mapv(A::$id)
})+
};
}
#[cfg(feature = "std")]
macro_rules! binary_ops {
($($(#[$meta:meta])* fn $id:ident($ty:ty))+) => {
$($(#[$meta])*
#[must_use = "method returns a new array and does not mutate the original value"]
pub fn $id(&self, rhs: $ty) -> Array<A, D> {
self.mapv(|v| A::$id(v, rhs))
})+
};
}
#[cfg(feature = "std")]
impl<A, S, D> ArrayBase<S, D>
where
A: 'static + Float,
S: Data<Elem = A>,
D: Dimension,
{
boolean_ops! {
fn is_nan
fn is_all_nan
fn is_any_nan
}
boolean_ops! {
fn is_infinite
fn is_all_infinite
fn is_any_infinite
}
unary_ops! {
fn floor
fn ceil
fn round
fn trunc
fn fract
fn abs
fn signum
fn recip
fn sqrt
fn exp
fn exp2
fn ln
fn log2
fn log10
fn cbrt
fn sin
fn cos
fn tan
fn to_degrees
fn to_radians
}
binary_ops! {
fn powi(i32)
fn powf(A)
fn log(A)
fn abs_sub(A)
}
#[must_use = "method returns a new array and does not mutate the original value"]
pub fn pow2(&self) -> Array<A, D>
{
self.mapv(|v: A| v * v)
}
}
impl<A, S, D> ArrayBase<S, D>
where
A: 'static + PartialOrd + Clone,
S: Data<Elem = A>,
D: Dimension,
{
pub fn clamp(&self, min: A, max: A) -> Array<A, D>
{
assert!(min <= max, "min must be less than or equal to max");
self.mapv(|a| num_traits::clamp(a, min.clone(), max.clone()))
}
}