From 2fed9b2e902776cc7a6c42a001cec0b20b18f27c Mon Sep 17 00:00:00 2001 From: Gianluigi Davassi Date: Wed, 11 Jun 2025 08:47:01 +0200 Subject: [PATCH] Add standard normal PDF function --- README.md | 1 + src/lib.rs | 1 + src/rpn_resolver.rs | 6 +++++- src/token.rs | 3 +++ tests/integration_tests.rs | 4 ++++ 5 files changed, 14 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index ec8aef7..f5e83dc 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 + Pdf Cdf ``` diff --git a/src/lib.rs b/src/lib.rs index 1acae66..ecd53c1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -109,6 +109,7 @@ //! Ceil //! Round //! Exp +//! Pdf //! Cdf //! ``` /// Parser diff --git a/src/rpn_resolver.rs b/src/rpn_resolver.rs index d7320af..f2eb505 100644 --- a/src/rpn_resolver.rs +++ b/src/rpn_resolver.rs @@ -2,7 +2,7 @@ use crate::{ parser::Parser, token::{self, MathFunction, Number, Operator, Token}, }; -use statrs::distribution::{ContinuousCDF, Normal}; +use statrs::distribution::{Continuous, ContinuousCDF, Normal}; use anyhow::anyhow; use log::debug; use std::{ @@ -201,6 +201,10 @@ impl RpnResolver<'_> { MathFunction::Floor => f64::floor(value.into()), MathFunction::Ceil => f64::ceil(value.into()), MathFunction::Round => f64::round(value.into()), + MathFunction::Pdf => { + let normal = Normal::new(0.0, 1.0).expect("valid normal dist"); + normal.pdf(value.into()) + } MathFunction::Cdf => { let normal = Normal::new(0.0, 1.0).expect("valid normal dist"); normal.cdf(value.into()) diff --git a/src/token.rs b/src/token.rs index b6bfe04..1d265eb 100644 --- a/src/token.rs +++ b/src/token.rs @@ -128,6 +128,8 @@ pub enum MathFunction { Round, /// e^x exponentiation Exp, + /// Standard Normal probability density function + Pdf, /// Standard Normal cumulative distribution function Cdf, /// No function expected @@ -184,6 +186,7 @@ impl Token<'_> { "ceil" => Some(MathFunction::Ceil), "round" => Some(MathFunction::Round), "exp" => Some(MathFunction::Exp), + "pdf" => Some(MathFunction::Pdf), "cdf" => Some(MathFunction::Cdf), &_ => None, } diff --git a/tests/integration_tests.rs b/tests/integration_tests.rs index 85037a2..c6e721c 100644 --- a/tests/integration_tests.rs +++ b/tests/integration_tests.rs @@ -148,6 +148,10 @@ fn test_expressions() { resolve_decimal!("round(3.4)", 3.0); resolve_decimal!("exp(1)", std::f64::consts::E); resolve_decimal!("cdf(0)", 0.5); + resolve_decimal!( + "pdf(0)", + 0.39894228040143265 + ); resolve_err!("min()"); resolve_err!("max()");