Do we need more unit tests for distributions?

Sorry, I was unnecessarily mysterious.

There is a bunch of functions that don’t admit std::complex<double> as argument by default, but I’ve succesfully made them work enough to compute complex step derivative of functions involving them:

  • log1p, expm1 etc. those have quite short code and usually fail due to lines like if(x < 1e-4) { ... }, providing a complex specialization often means just copying the code and replacing comparison of values with comparison of absolute value (e.g. if(abs(x) < 1e-4) { ... }) - the underlying approximations motivating many of the implementations are usually valid in complex plane as well.
  • lgamma() and other complex functions can be approximated via Taylor expansion around x.imag() == 0. This might not work when the argument to the function is already heavily transformed (e.g. lgamma(exp(15 * x)), but when the argument is “close” to the original (e.g. lgamma(x + 1)), the imaginary part will be the small “complex step” and the approximation holds. For lgamma this gives:
auto lgamma_c_approx = [](const std::complex<double>& x) {
  return std::complex<double>(lgamma(x.real()),
                              x.imag() * boost::math::digamma(x.real()));
  };

There are two possible approaches to computing complex step derivative with such custom implementations:

  • build specializations of necessary library functions admitting std::complex, making the current implementation of the function work with complex step. This could be a test-only library as we probably don’t want to invest in vouching for 100% correctness of the implementations. On the other hand, as there is work on std::complex<var>, such functions might be necessary anyway. For lgamma (and possibly others) there are complex implementations we could easily use, e.g. the one on Wikipedia
  • write a specialized test-only version of the function to be tested (or it’s simplest formula) using specialized functions - this is what I currently do for the neg_binomial_2_lpmf test against complex step

Hope that is more specific and actionable.

1 Like