Skip to content

Commit

Permalink
Trac #24667: Clean up partitions_c.cc
Browse files Browse the repository at this point in the history
1. Remove some unused stuff.

2. Compute the `double` and `long double` constants using MPFR. This
makes a lot of sense since we already computed MPFR versions of these
constants anyway. For extra safety, we also increase the precision used
to compute these constants.

3. No longer use the header file `partitions_c.h`. Instead, include the
`.cc` file in Cython.

Points 2. and 3. above allow to remove some platform-specific hacks.

4. Replace `T(int(x))` by `T(x)` to convert `x` to type `T`.

5. Only one temporary MPFR variable is really needed, call it `mptemp`.

6. Merge `initialize_mpz_and_mpq_variables`, `initialize_mpfr_variables`
and `initialize_constants` in one function `initialize_globals`.

7. Use some more specialized MPFR functions like `mpfr_set_prec()` where
applicable.

8. Define all internal functions as `static`.

9. Use `MPFR_RNDF` rounding mode where exact rounding is not required.

10. Ensure that the file compiles without compiler warnings.

11. Various style improvements.

URL: https://trac.sagemath.org/24667
Reported by: jdemeyer
Ticket author(s): Jeroen Demeyer
Reviewer(s): Dima Pasechnik
  • Loading branch information
Release Manager authored and vbraun committed Feb 15, 2018
2 parents c273e63 + 2dba6c8 commit 68d3975
Show file tree
Hide file tree
Showing 3 changed files with 373 additions and 662 deletions.
16 changes: 9 additions & 7 deletions src/sage/combinat/partitions.pyx
@@ -1,7 +1,6 @@
# The actual algorithm is implemented in the C++ file partitions_c.cc
# which requires the gmp and mpfr libraries.
#
# distutils: sources = sage/combinat/partitions_c.cc
# distutils: libraries = gmp mpfr
# distutils: language = c++
"""
Expand Down Expand Up @@ -32,8 +31,8 @@ from cysignals.signals cimport sig_on, sig_off

from sage.libs.gmp.types cimport mpz_t

cdef extern from "partitions_c.h":
int part(mpz_t answer, unsigned int n)
cdef extern from "partitions_c.cc":
void part(mpz_t answer, unsigned int n)
int test(bint longtest, bint forever)

from sage.rings.integer cimport Integer
Expand All @@ -45,6 +44,12 @@ def number_of_partitions(n):
EXAMPLES::
sage: from sage.combinat.partitions import number_of_partitions
sage: number_of_partitions(0)
1
sage: number_of_partitions(1)
1
sage: number_of_partitions(2)
2
sage: number_of_partitions(3)
3
sage: number_of_partitions(10)
Expand Down Expand Up @@ -90,14 +95,11 @@ def number_of_partitions(n):
sage: len([n for n in [1..500] if number_of_partitions(n) != Partitions(n).cardinality(algorithm='pari')])
0
"""
n = Integer(n)
if n < 0:
raise ValueError("n (=%s) must be a nonnegative integer"%n)
elif n <= 1:
return Integer(1) # part hangs on n=1 as input.
if n >= Integer('4294967296'):
if n >= Integer(4294967296):
raise ValueError("input must be a nonnegative integer less than 4294967296.")
cdef unsigned int nn = n

Expand Down

0 comments on commit 68d3975

Please sign in to comment.