@@ -76,6 +76,9 @@ def polyagamma_cdf(*args, **kwargs):
76
76
from scipy import stats
77
77
from scipy .interpolate import InterpolatedUnivariateSpline
78
78
from scipy .special import expit
79
+ from scipy .stats import norm
80
+ from scipy .optimize import newton
81
+ from scipy .special import ive , iv
79
82
80
83
from pymc .distributions import transforms
81
84
from pymc .distributions .dist_math import (
@@ -2993,6 +2996,23 @@ def logp(value, mu, sigma, alpha):
2993
2996
tau > 0 ,
2994
2997
msg = "tau > 0" ,
2995
2998
)
2999
+ def icdf (prob , mu , sigma , alpha , max_iter = 100 , tol = 1e-8 ):
3000
+ def cdf_difference (x ):
3001
+ return norm .cdf (x ) - 2 * norm .cdf (alpha * x ) - prob
3002
+
3003
+ x0 = norm .ppf (prob )
3004
+ x = x0
3005
+
3006
+ for _ in range (max_iter ):
3007
+ diff = cdf_difference (x )
3008
+
3009
+ if np .abs (diff ) < tol :
3010
+ return mu + sigma * x
3011
+
3012
+ derivative = norm .pdf (x ) - 2 * alpha * norm .pdf (alpha * x )
3013
+ x -= derivative
3014
+
3015
+ return mu + sigma * x
2996
3016
2997
3017
2998
3018
class Triangular (BoundedContinuous ):
@@ -3348,6 +3368,17 @@ def logp(value, b, sigma):
3348
3368
b >= 0 ,
3349
3369
msg = "sigma >= 0, b >= 0" ,
3350
3370
)
3371
+ def icdf (prob , nu , sigma , x0 = 1.0 , max_iter = 100 , tol = 1e-8 ):
3372
+ def cdf (x ):
3373
+ return (1 + x / sigma ** 2 ) * np .exp (- x ** 2 / (2 * sigma ** 2 )) * iv (0 , x * nu / sigma ** 2 ) - prob
3374
+
3375
+ def cdf_derivative (x ):
3376
+ return ((1 - x ** 2 / sigma ** 2 ) * np .exp (- x ** 2 / (2 * sigma ** 2 )) * iv (0 , x * nu / sigma ** 2 )
3377
+ + (x / sigma ** 2 ) * np .exp (- x ** 2 / (2 * sigma ** 2 )) * ive (0 , x * nu / sigma ** 2 )) * nu / sigma ** 2
3378
+
3379
+ approx_icdf = newton (cdf , x0 , fprime = cdf_derivative , tol = tol , maxiter = max_iter )
3380
+
3381
+ return approx_icdf
3351
3382
3352
3383
3353
3384
class Logistic (Continuous ):
0 commit comments