-
Notifications
You must be signed in to change notification settings - Fork 2.2k
Added icdf for Rice and skewnormal distributions #7095
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -76,6 +76,9 @@ def polyagamma_cdf(*args, **kwargs): | |
| from scipy import stats | ||
| from scipy.interpolate import InterpolatedUnivariateSpline | ||
| from scipy.special import expit | ||
| from scipy.stats import norm | ||
| from scipy.optimize import newton | ||
| from scipy.special import ive, iv | ||
|
|
||
| from pymc.distributions import transforms | ||
| from pymc.distributions.dist_math import ( | ||
|
|
@@ -2993,6 +2996,29 @@ def logp(value, mu, sigma, alpha): | |
| tau > 0, | ||
| msg="tau > 0", | ||
| ) | ||
| def icdf(prob, mu, sigma, alpha, max_iter=100, tol=1e-8): | ||
| def cdf_difference(x): | ||
| return norm.cdf(x) - 2 * norm.cdf(alpha * x) - prob | ||
|
|
||
| x0 = norm.ppf(prob) | ||
| x = x0 | ||
|
|
||
| for _ in range(max_iter): | ||
| diff = cdf_difference(x) | ||
|
|
||
| if pt.abs(diff) < tol: | ||
| return mu + sigma * x | ||
|
|
||
| derivative = norm.pdf(x) - 2 * alpha * norm.pdf(alpha * x) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. does |
||
| x -= derivative | ||
|
|
||
| res = mu + sigma * x | ||
| res = check_icdf_value(res, prob) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you explain in words (or math) what is going on here?
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The provided code defines a function icdf that aims to find the inverse cumulative distribution function (ICDF) for a specific probability distribution. Calculates the cumulative distribution function (CDF) for a given input Calculates the derivative of the CDF with respect to Uses the Newton-Raphson method to iteratively find a value of x such that Performs some checks on the calculated ICDF value (res) and potentially modifies it. Checks whether certain parameters, in this case, The main function icdf combines these components to find the ICDF for a given probability (prob) using the Newton-Raphson method.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sorry to ask but are you a bot? The code will clearly not work with PyTensor variables.
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No. I am not a bot
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'll fix everything and make a new pull request
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
What do you mean by "likely indicating", "potentially modifies it"? This wording seems strange to me. Again, none of this will work with PyTensor variables. If you are relying on AI to generate responses and code changes, we cannot accept them |
||
| return check_parameters( | ||
| res, | ||
| sigma > 0, | ||
| msg="sigma > 0" | ||
| ) | ||
|
|
||
|
|
||
| class Triangular(BoundedContinuous): | ||
|
|
@@ -3348,7 +3374,22 @@ def logp(value, b, sigma): | |
| b >= 0, | ||
| msg="sigma >= 0, b >= 0", | ||
| ) | ||
|
|
||
| def icdf(prob, nu, sigma, x0=1.0, max_iter=100, tol=1e-8): | ||
| def cdf(x): | ||
| return (1 + x / sigma**2) * pt.exp(-x**2 / (2 * sigma**2)) * iv(0, x * nu / sigma**2) - prob | ||
|
|
||
| def cdf_derivative(x): | ||
| return ((1 - x**2 / sigma**2) * pt.exp(-x**2 / (2 * sigma**2)) * iv(0, x * nu / sigma**2) | ||
| + (x / sigma**2) * pt.exp(-x**2 / (2 * sigma**2)) * ive(0, x * nu / sigma**2)) * nu / sigma**2 | ||
|
|
||
| approx_icdf = newton(cdf, x0, fprime=cdf_derivative, tol=tol, maxiter=max_iter) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Will |
||
| res = approx_icdf | ||
| res = check_icdf_value(res, prob) | ||
| return check_parameters( | ||
| res, | ||
| sigma > 0, | ||
| msg="sigma > 0" | ||
| ) | ||
|
|
||
| class Logistic(Continuous): | ||
| r""" | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What justifies the
icdfmethod having a different signature compared to thelogpmethod mentioned above?