Skip to main content

ferray_core/
constants.rs

1// ferray-core: Mathematical constants (REQ-33)
2//
3// Mirrors numpy's constants module: np.pi, np.e, np.inf, np.nan, etc.
4
5// `EULER_GAMMA` is a 16-digit canonical mathematical constant; underscore
6// separators would diverge from the form quoted by every reference.
7#![allow(clippy::unreadable_literal)]
8
9/// The ratio of a circle's circumference to its diameter.
10pub const PI: f64 = core::f64::consts::PI;
11
12/// Euler's number, the base of natural logarithms.
13pub const E: f64 = core::f64::consts::E;
14
15/// Positive infinity.
16pub const INF: f64 = f64::INFINITY;
17
18/// Negative infinity.
19pub const NEG_INF: f64 = f64::NEG_INFINITY;
20
21/// Not a number (quiet NaN).
22pub const NAN: f64 = f64::NAN;
23
24/// The Euler-Mascheroni constant (gamma ~ 0.5772...).
25///
26/// This is the limiting difference between the harmonic series and the
27/// natural logarithm: gamma = lim(n->inf) [sum(1/k, k=1..n) - ln(n)].
28pub const EULER_GAMMA: f64 = 0.5772156649015329;
29
30/// Positive zero (`+0.0`).
31pub const PZERO: f64 = 0.0_f64;
32
33/// Negative zero (`-0.0`).
34pub const NZERO: f64 = -0.0_f64;
35
36/// Sentinel value for `expand_dims` indicating a new axis should be inserted.
37///
38/// In `NumPy` this is `numpy.newaxis` (an alias for `None`). In ferray it is
39/// a `usize` sentinel that is recognized by `expand_dims`.
40pub const NEWAXIS: usize = usize::MAX;
41
42#[cfg(test)]
43mod tests {
44    use super::*;
45
46    #[test]
47    fn constants_values() {
48        assert_eq!(PI, std::f64::consts::PI);
49        assert_eq!(E, std::f64::consts::E);
50        assert_eq!(INF, f64::INFINITY);
51        assert_eq!(NEG_INF, f64::NEG_INFINITY);
52        assert!(NAN.is_nan());
53        assert!(PZERO.is_sign_positive());
54        assert!(NZERO.is_sign_negative());
55        assert_eq!(PZERO, 0.0);
56        assert_eq!(NZERO, 0.0);
57    }
58
59    #[test]
60    fn euler_gamma_approximate() {
61        // Known to ~16 decimal places
62        assert!((EULER_GAMMA - 0.5772156649015329).abs() < 1e-15);
63    }
64
65    #[test]
66    fn newaxis_is_sentinel() {
67        assert_eq!(NEWAXIS, usize::MAX);
68    }
69}