File Coverage

blib/lib/Math/Prime/Util.pm
Criterion Covered Total %
statement 384 508 75.5
branch 208 366 56.8
condition 69 159 43.4
subroutine 58 62 93.5
pod 27 27 100.0
total 746 1122 66.4


line stmt bran cond sub pod time code
1             package Math::Prime::Util;
2 48     48   2157242 use strict;
  48         461  
  48         1379  
3 48     48   255 use warnings;
  48         85  
  48         1337  
4 48     48   225 use Carp qw/croak confess carp/;
  48         76  
  48         3075  
5              
6             BEGIN {
7 48     48   148 $Math::Prime::Util::AUTHORITY = 'cpan:DANAJ';
8 48         1060 $Math::Prime::Util::VERSION = '0.68';
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 48     48   270 use base qw( Exporter );
  48         93  
  48         13818  
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
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 105 50   105   659 if ($] < 5.020) { # Prevent "used only once" warnings
86 0         0 my $pkg = caller;
87 48     48   305 no strict 'refs'; ## no critic(strict)
  48         89  
  48         8049  
88 0         0 ${"${pkg}::a"} = ${"${pkg}::a"};
  0         0  
  0         0  
89 0         0 ${"${pkg}::b"} = ${"${pkg}::b"};
  0         0  
  0         0  
90             }
91 105         253 foreach my $opt (qw/nobigint secure/) {
92 210         942 my @options = grep $_ ne "-$opt", @_;
93 210 50       603 $_Config{$opt} = 1 if @options != @_;
94 210         659 @_ = @options;
95             }
96 105 50 33     594 _XS_set_secure() if $_Config{'xs'} && $_Config{'secure'};
97 105         70374 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 48     48   297 use constant OLD_PERL_VERSION=> $] < 5.008;
  48         94  
  48         4204  
108 48     48   293 use constant MPU_MAXBITS => (~0 == 4294967295) ? 32 : 64;
  48         107  
  48         2476  
109 48     48   268 use constant MPU_32BIT => MPU_MAXBITS == 32;
  48         85  
  48         2344  
110 48     48   264 use constant MPU_MAXPARAM => MPU_32BIT ? 4294967295 : 18446744073709551615;
  48         94  
  48         2279  
111 48     48   263 use constant MPU_MAXDIGITS => MPU_32BIT ? 10 : 20;
  48         91  
  48         2270  
112 48     48   254 use constant MPU_MAXPRIME => MPU_32BIT ? 4294967291 : 18446744073709551557;
  48         97  
  48         2166  
113 48     48   263 use constant MPU_MAXPRIMEIDX => MPU_32BIT ? 203280221 : 425656284035217743;
  48         102  
  48         2288  
114 48     48   248 use constant UVPACKLET => MPU_32BIT ? 'L' : 'Q';
  48         104  
  48         2410  
115 48     48   245 use constant INTMAX => (!OLD_PERL_VERSION || MPU_32BIT) ? ~0 : 562949953421312;
  48         87  
  48         16126  
