use super::{private, NumericElement};
pub trait FloatElement: private::Sealed + NumericElement {
fn from_f32(val: f32) -> Self;
fn from_f64(val: f64) -> Self;
fn to_f32(self) -> f32;
#[inline]
fn exp(self) -> Self {
Self::from_f32(libm::expf(self.to_f32()))
}
#[inline]
fn ln(self) -> Self {
Self::from_f32(libm::logf(self.to_f32()))
}
#[inline]
fn sin(self) -> Self {
Self::from_f32(libm::sinf(self.to_f32()))
}
#[inline]
fn cos(self) -> Self {
Self::from_f32(libm::cosf(self.to_f32()))
}
#[inline]
fn acos(self) -> Self {
Self::from_f32(libm::acosf(self.to_f32()))
}
#[inline]
fn tan(self) -> Self {
Self::from_f32(libm::tanf(self.to_f32()))
}
#[inline]
fn sinh(self) -> Self {
Self::from_f32(libm::sinhf(self.to_f32()))
}
#[inline]
fn cosh(self) -> Self {
Self::from_f32(libm::coshf(self.to_f32()))
}
#[inline]
fn tanh(self) -> Self {
Self::from_f32(libm::tanhf(self.to_f32()))
}
#[inline]
fn atan2(self, other: Self) -> Self {
Self::from_f32(libm::atan2f(self.to_f32(), other.to_f32()))
}
#[inline]
fn powf(self, n: Self) -> Self {
Self::from_f32(libm::powf(self.to_f32(), n.to_f32()))
}
#[inline]
fn recip(self) -> Self {
Self::from_f32(1.0 / self.to_f32())
}
#[inline]
fn floor(self) -> Self {
Self::from_f32(libm::floorf(self.to_f32()))
}
#[inline]
fn ceil(self) -> Self {
Self::from_f32(libm::ceilf(self.to_f32()))
}
#[inline]
fn round(self) -> Self {
Self::from_f32(libm::roundf(self.to_f32()))
}
#[inline]
fn trunc(self) -> Self {
Self::from_f32(libm::truncf(self.to_f32()))
}
#[inline]
fn signum(self) -> Self {
let x = self.to_f32();
if x.is_nan() {
Self::from_f32(x)
} else {
Self::from_f32(libm::copysignf(1.0, x))
}
}
#[inline]
fn powi(self, mut n: i32) -> Self {
let mut base = self;
if n < 0 {
base = <Self as NumericElement>::ONE / base;
n = -n;
}
let mut acc = <Self as NumericElement>::ONE;
while n > 0 {
if n & 1 == 1 {
acc *= base;
}
base *= base;
n >>= 1;
}
acc
}
#[inline]
fn log10(self) -> Self {
Self::from_f32(libm::log10f(self.to_f32()))
}
#[inline]
fn log2(self) -> Self {
Self::from_f32(libm::log2f(self.to_f32()))
}
#[inline]
fn erf(self) -> Self {
Self::from_f32(libm::erff(self.to_f32()))
}
#[inline]
fn erfc(self) -> Self {
Self::from_f32(libm::erfcf(self.to_f32()))
}
#[inline]
fn lgamma(self) -> Self {
Self::from_f32(libm::lgammaf(self.to_f32()))
}
#[inline]
fn default_epsilon() -> Self
where
Self: crate::RealField,
{
<Self as crate::RealField>::EPSILON
}
#[inline]
fn pi() -> Self
where
Self: crate::RealField,
{
<Self as crate::RealField>::PI
}
#[inline]
fn max(self, other: Self) -> Self {
<Self as NumericElement>::max_scalar(self, other)
}
#[inline]
fn min(self, other: Self) -> Self {
<Self as NumericElement>::min_scalar(self, other)
}
#[inline]
fn norm(self) -> Self {
<Self as NumericElement>::abs(self)
}
}