stan-dev / stan-dev/math

Introduce inverse-CDF (a.k.a. quantile functions) for almost all univariate distributions

Open
#1,054 0 comments 3 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
C++
Stars
839
Forks
220
Avg merge
2d 4h
Merged PRs (30d)
14

Description

Description

The inverse of the CDF is often useful

https://en.wikipedia.org/wiki/Quantile_function

but rarely has an explicit form. We should make these a core part of Stan Math like the _cdf functions are.

  1. Utilize explicit forms wherever possible (there are a couple already, such as inv_logit)
  2. Utilize the quantile functions and their compliments in Boost when practical
  3. Utilize the one-dimensional root-finders in Boost when we have to find the quantile numerically as that which yields the given cumulative probability. These are nice because bounds can be imposed on the solution and higher derivatives can be utilized in the Halley and Schroder forms of the iterator

In cases (2) and (3), we would have to utilize implicit functions in order to subsequently calculate the derivative with respect to any unknown parameters at the solution, in much the same way that the algebraic_solver does. However, it is not necessary to bring in Eigen for unidimensional root finding, which does not enforce bounds and does not use higher-order derivatives anyway.

Example

The inv_Phi function is the only inverse CDF that we have implemented numerically and that was relatively easy because the standard normal distribution has no parameters.
https://github.com/stan-dev/math/blob/7a60a595a41dd2a137e1eb85b8305ea538d89fb3/stan/math/prim/scal/fun/inv_Phi.hpp#L26
It actually does one Newton step at the end to go from single-precision accuracy to double-precision accuracy. Doing this for other distributions would be conceptually similar.

Expected Output

parameters {
  real<lower = 0, upper = 1> p;
}
transformed parameters {
  real theta = foo_icdf(p);  // implies theta ~ foo
}

Current Math Version

v2.18.0

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with stan/math/prim/scal/fun/inv_Phi.hpp and compare its numerical approach with the existing algebraic_solver and the linked Boost quantile and root-finder documentation. The issue spans nearly all univariate distributions, so define the distribution scope and per-distribution completion criteria before implementation; done would require inverse-CDF functions and parameter derivatives across that agreed scope.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
tooling
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.