Skip to main content

radiate_utils/primitives/
float.rs

1use crate::{DataType, primitives::Primitive};
2use num_order::{NumHash, NumOrd};
3
4pub trait Float: Primitive + num_traits::Float + NumHash + NumOrd<Self> {
5    const DTYPE: DataType;
6    const THREE: Self;
7    const FOUR: Self;
8    const FIVE: Self;
9    const SIX: Self;
10    const EPS: Self;
11    const NAN: Self;
12    const TENTH: Self;
13    const HUNDREDTH: Self;
14    const THOUSANDTH: Self;
15    const PI: Self;
16
17    fn safe_clamp(self, min: Self, max: Self) -> Self {
18        if self.is_finite() {
19            self.clamp(min, max)
20        } else {
21            Self::EPS
22        }
23    }
24}
25
26#[macro_export]
27macro_rules! impl_float_scalar {
28    ($t:ty, $dtype:ident, $eps:expr, $pi:expr) => {
29        impl Primitive for $t {
30            const HALF: Self = 0.5;
31            const MIN: Self = <$t>::MIN;
32            const MAX: Self = <$t>::MAX;
33            const ZERO: Self = 0.0;
34            const ONE: Self = 1.0;
35            const TWO: Self = 2.0;
36
37            #[inline]
38            fn safe_add(self, rhs: Self) -> Self {
39                self + rhs
40            }
41
42            #[inline]
43            fn safe_sub(self, rhs: Self) -> Self {
44                self - rhs
45            }
46
47            #[inline]
48            fn safe_mul(self, rhs: Self) -> Self {
49                (self * rhs)
50            }
51
52            #[inline]
53            fn safe_div(self, rhs: Self) -> Self {
54                if rhs == Self::ZERO { self } else { self / rhs }
55            }
56
57            #[inline]
58            fn safe_mean(self, rhs: Self) -> Self {
59                (self + rhs) * Self::HALF
60            }
61
62            #[inline]
63            fn is_equal(self, rhs: Self) -> bool {
64                (self - rhs).abs() <= $eps
65            }
66        }
67
68        impl Float for $t {
69            const DTYPE: DataType = DataType::$dtype;
70            const THREE: Self = 3.0;
71            const FOUR: Self = 4.0;
72            const FIVE: Self = 5.0;
73            const SIX: Self = 6.0;
74            const NAN: Self = <$t>::NAN;
75            const EPS: Self = $eps;
76            const TENTH: Self = 0.1;
77            const HUNDREDTH: Self = 0.01;
78            const THOUSANDTH: Self = 0.001;
79            const PI: Self = $pi;
80        }
81    };
82}
83
84impl_float_scalar!(f32, Float32, 1e-6_f32, std::f32::consts::PI);
85impl_float_scalar!(f64, Float64, 1e-12_f64, std::f64::consts::PI);