diff --git a/Cargo.toml b/Cargo.toml index 7fa2629..354897c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -32,6 +32,7 @@ num = "0.4.1" num-bigint = "0.4.4" num-traits = "0.2.18" bigdecimal = "0.4.2" +statrs = "0.18.0" [profile.release] opt-level = 3 diff --git a/README.md b/README.md index 8512b2b..ec8aef7 100644 --- a/README.md +++ b/README.md @@ -142,6 +142,7 @@ There are many examples of processed expressions in the [integration test file]( Ceil Round Exp + Cdf ``` ## Built-in Defined Constants diff --git a/src/lib.rs b/src/lib.rs index 22bfffd..1acae66 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -103,6 +103,13 @@ //! Log //! Abs //! Sqrt +//! Max +//! Min +//! Floor +//! Ceil +//! Round +//! Exp +//! Cdf //! ``` /// Parser pub mod parser; diff --git a/src/rpn_resolver.rs b/src/rpn_resolver.rs index b7411b8..d7320af 100644 --- a/src/rpn_resolver.rs +++ b/src/rpn_resolver.rs @@ -2,6 +2,7 @@ use crate::{ parser::Parser, token::{self, MathFunction, Number, Operator, Token}, }; +use statrs::distribution::{ContinuousCDF, Normal}; use anyhow::anyhow; use log::debug; use std::{ @@ -200,6 +201,10 @@ impl RpnResolver<'_> { MathFunction::Floor => f64::floor(value.into()), MathFunction::Ceil => f64::ceil(value.into()), MathFunction::Round => f64::round(value.into()), + MathFunction::Cdf => { + let normal = Normal::new(0.0, 1.0).expect("valid normal dist"); + normal.cdf(value.into()) + } MathFunction::Exp => f64::exp(value.into()), MathFunction::None => return Err(anyhow!("This should never happen!")), }; diff --git a/src/token.rs b/src/token.rs index e7aeffc..b6bfe04 100644 --- a/src/token.rs +++ b/src/token.rs @@ -128,6 +128,8 @@ pub enum MathFunction { Round, /// e^x exponentiation Exp, + /// Standard Normal cumulative distribution function + Cdf, /// No function expected None, } @@ -182,6 +184,7 @@ impl Token<'_> { "ceil" => Some(MathFunction::Ceil), "round" => Some(MathFunction::Round), "exp" => Some(MathFunction::Exp), + "cdf" => Some(MathFunction::Cdf), &_ => None, } } diff --git a/tests/integration_tests.rs b/tests/integration_tests.rs index 5e9e5c9..85037a2 100644 --- a/tests/integration_tests.rs +++ b/tests/integration_tests.rs @@ -147,6 +147,7 @@ fn test_expressions() { resolve_decimal!("round(3.6)", 4.0); resolve_decimal!("round(3.4)", 3.0); resolve_decimal!("exp(1)", std::f64::consts::E); + resolve_decimal!("cdf(0)", 0.5); resolve_err!("min()"); resolve_err!("max()");