Skip to main content

complex_bessel/
machine.rs

1//! Machine constants and the `BesselFloat` trait.
2//!
3//! Constants follow the Fortran I1MACH/D1MACH conventions from TOMS 644.
4
5use num_traits::Float;
6
7/// Floating-point trait for Bessel function computation.
8///
9/// Implemented for `f64` and `f32`. Provides machine constants and
10/// derived thresholds used by the Amos algorithm.
11pub trait BesselFloat: Float + core::fmt::Debug + 'static {
12    /// Machine epsilon (D1MACH(3)).
13    const MACH_EPSILON: Self;
14    /// Smallest positive normal number (D1MACH(1)).
15    const MACH_TINY: Self;
16    /// Largest representable number (D1MACH(2)).
17    const MACH_HUGE: Self;
18    /// Number of binary digits in the mantissa (I1MACH(14)).
19    const MACH_DIGITS: i32;
20    /// Minimum binary exponent (I1MACH(12)).
21    const MACH_MIN_EXP: i32;
22    /// Maximum binary exponent (I1MACH(11)).
23    const MACH_MAX_EXP: i32;
24
25    /// Tolerance: max(MACH_EPSILON, 1e-18).
26    fn tol() -> Self;
27    /// Decimal digits: log10(2) * (DIGITS - 1).
28    fn dig() -> Self;
29    /// Large order threshold: 10 + 6*(DIG - 3).
30    fn fnul() -> Self;
31    /// Asymptotic region boundary: 1.2*DIG + 3.
32    fn rl() -> Self;
33    /// Underflow elimination threshold: 2.303*(K*R1M5 - 3), K = min(|MIN_EXP|, MAX_EXP).
34    fn elim() -> Self;
35    /// Overflow elimination threshold: ELIM + max(-2.303*R1M5*(DIGITS-1), -41.45).
36    fn alim() -> Self;
37}
38
39impl BesselFloat for f64 {
40    const MACH_EPSILON: f64 = 2.220446049250313e-16;
41    const MACH_TINY: f64 = 2.2250738585072014e-308;
42    const MACH_HUGE: f64 = 1.7976931348623157e+308;
43    const MACH_DIGITS: i32 = 53;
44    const MACH_MIN_EXP: i32 = -1021;
45    const MACH_MAX_EXP: i32 = 1024;
46
47    #[inline]
48    fn tol() -> f64 { 2.220446049250313e-16 }       // max(EPSILON, 1e-18)
49    #[inline]
50    fn dig() -> f64 { 15.653559774527022 }           // R1M5 * (DIGITS - 1)
51    #[inline]
52    fn fnul() -> f64 { 85.92135864716212 }           // 10 + 6*(DIG - 3)
53    #[inline]
54    fn rl() -> f64 { 21.784271729432426 }            // 1.2*DIG + 3
55    #[inline]
56    fn elim() -> f64 { 700.9217936944459 }           // 2.303*(K*R1M5 - 3)
57    #[inline]
58    fn alim() -> f64 { 664.8716455337102 }           // ELIM + max(-2.303*R1M5*(DIGITS-1), -41.45)
59}
60
61impl BesselFloat for f32 {
62    const MACH_EPSILON: f32 = 1.1920929e-7;
63    const MACH_TINY: f32 = 1.1754944e-38;
64    const MACH_HUGE: f32 = 3.4028235e+38;
65    const MACH_DIGITS: i32 = 24;
66    const MACH_MIN_EXP: i32 = -125;
67    const MACH_MAX_EXP: i32 = 128;
68
69    #[inline]
70    fn tol() -> f32 { 1.1920929e-7 }                // max(EPSILON, 1e-18)
71    #[inline]
72    fn dig() -> f32 { 6.923689900271568 }            // R1M5 * (DIGITS - 1)
73    #[inline]
74    fn fnul() -> f32 { 33.542139401629406 }          // 10 + 6*(DIG - 3)
75    #[inline]
76    fn rl() -> f32 { 11.308427880325882 }            // 1.2*DIG + 3
77    #[inline]
78    fn elim() -> f32 { 79.75001000176859 }           // 2.303*(K*R1M5 - 3)
79    #[inline]
80    fn alim() -> f32 { 63.80475216144317 }           // ELIM + max(-2.303*R1M5*(DIGITS-1), -41.45)
81}