stan-dev / math

The Stan Math Library is a C++ template library for automatic differentiation of any order using forward, reverse, and mixed modes. It includes a range of built-in functions for probabilistic modeling, linear algebra, and equation solving.
https://mc-stan.org
BSD 3-Clause "New" or "Revised" License
753 stars 188 forks source link

Add `log_inc_beta` function #2790

Open andrjohns opened 2 years ago

andrjohns commented 2 years ago

Description

The Binomial (LC)CDF functions are defined using the inc_beta function, however this can underflow to 0 for large inputs. By using the relationship with the Gauss Hypergeometric function, we can calculate inc_beta on the log scale: https://stats.stackexchange.com/a/148700

This provides greater resistance to underflow: https://godbolt.org/z/Pxn8MMYTv

Current Version:

v4.4.0

spinkney commented 2 years ago

Be careful with this as it does lose a lot of precision for very small x values. See discussion at https://bugs.r-project.org/show_bug.cgi?id=16332#c7. We'll have to branch across different values of x.

spinkney commented 2 years ago

Umm, when I tested this in R it wasn't good but boost's implementation in c++ is good in a wide range of x values.

andrjohns commented 2 years ago

Hmm, well it's not the easy fix I was hoping for, but it's a start!

Once we've got the 2F1 in I'll start investigating where the underflow could be coming from

andrjohns commented 2 years ago

But I also only brought this up for the beta/binomial CDFs (numerical stability for copulas), so let me know if there's a better or more robust approach that avoids all of these headaches!

spinkney commented 2 years ago

I think what you have will work! Looking forward to more stable cdfs!