File Coverage

blib/lib/Math/Prime/Util.pm
Criterion Covered Total %
statement 384 508 75.5
branch 206 366 56.2
condition 69 159 43.4
subroutine 58 62 93.5
pod 27 27 100.0
total 744 1122 66.3


line stmt bran cond sub pod time code
1             package Math::Prime::Util;
2 69     69   3138513 use strict;
  69         667  
  69         2263  
3 69     69   352 use warnings;
  69         108  
  69         1940  
4 69     69   367 use Carp qw/croak confess carp/;
  69         402  
  69         4340  
5              
6             BEGIN {
7 69     69   260 $Math::Prime::Util::AUTHORITY = 'cpan:DANAJ';
8 69         1464 $Math::Prime::Util::VERSION = '0.69';
9             }
10              
11             # parent is cleaner, and in the Perl 5.10.1 / 5.12.0 core, but not earlier.
12             # use parent qw( Exporter );
13 69     69   392 use base qw( Exporter );
  69         143  
  69         19100  
14             our @EXPORT_OK =
15             qw( prime_get_config prime_set_config
16             prime_precalc prime_memfree
17             is_prime is_prob_prime is_provable_prime is_provable_prime_with_cert
18             prime_certificate verify_prime
19             is_pseudoprime is_euler_pseudoprime is_strong_pseudoprime
20             is_euler_plumb_pseudoprime
21             is_lucas_pseudoprime
22             is_strong_lucas_pseudoprime
23             is_extra_strong_lucas_pseudoprime
24             is_almost_extra_strong_lucas_pseudoprime
25             is_frobenius_pseudoprime
26             is_frobenius_underwood_pseudoprime is_frobenius_khashin_pseudoprime
27             is_perrin_pseudoprime is_catalan_pseudoprime
28             is_aks_prime is_bpsw_prime is_ramanujan_prime is_mersenne_prime
29             is_power is_prime_power is_pillai is_semiprime is_square is_polygonal
30             is_square_free is_primitive_root is_carmichael is_quasi_carmichael
31             is_fundamental is_totient
32             sqrtint rootint logint
33             miller_rabin_random
34             lucas_sequence lucasu lucasv
35             primes twin_primes ramanujan_primes sieve_prime_cluster sieve_range
36             forprimes forcomposites foroddcomposites fordivisors
37             forpart forcomp forcomb forperm forderange formultiperm
38             lastfor
39             numtoperm permtonum randperm shuffle
40             prime_iterator prime_iterator_object
41             next_prime prev_prime
42             prime_count
43             prime_count_lower prime_count_upper prime_count_approx
44             nth_prime nth_prime_lower nth_prime_upper nth_prime_approx inverse_li
45             twin_prime_count twin_prime_count_approx
46             nth_twin_prime nth_twin_prime_approx
47             ramanujan_prime_count ramanujan_prime_count_approx
48             ramanujan_prime_count_lower ramanujan_prime_count_upper
49             nth_ramanujan_prime nth_ramanujan_prime_approx
50             nth_ramanujan_prime_lower nth_ramanujan_prime_upper
51             sum_primes print_primes
52             random_prime random_ndigit_prime random_nbit_prime random_strong_prime
53             random_proven_prime random_proven_prime_with_cert
54             random_maurer_prime random_maurer_prime_with_cert
55             random_shawe_taylor_prime random_shawe_taylor_prime_with_cert
56             random_semiprime random_unrestricted_semiprime
57             primorial pn_primorial consecutive_integer_lcm gcdext chinese
58             gcd lcm factor factor_exp divisors valuation hammingweight
59             todigits fromdigits todigitstring sumdigits
60             invmod sqrtmod addmod mulmod divmod powmod
61             vecsum vecmin vecmax vecprod vecreduce vecextract
62             vecany vecall vecnotall vecnone vecfirst vecfirstidx
63             moebius mertens euler_phi jordan_totient exp_mangoldt liouville
64             partitions bernfrac bernreal harmfrac harmreal
65             chebyshev_theta chebyshev_psi
66             divisor_sum carmichael_lambda kronecker hclassno
67             ramanujan_tau ramanujan_sum
68             binomial stirling znorder znprimroot znlog legendre_phi
69             factorial factorialmod
70             ExponentialIntegral LogarithmicIntegral RiemannZeta RiemannR LambertW Pi
71             irand irand64 drand urandomb urandomm csrand random_bytes entropy_bytes
72             );
73             our %EXPORT_TAGS = (all => [ @EXPORT_OK ],
74             rand => [qw/srand rand irand irand64/],
75             );
76              
77             # These are only exported if specifically asked for
78             push @EXPORT_OK, (qw/trial_factor fermat_factor holf_factor lehman_factor squfof_factor prho_factor pbrent_factor pminus1_factor pplus1_factor ecm_factor rand srand/);
79              
80             my %_Config;
81             my %_GMPfunc; # List of available MPU::GMP functions
82              
83             # Similar to how boolean handles its option
84             sub import {
85 148 50   148   881 if ($] < 5.020) { # Prevent "used only once" warnings
86 0         0 my $pkg = caller;
87 69     69   482 no strict 'refs'; ## no critic(strict)
  69         124  
  69         11822  
88 0         0 ${"${pkg}::a"} = ${"${pkg}::a"};
  0         0  
  0         0  
89 0         0 ${"${pkg}::b"} = ${"${pkg}::b"};
  0         0  
  0         0  
90             }
91 148         354 foreach my $opt (qw/nobigint secure/) {
92 296         1188 my @options = grep $_ ne "-$opt", @_;
93 296 50       869 $_Config{$opt} = 1 if @options != @_;
94 296         863 @_ = @options;
95             }
96 148 50 33     887 _XS_set_secure() if $_Config{'xs'} && $_Config{'secure'};
97 148         104136 goto &Exporter::import;
98             }
99              
100             #############################################################################
101              
102              
103             BEGIN {
104              
105             # Separate lines to keep compatible with default from 5.6.2.
106             # We could alternately use Config's $Config{uvsize} for MAXBITS
107 69     69   433 use constant OLD_PERL_VERSION=> $] < 5.008;
  69         136  
  69         5833  
108 69     69   400 use constant MPU_MAXBITS => (~0 == 4294967295) ? 32 : 64;
  69         146  
  69         3618  
