use crate::prelude::*;
#[derive(Clone, Copy, Debug, Default)]
pub struct InfClip;
impl Map for InfClip {
type Input = f64;
type Output = f64;
fn eval(&self, x: f64) -> f64 {
x.signum()
}
}
impl<S: Signal> eff::PwMapSgn<S, InfClip> {
pub const fn inf_clip(sgn: S) -> Self {
Self::new_pw(sgn, InfClip)
}
}
#[derive(Clone, Copy, Debug)]
pub struct Clip {
pub threshold: f64,
}
impl Clip {
#[must_use]
pub const fn new(threshold: f64) -> Self {
Self { threshold }
}
}
impl Default for Clip {
fn default() -> Self {
Self::new(1.0)
}
}
impl Map for Clip {
type Input = f64;
type Output = f64;
fn eval(&self, x: f64) -> f64 {
x.clamp(-self.threshold, self.threshold) / self.threshold
}
}
impl<S: Signal> eff::PwMapSgn<S, Clip> {
pub const fn clip(sgn: S, threshold: f64) -> Self {
Self::new_pw(sgn, Clip::new(threshold))
}
}
#[derive(Clone, Copy, Debug)]
pub struct Atan {
pub shape: f64,
}
impl Atan {
#[must_use]
pub const fn new(shape: f64) -> Self {
Self { shape }
}
}
impl Default for Atan {
fn default() -> Self {
Self::new(1.0)
}
}
impl Map for Atan {
type Input = f64;
type Output = f64;
fn eval(&self, x: f64) -> f64 {
(self.shape * x).atan() / std::f64::consts::FRAC_PI_2
}
}
impl<S: Signal> eff::PwMapSgn<S, Atan> {
pub const fn atan(sgn: S, shape: f64) -> Self {
Self::new_pw(sgn, Atan::new(shape))
}
}
#[derive(Clone, Copy, Debug)]
pub struct Pow {
pub exponent: u16,
}
impl Pow {
#[must_use]
pub const fn new(exponent: u16) -> Self {
Self { exponent }
}
#[must_use]
pub const fn linear() -> Self {
Self::new(1)
}
#[must_use]
pub const fn cubic() -> Self {
Self::new(3)
}
}
impl Default for Pow {
fn default() -> Self {
Self::linear()
}
}
impl Map for Pow {
type Input = f64;
type Output = f64;
fn eval(&self, x: f64) -> f64 {
let res = x.powi(i32::from(self.exponent));
if self.exponent % 2 == 0 {
map::sgn(res)
} else {
res
}
}
}
impl<S: Signal> eff::PwMapSgn<S, Pow> {
pub const fn pow(sgn: S, exponent: u16) -> Self {
Self::new_pw(sgn, Pow::new(exponent))
}
pub const fn cubic(sgn: S) -> Self {
Self::pow(sgn, 3)
}
}