Ticket #3542: bernmm.2.patch

File bernmm.2.patch, 4.6 KB (added by dmharvey, 20 months ago)
  • sage/rings/arith.py

    # HG changeset patch
    # User dmharvey@math.harvard.edu
    # Date 1217600922 14400
    # Node ID 36c9629974915525ae9d0297b034136c68433637
    # Parent  7daa34e031e74c472f648d9576cc88b8bc0b17c1
    fixed overflow bug, added "r" prefix to comments, added algorithm="default" option to bernoulli(), per reviewer's comment on #3542
    
    diff -r 7daa34e031e7 -r 36c962997491 sage/rings/arith.py
    a b  
    145145 
    146146algebraic_dependency = algdep 
    147147 
    148 def bernoulli(n, algorithm='pari', num_threads=1): 
     148def bernoulli(n, algorithm='default', num_threads=1): 
    149149    r""" 
    150150    Return the n-th Bernoulli number, as a rational number. 
    151151 
    152152    INPUT: 
    153153        n -- an integer 
    154154        algorithm: 
    155             'pari' -- (default) use the PARI C library, which is 
    156                       by *far* the fastest. 
     155            'default' -- (default) use 'pari' for n <= 30000, and 
     156                         'bernmm' for n > 30000 (this is just a heuristic, 
     157                         and not guaranteed to be optimal on all hardware) 
     158            'pari' -- use the PARI C library 
    157159            'gap'  -- use GAP 
    158160            'gp'   -- use PARI/GP interpreter 
    159161            'magma' -- use MAGMA (optional) 
     
    192194    """ 
    193195    from sage.rings.all import Integer, Rational 
    194196    n = Integer(n) 
     197 
     198    if algorithm == 'default': 
     199        algorithm = 'pari' if n <= 30000 else 'bernmm' 
     200 
    195201    if n > 50000 and algorithm == 'pari': 
    196202        algorithm = 'gp' 
     203 
    197204    if algorithm == 'pari': 
    198205        x = pari(n).bernfrac()         # Use the PARI C library 
    199206        return Rational(x) 
  • sage/rings/bernmm.pyx

    diff -r 7daa34e031e7 -r 36c962997491 sage/rings/bernmm.pyx
    a b  
    2929 
    3030 
    3131def bernmm_bern_rat(long k, int num_threads = 1): 
    32     """ 
     32    r""" 
    3333    Computes k-th Bernoulli number using a multimodular algorithm. 
    3434    (Wrapper for bernmm library.) 
    3535 
     
    3939 
    4040    COMPLEXITY: 
    4141        Pretty much quadratic in $k$. See the paper ``A multimodular algorithm 
    42         for computing isolated Bernoulli numbers'', David Harvey, 2008, for 
    43         more details. 
     42        for computing Bernoulli numbers'', David Harvey, 2008, for more details. 
    4443 
    4544    EXAMPLES: 
    4645        sage: from sage.rings.bernmm import bernmm_bern_rat 
     
    7372 
    7473 
    7574def bernmm_bern_modp(long p, long k): 
    76     """ 
     75    r""" 
    7776    Computes $B_k \mod p$, where $B_k$ is the k-th Bernoulli number. 
    7877 
    7978    If $B_k$ is not $p$-integral, returns -1. 
  • sage/rings/bernmm/bern_modp.cpp

    diff -r 7daa34e031e7 -r 36c962997491 sage/rings/bernmm/bern_modp.cpp
    a b  
    436436 
    437437   PRECONDITIONS: 
    438438      3 <= n < F, n odd 
    439       0 <= x < nF 
     439      0 <= x < nF    (if n < F/2) 
     440      0 <= x < nF/2  (if n > F/2) 
    440441      ninv2 = -1/n mod F 
    441442*/ 
    442443#define LOW_MASK ((1L << (LONG_BIT / 2)) - 1) 
     
    638639         sum += y; 
    639640      } 
    640641 
    641       x = RedcFast(x * x_jump_redc, p, pinv2); 
     642      x = Redc(x * x_jump_redc, p, pinv2); 
    642643   } 
    643644 
    644645   return sum % p; 
  • sage/rings/bernmm/bernmm-test.cpp

    diff -r 7daa34e031e7 -r 36c962997491 sage/rings/bernmm/bernmm-test.cpp
    a b  
    189189      for (long k = 2; k <= p - 3 && success; k += 2) 
    190190         success = success && testcase__bern_modp_pow2(p, k); 
    191191   } 
    192     
     192 
    193193   // a few larger values of p 
    194194   for (long p = 1000000; p < 1030000; p++) 
    195195   { 
     
    210210      success = success & testcase__bern_modp_pow2(p, 10); 
    211211   } 
    212212    
    213    // one just below the REDC barrier 
     213   // try a few just below the REDC barrier 
     214   if (LONG_BIT == 32) 
    214215   { 
     216      long boundary = 1L << (LONG_BIT/2 - 1); 
     217      for (long p = boundary - 1000; p < boundary && success; p++) 
     218      { 
     219         if (ProbPrime(p)) 
     220         { 
     221            for (long trial = 0; trial < 1000 && success; trial++) 
     222            { 
     223               long k = 2 * (rand() % ((p-3)/2)) + 2; 
     224               success = success && testcase__bern_modp_pow2(p, k); 
     225            } 
     226         } 
     227      } 
     228   } 
     229   else 
     230   { 
     231      // on a 64-bit machine, only try one, since these are huge! 
    215232      long p = 1L << (LONG_BIT/2 - 1); 
    216233      while (!ProbPrime(p)) 
    217234         p--; 
    218       success = success && testcase__bern_modp_pow2(p, 10); 
    219    } 
    220  
    221    // and one above the REDC barrier 
    222    { 
    223       long p = 1L << (LONG_BIT/2 - 1); 
    224       while (!ProbPrime(p)) 
    225          p++; 
    226235      success = success && testcase__bern_modp_pow2(p, 10); 
    227236   } 
    228237