use crate::{Dual, Real};
use core::ops::Div;
impl<T: Real + Div<Output = T>> Real for Dual<T> {
#[inline]
fn nan() -> Self {
Self::new(T::nan(), T::zero())
}
#[inline]
fn is_nan(self) -> bool {
self.re.is_nan()
}
#[inline]
fn is_infinite(self) -> bool {
self.re.is_infinite()
}
#[inline]
fn is_finite(self) -> bool {
self.re.is_finite()
}
#[inline]
fn clamp(self, min: Self, max: Self) -> Self {
if self.re < min.re {
min
} else if self.re > max.re {
max
} else {
self
}
}
#[inline]
fn sqrt(self) -> Self {
let s = self.re.sqrt();
Self::new(s, self.du / (s * (T::one() + T::one())))
}
#[inline]
fn abs(self) -> Self {
if self.re < T::zero() {
Self::new(self.re.abs(), -self.du)
} else {
Self::new(self.re.abs(), self.du)
}
}
#[inline]
fn floor(self) -> Self {
Self::new(self.re.floor(), T::zero())
}
#[inline]
fn ceil(self) -> Self {
Self::new(self.re.ceil(), T::zero())
}
#[inline]
fn round(self) -> Self {
Self::new(self.re.round(), T::zero())
}
#[inline]
fn exp(self) -> Self {
let e = self.re.exp();
Self::new(e, e * self.du)
}
#[inline]
fn ln(self) -> Self {
Self::new(self.re.ln(), self.du / self.re)
}
#[inline]
fn log(self, base: Self) -> Self {
self.ln() / base.ln()
}
#[inline]
fn log2(self) -> Self {
let two = T::one() + T::one();
Self::new(self.re.log2(), self.du / (self.re * two.ln()))
}
#[inline]
fn log10(self) -> Self {
let two = T::one() + T::one();
let five = two + two + T::one();
let ten = two * five;
Self::new(self.re.log10(), self.du / (self.re * ten.ln()))
}
#[inline]
fn powf(self, n: Self) -> Self {
(n * self.ln()).exp()
}
#[inline]
fn sin(self) -> Self {
Self::new(self.re.sin(), self.re.cos() * self.du)
}
#[inline]
fn asin(self) -> Self {
let d = (T::one() - self.re * self.re).sqrt();
Self::new(self.re.asin(), self.du / d)
}
#[inline]
fn cos(self) -> Self {
Self::new(self.re.cos(), -(self.re.sin() * self.du))
}
#[inline]
fn acos(self) -> Self {
let d = (T::one() - self.re * self.re).sqrt();
Self::new(self.re.acos(), -(self.du / d))
}
#[inline]
fn tan(self) -> Self {
let c = self.re.cos();
Self::new(self.re.tan(), self.du / (c * c))
}
#[inline]
fn sinh(self) -> Self {
Self::new(self.re.sinh(), self.re.cosh() * self.du)
}
#[inline]
fn cosh(self) -> Self {
Self::new(self.re.cosh(), self.re.sinh() * self.du)
}
#[inline]
fn tanh(self) -> Self {
let t = self.re.tanh();
Self::new(t, (T::one() - t * t) * self.du)
}
#[inline]
fn atan(self) -> Self {
Self::new(self.re.atan(), self.du / (T::one() + self.re * self.re))
}
#[inline]
fn atan2(self, other: Self) -> Self {
let denom = self.re * self.re + other.re * other.re;
Self::new(
self.re.atan2(other.re),
(other.re * self.du - self.re * other.du) / denom,
)
}
#[inline]
fn pi() -> Self {
Self::new(T::pi(), T::zero())
}
#[inline]
fn e() -> Self {
Self::new(T::e(), T::zero())
}
#[inline]
fn epsilon() -> Self {
Self::new(T::epsilon(), T::zero())
}
}