multicalc 0.9.0

Math for real-time embedded systems, in stable no_std Rust: state estimation, control, kinematics, Lie groups, autodiff, and linear algebra — from 64-bit servers to bare-metal microcontrollers
Documentation
//! Edge-only projection to `f64` / `f32` (the reverse of [`Numeric::from_f64`]).
//!
//! Kept separate from [`Numeric`] so generic algorithms cannot strip autodiff.
//! Autodiff types return their value part; nesting such as `Dual<HyperDual<f64>>` works.

use crate::{Dual, HyperDual, Jet, Numeric};

/// A scalar that can be projected to `f64` and `f32`.
///
/// ```
/// use multicalc::scalar::{Dual, Primal};
///
/// let x = Dual::new(2.0, 99.0);
/// assert_eq!(x.to_f64(), 2.0);
/// ```
pub trait Primal {
    /// Returns the value as an `f64` (the primal part, for autodiff scalars).
    fn to_f64(&self) -> f64;

    /// Returns the value as an `f32` (the primal part, for autodiff scalars).
    fn to_f32(&self) -> f32;
}

impl Primal for f64 {
    fn to_f64(&self) -> f64 {
        *self
    }

    fn to_f32(&self) -> f32 {
        *self as f32
    }
}

impl Primal for f32 {
    fn to_f64(&self) -> f64 {
        *self as f64
    }

    fn to_f32(&self) -> f32 {
        *self
    }
}

impl<T: Numeric + Primal> Primal for Dual<T> {
    fn to_f64(&self) -> f64 {
        self.value.to_f64()
    }

    fn to_f32(&self) -> f32 {
        self.value.to_f32()
    }
}

impl<T: Numeric + Primal> Primal for HyperDual<T> {
    fn to_f64(&self) -> f64 {
        self.real.to_f64()
    }

    fn to_f32(&self) -> f32 {
        self.real.to_f32()
    }
}

impl<T: Numeric + Primal, const N: usize> Primal for Jet<T, N> {
    fn to_f64(&self) -> f64 {
        self.value().to_f64()
    }

    fn to_f32(&self) -> f32 {
        self.value().to_f32()
    }
}