Skip to content
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

bpo-35431: Implemented math.comb #11414

Merged
merged 11 commits into from
Jun 1, 2019
Merged

Conversation

FR4NKESTI3N
Copy link
Contributor

@FR4NKESTI3N FR4NKESTI3N commented Jan 2, 2019

Implemented the function math.comb to calculate binomial coefficient. Simple O(k) algorithm is used for now. ValueError if condition 0 <= k <= n is not satisfied and TypeError if non-integer arguments passed to function.

https://bugs.python.org/issue35431

@FR4NKESTI3N FR4NKESTI3N changed the title bpo-35434: Implemented math.comb bpo-35431: Implemented math.comb Jan 2, 2019
Modules/mathmodule.c Outdated Show resolved Hide resolved
Modules/mathmodule.c Outdated Show resolved Hide resolved
Modules/mathmodule.c Outdated Show resolved Hide resolved
Modules/mathmodule.c Outdated Show resolved Hide resolved
Modules/mathmodule.c Outdated Show resolved Hide resolved
Modules/mathmodule.c Outdated Show resolved Hide resolved
Modules/mathmodule.c Show resolved Hide resolved
Modules/mathmodule.c Outdated Show resolved Hide resolved
Modules/mathmodule.c Outdated Show resolved Hide resolved
Modules/mathmodule.c Outdated Show resolved Hide resolved
Lib/test/test_math.py Outdated Show resolved Hide resolved
Lib/test/test_math.py Outdated Show resolved Hide resolved
Doc/library/math.rst Outdated Show resolved Hide resolved
Modules/mathmodule.c Outdated Show resolved Hide resolved
Modules/mathmodule.c Outdated Show resolved Hide resolved
Modules/mathmodule.c Outdated Show resolved Hide resolved
Modules/mathmodule.c Outdated Show resolved Hide resolved
Copy link
Member

@pablogsal pablogsal left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can use Jebelean’s exact division algorithm to speed up the division as if you factor out the coefficients as the product of(n-k+1)* PROD(i,2,k,(n-k+i)/i), i will always divide the already calculated product.

@FR4NKESTI3N
Copy link
Contributor Author

@pablogsal I haven't started working on optimization yet since Raymond Hettinger suggested to wait till everyone has agreed on the behaviour : https://bugs.python.org/issue35431#msg332838
Can I consider that current behaviour is acceptable and write optimizations?

I was also considering using prime factorization for smaller k values : https://dl.acm.org/citation.cfm?id=26272 but seems like an overkill now

KellerFuchs added a commit to KellerFuchs/cpython that referenced this pull request Jan 28, 2019
@KellerFuchs
Copy link

@FR4NKESTI3N Thanks a lot for starting on this. I merged our PRs in #11018, as the testsuite I had started there was more complete (and used as the basis for discussing the desired behaviour, in the bugs.python.org issue).

@KellerFuchs
Copy link

PS: I added you as a collaborator on my repository, so if you accept the invite you can push directly to that PR's branch.

Doc/library/math.rst Show resolved Hide resolved
Modules/mathmodule.c Outdated Show resolved Hide resolved
Modules/mathmodule.c Outdated Show resolved Hide resolved
Modules/mathmodule.c Outdated Show resolved Hide resolved
Modules/mathmodule.c Outdated Show resolved Hide resolved
@bedevere-bot
Copy link

A Python core developer has requested some changes be made to your pull request before we can consider merging it. If you could please address their requests along with any other requests in other reviews from core developers that would be appreciated.

Once you have made the requested changes, please leave a comment on this pull request containing the phrase I have made the requested changes; please review again. I will then notify any core developers who have left a review that you're ready for them to take another look at this pull request.

@FR4NKESTI3N
Copy link
Contributor Author

I have made the requested changes; please review again
@rhettinger I have used long_long instead of long in the boilerplate.
Using object allowed evaluation of expressions like comb(10**400, 200) and overflow was caused if min(k, n-k) was larger than LLONG_MAX. I feel using object conversion gave the function more flexibility.

@bedevere-bot
Copy link

Thanks for making the requested changes!

@rhettinger: please review the changes made to this pull request.

KellerFuchs added a commit to KellerFuchs/cpython that referenced this pull request Apr 7, 2019
Copy link
Member

@serhiy-storchaka serhiy-storchaka left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. Use PyNumber_Index() for converting arguments to Python integers. See gcd() for example.
  2. Do not convert n to C long long. comb(2**1000, 5) should work.
  3. Do not use PyNumber_Long().

It is convenient to implement perm(n, k) first. comb(n, k) can be easily implemented as perm(n, k) // factorial(k) (or perm(n, n-k) // factorial(n-k) if k > n-k).

@FR4NKESTI3N
Copy link
Contributor Author

@serhiy-storchaka So boilerplate should be changed back to have n and k as objects right?
@KellerFuchs I will be busy for 2 weeks, can you get in on this.

@rhettinger rhettinger merged commit 4a68650 into python:master Jun 1, 2019
DinoV pushed a commit to DinoV/cpython that referenced this pull request Jan 14, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants