mathhook_core/functions/elementary/
abs_eval.rs

1//! Absolute value function evaluation
2
3use crate::core::{Expression, Number};
4use num_traits::Signed;
5
6/// Evaluate absolute value function
7///
8/// # Mathematical Definition
9///
10/// |x| = { x   if x ≥ 0
11///      { -x  if x < 0
12///
13/// # Arguments
14///
15/// * `arg` - Expression to compute absolute value of
16///
17/// # Returns
18///
19/// Absolute value expression
20///
21/// # Examples
22///
23/// ```
24/// use mathhook_core::functions::elementary::abs_eval::abs;
25/// use mathhook_core::expr;
26///
27/// let result = abs(&expr!(-5));
28/// assert_eq!(result, expr!(5));
29/// ```
30pub fn abs(arg: &Expression) -> Expression {
31    match arg {
32        Expression::Number(n) => evaluate_abs_number(n),
33        _ => Expression::function("abs", vec![arg.clone()]),
34    }
35}
36
37fn evaluate_abs_number(n: &Number) -> Expression {
38    match n {
39        Number::Integer(i) => Expression::integer(i.abs()),
40        Number::Float(f) => Expression::float(f.abs()),
41        Number::BigInteger(bi) => Expression::big_integer(bi.abs()),
42        Number::Rational(r) => Expression::Number(Number::rational(
43            num_rational::BigRational::new(r.numer().abs(), r.denom().clone()),
44        )),
45    }
46}
47
48#[cfg(test)]
49mod tests {
50    use super::*;
51
52    #[test]
53    fn test_abs_zero() {
54        assert_eq!(abs(&Expression::integer(0)), Expression::integer(0));
55    }
56
57    #[test]
58    fn test_abs_positive() {
59        assert_eq!(abs(&Expression::integer(5)), Expression::integer(5));
60    }
61
62    #[test]
63    fn test_abs_negative() {
64        assert_eq!(abs(&Expression::integer(-5)), Expression::integer(5));
65    }
66
67    #[test]
68    fn test_abs_float() {
69        assert_eq!(abs(&Expression::float(-3.4)), Expression::float(3.4));
70    }
71}