From 7bd68eb527d43aadef3ed631680dac5877f41e85 Mon Sep 17 00:00:00 2001 From: seuabeia <126102654+seuabeia@users.noreply.github.com> Date: Wed, 31 May 2023 23:08:01 -0400 Subject: [PATCH 1/5] adding icdf function for lognormal --- pymc/distributions/continuous.py | 9 +++++++++ tests/distributions/test_continuous.py | 10 ++++++++++ 2 files changed, 19 insertions(+) diff --git a/pymc/distributions/continuous.py b/pymc/distributions/continuous.py index d597299997..1eee1323ca 100644 --- a/pymc/distributions/continuous.py +++ b/pymc/distributions/continuous.py @@ -1721,6 +1721,15 @@ def logcdf(value, mu, sigma): msg="sigma > 0", ) + def icdf(value, mu, sigma): + res = np.exp(mu - np.sqrt(2 * sigma**2) * pt.erfcinv(2 * value)) + res = check_icdf_value(res, value) + return check_icdf_parameters( + res, + sigma > 0, + msg="sigma > 0", + ) + Lognormal = LogNormal diff --git a/tests/distributions/test_continuous.py b/tests/distributions/test_continuous.py index b84a77e049..8017ff6855 100644 --- a/tests/distributions/test_continuous.py +++ b/tests/distributions/test_continuous.py @@ -502,6 +502,16 @@ def test_lognormal(self): {"mu": R, "sigma": Rplusbig}, lambda value, mu, sigma: st.lognorm.logcdf(value, sigma, 0, np.exp(mu)), ) + check_icdf( + pm.LogNormal, + {"mu": R, "tau": Rplusbig}, + lambda q, mu, tau: st.lognorm.ppf(q, tau**-0.5, 0, np.exp(mu)), + ) + check_icdf( + pm.LogNormal, + {"mu": R, "sigma": Rplusbig}, + lambda q, mu, sigma: st.lognorm.ppf(q, sigma, 0, np.exp(mu)), + ) def test_studentt_logp(self): check_logp( From 5578f756a61f011642f74ed4ba495b102e395597 Mon Sep 17 00:00:00 2001 From: seuabeia <126102654+seuabeia@users.noreply.github.com> Date: Thu, 1 Jun 2023 13:19:55 -0400 Subject: [PATCH 2/5] adding Cauchy and Logistic ICDF functions with test --- pymc/distributions/continuous.py | 22 ++++++++++++++++++++-- tests/distributions/test_continuous.py | 11 +++++++++++ 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/pymc/distributions/continuous.py b/pymc/distributions/continuous.py index 1eee1323ca..80cf6dcb80 100644 --- a/pymc/distributions/continuous.py +++ b/pymc/distributions/continuous.py @@ -1722,7 +1722,7 @@ def logcdf(value, mu, sigma): ) def icdf(value, mu, sigma): - res = np.exp(mu - np.sqrt(2 * sigma**2) * pt.erfcinv(2 * value)) + res = pt.exp(mu - pt.sqrt(2 * sigma**2) * pt.erfcinv(2 * value)) res = check_icdf_value(res, value) return check_icdf_parameters( res, @@ -2047,6 +2047,15 @@ def logcdf(value, alpha, beta): beta > 0, msg="beta > 0", ) + + def icdf(value, alpha, beta): + res = alpha + beta * pt.tan(np.pi * (value-0.5)) + res = check_icdf_value(res, value) + return check_parameters( + res, + beta > 0, + msg="beta > 0", + ) class HalfCauchy(PositiveContinuous): @@ -3359,7 +3368,16 @@ def logp(value, mu, s): def logcdf(value, mu, s): res = -pt.log1pexp(-(value - mu) / s) - + + return check_parameters( + res, + s > 0, + msg="s > 0", + ) + + def icdf(value, mu, s): + res = mu + s * pt.log(value/(1 - value)) + res = check_icdf_value(res, value) return check_parameters( res, s > 0, diff --git a/tests/distributions/test_continuous.py b/tests/distributions/test_continuous.py index 8017ff6855..2eeb1974da 100644 --- a/tests/distributions/test_continuous.py +++ b/tests/distributions/test_continuous.py @@ -558,6 +558,11 @@ def test_cauchy(self): {"alpha": R, "beta": Rplusbig}, lambda value, alpha, beta: st.cauchy.logcdf(value, alpha, beta), ) + check_icdf( + pm.Cauchy, + {"alpha": R, "beta": Rplusbig}, + lambda q, alpha, beta: st.cauchy.ppf(q, alpha, beta), + ) def test_half_cauchy(self): check_logp( @@ -778,6 +783,12 @@ def test_logistic(self): lambda value, mu, s: st.logistic.logcdf(value, mu, s), decimal=select_by_precision(float64=6, float32=1), ) + check_icdf( + pm.Logistic, + {"mu": R, "s": Rplus}, + lambda q, mu, s: st.logistic.ppf(q, mu, s), + decimal=select_by_precision(float64=6, float32=1), + ) def test_logitnormal(self): check_logp( From a5b9eb5e84d3e67ebd32273ac6a5c0c1a9693e95 Mon Sep 17 00:00:00 2001 From: seuabeia <126102654+seuabeia@users.noreply.github.com> Date: Thu, 1 Jun 2023 13:29:12 -0400 Subject: [PATCH 3/5] fixing whitespace --- pymc/distributions/continuous.py | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/pymc/distributions/continuous.py b/pymc/distributions/continuous.py index 80cf6dcb80..164a83ac0e 100644 --- a/pymc/distributions/continuous.py +++ b/pymc/distributions/continuous.py @@ -2047,14 +2047,14 @@ def logcdf(value, alpha, beta): beta > 0, msg="beta > 0", ) - + def icdf(value, alpha, beta): - res = alpha + beta * pt.tan(np.pi * (value-0.5)) + res = alpha + beta * pt.tan(np.pi * (value - 0.5)) res = check_icdf_value(res, value) return check_parameters( - res, - beta > 0, - msg="beta > 0", + res, + beta > 0, + msg="beta > 0", ) @@ -3368,15 +3368,14 @@ def logp(value, mu, s): def logcdf(value, mu, s): res = -pt.log1pexp(-(value - mu) / s) - return check_parameters( res, s > 0, msg="s > 0", ) - + def icdf(value, mu, s): - res = mu + s * pt.log(value/(1 - value)) + res = mu + s * pt.log(value / (1 - value)) res = check_icdf_value(res, value) return check_parameters( res, From e00407ceeca8f535f47248668732607a9d6f12aa Mon Sep 17 00:00:00 2001 From: seuabeia <126102654+seuabeia@users.noreply.github.com> Date: Fri, 2 Jun 2023 12:48:37 -0400 Subject: [PATCH 4/5] only Caucy and Logistic - saving lognormal for another PR --- pymc/distributions/continuous.py | 25 ++++++++----------------- tests/distributions/test_continuous.py | 10 ---------- 2 files changed, 8 insertions(+), 27 deletions(-) diff --git a/pymc/distributions/continuous.py b/pymc/distributions/continuous.py index 164a83ac0e..d235426cee 100644 --- a/pymc/distributions/continuous.py +++ b/pymc/distributions/continuous.py @@ -1714,22 +1714,12 @@ def logcdf(value, mu, sigma): -np.inf, normal_lcdf(mu, sigma, pt.log(value)), ) - return check_parameters( res, sigma > 0, msg="sigma > 0", ) - def icdf(value, mu, sigma): - res = pt.exp(mu - pt.sqrt(2 * sigma**2) * pt.erfcinv(2 * value)) - res = check_icdf_value(res, value) - return check_icdf_parameters( - res, - sigma > 0, - msg="sigma > 0", - ) - Lognormal = LogNormal @@ -2047,14 +2037,14 @@ def logcdf(value, alpha, beta): beta > 0, msg="beta > 0", ) - + def icdf(value, alpha, beta): - res = alpha + beta * pt.tan(np.pi * (value - 0.5)) + res = alpha + beta * pt.tan(np.pi * (value-0.5)) res = check_icdf_value(res, value) return check_parameters( - res, - beta > 0, - msg="beta > 0", + res, + beta > 0, + msg="beta > 0", ) @@ -3368,14 +3358,15 @@ def logp(value, mu, s): def logcdf(value, mu, s): res = -pt.log1pexp(-(value - mu) / s) + return check_parameters( res, s > 0, msg="s > 0", ) - + def icdf(value, mu, s): - res = mu + s * pt.log(value / (1 - value)) + res = mu + s * pt.log(value/(1 - value)) res = check_icdf_value(res, value) return check_parameters( res, diff --git a/tests/distributions/test_continuous.py b/tests/distributions/test_continuous.py index 2eeb1974da..a4512b8a61 100644 --- a/tests/distributions/test_continuous.py +++ b/tests/distributions/test_continuous.py @@ -502,16 +502,6 @@ def test_lognormal(self): {"mu": R, "sigma": Rplusbig}, lambda value, mu, sigma: st.lognorm.logcdf(value, sigma, 0, np.exp(mu)), ) - check_icdf( - pm.LogNormal, - {"mu": R, "tau": Rplusbig}, - lambda q, mu, tau: st.lognorm.ppf(q, tau**-0.5, 0, np.exp(mu)), - ) - check_icdf( - pm.LogNormal, - {"mu": R, "sigma": Rplusbig}, - lambda q, mu, sigma: st.lognorm.ppf(q, sigma, 0, np.exp(mu)), - ) def test_studentt_logp(self): check_logp( From cfcfa058493a5d4107066430445f8a9b7efe4071 Mon Sep 17 00:00:00 2001 From: seuabeia <126102654+seuabeia@users.noreply.github.com> Date: Fri, 2 Jun 2023 12:50:36 -0400 Subject: [PATCH 5/5] only Caucy and Logistic - saving lognormal for another PR - fix whitespace --- pymc/distributions/continuous.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/pymc/distributions/continuous.py b/pymc/distributions/continuous.py index d235426cee..e5efeb775a 100644 --- a/pymc/distributions/continuous.py +++ b/pymc/distributions/continuous.py @@ -2037,14 +2037,14 @@ def logcdf(value, alpha, beta): beta > 0, msg="beta > 0", ) - + def icdf(value, alpha, beta): - res = alpha + beta * pt.tan(np.pi * (value-0.5)) + res = alpha + beta * pt.tan(np.pi * (value - 0.5)) res = check_icdf_value(res, value) return check_parameters( - res, - beta > 0, - msg="beta > 0", + res, + beta > 0, + msg="beta > 0", ) @@ -3358,15 +3358,15 @@ def logp(value, mu, s): def logcdf(value, mu, s): res = -pt.log1pexp(-(value - mu) / s) - + return check_parameters( res, s > 0, msg="s > 0", ) - + def icdf(value, mu, s): - res = mu + s * pt.log(value/(1 - value)) + res = mu + s * pt.log(value / (1 - value)) res = check_icdf_value(res, value) return check_parameters( res,