probability icon indicating copy to clipboard operation
probability copied to clipboard

Add `tfp.math.betaincinv`

Open leandrolcampos opened this issue 3 years ago • 2 comments

This PR provides an implementation for tfp.math.betaincinv, the inverse of the regularized incomplete beta function (tfp.math.betainc) with respect to x. It addresses the issue #1581.

This implementation is based on ideas and equations available in the following references: [1] Milton Abramowitz and Irene A. Stegun. Handbook of Mathematical Functions with Formulas, Graphs, and Mathematical Tables. US Government Printing Office, 1964 (reprinted 1972). [Link] [2] William Press, Saul Teukolsky, William Vetterling and Brian Flannery. Numerical Recipes: The Art of Scientific Computing. Cambridge University Press, 2007 (Third Edition). [Link] [3] John Maddock, Paul A. Bristow, et al. The Incomplete Beta Function Inverses. [Link] [4] Stephen L. Moshier. Cephes Mathematical Library. [Link]

The expression of these ideas and equations as source code is my own.

In the following notebook, I measure and present the numerical accuracy of this implementation:

As references (especially for single-precision results), I also measure and present the numerical accuracy of the following methods:

In addition to implementing the function tfp.math.betaincinv, this PR also fixes a bug in the implementation of the partial derivative of tfp.math.betainc with respect to x: it's not true that this partial is equal to 0 whenever the parameter x is equal to 0 or 1.

leandrolcampos avatar Aug 03 '22 03:08 leandrolcampos

I'm a bit worried about dtype support in the implementations for tfp.math._betainc_partials and tfp.math.betaincinv. They only support float32 and float64 by design, like the TF C++ and XLA implementations for betainc. But there is an important difference between these last two implementations: the former raises an error when the input dtype is float16 or bfloat16, while the latter converts a float16 or bfloat16 input to float32 and then, after the computations, converts the result back to the original dtype [link].

Thinking about consistency, should we cast a float16 or bfloat16 input to float32 and then, after the computations, convert the result back to the original dtype?

UPDATE:

I implemented this idea in the last commit. If you don't like the idea, I can revert the commit.

leandrolcampos avatar Aug 05 '22 15:08 leandrolcampos

Hi, @srvasude!

I hope this message finds you very well.

When you have time, could you review this PR, please?

All the best,

leandrolcampos avatar Aug 10 '22 00:08 leandrolcampos

Hi @srvasude,

Thank you very much for your time reviewing this PR. It's always a pleasure to learn from you!

Please let me know if I've properly addressed all your comments.

All the best,

leandrolcampos avatar Aug 22 '22 12:08 leandrolcampos