New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
MAINT: Translate binom to C++ #19471
Conversation
The unrelated failure seems to be due to the recent NumPy integer dtype changes. #19466, #19462, numpy/numpy#24224. |
it seems so yeah, there's a discussion on #19466 that seems to (maybe?) address the issue for sobol. I can take a closer look this weekend once I update #19287 to get merged lambert code incorporated. Thanks for getting this up so quickly @steppi |
Let me devil advocate a bit. Since we pull stuff from boost already, can https://beta.boost.org/doc/libs/1_37_0/libs/math/doc/sf_and_dist/html/math_toolkit/special/factorials/sf_binomial.html replace our implementation? |
I’d prefer to be able to use boost if we could. We’re avoiding boost for now until they make the changes necessary to get their stuff to run on Cuda. |
scipy/special/_binom.h
Outdated
#include "cephes.hh" | ||
|
||
|
||
using std::numeric_limits; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think we should import things like this in header files. Best to keep it fully qualified.
If you really want to do using std::numeric_limits;
, you can actually do that within either the functions or namespaces it is used in. But I'd stick with not doing it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, good catch. Agreed on not wanting to have unexpected side effects when including a header. There are some imports in _lambertw.h
that can be removed in another PR.
scipy/scipy/special/_lambertw.h
Lines 32 to 34 in 4d790c1
using namespace std::complex_literals; | |
using std::numeric_limits; |
} | ||
if (k > 1E8*std::fabs(n)) { | ||
// avoid loss of precision | ||
num = cephes::Gamma(1 + n) / std::fabs(k) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Curious why is it Gamma
with a capital 'G'?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No clue, but cephes gamma function has been capital G
in SciPy from the start: 52c64a9.
#include "_lambertw.h" | ||
|
||
inline double binom(double n, double k) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we want this to be npy_double
or just double
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think it matters for double
. It seems like the convention in other parts of the code base is to just have double
. Check out specfun_wrappers for instance.
#undef kolmogp | ||
#undef kolmogc | ||
#undef kolmogci | ||
#undef owens_t |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah... I've actually messed about with cephes in SciPy before. It has some things going on that are definitely not best practices. Our long term aim should be to not use it like this, and just adapt it to current best practices for C / C++.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I plan to make another mailing list post and RFC issue about what to do with cephes.
@steppi Just read through and left some comments! Generally looks quite good, well done. A few things I think we should change. Yeah, we'll need to do something to integrate cephes a bit better. I don't think it's so hard, more annoying, but what we have now is certainly not ideal. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @rlucas7! |
Reference issue
This PR closes no issues, but continues the work discussed in the RFC issue #19404.
What does this implement/fix?
This PR translates the real valued binomial coefficient function
binom
from Cython into C++. Again, the translation is as literal as possible.Additional information
Since
binom
depends oncephes
I needed to work out how to includecephes
functions in C++ code. This was not immediately possible becausecephes
has a headercephes_names.h
which defines aliases of the formbeta
->cephes_beta
etc. So far so good, but because of how they are implemented, the aliases bleed into all code in the same translation unit, for instance, expandingexpm1
when it appears in boost tocephes_expm1
. Rather than trying to sort that out directly, I've created a new headercephes.hh
for inclusion in C++ files, which puts cephes functions in thescipy::special::cephes
namespace without a prefix in the name, and undefs all of the aliasesFor now, I've kept the
binom
implementation withinorthogonal_eval.pxd
and it is still used internally there.As is, this
binom
implementation is not header only because it depends on cephes. We'll need to discuss the possibility of making cephes or parts of cephes header only in the future.This PR should unblock the work that is stalled on gh-19287.
cc @izaid, @tirthasheshpatel, @rlucas7, @ilayn