116              
117             eval {
118 48 50 33     339 return 0 if defined $ENV{MPU_NO_XS} && $ENV{MPU_NO_XS} == 1;
119 48         269 require XSLoader;
120 48         52081 XSLoader::load(__PACKAGE__, $Math::Prime::Util::VERSION);
121 48         4385 prime_precalc(0);
122 48         193 $_Config{'maxbits'} = _XS_prime_maxbits();
123 48         96 $_Config{'xs'} = 1;
124 48         220 1;
125 48 50   48   171 } 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 48         115 $_Config{'secure'} = 0;
144 48         99 $_Config{'nobigint'} = 0;
145 48         96 $_Config{'gmp'} = 0;
146             # See if they have the GMP module and haven't requested it not to be used.
147 48 50 33     239 if (!defined $ENV{MPU_NO_GMP} || $ENV{MPU_NO_GMP} != 1) {
148 48 50       107 if (eval { require Math::Prime::Util::GMP;
  48         4574  
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 48         226 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 48 0 33     234982 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 2161     2161 1 49768 my %config = %_Config;
189              
190 2161 100       8682 $config{'precalc_to'} = ($_Config{'xs'})
191             ? _get_prime_cache_size()
192             : Math::Prime::Util::PP::_get_prime_cache_size();
193              
194 2161         6050 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 104123 my %params = (@_); # no defaults
201 20         76 foreach my $param (keys %params) {
202 23         61 my $value = $params{$param};
203 23         65 $param = lc $param;
204             # dispatch table should go here.
205 23 100 66     283 if ($param eq 'xs') {
    100          
    100          
    50          
    50          
    50          
    100          
    50          
206 2 100       8 $_Config{'xs'} = ($value) ? 1 : 0;
207 2 100       8 $_XS_MAXVAL = $_Config{'xs'} ? MPU_MAXPARAM : -1;
208             } elsif ($param eq 'gmp') {
209 2 50       12 $_HAVE_GMP = ($value) ? int(100*$Math::Prime::Util::GMP::VERSION) : 0;
210 2         5 $_Config{'gmp'} = $_HAVE_GMP;
211             $Math::Prime::Util::_GMPfunc{$_} = $_HAVE_GMP
212 2         9 for keys %Math::Prime::Util::_GMPfunc;
213 2 100       12 _XS_set_callgmp($_HAVE_GMP) if $_Config{'xs'};
214             } elsif ($param eq 'nobigint') {
215 2 100       9 $_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       28 $_Config{'assume_rh'} = ($value) ? 1 : 0;
228             } elsif ($param eq 'verbose') {
229 9 50       56 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 100       50 _XS_set_verbose($value) if $_Config{'xs'};
235 9 50       36 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         152 1;
241             }
242              
243             sub _bigint_to_int {
244 18     18   3083 return (OLD_PERL_VERSION) ? unpack(UVPACKLET,pack(UVPACKLET,$_[0]->bstr))
245             : int($_[0]->bstr);
246             }
247             sub _to_bigint {
248 7422 50   7422   44436 do { require Math::BigInt; Math::BigInt->import(try=>"GMP,Pari"); }
  0         0  
  0         0  
249             unless defined $Math::BigInt::VERSION;
250 7422 100 66     115010 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 568 50   568   1240 return unless defined $_[1];
262 568         892 my $ref0 = ref($_[0]);
263 568 100       1054 if ($ref0) {
264 2 50       9 return ($ref0 eq ref($_[1])) ? $_[1] : $ref0->new("$_[1]");
265             }
266 566 50       969 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       1329 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 64     64   1598 my($n, $min, $max) = @_;
284 64 50       166 croak "Parameter must be defined" if !defined $n;
285 64 50       202 if (ref($n) eq 'CODE') {
286 0         0 $_[0] = $_[0]->();
287 0         0 $n = $_[0];
288             }
289 64 100       182 if (ref($n) eq 'Math::BigInt') {
    50          
290 51 50 33     182 croak "Parameter '$n' must be a positive integer"
291             if $n->sign() ne '+' || !$n->is_int();
292 51 50       895 $_[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     60 croak "Parameter '$strn' must be a positive integer"
      33        
299             if $strn eq '' || ($strn =~ tr/0123456789//c && $strn !~ /^\+?\d+$/);
300 13 100       37 if ($n <= INTMAX) {
301 7 50       14 $_[0] = $strn if ref($n);
302             } else {
303             #$_[0] = Math::BigInt->new($strn)
304 6         23 $_[0] = _to_bigint($strn);
305             }
306             }
307 64 50 66     6461 $_[0]->upgrade(undef) if ref($_[0]) eq 'Math::BigInt' && $_[0]->upgrade();
308 64 50 33     750 croak "Parameter '$_[0]' must be >= $min" if defined $min && $_[0] < $min;
309 64 50 33     153 croak "Parameter '$_[0]' must be <= $max" if defined $max && $_[0] > $max;
310 64         96 1;
311             }
312              
313             #############################################################################
314              
315             sub primes {
316 1153     1153 1 31541 my($low,$high) = @_;
317 1153 100       1924 if (scalar @_ > 1) {
318 117 100       626 _validate_num($low) || _validate_positive_integer($low);
319             } else {
320 1036         1492 ($low,$high) = (2, $low);
321             }
322 1146 100       2479 _validate_num($high) || _validate_positive_integer($high);
323              
324 1138         1466 my $sref = [];
325 1138 100 100     3020 return $sref if ($low > $high) || ($high < 2);
326              
327 1128 100       1724 if ($high > $_XS_MAXVAL) {
328 1 50       106 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         10 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 1127 100 66     3440 if (($low+1) >= $high || # Tiny range, or
    100 100        
      100        
349             $high > 10**14 && ($high-$low) < 50000) { # Small relative range
350              
351 18         310 $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 1102         48196 $sref = sieve_primes($low, $high);
357              
358             } else {
359              
360 7         15449 $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 1127         11635 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 7644 my($low,$high) = @_;
375 20 100       55 if (scalar @_ > 1) {
376 18 100       77 _validate_num($low) || _validate_positive_integer($low);
377             } else {
378 2         6 ($low,$high) = (2, $low);
379             }
380 20 100       76 _validate_num($high) || _validate_positive_integer($high);
381              
382 20 50 33     95 return [] if ($low > $high) || ($high < 2);
383              
384 20 100       177 if ($high > $_XS_MAXVAL) {
385 3         109 my @tp;
386 3 50 33     28 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         30 require Math::Prime::Util::PP;
390 3         18 @tp = map { _reftyped($_[0],$_) } Math::Prime::Util::PP::sieve_prime_cluster($low,$high, 2);
  566         1018  
391             }
392 3         49 return \@tp;
393             }
394              
395 17         2763 return segment_twin_primes($low, $high);
396             }
397              
398             sub ramanujan_primes {
399 15     15 1 6223 my($low,$high) = @_;
400 15 100       38 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       44 _validate_num($high) || _validate_positive_integer($high);
406              
407 15 50 33     67 return [] if ($low > $high) || ($high < 2);
408              
409 15 50       28 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         468 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 2769 my($bits) = @_;
422 1 50       13 _validate_num($bits, 2) || _validate_positive_integer($bits, 2);
423              
424 1 50       4 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         351 require Math::Prime::Util::RandomPrimes;
430 1         4 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 422 my($bits) = @_;
435 1 50       7 _validate_num($bits, 2) || _validate_positive_integer($bits, 2);
436              
437 1 50       5 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         9 require Math::Prime::Util::RandomPrimes;
443 1         7 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 891 my($bits) = @_;
448 1 50       10 _validate_num($bits, 2) || _validate_positive_integer($bits, 2);
449              
450             # Go to Maurer with GMP
451 1 50       6 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         13 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 19718 my($n) = @_;
468 35 50       168 _validate_num($n) || _validate_positive_integer($n);
469 35 100       116 return (1,1,2,6,6,30,30,210,210,210)[$n] if $n < 10;
470              
471 30 50 33     73 if ($_HAVE_GMP && defined &Math::Prime::Util::GMP::primorial) {
472 0         0 return _reftyped($_[0], Math::Prime::Util::GMP::primorial($n));
473             }
474 30         1085 require Math::Prime::Util::PP;
475 30         72 return Math::Prime::Util::PP::primorial($n);
476             }
477              
478             sub pn_primorial {
479 36     36 1 77 my($n) = @_;
480 36 50       132 _validate_num($n) || _validate_positive_integer($n);
481 36 100       277 return (1,2,6,30,210,2310,30030,510510,9699690,223092870)[$n] if $n < 10;
482              
483 25 50 33     59 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         113 require Math::Prime::Util::PP;
488 25         120 return Math::Prime::Util::PP::primorial(nth_prime($n));
489             }
490              
491             sub consecutive_integer_lcm {
492 104     104 1 46576 my($n) = @_;
493 104 50       355 _validate_num($n) || _validate_positive_integer($n);
494 104 100       190 return 0 if $n < 1;
495              
496 103 50 33     243 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         1269 require Math::Prime::Util::PP;
500 103         236 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 26755 my($n) = @_;
512 58 100 66     241 return 1 if defined $n && $n <= 0;
513 57 50       197 _validate_num($n) || _validate_positive_integer($n);
514              
515 57 50 33     113 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         1171 require Math::Prime::Util::PP;
520 57         141 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   5 my($sub, $beg, $end) = @_;
529 1 50       3 if (!defined $end) { $end = $beg; $beg = 2; }
  0         0  
  0         0  
530 1         6 _validate_positive_integer($beg);
531 1         3 _validate_positive_integer($end);
532 1 50       3 $beg = 2 if $beg < 2;
533 1         7 my $oldforexit = Math::Prime::Util::_start_for_loop();
534             {
535 1         2 my $pp;
  1         3  
536 1         3 local *_ = \$pp;
537 1         15 for (my $p = next_prime($beg-1); $p <= $end; $p = next_prime($p)) {
538 7         10 $pp = $p;
539 7         15 $sub->();
540 7 50       44 last if Math::Prime::Util::_get_forexit();
541             }
542             }
543 1         5 Math::Prime::Util::_end_for_loop($oldforexit);
544             }
545              
546             sub _generic_forcomposites {
547 1     1   565 my($sub, $beg, $end) = @_;
548 1 50       5 if (!defined $end) { $end = $beg; $beg = 4; }
  0         0  
  0         0  
549 1         5 _validate_positive_integer($beg);
550 1         4 _validate_positive_integer($end);
551 1 50       4 $beg = 4 if $beg < 4;
552 1 50 33     8 $end = Math::BigInt->new(''.~0) if ref($end) ne 'Math::BigInt' && $end == ~0;
553 1         6 my $oldforexit = Math::Prime::Util::_start_for_loop();
554             {
555 1         2 my $pp;
  1         2  
556 1         4 local *_ = \$pp;
557 1         15 for (my $p = next_prime($beg-1); $beg <= $end; $p = next_prime($p)) {
558 5   100     17 for ( ; $beg < $p && $beg <= $end ; $beg++ ) {
559 8         10 $pp = $beg;
560 8         15 $sub->();
561 8 50       37 last if Math::Prime::Util::_get_forexit();
562             }
563 5         6 $beg++;
564 5 50       25 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   506 my($sub, $beg, $end) = @_;
572 1 50       5 if (!defined $end) { $end = $beg; $beg = 9; }
  0         0  
  0         0  
573 1         4 _validate_positive_integer($beg);
574 1         3 _validate_positive_integer($end);
575 1 50       4 $beg = 9 if $beg < 9;
576 1 50       4 $beg++ unless $beg & 1;
577 1 50 33     7 $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         2 local *_ = \$pp;
582 1         9 for (my $p = next_prime($beg-1); $beg <= $end; $p = next_prime($p)) {
583 5   100     19 for ( ; $beg < $p && $beg <= $end ; $beg += 2 ) {
584 2         3 $pp = $beg;
585 2         5 $sub->();
586 2 50       10 last if Math::Prime::Util::_get_forexit();
587             }
588 5         10 $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   433 my($sub, $n) = @_;
597 1         3 _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         2  
602 1         3 local *_ = \$pp;
603 1         3 foreach my $d (@divisors) {
604 16         17 $pp = $d;
605 16         25 $sub->();
606 16 50       46 last if Math::Prime::Util::_get_forexit();
607             }
608             }
609 1         4 Math::Prime::Util::_end_for_loop($oldforexit);
610             }
611              
612             sub formultiperm (&$) { ## no critic qw(ProhibitSubroutinePrototypes)
613 5     5 1 142626 my($sub, $iref) = @_;
614 5 50       31 croak("formultiperm first argument must be an array reference") unless ref($iref) eq 'ARRAY';
615              
616 5         18 my($sum, %h, @n) = (0);
617 5         27 $h{$_}++ for @$iref;
618 5         34 @n = map { [$_, $h{$_}] } sort(keys(%h));
  11         33  
619 5         36 $sum += $_->[1] for @n;
620              
621 5         52 require Math::Prime::Util::PP;
622 5         24 my $oldforexit = Math::Prime::Util::_start_for_loop();
623 5         35 Math::Prime::Util::PP::_multiset_permutations( $sub, [], \@n, $sum );
624 5         29 Math::Prime::Util::_end_for_loop($oldforexit);
625             }
626              
627             #############################################################################
628             # Iterators
629              
630             sub prime_iterator {
631 26     26 1 23939 my($start) = @_;
632 26 100       55 $start = 0 unless defined $start;
633 26 100       92 _validate_num($start) || _validate_positive_integer($start);
634 23 100       100 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     383 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         31 my $pr = [];
642             return sub {
643 88 100   88   408 if (scalar(@$pr) == 0) {
644             # Once we're into bigints, just use next_prime
645 22 50       33 return $p=next_prime($p) if $p >= MPU_MAXPRIME;
646             # Get about 10k primes
647 22 100       46 my $segment = ($p <= 1e4) ? 10_000 : int(10000*log($p)+1);
648 22 50 33     39 $segment = ~0-$p if $p+$segment > ~0 && $p+1 < ~0;
649 22         44 $pr = primes($p+1, $p+$segment);
650             }
651 88         176 return $p = shift(@$pr);
652 22         97 };
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         9 require Math::Prime::Util::PP;
657 3     3   24 return sub { $p = Math::Prime::Util::PP::next_prime($p); return $p; }
  3         32  
658 1         8 }
659             }
660              
661             sub prime_iterator_object {
662 11     11 1 3606 my($start) = @_;
663 11         678 require Math::Prime::Util::PrimeIterator;
664 11         46 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   1601 my($low,$high) = @_;
676 1 50       5 if (defined $high) {
677 1 50       4 _validate_num($low) || _validate_positive_integer($low);
678 1 50       7 _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     5 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     176 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         12 require Math::Prime::Util::PP;
692 1         8 return Math::Prime::Util::PP::prime_count($low,$high);
693             }
694              
695             sub _generic_factor {
696 26     26   7286 my($n) = @_;
697 26 50       105 _validate_num($n) || _validate_positive_integer($n);
698              
699 26 50       89 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 26         162 require Math::Prime::Util::PP;
714 26         101 return Math::Prime::Util::PP::factor($n);
715             }
716              
717             sub _generic_factor_exp {
718 13     13   397 my($n) = @_;
719 13 50       62 _validate_num($n) || _validate_positive_integer($n);
720              
721 13         22 my %exponents;
722 13         53 my @factors = grep { !$exponents{$_}++ } factor($n);
  444         1085  
723 13 50       95 return scalar @factors unless wantarray;
724 13         30 return (map { [$_, $exponents{$_}] } @factors);
  221         404  
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 11 my($n) = @_;
741 4         9 my ($is_prime, $cert) = is_provable_prime_with_cert($n);
742 4         16 return $cert;
743             }
744              
745              
746             sub is_provable_prime_with_cert {
747 125     125 1 3281 my($n) = @_;
748 125 50 33     799 return 0 if defined $n && $n < 2;
749 125 100       12860 _validate_num($n) || _validate_positive_integer($n);
750 125         5158 my $header = "[MPU - Primality Certificate]\nVersion 1.0\n\nProof for:\nN $n\n\n";
751              
752 125 100       709 if ($n <= $_XS_MAXVAL) {
753 114         660 my $isp = is_prime($n);
754 114 100       371 return ($isp, '') unless $isp == 2;
755 84         483 return (2, $header . "Type Small\nN $n\n");
756             }
757              
758 11 50 33     1578 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         27 my $isp = is_prob_prime($n);
  11         68  
774 11 50       1615 return ($isp, '') if $isp == 0;
775 11 50       43 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         1010 require Math::Prime::Util::PrimalityProving;
792             #my ($isp, $pref) = Math::Prime::Util::PrimalityProving::primality_proof_lucas($n);
793 11         83 my ($isp, $pref) = Math::Prime::Util::PrimalityProving::primality_proof_bls75($n);
794 11 50       42 carp "proved $n is not prime\n" if !$isp;
795 11         64 return ($isp, $pref);
796             }
797              
798              
799             sub verify_prime {
800 50     50 1 17561 require Math::Prime::Util::PrimalityProving;
801 50         190 return Math::Prime::Util::PrimalityProving::verify_cert(@_);
802             }
803              
804             #############################################################################
805              
806             sub RiemannZeta {
807 6     6 1 2780 my($n) = @_;
808 6 50       22 croak("Invalid input to ReimannZeta: x must be > 0") if $n <= 0;
809              
810 6 50       11 return $n-$n if $n > 10_000_000; # Over 3M leading zeros
811              
812             return _XS_RiemannZeta($n)
813 6 50 33     83 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 5216 my($n) = @_;
821 11 100       183 croak("Invalid input to ReimannR: x must be > 0") if $n <= 0;
822              
823             return _XS_RiemannR($n)
824 9 50 33     224 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 7678 my($n) = @_;
832 23 100       81 return $_Neg_Infinity if $n == 0;
833 22 100       54 return 0 if $n == $_Neg_Infinity;
834 21 100       41 return $_Infinity if $n == $_Infinity;
835              
836             return _XS_ExponentialIntegral($n)
837 20 100 33     290 if !defined $bignum::VERSION && ref($n) ne 'Math::BigFloat' && $_Config{'xs'};
      66        
838              
839 2         30 require Math::Prime::Util::PP;
840 2         12 return Math::Prime::Util::PP::ExponentialIntegral($n);
841             }
842              
843             sub LogarithmicIntegral {
844 28     28 1 6216 my($n) = @_;
845 28 100       69 return 0 if $n == 0;
846 26 100       50 return $_Neg_Infinity if $n == 1;
847 25 100       49 return $_Infinity if $n == $_Infinity;
848              
849 24 100       170 croak("Invalid input to LogarithmicIntegral: x must be >= 0") if $n <= 0;
850              
851 23 50 33     132 if (!defined $bignum::VERSION && ref($n) ne 'Math::BigFloat' && $_Config{'xs'}) {
      33        
852 23 100       50 return 1.045163780117492784844588889194613136522615578151 if $n == 2;
853 22         160 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 4148 my($x) = @_;
862              
863             return _XS_LambertW($x)
864 9 50 33     133 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 3574 my($n) = @_;
874 116 50 33     815 return map { _to_bigint($_) } (0,1) if defined $n && $n < 0;
  0         0  
875 116 50       750 _validate_num($n) || _validate_positive_integer($n);
876 116 100 100     692 return map { _to_bigint($_) } (0,1) if $n > 1 && ($n & 1);
  22         1026  
877              
878 105 50       402 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         2277 require Math::Prime::Util::PP;
883 105         323 return Math::Prime::Util::PP::bernfrac($n);
884             }
885             sub bernreal {
886 26     26 1 54511 my($n, $precision) = @_;
887 26 100       77 do { require Math::BigFloat; Math::BigFloat->import(); } unless defined $Math::BigFloat::VERSION;
  1         727  
  1         41537  
888              
889 26 50       17620 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         62 my($num,$den) = bernfrac($n);
895 26 100       422 return Math::BigFloat->bzero if $num->is_zero;
896 15         206 scalar Math::BigFloat->new($num)->bdiv($den, $precision);
897             }
898              
899             sub harmfrac {
900 79     79 1 23958 my($n) = @_;
901 79 50       442 _validate_num($n) || _validate_positive_integer($n);
902 79 50       195 return map { _to_bigint($_) } (0,1) if $n <= 0;
  0         0  
903              
904 79 50       254 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         765 require Math::Prime::Util::PP;
909 79         533 Math::Prime::Util::PP::harmfrac($n);
910             }
911             sub harmreal {
912 22     22 1 59486 my($n, $precision) = @_;
913 22 50       154 _validate_num($n) || _validate_positive_integer($n);
914 22 50       63 do { require Math::BigFloat; Math::BigFloat->import(); } unless defined $Math::BigFloat::VERSION;
  0         0  
  0         0  
915 22 100       77 return Math::BigFloat->bzero if $n <= 0;
916              
917 21 50       72 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     65 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       47 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         181 require Math::Prime::Util::PP;
937 21         81 Math::Prime::Util::PP::harmreal($n, $precision);
938             }
939              
940             #############################################################################
941              
942 48     48   16926 use Math::Prime::Util::MemFree;
  48         136  
  48         3161  
943              
944             1;
945              
946             __END__