109 69     69   381 use constant MPU_32BIT => MPU_MAXBITS == 32;
  69         140  
  69         3377  
110 69     69   370 use constant MPU_MAXPARAM => MPU_32BIT ? 4294967295 : 18446744073709551615;
  69         134  
  69         3292  
111 69     69   361 use constant MPU_MAXDIGITS => MPU_32BIT ? 10 : 20;
  69         129  
  69         3131  
112 69     69   369 use constant MPU_MAXPRIME => MPU_32BIT ? 4294967291 : 18446744073709551557;
  69         127  
  69         3132  
113 69     69   359 use constant MPU_MAXPRIMEIDX => MPU_32BIT ? 203280221 : 425656284035217743;
  69         126  
  69         3109  
114 69     69   359 use constant UVPACKLET => MPU_32BIT ? 'L' : 'Q';
  69         117  
  69         3480  
115 69     69   356 use constant INTMAX => (!OLD_PERL_VERSION || MPU_32BIT) ? ~0 : 562949953421312;
  69         117  
  69         22314  
116              
117             eval {
118 69 50 33     469 return 0 if defined $ENV{MPU_NO_XS} && $ENV{MPU_NO_XS} == 1;
119 69         367 require XSLoader;
120 69         74476 XSLoader::load(__PACKAGE__, $Math::Prime::Util::VERSION);
121 69         6137 prime_precalc(0);
122 69         266 $_Config{'maxbits'} = _XS_prime_maxbits();
123 69         146 $_Config{'xs'} = 1;
124 69         272 1;
125 69 50   69   237 } or do {
126             carp "Using Pure Perl implementation: $@"
127 0 0 0     0 unless defined $ENV{MPU_NO_XS} && $ENV{MPU_NO_XS} == 1;
128              
129 0         0 $_Config{'xs'} = 0;
130 0         0 $_Config{'maxbits'} = MPU_MAXBITS;
131              
132             # Load PP front end code
133 0         0 require Math::Prime::Util::PPFE;
134              
135             # Init rand
136 0         0 Math::Prime::Util::csrand();
137              
138 0         0 *prime_count = \&Math::Prime::Util::_generic_prime_count;
139 0         0 *factor = \&Math::Prime::Util::_generic_factor;
140 0         0 *factor_exp = \&Math::Prime::Util::_generic_factor_exp;
141             };
142              
143 69         140 $_Config{'secure'} = 0;
144 69         135 $_Config{'nobigint'} = 0;
145 69         117 $_Config{'gmp'} = 0;
146             # See if they have the GMP module and haven't requested it not to be used.
147 69 50 33     358 if (!defined $ENV{MPU_NO_GMP} || $ENV{MPU_NO_GMP} != 1) {
148 69 50       150 if (eval { require Math::Prime::Util::GMP;
  69         5590  
149 0         0 Math::Prime::Util::GMP->import();
150 0         0 1; }) {
151 0         0 $_Config{'gmp'} = int(100*$Math::Prime::Util::GMP::VERSION);
152             }
153 69         318 for my $e (@Math::Prime::Util::GMP::EXPORT_OK) {
154 0         0 $Math::Prime::Util::_GMPfunc{"$e"} = $_Config{'gmp'};
155             }
156             # If we have GMP, it is not seeded properly but we are, seed with our data.
157 69 0 33     332442 if ( $_Config{'gmp'} >= 42
      33        
158             && !Math::Prime::Util::GMP::is_csprng_well_seeded()
159             && Math::Prime::Util::_is_csprng_well_seeded()) {
160 0         0 Math::Prime::Util::GMP::seed_csprng(256, random_bytes(256));
161             }
162             }
163             }
164              
165             croak "Perl and XS don't agree on bit size"
166             if $_Config{'xs'} && MPU_MAXBITS != _XS_prime_maxbits();
167              
168             $_Config{'maxparam'} = MPU_MAXPARAM;
169             $_Config{'maxdigits'} = MPU_MAXDIGITS;
170             $_Config{'maxprime'} = MPU_MAXPRIME;
171             $_Config{'maxprimeidx'} = MPU_MAXPRIMEIDX;
172             $_Config{'assume_rh'} = 0;
173             $_Config{'verbose'} = 0;
174              
175             # used for code like:
176             # return _XS_foo($n) if $n <= $_XS_MAXVAL
177             # which builds into one scalar whether XS is available and if we can call it.
178             my $_XS_MAXVAL = $_Config{'xs'} ? MPU_MAXPARAM : -1;
179             my $_HAVE_GMP = $_Config{'gmp'};
180             _XS_set_callgmp($_HAVE_GMP) if $_Config{'xs'};
181              
182             # Infinity in Perl is rather O/S specific.
183             our $_Infinity = 0+'inf';
184             $_Infinity = 20**20**20 if 65535 > $_Infinity; # E.g. Windows
185             our $_Neg_Infinity = -$_Infinity;
186              
187             sub prime_get_config {
188 2318     2318 1 54375 my %config = %_Config;
189              
190 2318 100       9551 $config{'precalc_to'} = ($_Config{'xs'})
191             ? _get_prime_cache_size()
192             : Math::Prime::Util::PP::_get_prime_cache_size();
193              
194 2318         6280 return \%config;
195             }
196              
197             # Note: You can cause yourself pain if you turn on xs or gmp when they're not
198             # loaded. Your calls will probably die horribly.
199             sub prime_set_config {
200 20     20 1 110167 my %params = (@_); # no defaults
201 20         85 foreach my $param (keys %params) {
202 23         63 my $value = $params{$param};
203 23         74 $param = lc $param;
204             # dispatch table should go here.
205 23 100 66     330 if ($param eq 'xs') {
    100          
    100          
    50          
    50          
    50          
    100          
    50          
206 2 100       9 $_Config{'xs'} = ($value) ? 1 : 0;
207 2 100       11 $_XS_MAXVAL = $_Config{'xs'} ? MPU_MAXPARAM : -1;
208             } elsif ($param eq 'gmp') {
209 2 50       8 $_HAVE_GMP = ($value) ? int(100*$Math::Prime::Util::GMP::VERSION) : 0;
210 2         9 $_Config{'gmp'} = $_HAVE_GMP;
211             $Math::Prime::Util::_GMPfunc{$_} = $_HAVE_GMP
212 2         7 for keys %Math::Prime::Util::_GMPfunc;
213 2 50       16 _XS_set_callgmp($_HAVE_GMP) if $_Config{'xs'};
214             } elsif ($param eq 'nobigint') {
215 2 100       10 $_Config{'nobigint'} = ($value) ? 1 : 0;
216             } elsif ($param eq 'secure') {
217 0 0 0     0 croak "Cannot disable secure once set" if !$value && $_Config{'secure'};
218 0 0       0 if ($value) {
219 0         0 $_Config{'secure'} = 1;
220 0 0       0 _XS_set_secure() if $_Config{'xs'};
221             }
222             } elsif ($param eq 'irand') {
223 0         0 carp "ntheory irand option is deprecated";
224             } elsif ($param eq 'use_primeinc') {
225 0         0 carp "ntheory use_primeinc option is deprecated";
226             } elsif ($param =~ /^(assume[_ ]?)?[ge]?rh$/ || $param =~ /riemann\s*h/) {
227 8 100       37 $_Config{'assume_rh'} = ($value) ? 1 : 0;
228             } elsif ($param eq 'verbose') {
229 9 50       59 if ($value =~ /^\d+$/) { }
    0          
    0          
230 0         0 elsif ($value =~ /^[ty]/i) { $value = 1; }
231 0         0 elsif ($value =~ /^[fn]/i) { $value = 0; }
232 0         0 else { croak("Invalid setting for verbose. 0, 1, 2, etc."); }
233 9         25 $_Config{'verbose'} = $value;
234 9 50       52 _XS_set_verbose($value) if $_Config{'xs'};
235 9 50       30 Math::Prime::Util::GMP::_GMP_set_verbose($value) if $_Config{'gmp'};
236             } else {
237 0         0 croak "Unknown or invalid configuration setting: $param\n";
238             }
239             }
240 20         181 1;
241             }
242              
243             sub _bigint_to_int {
244 20     20   3198 return (OLD_PERL_VERSION) ? unpack(UVPACKLET,pack(UVPACKLET,$_[0]->bstr))
245             : int($_[0]->bstr);
246             }
247             sub _to_bigint {
248 7451 50   7451   29488 do { require Math::BigInt; Math::BigInt->import(try=>"GMP,Pari"); }
  0         0  
  0         0  
249             unless defined $Math::BigInt::VERSION;
250 7451 100 66     81963 return (!defined($_[0]) || ref($_[0]) eq 'Math::BigInt') ? $_[0] : Math::BigInt->new("$_[0]");
251             }
252             sub _to_gmpz {
253 0 0   0   0 do { require Math::GMPz; } unless defined $Math::GMPz::VERSION;
  0         0  
254 0 0       0 return (ref($_[0]) eq 'Math::GMPz') ? $_[0] : Math::GMPz->new($_[0]);
255             }
256             sub _to_gmp {
257 0 0   0   0 do { require Math::GMP; } unless defined $Math::GMP::VERSION;
  0         0  
258 0 0       0 return (ref($_[0]) eq 'Math::GMP') ? $_[0] : Math::GMP->new($_[0]);
259             }
260             sub _reftyped {
261 569 50   569   920 return unless defined $_[1];
262 569         637 my $ref0 = ref($_[0]);
263 569 100       782 if ($ref0) {
264 3 100       17 return ($ref0 eq ref($_[1])) ? $_[1] : $ref0->new("$_[1]");
265             }
266 566 50       728 if (OLD_PERL_VERSION) {
267             # Perl 5.6 truncates arguments to doubles if you look at them funny
268             return "$_[1]" if "$_[1]" <= INTMAX;
269 0         0 } elsif ($_[1] >= 0) {
270             # TODO: This wasn't working right in 5.20.0-RC1, verify correct
271 566 50       958 return $_[1] if $_[1] <= ~0;
272             } else {
273 0 0       0 return $_[1] if ''.int($_[1]) >= -(~0>>1);
274             }
275 0 0       0 do { require Math::BigInt; Math::BigInt->import(try=>"GMP,Pari"); }
  0         0  
  0         0  
276             unless defined $Math::BigInt::VERSION;
277 0         0 return Math::BigInt->new("$_[1]");
278             }
279              
280              
281             #*_validate_positive_integer = \&Math::Prime::Util::PP::_validate_positive_integer;
282             sub _validate_positive_integer {
283 132     132   3301 my($n, $min, $max) = @_;
284 132 50       412 croak "Parameter must be defined" if !defined $n;
285 132 50       468 if (ref($n) eq 'CODE') {
286 0         0 $_[0] = $_[0]->();
287 0         0 $n = $_[0];
288             }
289 132 100       408 if (ref($n) eq 'Math::BigInt') {
    50          
290 119 50 33     347 croak "Parameter '$n' must be a positive integer"
291             if $n->sign() ne '+' || !$n->is_int();
292 119 50       1789 $_[0] = _bigint_to_int($_[0]) if $n <= '' . INTMAX;
293             } elsif (ref($n) eq 'Math::GMPz') {
294 0 0       0 croak "Parameter '$n' must be a positive integer" if Math::GMPz::Rmpz_sgn($n) < 0;
295 0 0       0 $_[0] = _bigint_to_int($_[0]) if $n <= INTMAX;
296             } else {
297 13         31 my $strn = "$n";
298 13 50 33     65 croak "Parameter '$strn' must be a positive integer"
      33        
299             if $strn eq '' || ($strn =~ tr/0123456789//c && $strn !~ /^\+?\d+$/);
300 13 100       45 if ($n <= INTMAX) {
301 7 50       9 $_[0] = $strn if ref($n);
302             } else {
303             #$_[0] = Math::BigInt->new($strn)
304 6         23 $_[0] = _to_bigint($strn);
305             }
306             }
307 132 50 66     14075 $_[0]->upgrade(undef) if ref($_[0]) eq 'Math::BigInt' && $_[0]->upgrade();
308 132 50 33     1581 croak "Parameter '$_[0]' must be >= $min" if defined $min && $_[0] < $min;
309 132 50 33     402 croak "Parameter '$_[0]' must be <= $max" if defined $max && $_[0] > $max;
310 132         207 1;
311             }
312              
313             #############################################################################
314              
315             sub primes {
316 1151     1151 1 33132 my($low,$high) = @_;
317 1151 100       2201 if (scalar @_ > 1) {
318 115 100       555 _validate_num($low) || _validate_positive_integer($low);
319             } else {
320 1036         1473 ($low,$high) = (2, $low);
321             }
322 1144 100       2427 _validate_num($high) || _validate_positive_integer($high);
323              
324 1136         1592 my $sref = [];
325 1136 100 100     3119 return $sref if ($low > $high) || ($high < 2);
326              
327 1126 100       1927 if ($high > $_XS_MAXVAL) {
328 1 50       105 if ($_HAVE_GMP) {
329 0         0 $sref = Math::Prime::Util::GMP::primes($low,$high);
330 0 0       0 if ($high > ~0) {
331             # Convert the returned strings into BigInts
332 0         0 @$sref = map { _reftyped($_[0],$_) } @$sref;
  0         0  
333             } else {
334 0         0 @$sref = map { int($_) } @$sref;
  0         0  
335             }
336 0         0 return $sref;
337             }
338 1         12 require Math::Prime::Util::PP;
339 1         6 return Math::Prime::Util::PP::primes($low,$high);
340             }
341              
342             # Decide the method to use. We have four to choose from:
343             # 1. Trial No memory, no overhead, but more time per prime.
344             # 2. Sieve Monolithic cached sieve.
345             # 3. Erat Monolithic uncached sieve.
346             # 4. Segment Segment sieve. Never a bad decision.
347              
348 1125 100 66     3721 if (($low+1) >= $high || # Tiny range, or
    100 100        
      100        
349             $high > 10**14 && ($high-$low) < 50000) { # Small relative range
350              
351 18         297 $sref = trial_primes($low, $high);
352              
353             } elsif ($high <= (65536*30) || # Very small, or
354             $high <= _get_prime_cache_size()) { # already in the main cache.
355              
356 1100         48225 $sref = sieve_primes($low, $high);
357              
358             } else {
359              
360 7         17102 $sref = segment_primes($low, $high);
361              
362             }
363              
364             # We could return an array ref in scalar context, array in list context with:
365             # return (wantarray) ? @{$sref} : $sref;
366             # but I think the dual interface could be confusing, albeit often handy.
367 1125         11980 return $sref;
368             }
369              
370             # Shortcut for primes returning an array instead of array reference.
371             # sub aprimes { @{primes(@_)}; }
372              
373             sub twin_primes {
374 20     20 1 9668 my($low,$high) = @_;
375 20 100       64 if (scalar @_ > 1) {
376 18 100       90 _validate_num($low) || _validate_positive_integer($low);
377             } else {
378 2         8 ($low,$high) = (2, $low);
379             }
380 20 100       79 _validate_num($high) || _validate_positive_integer($high);
381              
382 20 50 33     103 return [] if ($low > $high) || ($high < 2);
383              
384 20 100       191 if ($high > $_XS_MAXVAL) {
385 3         112 my @tp;
386 3 50 33     17 if ($_HAVE_GMP && defined &Math::Prime::Util::GMP::sieve_twin_primes && $low > 2**31) {
      33        
387 0         0 @tp = map { _reftyped($_[0],$_) } Math::Prime::Util::GMP::sieve_twin_primes($low, $high);
  0         0  
388             } else {
389 3         32 require Math::Prime::Util::PP;
390 3         20 @tp = map { _reftyped($_[0],$_) } Math::Prime::Util::PP::sieve_prime_cluster($low,$high, 2);
  566         737  
391             }
392 3         39 return \@tp;
393             }
394              
395 17         2770 return segment_twin_primes($low, $high);
396             }
397              
398             sub ramanujan_primes {
399 15     15 1 7860 my($low,$high) = @_;
400 15 100       40 if (scalar @_ > 1) {
401 14 50       54 _validate_num($low) || _validate_positive_integer($low);
402             } else {
403 1         3 ($low,$high) = (2, $low);
404             }
405 15 50       42 _validate_num($high) || _validate_positive_integer($high);
406              
407 15 50 33     65 return [] if ($low > $high) || ($high < 2);
408              
409 15 50       30 if ($high > $_XS_MAXVAL) {
410 0         0 require Math::Prime::Util::PP;
411 0         0 return Math::Prime::Util::PP::_ramanujan_primes($low,$high);
412             }
413 15         477 return _ramanujan_primes($low, $high);
414             }
415              
416             #############################################################################
417             # Random primes. These are front end functions that do input validation,
418             # load the RandomPrimes module, and call its function.
419              
420             sub random_maurer_prime_with_cert {
421 1     1 1 3265 my($bits) = @_;
422 1 50       23 _validate_num($bits, 2) || _validate_positive_integer($bits, 2);
423              
424 1 50       5 if ($Math::Prime::Util::_GMPfunc{"random_maurer_prime_with_cert"}) {
425 0         0 my($n,$cert) = Math::Prime::Util::GMP::random_maurer_prime_with_cert($bits);
426 0         0 return (Math::Prime::Util::_reftyped($_[0],$n), $cert);
427             }
428              
429 1         407 require Math::Prime::Util::RandomPrimes;
430 1         9 return Math::Prime::Util::RandomPrimes::random_maurer_prime_with_cert($bits);
431             }
432              
433             sub random_shawe_taylor_prime_with_cert {
434 1     1 1 576 my($bits) = @_;
435 1 50       8 _validate_num($bits, 2) || _validate_positive_integer($bits, 2);
436              
437 1 50       6 if ($Math::Prime::Util::_GMPfunc{"random_shawe_taylor_prime_with_cert"}) {
438 0         0 my($n,$cert) =Math::Prime::Util::GMP::random_shawe_taylor_prime_with_cert($bits);
439 0         0 return (Math::Prime::Util::_reftyped($_[0],$n), $cert);
440             }
441              
442 1         10 require Math::Prime::Util::RandomPrimes;
443 1         10 return Math::Prime::Util::RandomPrimes::random_shawe_taylor_prime_with_cert($bits);
444             }
445              
446             sub random_proven_prime_with_cert {
447 1     1 1 517 my($bits) = @_;
448 1 50       11 _validate_num($bits, 2) || _validate_positive_integer($bits, 2);
449              
450             # Go to Maurer with GMP
451 1 50       5 if ($Math::Prime::Util::_GMPfunc{"random_maurer_prime_with_cert"}) {
452 0         0 my($n,$cert) = Math::Prime::Util::GMP::random_maurer_prime_with_cert($bits);
453 0         0 return (Math::Prime::Util::_reftyped($_[0],$n), $cert);
454             }
455              
456 1         12 require Math::Prime::Util::RandomPrimes;
457 1         8 return Math::Prime::Util::RandomPrimes::random_proven_prime_with_cert($bits);
458             }
459              
460              
461             #############################################################################
462             # These functions almost always return bigints, so there is no XS
463             # implementation. Try to run the GMP version, and if it isn't available,
464             # load PP and call it.
465              
466             sub primorial {
467 35     35 1 21700 my($n) = @_;
468 35 50       170 _validate_num($n) || _validate_positive_integer($n);
469 35 100       117 return (1,1,2,6,6,30,30,210,210,210)[$n] if $n < 10;
470              
471 30 50 33     75 if ($_HAVE_GMP && defined &Math::Prime::Util::GMP::primorial) {
472 0         0 return _reftyped($_[0], Math::Prime::Util::GMP::primorial($n));
473             }
474 30         1175 require Math::Prime::Util::PP;
475 30         90 return Math::Prime::Util::PP::primorial($n);
476             }
477              
478             sub pn_primorial {
479 36     36 1 86 my($n) = @_;
480 36 50       151 _validate_num($n) || _validate_positive_integer($n);
481 36 100       329 return (1,2,6,30,210,2310,30030,510510,9699690,223092870)[$n] if $n < 10;
482              
483 25 50 33     68 if ($_HAVE_GMP && defined &Math::Prime::Util::GMP::pn_primorial) {
484 0         0 return _reftyped($_[0], Math::Prime::Util::GMP::pn_primorial($n));
485             }
486              
487 25         124 require Math::Prime::Util::PP;
488 25         158 return Math::Prime::Util::PP::primorial(nth_prime($n));
489             }
490              
491             sub consecutive_integer_lcm {
492 104     104 1 48051 my($n) = @_;
493 104 50       445 _validate_num($n) || _validate_positive_integer($n);
494 104 100       208 return 0 if $n < 1;
495              
496 103 50 33     216 if ($_HAVE_GMP && defined &Math::Prime::Util::GMP::consecutive_integer_lcm) {
497 0         0 return _reftyped($_[0],Math::Prime::Util::GMP::consecutive_integer_lcm($n));
498             }
499 103         1392 require Math::Prime::Util::PP;
500 103         258 return Math::Prime::Util::PP::consecutive_integer_lcm($n);
501             }
502              
503             # See 2011+ FLINT and Fredrik Johansson's work for state of the art.
504             # Very crude timing estimates (ignores growth rates).
505             # Perl-comb partitions(10^5) ~ 300 seconds ~200,000x slower than Pari
506             # GMP-comb partitions(10^6) ~ 120 seconds ~1,000x slower than Pari
507             # Pari partitions(10^8) ~ 100 seconds
508             # Bober 0.6 partitions(10^9) ~ 20 seconds ~50x faster than Pari
509             # Johansson partitions(10^12) ~ 10 seconds >1000x faster than Pari
510             sub partitions {
511 58     58 1 34190 my($n) = @_;
512 58 100 66     288 return 1 if defined $n && $n <= 0;
513 57 50       224 _validate_num($n) || _validate_positive_integer($n);
514              
515 57 50 33     134 if ($_HAVE_GMP && defined &Math::Prime::Util::GMP::partitions) {
516 0         0 return _reftyped($_[0],Math::Prime::Util::GMP::partitions($n));
517             }
518              
519 57         1266 require Math::Prime::Util::PP;
520 57         159 return Math::Prime::Util::PP::partitions($n);
521             }
522              
523             #############################################################################
524             # forprimes, forcomposites, fordivisors.
525             # These are used when the XS code can't handle it.
526              
527             sub _generic_forprimes {
528 1     1   3 my($sub, $beg, $end) = @_;
529 1 50       5 if (!defined $end) { $end = $beg; $beg = 2; }
  0         0  
  0         0  
530 1         5 _validate_positive_integer($beg);
531 1         4 _validate_positive_integer($end);
532 1 50       5 $beg = 2 if $beg < 2;
533 1         6 my $oldforexit = Math::Prime::Util::_start_for_loop();
534             {
535 1         3 my $pp;
  1         1  
536 1         4 local *_ = \$pp;
537 1         14 for (my $p = next_prime($beg-1); $p <= $end; $p = next_prime($p)) {
538 7         10 $pp = $p;
539 7         14 $sub->();
540 7 50       38 last if Math::Prime::Util::_get_forexit();
541             }
542             }
543 1         4 Math::Prime::Util::_end_for_loop($oldforexit);
544             }
545              
546             sub _generic_forcomposites {
547 1     1   645 my($sub, $beg, $end) = @_;
548 1 50       4 if (!defined $end) { $end = $beg; $beg = 4; }
  0         0  
  0         0  
549 1         4 _validate_positive_integer($beg);
550 1         3 _validate_positive_integer($end);
551 1 50       4 $beg = 4 if $beg < 4;
552 1 50 33     7 $end = Math::BigInt->new(''.~0) if ref($end) ne 'Math::BigInt' && $end == ~0;
553 1         4 my $oldforexit = Math::Prime::Util::_start_for_loop();
554             {
555 1         3 my $pp;
  1         2  
556 1         3 local *_ = \$pp;
557 1         8 for (my $p = next_prime($beg-1); $beg <= $end; $p = next_prime($p)) {
558 5   100     16 for ( ; $beg < $p && $beg <= $end ; $beg++ ) {
559 8         10 $pp = $beg;
560 8         18 $sub->();
561 8 50       36 last if Math::Prime::Util::_get_forexit();
562             }
563 5         5 $beg++;
564 5 50       26 last if Math::Prime::Util::_get_forexit();
565             }
566             }
567 1         4 Math::Prime::Util::_end_for_loop($oldforexit);
568             }
569              
570             sub _generic_foroddcomposites {
571 1     1   581 my($sub, $beg, $end) = @_;
572 1 50       4 if (!defined $end) { $end = $beg; $beg = 9; }
  0         0  
  0         0  
573 1         4 _validate_positive_integer($beg);
574 1         2 _validate_positive_integer($end);
575 1 50       3 $beg = 9 if $beg < 9;
576 1 50       6 $beg++ unless $beg & 1;
577 1 50 33     34 $end = Math::BigInt->new(''.~0) if ref($end) ne 'Math::BigInt' && $end == ~0;
578 1         5 my $oldforexit = Math::Prime::Util::_start_for_loop();
579             {
580 1         2 my $pp;
  1         2  
581 1         3 local *_ = \$pp;
582 1         9 for (my $p = next_prime($beg-1); $beg <= $end; $p = next_prime($p)) {
583 5   100     15 for ( ; $beg < $p && $beg <= $end ; $beg += 2 ) {
584 2         3 $pp = $beg;
585 2         15 $sub->();
586 2 50       16 last if Math::Prime::Util::_get_forexit();
587             }
588 5         7 $beg += 2;
589 5 50       26 last if Math::Prime::Util::_get_forexit();
590             }
591             }
592 1         4 Math::Prime::Util::_end_for_loop($oldforexit);
593             }
594              
595             sub _generic_fordivisors {
596 1     1   544 my($sub, $n) = @_;
597 1         4 _validate_positive_integer($n);
598 1         14 my @divisors = divisors($n);
599 1         5 my $oldforexit = Math::Prime::Util::_start_for_loop();
600             {
601 1         2 my $pp;
  1         3  
602 1         3 local *_ = \$pp;
603 1         3 foreach my $d (@divisors) {
604 16         17 $pp = $d;
605 16         24 $sub->();
606 16 50       47 last if Math::Prime::Util::_get_forexit();
607             }
608             }
609 1         5 Math::Prime::Util::_end_for_loop($oldforexit);
610             }
611              
612             sub formultiperm (&$) { ## no critic qw(ProhibitSubroutinePrototypes)
613 5     5 1 48281 my($sub, $iref) = @_;
614 5 50       19 croak("formultiperm first argument must be an array reference") unless ref($iref) eq 'ARRAY';
615              
616 5         13 my($sum, %h, @n) = (0);
617 5         19 $h{$_}++ for @$iref;
618 5         24 @n = map { [$_, $h{$_}] } sort(keys(%h));
  11         25  
619 5         15 $sum += $_->[1] for @n;
620              
621 5         27 require Math::Prime::Util::PP;
622 5         17 my $oldforexit = Math::Prime::Util::_start_for_loop();
623 5         23 Math::Prime::Util::PP::_multiset_permutations( $sub, [], \@n, $sum );
624 5         22 Math::Prime::Util::_end_for_loop($oldforexit);
625             }
626              
627             #############################################################################
628             # Iterators
629              
630             sub prime_iterator {
631 26     26 1 29632 my($start) = @_;
632 26 100       90 $start = 0 unless defined $start;
633 26 100       155 _validate_num($start) || _validate_positive_integer($start);
634 23 100       174 my $p = ($start > 0) ? $start-1 : 0;
635             # This works fine:
636             # return sub { $p = next_prime($p); return $p; };
637             # but we can optimize a little
638 23 100 66     752 if (ref($p) ne 'Math::BigInt' && $p <= $_XS_MAXVAL) {
    50          
639             # This is simple and low memory, but slower than segments:
640             # return sub { $p = next_prime($p); return $p; };
641 22         57 my $pr = [];
642             return sub {
643 88 100   88   789 if (scalar(@$pr) == 0) {
644             # Once we're into bigints, just use next_prime
645 22 50       65 return $p=next_prime($p) if $p >= MPU_MAXPRIME;
646             # Get about 10k primes
647 22 100       77 my $segment = ($p <= 1e4) ? 10_000 : int(10000*log($p)+1);
648 22 50 33     84 $segment = ~0-$p if $p+$segment > ~0 && $p+1 < ~0;
649 22         77 $pr = primes($p+1, $p+$segment);
650             }
651 88         347 return $p = shift(@$pr);
652 22         185 };
653             } elsif ($_HAVE_GMP) {
654 0     0   0 return sub { $p = $p-$p+Math::Prime::Util::GMP::next_prime($p); return $p;};
  0         0  
  0         0  
655             } else {
656 1         14 require Math::Prime::Util::PP;
657 3     3   24 return sub { $p = Math::Prime::Util::PP::next_prime($p); return $p; }
  3         27  
658 1         11 }
659             }
660              
661             sub prime_iterator_object {
662 11     11 1 6598 my($start) = @_;
663 11         1244 require Math::Prime::Util::PrimeIterator;
664 11         81 return Math::Prime::Util::PrimeIterator->new($start);
665             }
666              
667             #############################################################################
668             # Front ends to functions.
669             #
670             # These will do input validation, then call the appropriate internal function
671             # based on the input (XS, GMP, PP).
672             #############################################################################
673              
674             sub _generic_prime_count {
675 1     1   1761 my($low,$high) = @_;
676 1 50       5 if (defined $high) {
677 1 50       6 _validate_num($low) || _validate_positive_integer($low);
678 1 50       4 _validate_num($high) || _validate_positive_integer($high);
679             } else {
680 0         0 ($low,$high) = (2, $low);
681 0 0       0 _validate_num($high) || _validate_positive_integer($high);
682             }
683 1 50 33     4 return 0 if $high < 2 || $low > $high;
684              
685             # We can relax these constraints if MPU::GMP gets a fast implementation.
686 1 0 33     141 return Math::Prime::Util::GMP::prime_count($low,$high) if $_HAVE_GMP
      0        
      33        
687             && defined &Math::Prime::Util::GMP::prime_count
688             && ( (ref($high) eq 'Math::BigInt')
689             || (($high-$low) < int($low/1_000_000))
690             );
691 1         11 require Math::Prime::Util::PP;
692 1         5 return Math::Prime::Util::PP::prime_count($low,$high);
693             }
694              
695             sub _generic_factor {
696 93     93   14721 my($n) = @_;
697 93 50       411 _validate_num($n) || _validate_positive_integer($n);
698              
699 93 50       306 if ($_HAVE_GMP) {
700 0         0 my @factors;
701 0 0       0 if ($n != 1) {
702 0         0 @factors = Math::Prime::Util::GMP::factor($n);
703             #if (ref($_[0]) eq 'Math::BigInt') {
704             # @factors = map { ($_ > ~0) ? Math::BigInt->new(''.$_) : $_ } @factors;
705             #}
706 0 0       0 if (ref($_[0])) {
707 0 0       0 @factors = map { ($_ > ~0) ? ref($_[0])->new(''.$_) : $_ } @factors;
  0         0  
708             }
709             }
710 0         0 return @factors;
711             }
712              
713 93         585 require Math::Prime::Util::PP;
714 93         394 return Math::Prime::Util::PP::factor($n);
715             }
716              
717             sub _generic_factor_exp {
718 14     14   433 my($n) = @_;
719 14 50       84 _validate_num($n) || _validate_positive_integer($n);
720              
721 14         33 my %exponents;
722 14         59 my @factors = grep { !$exponents{$_}++ } factor($n);
  447         875  
723 14 50       108 return scalar @factors unless wantarray;
724 14         36 return (map { [$_, $exponents{$_}] } @factors);
  224         440  
725             }
726              
727             #############################################################################
728              
729             sub _is_gaussian_prime {
730 0     0   0 my($a,$b) = @_;
731 0 0       0 return ((($b % 4) == 3) ? is_prime($b) : 0) if $a == 0;
    0          
732 0 0       0 return ((($a % 4) == 3) ? is_prime($a) : 0) if $b == 0;
    0          
733 0         0 is_prime( vecsum( vecprod($a,$a), vecprod($b,$b) ) );
734             }
735              
736             #############################################################################
737              
738             # Return just the cert portion.
739             sub prime_certificate {
740 4     4 1 13 my($n) = @_;
741 4         13 my ($is_prime, $cert) = is_provable_prime_with_cert($n);
742 4         13 return $cert;
743             }
744              
745              
746             sub is_provable_prime_with_cert {
747 95     95 1 2957 my($n) = @_;
748 95 50 33     680 return 0 if defined $n && $n < 2;
749 95 100       12301 _validate_num($n) || _validate_positive_integer($n);
750 95         4983 my $header = "[MPU - Primality Certificate]\nVersion 1.0\n\nProof for:\nN $n\n\n";
751              
752 95 100       598 if ($n <= $_XS_MAXVAL) {
753 84         539 my $isp = is_prime($n);
754 84 50       265 return ($isp, '') unless $isp == 2;
755 84         431 return (2, $header . "Type Small\nN $n\n");
756             }
757              
758 11 50 33     1233 if ($_HAVE_GMP && defined &Math::Prime::Util::GMP::is_provable_prime_with_cert) {
759 0         0 my ($isp, $cert) = Math::Prime::Util::GMP::is_provable_prime_with_cert($n);
760             # New version that returns string format.
761             #return ($isp, $cert) if ref($cert) ne 'ARRAY';
762 0 0       0 if (ref($cert) ne 'ARRAY') {
763             # Fix silly 0.13 mistake (TODO: deprecate this)
764 0         0 $cert =~ s/^Type Small\n(\d+)/Type Small\nN $1/smg;
765 0         0 return ($isp, $cert);
766             }
767             # Old version. Convert.
768 0         0 require Math::Prime::Util::PrimalityProving;
769 0         0 return ($isp, Math::Prime::Util::PrimalityProving::convert_array_cert_to_string($cert));
770             }
771              
772             {
773 11         20 my $isp = is_prob_prime($n);
  11         45  
774 11 50       1664 return ($isp, '') if $isp == 0;
775 11 50       46 return (2, $header . "Type Small\nN $n\n") if $isp == 2;
776             }
777              
778             # Choice of methods for proof:
779             # ECPP needs a fair bit of programming work
780             # APRCL needs a lot of programming work
781             # BLS75 combo Corollary 11 of BLS75. Trial factor n-1 and n+1 to B, find
782             # factors F1 of n-1 and F2 of n+1. Quit when:
783             # B > (N/(F1*F1*(F2/2)))^1/3 or B > (N/((F1/2)*F2*F2))^1/3
784             # BLS75 n+1 Requires factoring n+1 to (n/2)^1/3 (theorem 19)
785             # BLS75 n-1 Requires factoring n-1 to (n/2)^1/3 (theorem 5 or 7)
786             # Pocklington Requires factoring n-1 to n^1/2 (BLS75 theorem 4)
787             # Lucas Easy, requires factoring of n-1 (BLS75 theorem 1)
788             # AKS horribly slow
789             # See http://primes.utm.edu/prove/merged.html or other sources.
790              
791 11         1302 require Math::Prime::Util::PrimalityProving;
792             #my ($isp, $pref) = Math::Prime::Util::PrimalityProving::primality_proof_lucas($n);
793 11         82 my ($isp, $pref) = Math::Prime::Util::PrimalityProving::primality_proof_bls75($n);
794 11 50       40 carp "proved $n is not prime\n" if !$isp;
795 11         62 return ($isp, $pref);
796             }
797              
798              
799             sub verify_prime {
800 50     50 1 32916 require Math::Prime::Util::PrimalityProving;
801 50         257 return Math::Prime::Util::PrimalityProving::verify_cert(@_);
802             }
803              
804             #############################################################################
805              
806             sub RiemannZeta {
807 6     6 1 2439 my($n) = @_;
808 6 50       23 croak("Invalid input to ReimannZeta: x must be > 0") if $n <= 0;
809              
810 6 50       13 return $n-$n if $n > 10_000_000; # Over 3M leading zeros
811              
812             return _XS_RiemannZeta($n)
813 6 50 33     127 if !defined $bignum::VERSION && ref($n) ne 'Math::BigFloat' && $_Config{'xs'};
      33        
814              
815 0         0 require Math::Prime::Util::PP;
816 0         0 return Math::Prime::Util::PP::RiemannZeta($n);
817             }
818              
819             sub RiemannR {
820 11     11 1 4444 my($n) = @_;
821 11 100       182 croak("Invalid input to ReimannR: x must be > 0") if $n <= 0;
822              
823             return _XS_RiemannR($n)
824 9 50 33     220 if !defined $bignum::VERSION && ref($n) ne 'Math::BigFloat' && $_Config{'xs'};
      33        
825              
826 0         0 require Math::Prime::Util::PP;
827 0         0 return Math::Prime::Util::PP::RiemannR($n);
828             }
829              
830             sub ExponentialIntegral {
831 23     23 1 6521 my($n) = @_;
832 23 100       81 return $_Neg_Infinity if $n == 0;
833 22 100       55 return 0 if $n == $_Neg_Infinity;
834 21 100       39 return $_Infinity if $n == $_Infinity;
835              
836             return _XS_ExponentialIntegral($n)
837 20 100 33     296 if !defined $bignum::VERSION && ref($n) ne 'Math::BigFloat' && $_Config{'xs'};
      66        
838              
839 2         25 require Math::Prime::Util::PP;
840 2         12 return Math::Prime::Util::PP::ExponentialIntegral($n);
841             }
842              
843             sub LogarithmicIntegral {
844 28     28 1 5059 my($n) = @_;
845 28 100       72 return 0 if $n == 0;
846 26 100       51 return $_Neg_Infinity if $n == 1;
847 25 100       45 return $_Infinity if $n == $_Infinity;
848              
849 24 100       176 croak("Invalid input to LogarithmicIntegral: x must be >= 0") if $n <= 0;
850              
851 23 50 33     100 if (!defined $bignum::VERSION && ref($n) ne 'Math::BigFloat' && $_Config{'xs'}) {
      33        
852 23 100       45 return 1.045163780117492784844588889194613136522615578151 if $n == 2;
853 22         165 return _XS_LogarithmicIntegral($n);
854             }
855              
856 0         0 require Math::Prime::Util::PP;
857 0         0 return Math::Prime::Util::PP::LogarithmicIntegral(@_);
858             }
859              
860             sub LambertW {
861 9     9 1 3502 my($x) = @_;
862              
863             return _XS_LambertW($x)
864 9 50 33     144 if !defined $bignum::VERSION && ref($x) ne 'Math::BigFloat' && $_Config{'xs'};
      33        
865              
866             # TODO: Call GMP function here directly
867              
868 0         0 require Math::Prime::Util::PP;
869 0         0 return Math::Prime::Util::PP::LambertW($x);
870             }
871              
872             sub bernfrac {
873 116     116 1 2887 my($n) = @_;
874 116 50 33     519 return map { _to_bigint($_) } (0,1) if defined $n && $n < 0;
  0         0  
875 116 50       499 _validate_num($n) || _validate_positive_integer($n);
876 116 100 100     487 return map { _to_bigint($_) } (0,1) if $n > 1 && ($n & 1);
  22         1053  
877              
878 105 50       253 if ($Math::Prime::Util::_GMPfunc{"bernfrac"}) {
879 0         0 return map { _to_bigint($_) } Math::Prime::Util::GMP::bernfrac($n);
  0         0  
880             }
881              
882 105         1810 require Math::Prime::Util::PP;
883 105         273 return Math::Prime::Util::PP::bernfrac($n);
884             }
885             sub bernreal {
886 26     26 1 47492 my($n, $precision) = @_;
887 26 100       65 do { require Math::BigFloat; Math::BigFloat->import(); } unless defined $Math::BigFloat::VERSION;
  1         897  
  1         41766  
888              
889 26 50       18998 if ($Math::Prime::Util::_GMPfunc{"bernreal"}) {
890 0 0       0 return Math::BigFloat->new(Math::Prime::Util::GMP::bernreal($n)) if !defined $precision;
891 0         0 return Math::BigFloat->new(Math::Prime::Util::GMP::bernreal($n,$precision),$precision);
892             }
893              
894 26         49 my($num,$den) = bernfrac($n);
895 26 100       407 return Math::BigFloat->bzero if $num->is_zero;
896 15         166 scalar Math::BigFloat->new($num)->bdiv($den, $precision);
897             }
898              
899             sub harmfrac {
900 79     79 1 18934 my($n) = @_;
901 79 50       297 _validate_num($n) || _validate_positive_integer($n);
902 79 50       152 return map { _to_bigint($_) } (0,1) if $n <= 0;
  0         0  
903              
904 79 50       172 if ($Math::Prime::Util::_GMPfunc{"harmfrac"}) {
905 0         0 return map { _to_bigint($_) } Math::Prime::Util::GMP::harmfrac($n);
  0         0  
906             }
907              
908 79         440 require Math::Prime::Util::PP;
909 79         190 Math::Prime::Util::PP::harmfrac($n);
910             }
911             sub harmreal {
912 22     22 1 49849 my($n, $precision) = @_;
913 22 50       91 _validate_num($n) || _validate_positive_integer($n);
914 22 50       43 do { require Math::BigFloat; Math::BigFloat->import(); } unless defined $Math::BigFloat::VERSION;
  0         0  
  0         0  
915 22 100       50 return Math::BigFloat->bzero if $n <= 0;
916              
917 21 50       41 if ($Math::Prime::Util::_GMPfunc{"harmreal"}) {
918 0 0       0 return Math::BigFloat->new(Math::Prime::Util::GMP::harmreal($n)) if !defined $precision;
919 0         0 return Math::BigFloat->new(Math::Prime::Util::GMP::harmreal($n,$precision),$precision);
920             }
921              
922             # If low enough precision, use native floating point. Fast.
923 21 50 33     48 if (defined $precision && $precision <= 13) {
924             return Math::BigFloat->new(
925 0 0       0 ($n < 80) ? do { my $h = 0; $h += 1/$_ for 1..$n; $h; }
  0         0  
  0         0  
  0         0  
926             : log($n) + 0.57721566490153286060651209 + 1/(2*$n) - 1/(12*$n*$n) + 1/(120*$n*$n*$n*$n)
927             ,$precision
928             );
929             }
930              
931 21 50       32 if ($Math::Prime::Util::_GMPfunc{"harmfrac"}) {
932 0         0 my($num,$den) = map { _to_bigint($_) } Math::Prime::Util::GMP::harmfrac($n);
  0         0  
933 0         0 return scalar Math::BigFloat->new($num)->bdiv($den, $precision);
934             }
935              
936 21         117 require Math::Prime::Util::PP;
937 21         65 Math::Prime::Util::PP::harmreal($n, $precision);
938             }
939              
940             #############################################################################
941              
942 69     69   22762 use Math::Prime::Util::MemFree;
  69         218  
  69         4371  
943              
944             1;
945              
946             __END__