math: Possible incorrect argument used in test of inc_beta_ddb
I think an incorrect argument is being passed to the function calls inc_beta_ddb_test:
Shouldn’t the fourth argument be digamma(small_b) instead of digamma(small_a) (and similarly to the other tests)?
Obviously this does not mean anything for the function itself, but it makes it difficult to check independently what the expected value should have been.
Apologies if I misunderstood something 😃
About this issue
- Original URL
- State: open
- Created 3 years ago
- Reactions: 1
- Comments: 32 (19 by maintainers)
I think this issue is drifting so I wanted to address the original question: it does look like the wrong argument is used in the test.
That’s a good question. To answer it we would need to compare
inc_beta_ddbtograd_inc_betaover the same domain both in terms of accuracy and runtime. Is that something you are interested in trying? That seems to be where Ben is going with this as well. Either we get a clear answer about the need for a betterinc_beta_ddbor we get to remove extra code. Ultimately it’s going a be a PR with a pretty significant testing burden…Some history: so I looked at this function (https://github.com/stan-dev/math/blob/9895be8ee0a27a9c7935cf19345d76fcbc85a69d/stan/math/prim/fun/inc_beta_ddb.hpp) and at grad_inc_beta and I think the original code was Michael Betancourt, and that I modified some of the current code to improve accuracy in parts of the domain (that’s those if statements at the head of the function which use standard identities).
grad_inc_betacurrently defers tograd_2F1and that avoids duplicating this kind of code… I wrote that version of the algorithm and we (me and @bbbales2 I think…) updated the convergence conditions there so it might make sense to look at that version of the calculation if we want to improve the convergence checks.So tl;dr: @ricardoV94 if you’re interested in improving this algorithm in a specific direction I think that would make the lib better and I’m happy to help with the implementation.
Since there’s almost always a range beyond which these functions fail it seems like the standard is to document the range in the function doc (it’s a soft failure, they get less accurate and there’s error in everything else, it often doesn’t matter much, it can often be avoided by rescaling). I would modify the test range so the function passes and leave an issue that states that beyond a certain point the function looses accuracy. If somebody needs that region we can add a PR to fix that region.
My suggestion is: 1) update the main post on the issue to document the reference values used (with code) and where you think the range should be extended; 2) make a branch that documents the failure; and 3) create a PR that fixes the branch to pass the new tests. So far I see mentions of various reference values and I’d be happy to help fix issues with the function but I’m not currently up to documenting the issue b/c you guys seem to have a handle on that already.
Yes, there’s usually some efficiency to be gained by computing both at the same time, and sometimes you can get better stability but you’d have to compare the code between the different functions (I can help with that once it gets there if you want).
The algorithm may well be that some took the power-series used for the more general function and simplified the calculation where possible. I don’t know what the current math lib standards are but from my point of view getting closer to known errors for specific domains would help the Stan math library.
My main point was that all the other implementations fail beyond some domain too. They just do it more or less gracefully and some of them cover a larger domain before failing.
Obviously we also need to check for the accuracy of the computations, but those speed benchmarks look promising.
I’ll do a more careful test soon taking into consideration whether/where the outputs agree or diverge also with finite differences and autodiff (I don’t have Mathematica to compare, but maybe someone here has?) I can also check for that other implementation on that repo.
I just did a very rough comparison (in Python) and the
inc_beta_dd*seems to be a couple order of magnitudes faster than thegrad_reg_inc_beta(even when calling both_ddaand_ddbseparately):Of course this may not be the case for other values + the accuracy doubts raised above
It looks like inc_beta_dda is used in
neg_binomial_cdf,neg_binomial_2_cdfandbeta_cdf. So it seems like the function with a smaller reach. Ifgrad_inc_betacovers that domain, then yeah I think we can just usegrad_inc_beta.