scalars 0.3.3

Minimal numeric traits: Zero, One, Inv, Sqrt, Exp, Logarithm, Trigonometry, Real, Integer
Documentation
#![no_std]
#![doc = "Minimal numeric traits for the vector-space/GA ecosystem."]

mod float;
mod int;

use core::ops::{Add, Div, Mul, Neg, Rem, Sub};

/// Frame-rate independent damping factor in `[0, 1)`.
///
/// Returns `1 - 2^(-half_lives)`, the fraction by which a value should move toward
/// its target over the given number of half-lives. Since the base is `2`, one half-life
/// removes half the remaining distance. Callers typically pass `rate · timestep`.
#[must_use]
#[inline]
pub fn damp_factor<R: Real>(half_lives: R) -> R {
    R::one() - (-half_lives).exp2()
}

/// Frame-rate independent asymptotic approach of `current` toward `target`.
///
/// Moves `current` toward `target` by [`damp_factor`] of the given `half_lives`,
/// i.e. `current + (target - current) · damp_factor(half_lives)`. Independent of how
/// `half_lives` is subdivided across calls.
#[must_use]
#[inline]
pub fn damp<R: Real>(current: R, target: R, half_lives: R) -> R {
    current + (target - current) * damp_factor(half_lives)
}

/// Additive identity.
pub trait Zero {
    /// Returns the additive identity.
    #[must_use]
    fn zero() -> Self;
    /// Returns whether `self` is the additive identity.
    fn is_zero(&self) -> bool;
}

/// Multiplicative identity.
pub trait One {
    /// Returns the multiplicative identity.
    #[must_use]
    fn one() -> Self;
    /// Returns whether `self` is the multiplicative identity.
    fn is_one(&self) -> bool;
}

/// Multiplicative inverse.
pub trait Inv {
    /// The type produced by inversion.
    type Output;
    /// Returns the multiplicative inverse.
    #[must_use]
    fn inv(self) -> Self::Output;
}

/// Square root.
pub trait Sqrt {
    /// Returns the square root.
    #[must_use]
    fn sqrt(self) -> Self;
}

/// Exponentiation.
pub trait Exp {
    /// The type produced by exponentiation (e.g. Bivector → Rotor).
    type Output;
    /// Returns `e` raised to `self`.
    #[must_use]
    fn exp(self) -> Self::Output;
    /// Returns `2` raised to `self`.
    #[must_use]
    fn exp2(self) -> Self::Output;
}

/// Logarithms and arbitrary powers.
pub trait Logarithm {
    /// Returns the natural logarithm.
    #[must_use]
    fn ln(self) -> Self;
    /// Returns the base-2 logarithm.
    #[must_use]
    fn log2(self) -> Self;
    /// Returns `self` raised to `exponent`.
    #[must_use]
    fn powf(self, exponent: Self) -> Self;
}

/// Trigonometric functions.
pub trait Trigonometry: Sized {
    /// Returns `[sin, cos]` of `self`.
    #[must_use]
    fn sin_cos(self) -> [Self; 2];

    /// Returns the sine of `self`.
    #[must_use]
    fn sin(self) -> Self {
        let [sin, _] = self.sin_cos();
        sin
    }

    /// Returns the cosine of `self`.
    #[must_use]
    fn cos(self) -> Self {
        let [_, cos] = self.sin_cos();
        cos
    }

    /// Returns the tangent of `self`.
    #[must_use]
    fn tan(self) -> Self;
}

/// Inverse trigonometric functions.
pub trait InverseTrigonometry {
    /// Returns the arcsine of `self`.
    #[must_use]
    fn asin(self) -> Self;
    /// Returns the arccosine of `self`.
    #[must_use]
    fn acos(self) -> Self;
    /// Returns the arctangent of `self`.
    #[must_use]
    fn atan(self) -> Self;
    /// Returns the arctangent of `self / other`, using the signs of both to select the quadrant.
    #[must_use]
    fn atan2(self, other: Self) -> Self;
}

/// Ordering-based minimum, maximum and clamping.
pub trait Clamp: Sized {
    /// Returns the lesser of `self` and `other`.
    #[must_use]
    fn min(self, other: Self) -> Self;
    /// Returns the greater of `self` and `other`.
    #[must_use]
    fn max(self, other: Self) -> Self;

    /// Returns `self` clamped to `[lower, upper]`.
    #[must_use]
    fn clamp(self, lower: Self, upper: Self) -> Self {
        self.max(lower).min(upper)
    }
}

/// Parsing from a string in a given radix.
#[cfg(feature = "std")]
pub trait FromStrRadix: Sized {
    /// The error produced on a failed parse.
    type Error;
    /// Parses `source` interpreted in `radix`.
    ///
    /// # Errors
    ///
    /// Returns an error if `source` is not a valid value in `radix`.
    fn from_str_radix(source: &str, radix: u32) -> Result<Self, Self::Error>;
}

/// A type forming a commutative ring: copyable, comparable, with the four basic operations and both identities.
pub trait Numeric:
    Copy + PartialEq + Add<Output = Self> + Sub<Output = Self> + Mul<Output = Self> + Zero + One
{
}

impl<T> Numeric for T where
    T: Copy + PartialEq + Add<Output = Self> + Sub<Output = Self> + Mul<Output = Self> + Zero + One
{
}

/// A totally ordered numeric type with integer division and remainder.
pub trait Integer: Numeric + Eq + Ord + Div<Output = Self> + Rem<Output = Self> {}

impl<T> Integer for T where T: Numeric + Eq + Ord + Div<Output = Self> + Rem<Output = Self> {}

/// A real-valued numeric type with the full set of algebraic and analytic operations.
pub trait Real:
    Numeric
    + PartialOrd
    + Div<Output = Self>
    + Neg<Output = Self>
    + Inv<Output = Self>
    + Sqrt
    + Exp<Output = Self>
    + Logarithm
    + Trigonometry
    + InverseTrigonometry
    + Clamp
{
}

impl<T> Real for T where
    T: Numeric
        + PartialOrd
        + Div<Output = Self>
        + Neg<Output = Self>
        + Inv<Output = Self>
        + Sqrt
        + Exp<Output = Self>
        + Logarithm
        + Trigonometry
        + InverseTrigonometry
        + Clamp
{
}