use crate::{AbelianGroup, DivisionAlgebra, Field};
use core::cmp::PartialOrd;
use core::ops::{AddAssign, DivAssign, MulAssign, Neg, SubAssign};
pub trait RealField:
Field
+ PartialOrd
+ Neg<Output = Self>
+ Copy
+ Clone
+ AddAssign
+ SubAssign
+ MulAssign
+ DivAssign
{
fn nan() -> Self;
fn is_nan(self) -> bool;
fn is_infinite(self) -> bool;
fn is_finite(self) -> bool;
fn clamp(self, min: Self, max: Self) -> Self;
fn sqrt(self) -> Self;
fn abs(self) -> Self;
fn floor(self) -> Self;
fn ceil(self) -> Self;
fn round(self) -> Self;
fn exp(self) -> Self;
fn ln(self) -> Self;
fn log(self, base: Self) -> Self;
fn powf(self, n: Self) -> Self;
fn sin(self) -> Self;
fn asin(self) -> Self;
fn cos(self) -> Self;
fn acos(self) -> Self;
fn tan(self) -> Self;
fn sinh(self) -> Self;
fn cosh(self) -> Self;
fn tanh(self) -> Self;
fn atan(self) -> Self;
fn atan2(self, other: Self) -> Self;
fn pi() -> Self;
fn e() -> Self;
fn epsilon() -> Self; }
impl AbelianGroup for f32 {}
impl AbelianGroup for f64 {}
impl DivisionAlgebra<f32> for f32 {
#[inline]
fn conjugate(&self) -> Self {
*self
}
#[inline]
fn norm_sqr(&self) -> f32 {
*self * *self
}
#[inline]
fn inverse(&self) -> Self {
1.0 / *self
}
}
impl DivisionAlgebra<f64> for f64 {
#[inline]
fn conjugate(&self) -> Self {
*self
}
#[inline]
fn norm_sqr(&self) -> f64 {
*self * *self
}
#[inline]
fn inverse(&self) -> Self {
1.0 / *self
}
}
impl RealField for f32 {
#[inline]
fn nan() -> Self {
f32::NAN
}
fn is_nan(self) -> bool {
f32::is_nan(self)
}
fn is_infinite(self) -> bool {
f32::is_infinite(self)
}
fn is_finite(self) -> bool {
f32::is_finite(self)
}
#[inline]
fn clamp(self, min: Self, max: Self) -> Self {
f32::clamp(self, min, max)
}
#[inline]
fn sqrt(self) -> Self {
#[cfg(feature = "std")]
return self.sqrt();
#[cfg(all(not(feature = "std"), feature = "libm_math"))]
return libm::sqrtf(self);
}
#[inline]
fn abs(self) -> Self {
self.abs()
}
#[inline]
fn floor(self) -> Self {
#[cfg(feature = "std")]
return self.floor();
#[cfg(all(not(feature = "std"), feature = "libm_math"))]
return libm::floorf(self);
}
#[inline]
fn ceil(self) -> Self {
#[cfg(feature = "std")]
return self.ceil();
#[cfg(all(not(feature = "std"), feature = "libm_math"))]
return libm::ceilf(self);
}
#[inline]
fn round(self) -> Self {
#[cfg(feature = "std")]
return self.round();
#[cfg(all(not(feature = "std"), feature = "libm_math"))]
return libm::roundf(self);
}
#[inline]
fn exp(self) -> Self {
#[cfg(feature = "std")]
return self.exp();
#[cfg(all(not(feature = "std"), feature = "libm_math"))]
return libm::expf(self);
}
#[inline]
fn ln(self) -> Self {
#[cfg(feature = "std")]
return self.ln();
#[cfg(all(not(feature = "std"), feature = "libm_math"))]
return libm::logf(self);
}
#[inline]
fn log(self, base: Self) -> Self {
#[cfg(feature = "std")]
return self.log(base);
#[cfg(all(not(feature = "std"), feature = "libm_math"))]
return libm::logf(self) / libm::logf(base);
}
#[inline]
fn powf(self, n: Self) -> Self {
#[cfg(feature = "std")]
return self.powf(n);
#[cfg(all(not(feature = "std"), feature = "libm_math"))]
return libm::powf(self, n);
}
#[inline]
fn sin(self) -> Self {
#[cfg(feature = "std")]
return self.sin();
#[cfg(all(not(feature = "std"), feature = "libm_math"))]
return libm::sinf(self);
}
#[inline]
fn asin(self) -> Self {
#[cfg(feature = "std")]
return self.asin();
#[cfg(all(not(feature = "std"), feature = "libm_math"))]
return libm::asinf(self);
}
#[inline]
fn cos(self) -> Self {
#[cfg(feature = "std")]
return self.cos();
#[cfg(all(not(feature = "std"), feature = "libm_math"))]
return libm::cosf(self);
}
#[inline]
fn acos(self) -> Self {
#[cfg(feature = "std")]
return self.acos();
#[cfg(all(not(feature = "std"), feature = "libm_math"))]
return libm::acosf(self);
}
#[inline]
fn tan(self) -> Self {
#[cfg(feature = "std")]
return self.tan();
#[cfg(all(not(feature = "std"), feature = "libm_math"))]
return libm::tanf(self);
}
#[inline]
fn sinh(self) -> Self {
#[cfg(feature = "std")]
return self.sinh();
#[cfg(all(not(feature = "std"), feature = "libm_math"))]
return libm::sinhf(self);
}
#[inline]
fn cosh(self) -> Self {
#[cfg(feature = "std")]
return self.cosh();
#[cfg(all(not(feature = "std"), feature = "libm_math"))]
return libm::coshf(self);
}
#[inline]
fn tanh(self) -> Self {
#[cfg(feature = "std")]
return self.tanh();
#[cfg(all(not(feature = "std"), feature = "libm_math"))]
return libm::tanhf(self);
}
#[inline]
fn atan(self) -> Self {
#[cfg(feature = "std")]
return self.atan();
#[cfg(all(not(feature = "std"), feature = "libm_math"))]
return libm::atanf(self);
}
#[inline]
fn atan2(self, other: Self) -> Self {
#[cfg(feature = "std")]
return self.atan2(other);
#[cfg(all(not(feature = "std"), feature = "libm_math"))]
return libm::atan2f(self, other);
}
#[inline]
fn pi() -> Self {
core::f32::consts::PI
}
#[inline]
fn e() -> Self {
core::f32::consts::E
}
#[inline]
fn epsilon() -> Self {
f32::EPSILON
}
}
impl RealField for f64 {
#[inline]
fn nan() -> Self {
f64::NAN
}
#[inline]
fn clamp(self, min: Self, max: Self) -> Self {
f64::clamp(self, min, max)
}
#[inline]
fn abs(self) -> Self {
self.abs()
}
#[inline]
fn sqrt(self) -> Self {
#[cfg(feature = "std")]
return self.sqrt();
#[cfg(all(not(feature = "std"), feature = "libm_math"))]
return libm::sqrt(self);
}
#[inline]
fn floor(self) -> Self {
#[cfg(feature = "std")]
return self.floor();
#[cfg(all(not(feature = "std"), feature = "libm_math"))]
return libm::floor(self);
}
#[inline]
fn ceil(self) -> Self {
#[cfg(feature = "std")]
return self.ceil();
#[cfg(all(not(feature = "std"), feature = "libm_math"))]
return libm::ceil(self);
}
#[inline]
fn round(self) -> Self {
#[cfg(feature = "std")]
return self.round();
#[cfg(all(not(feature = "std"), feature = "libm_math"))]
return libm::round(self);
}
#[inline]
fn exp(self) -> Self {
#[cfg(feature = "std")]
return self.exp();
#[cfg(all(not(feature = "std"), feature = "libm_math"))]
return libm::exp(self);
}
#[inline]
fn ln(self) -> Self {
#[cfg(feature = "std")]
return self.ln();
#[cfg(all(not(feature = "std"), feature = "libm_math"))]
return libm::log(self);
}
#[inline]
fn log(self, base: Self) -> Self {
#[cfg(feature = "std")]
return self.log(base);
#[cfg(all(not(feature = "std"), feature = "libm_math"))]
return libm::log(self) / libm::log(base);
}
#[inline]
fn powf(self, n: Self) -> Self {
#[cfg(feature = "std")]
return self.powf(n);
#[cfg(all(not(feature = "std"), feature = "libm_math"))]
return libm::pow(self, n);
}
#[inline]
fn sin(self) -> Self {
#[cfg(feature = "std")]
return self.sin();
#[cfg(all(not(feature = "std"), feature = "libm_math"))]
return libm::sin(self);
}
#[inline]
fn cos(self) -> Self {
#[cfg(feature = "std")]
return self.cos();
#[cfg(all(not(feature = "std"), feature = "libm_math"))]
return libm::cos(self);
}
#[inline]
fn acos(self) -> Self {
#[cfg(feature = "std")]
return self.acos();
#[cfg(all(not(feature = "std"), feature = "libm_math"))]
return libm::acos(self);
}
#[inline]
fn tan(self) -> Self {
#[cfg(feature = "std")]
return self.tan();
#[cfg(all(not(feature = "std"), feature = "libm_math"))]
return libm::tan(self);
}
#[inline]
fn sinh(self) -> Self {
#[cfg(feature = "std")]
return self.sinh();
#[cfg(all(not(feature = "std"), feature = "libm_math"))]
return libm::sinh(self);
}
#[inline]
fn cosh(self) -> Self {
#[cfg(feature = "std")]
return self.cosh();
#[cfg(all(not(feature = "std"), feature = "libm_math"))]
return libm::cosh(self);
}
#[inline]
fn tanh(self) -> Self {
#[cfg(feature = "std")]
return self.tanh();
#[cfg(all(not(feature = "std"), feature = "libm_math"))]
return libm::tanh(self);
}
#[inline]
fn atan2(self, other: Self) -> Self {
#[cfg(feature = "std")]
return self.atan2(other);
#[cfg(all(not(feature = "std"), feature = "libm_math"))]
return libm::atan2(self, other);
}
#[inline]
fn pi() -> Self {
core::f64::consts::PI
}
#[inline]
fn e() -> Self {
core::f64::consts::E
}
#[inline]
fn epsilon() -> Self {
f64::EPSILON
}
#[inline]
fn atan(self) -> Self {
#[cfg(feature = "std")]
return self.atan();
#[cfg(all(not(feature = "std"), feature = "libm_math"))]
return libm::atan(self);
}
#[inline]
fn asin(self) -> Self {
#[cfg(feature = "std")]
return self.asin();
#[cfg(all(not(feature = "std"), feature = "libm_math"))]
return libm::asin(self);
}
fn is_nan(self) -> bool {
f64::is_nan(self)
}
fn is_infinite(self) -> bool {
f64::is_infinite(self)
}
fn is_finite(self) -> bool {
f64::is_finite(self)
}
}