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