File Coverage

blib/lib/Math/Prime/Util.pm
Criterion Covered Total %
statement 260 370 70.2
branch 142 260 54.6
condition 48 99 48.4
subroutine 47 53 88.6
pod 18 18 100.0
total 515 800 64.3


line stmt bran cond sub pod time code
1             package Math::Prime::Util;
2 121     121   14973197 use strict;
  121         313  
  121         5420  
3 121     121   1393 use warnings;
  121         307  
  121         8427  
4 121     121   826 use Carp qw/croak confess carp/;
  121         315  
  121         11718  
5              
6             BEGIN {
7 121     121   443 $Math::Prime::Util::AUTHORITY = 'cpan:DANAJ';
8 121         3994 $Math::Prime::Util::VERSION = '0.74';
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 121     121   1010 use base qw( Exporter );
  121         325  
  121         87301  
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_delicate_prime is_chen_prime
30             is_odd is_even is_divisible is_congruent
31             is_power is_prime_power is_perfect_power is_square
32             is_square_free is_powerfree
33             is_pillai is_polygonal is_congruent_number is_perfect_number
34             is_semiprime is_almost_prime is_omega_prime
35             is_primitive_root is_carmichael is_quasi_carmichael is_cyclic
36             is_fundamental is_totient is_gaussian_prime is_sum_of_squares
37             is_smooth is_rough is_powerful is_practical is_lucky is_happy
38             sqrtint rootint logint lshiftint rshiftint rashiftint absint negint
39             signint cmpint addint subint add1int sub1int mulint powint
40             divint modint cdivint divrem fdivrem cdivrem tdivrem
41             miller_rabin_random
42             lucas_sequence
43             lucasu lucasv lucasuv lucasumod lucasvmod lucasuvmod pisano_period
44             primes twin_primes semi_primes almost_primes omega_primes ramanujan_primes
45             sieve_prime_cluster sieve_range prime_powers lucky_numbers
46             forprimes forcomposites foroddcomposites forsemiprimes foralmostprimes
47             forpart forcomp forcomb forperm forderange formultiperm forsetproduct
48             fordivisors forfactored forsquarefree forsquarefreeint
49             lastfor
50             numtoperm permtonum randperm shuffle vecsample
51             prime_iterator prime_iterator_object
52             next_prime prev_prime
53             next_prime_power prev_prime_power
54             next_perfect_power prev_perfect_power
55             next_chen_prime
56             prime_count prime_count_lower prime_count_upper prime_count_approx
57             nth_prime nth_prime_lower nth_prime_upper nth_prime_approx
58             inverse_li inverse_li_nv
59             twin_prime_count twin_prime_count_approx
60             nth_twin_prime nth_twin_prime_approx
61             semiprime_count semiprime_count_approx
62             nth_semiprime nth_semiprime_approx
63             almost_prime_count almost_prime_count_approx
64             almost_prime_count_lower almost_prime_count_upper
65             nth_almost_prime nth_almost_prime_approx
66             nth_almost_prime_lower nth_almost_prime_upper
67             omega_prime_count nth_omega_prime
68             ramanujan_prime_count ramanujan_prime_count_approx
69             ramanujan_prime_count_lower ramanujan_prime_count_upper
70             nth_ramanujan_prime nth_ramanujan_prime_approx
71             nth_ramanujan_prime_lower nth_ramanujan_prime_upper
72             powerful_count nth_powerful sumpowerful powerful_numbers
73             prime_power_count prime_power_count_approx
74             prime_power_count_lower prime_power_count_upper
75             nth_prime_power nth_prime_power_approx
76             nth_prime_power_lower nth_prime_power_upper
77             perfect_power_count perfect_power_count_approx
78             perfect_power_count_lower perfect_power_count_upper
79             nth_perfect_power nth_perfect_power_approx
80             nth_perfect_power_lower nth_perfect_power_upper
81             nth_powerfree powerfree_count powerfree_sum squarefree_kernel
82             powerfree_part powerfree_part_sum
83             smooth_count rough_count powersum
84             lucky_count lucky_count_approx lucky_count_lower lucky_count_upper
85             nth_lucky nth_lucky_approx nth_lucky_lower nth_lucky_upper
86             minimal_goldbach_pair goldbach_pairs goldbach_pair_count
87             sum_primes print_primes
88             random_prime random_ndigit_prime
89             random_nbit_prime random_safe_prime random_strong_prime
90             random_proven_prime random_proven_prime_with_cert
91             random_maurer_prime random_maurer_prime_with_cert
92             random_shawe_taylor_prime random_shawe_taylor_prime_with_cert
93             random_semiprime random_unrestricted_semiprime
94             random_factored_integer
95             primorial pn_primorial consecutive_integer_lcm gcdext chinese chinese2
96             gcd lcm factor factor_exp divisors valuation hammingweight
97             frobenius_number
98             todigits fromdigits todigitstring sumdigits
99             tozeckendorf fromzeckendorf
100             sqrtmod allsqrtmod rootmod allrootmod cornacchia
101             negmod invmod addmod submod mulmod divmod powmod muladdmod mulsubmod
102             vecsum vecmin vecmax vecprod vecreduce vecextract vecequal vecuniq
103             vecany vecall vecnotall vecnone vecfirst vecfirstidx vecmex vecpmex
104             vecsort vecsorti vecfreq vecsingleton vecslide
105             setbinop sumset toset
106             setunion setintersect setminus setdelta
107             setcontains setcontainsany setinsert setremove setinvert
108             is_sidon_set is_sumfree_set
109             set_is_disjoint set_is_equal set_is_proper_intersection
110             set_is_subset set_is_proper_subset set_is_superset set_is_proper_superset
111             moebius mertens liouville sumliouville prime_omega prime_bigomega
112             euler_phi jordan_totient exp_mangoldt sumtotient
113             partitions bernfrac bernreal harmfrac harmreal
114             chebyshev_theta chebyshev_psi
115             divisor_sum carmichael_lambda hclassno inverse_totient
116             kronecker is_qr qnr
117             ramanujan_tau ramanujan_sum
118             stirling fubini znorder znprimroot znlog legendre_phi
119             factorial factorialmod subfactorial binomial binomialmod
120             falling_factorial rising_factorial
121             contfrac from_contfrac
122             next_calkin_wilf next_stern_brocot
123             calkin_wilf_n stern_brocot_n
124             nth_calkin_wilf nth_stern_brocot
125             nth_stern_diatomic
126             farey next_farey farey_rank
127             ExponentialIntegral LogarithmicIntegral RiemannZeta RiemannR LambertW Pi
128             irand irand64 drand urandomb urandomm csrand random_bytes entropy_bytes
129             );
130             our %EXPORT_TAGS = (all => [ @EXPORT_OK ],
131             rand => [qw/srand rand irand irand64/],
132             );
133              
134             # These are only exported if specifically asked for
135             push @EXPORT_OK, (qw/trial_factor fermat_factor holf_factor lehman_factor squfof_factor prho_factor pbrent_factor pminus1_factor pplus1_factor cheb_factor ecm_factor rand srand/);
136              
137             my %_Config;
138             my %_GMPfunc; # Available MPU::GMP functions
139              
140             # Similar to how boolean handles its option
141             sub import {
142 132 50   132   1853 if ($] < 5.020) { # Prevent "used only once" warnings
143 0         0 my $pkg = caller;
144 121     121   1091 no strict 'refs'; ## no critic(strict)
  121         282  
  121         42187  
145 0         0 ${"${pkg}::a"} = ${"${pkg}::a"};
  0         0  
  0         0  
146 0         0 ${"${pkg}::b"} = ${"${pkg}::b"};
  0         0  
  0         0  
147             }
148 132         498 foreach my $opt (qw/nobigint secure/) {
149 264         1883 my @options = grep $_ ne "-$opt", @_;
150 264 50       857 $_Config{$opt} = 1 if @options != @_;
151 264         1209 @_ = @options;
152             }
153 132 50 66     889 _XS_set_secure() if $_Config{'xs'} && $_Config{'secure'};
154 132         349506 goto &Exporter::import;
155             }
156              
157             #############################################################################
158              
159              
160             BEGIN {
161              
162             # Separate lines to keep compatible with default from 5.6.2.
163             # We could alternately use Config's $Config{uvsize} for MAXBITS
164 121     121   1025 use constant OLD_PERL_VERSION=> $] < 5.008;
  121         260  
  121         16865  
165 121     121   905 use constant MPU_MAXBITS => (~0 == 4294967295) ? 32 : 64;
  121         620  
  121         8850  
166 121     121   969 use constant MPU_32BIT => MPU_MAXBITS == 32;
  121         303  
  121         7987  
167 121     121   745 use constant MPU_MAXPARAM => MPU_32BIT ? 4294967295 : 18446744073709551615;
  121         308  
  121         7583  
168 121     121   762 use constant MPU_MAXDIGITS => MPU_32BIT ? 10 : 20;
  121         351  
  121         7573  
169 121     121   715 use constant MPU_MAXPRIME => MPU_32BIT ? 4294967291 : 18446744073709551557;
  121         287  
  121         7046  
170 121     121   722 use constant MPU_MAXPRIMEIDX => MPU_32BIT ? 203280221 : 425656284035217743;
  121         319  
  121         11672  
171 121     121   720 use constant UVPACKLET => MPU_32BIT ? 'L' : 'Q';
  121         333  
  121         8364  
172 121     121   2285 use constant INTMAX => (!OLD_PERL_VERSION || MPU_32BIT) ? ~0 : 562949953421312;
  121         751  
  121         8352  
173 121     121   837 use constant INTMIN => -(INTMAX >> 1) - 1;
  121         279  
  121         61623  
174              
175             eval {
176 121 100 66     1035 return 0 if defined $ENV{MPU_NO_XS} && $ENV{MPU_NO_XS} == 1;
177 120         844 require XSLoader;
178 120         621765 XSLoader::load(__PACKAGE__, $Math::Prime::Util::VERSION);
179 120         19970 prime_precalc(0);
180 120         756 $_Config{'maxbits'} = _XS_prime_maxbits();
181 120         285 $_Config{'xs'} = 1;
182 120         733 1;
183 121 100   121   501 } or do {
184             carp "Using Pure Perl implementation: $@"
185 1 50 33     5 unless defined $ENV{MPU_NO_XS} && $ENV{MPU_NO_XS} == 1;
186              
187 1         2 $_Config{'xs'} = 0;
188 1         2 $_Config{'maxbits'} = MPU_MAXBITS;
189              
190             # Load PP front end code
191 1         849 require Math::Prime::Util::PPFE;
192              
193             # Init rand
194 1         7 Math::Prime::Util::csrand();
195             };
196              
197 121         272 $_Config{'secure'} = 0;
198 121         266 $_Config{'nobigint'} = 0;
199 121         296 $_Config{'gmp'} = 0;
200             # See if they have the GMP module and haven't requested it not to be used.
201 121 100 66     918 if (!defined $ENV{MPU_NO_GMP} || $ENV{MPU_NO_GMP} != 1) {
202 120 50       369 if (eval { require Math::Prime::Util::GMP;
  120         18982  
203 0         0 Math::Prime::Util::GMP->import();
204 0         0 1; }) {
205 0         0 $_Config{'gmp'} = int(100 * $Math::Prime::Util::GMP::VERSION + 1e-6);
206             }
207 120         526 for my $e (@Math::Prime::Util::GMP::EXPORT_OK) {
208 0         0 $Math::Prime::Util::_GMPfunc{"$e"} = $_Config{'gmp'};
209             }
210             # If we have GMP, it is not seeded properly but we are, seed with our data.
211 120 0 33     802 if ( $_Config{'gmp'} >= 42
      33        
212             && !Math::Prime::Util::GMP::is_csprng_well_seeded()
213             && Math::Prime::Util::_is_csprng_well_seeded()) {
214 0         0 Math::Prime::Util::GMP::seed_csprng(256, random_bytes(256));
215             }
216             }
217              
218             # Alias PP and GMP if requested. Very convenient but a big hammer.
219 121 50 33     669675 if (defined $ENV{MPU_DEVNAMES} && $ENV{MPU_DEVNAMES} == 1) {
220 121     121   1003 no strict 'refs'; ## no critic(strict)
  121         265  
  121         19037  
221 0         0 *MPU:: = \*Math::Prime::Util::;
222 0 0       0 *PP:: = \*Math::Prime::Util::PP:: if eval { require Math::Prime::Util::PP; Math::Prime::Util::PP->import(); 1; };
  0         0  
  0         0  
  0         0  
223 0 0       0 *GMP:: = \*Math::Prime::Util::GMP:: if $_Config{'gmp'};
224             }
225             }
226              
227             croak "Perl and XS don't agree on bit size"
228             if $_Config{'xs'} && MPU_MAXBITS != _XS_prime_maxbits();
229              
230             $_Config{'maxparam'} = MPU_MAXPARAM;
231             $_Config{'maxdigits'} = MPU_MAXDIGITS;
232             $_Config{'maxprime'} = MPU_MAXPRIME;
233             $_Config{'maxprimeidx'} = MPU_MAXPRIMEIDX;
234             $_Config{'assume_rh'} = 0;
235             $_Config{'verbose'} = 0;
236             $_Config{'bigintclass'} = undef;
237              
238             # used for code like:
239             # return _XS_foo($n) if $n <= $_XS_MAXVAL
240             # which builds into one scalar whether XS is available and if we can call it.
241             my $_XS_MAXVAL = $_Config{'xs'} ? MPU_MAXPARAM : -1;
242             my $_HAVE_GMP = $_Config{'gmp'};
243             _XS_set_callgmp($_HAVE_GMP) if $_Config{'xs'};
244              
245             our $_BIGINT = $_Config{'bigintclass'};
246              
247             # Infinity in Perl is rather O/S specific.
248             our $_Infinity = 0+'inf';
249             $_Infinity = 20**20**20 if 65535 > $_Infinity; # E.g. Windows
250             our $_Neg_Infinity = -$_Infinity;
251              
252             sub prime_get_config {
253 2312     2312 1 13186568 my %config = %_Config;
254              
255 2312 100       15453 $config{'precalc_to'} = ($_Config{'xs'})
256             ? _get_prime_cache_size()
257             : Math::Prime::Util::PP::_get_prime_cache_size();
258              
259 2312         9094 return \%config;
260             }
261              
262             # Note: You can cause yourself pain if you turn on xs or gmp when they're not
263             # loaded. Your calls will probably die horribly.
264             sub prime_set_config {
265 19     19 1 75174 my %params = (@_); # no defaults
266 19         87 foreach my $param (keys %params) {
267 19         69 my $value = $params{$param};
268 19         77 $param = lc $param;
269             # dispatch table should go here.
270 19 50 33     520 if ($param eq 'xs') {
    50 66        
    100          
    50          
    50          
    50          
    50          
    100          
    50          
271 0 0       0 $_Config{'xs'} = ($value) ? 1 : 0;
272 0 0       0 $_XS_MAXVAL = $_Config{'xs'} ? MPU_MAXPARAM : -1;
273             } elsif ($param eq 'gmp') {
274 0 0       0 $_HAVE_GMP = ($value) ? int(100*$Math::Prime::Util::GMP::VERSION) : 0;
275 0         0 $_Config{'gmp'} = $_HAVE_GMP;
276             $Math::Prime::Util::_GMPfunc{$_} = $_HAVE_GMP
277 0         0 for keys %Math::Prime::Util::_GMPfunc;
278 0 0       0 _XS_set_callgmp($_HAVE_GMP) if $_Config{'xs'};
279             } elsif ($param eq 'nobigint') {
280 2 100       11 $_Config{'nobigint'} = ($value) ? 1 : 0;
281             } elsif ($param eq 'bigint' || $param eq 'trybigint') {
282 0         0 my $class = _load_bigint_class($value);
283 0 0       0 if (defined $class) {
284 0         0 $_BIGINT = $_Config{'bigintclass'} = $class;
285             } else {
286 0 0       0 carp "ntheory could not load bigint class from '$value'"
287             unless $param =~ /try/;
288             }
289             } elsif ($param eq 'secure') {
290 0 0 0     0 croak "Cannot disable secure once set" if !$value && $_Config{'secure'};
291 0 0       0 if ($value) {
292 0         0 $_Config{'secure'} = 1;
293 0 0       0 _XS_set_secure() if $_Config{'xs'};
294             }
295             } elsif ($param eq 'irand') {
296 0         0 carp "ntheory irand option is deprecated";
297             } elsif ($param eq 'use_primeinc') {
298 0         0 carp "ntheory use_primeinc option is deprecated";
299             } elsif ($param =~ /^(assume[_ ]?)?[ge]?rh$/ || $param =~ /riemann\s*h/) {
300 9 100       57 $_Config{'assume_rh'} = ($value) ? 1 : 0;
301             } elsif ($param eq 'verbose') {
302 8 50       64 if ($value =~ /^\d+$/) { }
    0          
    0          
303 0         0 elsif ($value =~ /^[ty]/i) { $value = 1; }
304 0         0 elsif ($value =~ /^[fn]/i) { $value = 0; }
305 0         0 else { croak("Invalid setting for verbose. 0, 1, 2, etc."); }
306 8         27 $_Config{'verbose'} = $value;
307 8 50       65 _XS_set_verbose($value) if $_Config{'xs'};
308 8 50       45 Math::Prime::Util::GMP::_GMP_set_verbose($value) if $_Config{'gmp'};
309             } else {
310 0         0 croak "Unknown or invalid configuration setting: $param\n";
311             }
312             }
313 19         231 1;
314             }
315              
316             # Input: object, or comma separated list of class names
317             # Output: class name or undef
318             sub _load_bigint_class {
319 0     0   0 my($val) = @_;
320              
321 0         0 my $class = undef;
322 0 0       0 if (ref($val)) { # We are given an object, e.g. a Math::GMPz number
323 0         0 $class = ref($val);
324             } else { # Comma separated list of class names
325 0         0 for my $name (split /,/, $val) {
326 0         0 $name =~ s/^\s+|\s+$//g;
327 0         0 (my $cfname="$name.pm")=~s|::|/|g; # Foo::Bar::Baz => Foo/Bar/Baz.pm
328 0 0 0     0 if ($INC{$cfname} || eval { require $cfname; $name->import(); 1; }) {
  0         0  
  0         0  
  0         0  
329 0         0 $class = $name;
330 0         0 last;
331             }
332             }
333             }
334 0 0       0 if ($class) { # Check we can make a number with it
335 0 0       0 $class = undef unless eval { $class->new(1) == 1 };
  0         0  
336             }
337 0         0 return $class;
338             }
339              
340             # This is for loading the default bigint class the very first time.
341             sub _load_bigint {
342 70 50   70   266 return $_BIGINT if defined $_BIGINT;
343              
344             # TODO: turn this on for next release
345             #prime_set_config( trybigint => 'Math::GMPz,Math::GMP' );
346             #return $_BIGINT if defined $_BIGINT;
347              
348 70 100       296 do { require Math::BigInt; Math::BigInt->import(try=>"GMP,GMPz,LTM,Pari"); } unless defined $Math::BigInt::VERSION;
  3         7695  
  3         140479  
349 70         89993 $_BIGINT = $_Config{'bigintclass'} = 'Math::BigInt';
350             }
351              
352             sub _bigint_to_int {
353 54013     54013   13053892 return (OLD_PERL_VERSION && $_[0] >= 0) ? unpack(UVPACKLET,pack(UVPACKLET,"$_[0]"))
354             : int("$_[0]");
355             }
356             sub _to_bigint {
357 60295 50   60295   5142575 return undef unless defined($_[0]);
358 60295 100       148984 _load_bigint() unless defined $_BIGINT;
359             # We don't do any validation other than that the class is happy.
360 60295         108490 my $n;
361 60295 100 66     345271 if (ref($_[0]) eq $_BIGINT) {
    50 33        
    50          
362 2805         10117 $n = $_[0];
363             } elsif (ref($_[0]) eq 'Math::BigFloat' && !$_[0]->is_int()) {
364 0         0 $n = Math::BigInt->bnan;
365             } elsif ($_BIGINT eq 'Math::Pari' && $_[0] =~ /^0[bx]/) {
366             # Pari added support for this in 2.8, so not in Math::Pari
367 0 0       0 do { require Math::BigInt; Math::BigInt->import(try=>"GMP,GMPz,LTM,Pari"); } unless defined $Math::BigInt::VERSION;
  0         0  
  0         0  
368 0         0 $n = Math::BigInt->new("$_[0]");
369 0         0 $n = $_BIGINT->new("$n");
370             } else {
371 57490         296989 $n = $_BIGINT->new("$_[0]");
372             }
373 60295 50 33     6023863 croak "Parameter '$_[0]' must be an integer" unless $_BIGINT ne 'Math::BigInt' || $n->is_int();
374 60295         856837 $n;
375             }
376             sub _to_bigint_nonneg {
377 49 50   49   231 return undef unless defined($_[0]);
378 49 100       199 _load_bigint() unless defined $_BIGINT;
379 49         98 my $n;
380 49 50 100     342 if (ref($_[0]) eq $_BIGINT) {
    100          
381 0         0 $n = $_[0];
382             } elsif (ref($_[0]) eq 'Math::BigFloat' && !$_[0]->is_int()) {
383 1         24 $n = Math::BigInt->bnan;
384             } else {
385 48         365 $n = $_BIGINT->new("$_[0]");
386             }
387 49 100 66     7167 croak "Parameter '$_[0]' must be a non-negative integer" unless ($_BIGINT ne 'Math::BigInt' || $n->is_int()) && $n >= 0;
      66        
388 48         13454 $n;
389             }
390             sub _to_bigint_abs {
391 1650 50   1650   92062 return undef unless defined($_[0]);
392 1650         6040 my $n = _to_bigint($_[0]);
393 1650 100       5795 return ($n < 0) ? -$n : $n;
394             }
395             sub _to_bigint_if_needed {
396 27 50 33 27   382 return $_[0] if !defined $_[0] || ref($_[0]);
397 27 50 33     232 if ($_[0] >= INTMAX || $_[0] <= INTMIN) { # Probably a bigint
398 27         119 my $n = _to_bigint($_[0]);
399 27 50 33     121 return $n if $n > INTMAX || $n < INTMIN; # Definitely a bigint
400             }
401 0         0 $_[0];
402             }
403             sub _to_gmpz {
404 0 0   0   0 do { require Math::GMPz; } unless defined $Math::GMPz::VERSION;
  0         0  
405 0 0       0 return (ref($_[0]) eq 'Math::GMPz') ? $_[0] : Math::GMPz->new($_[0]);
406             }
407             sub _to_gmp {
408 0 0   0   0 do { require Math::GMP; } unless defined $Math::GMP::VERSION;
  0         0  
409 0 0       0 return (ref($_[0]) eq 'Math::GMP') ? $_[0] : Math::GMP->new($_[0]);
410             }
411             sub _reftyped {
412 270 50   270   533 return undef unless defined $_[1];
413 270         392 my $ref0 = ref($_[0]);
414 270 100       562 if (OLD_PERL_VERSION) {
415             # Perl 5.6 truncates arguments to doubles if you look at them funny
416             return "$_[1]" if "$_[1]" <= INTMAX && "$_[1]" >= INTMIN;
417 0         0 } elsif ($_[1] >= 0) {
418 245 100       7796 return $_[1] if $_[1] < ~0;
419             } else {
420 25 50       82 return $_[1] if $_[1] > -(~0>>1);
421             }
422 55         7408 my $bign;
423 55 100       153 if ($ref0) {
424 5         19 $bign = $ref0->new("$_[1]");
425             } else {
426 50 100       156 _load_bigint() unless defined $_BIGINT;
427 50         283 $bign = $_BIGINT->new("$_[1]");
428             }
429 55 100 100     8560 return $bign if $bign > INTMAX || $bign < INTMIN;
430 7         3916 0+"$_[1]";
431             }
432              
433             sub _maybe_bigint_allargs {
434 1 50   1   5 _load_bigint() unless defined $_BIGINT;
435 1         6 for my $i (0..$#_) {
436 2 50 33     14 next if !defined $_[$i] || ref($_[$i]);
437 0 0 0     0 next if $_[$i] < INTMAX && $_[$i] > INTMIN;
438 0         0 my $n = $_BIGINT->new("$_[$i]");
439 0 0 0     0 $_[$i] = $n if $n > INTMAX || $n < INTMIN;
440             }
441 1         11 @_;
442             }
443              
444             #############################################################################
445              
446             # These are called by the XS code to keep the GMP CSPRNG in sync with us.
447              
448             sub _srand_p {
449 0     0   0 my($seedval) = @_;
450 0 0       0 return unless $_Config{'gmp'} >= 42;
451 0 0       0 $seedval = unpack("L",entropy_bytes(4)) unless defined $seedval;
452 0         0 Math::Prime::Util::GMP::seed_csprng(4, pack("L",$seedval));
453 0         0 $seedval;
454             }
455              
456             sub _csrand_p {
457 0     0   0 my($str) = @_;
458 0 0       0 return unless $_Config{'gmp'} >= 42;
459 0 0       0 $str = entropy_bytes(256) unless defined $str;
460 0         0 Math::Prime::Util::GMP::seed_csprng(length($str), $str);
461             }
462              
463             #############################################################################
464              
465              
466             #############################################################################
467             # Random primes. These are front end functions that do input validation,
468             # load the RandomPrimes module, and call its function.
469              
470             sub random_maurer_prime_with_cert {
471 1     1 1 7021 my($bits) = @_;
472 1         22 _validate_integer_nonneg($bits);
473 1 50       6 croak "random_maurer_prime bits must be >= 2" unless $bits >= 2;
474              
475 1 50       6 if ($Math::Prime::Util::_GMPfunc{"random_maurer_prime_with_cert"}) {
476 0         0 my($n,$cert) = Math::Prime::Util::GMP::random_maurer_prime_with_cert($bits);
477 0         0 return (Math::Prime::Util::_reftyped($_[0],$n), $cert);
478             }
479              
480 1         1012 require Math::Prime::Util::RandomPrimes;
481 1         8 return Math::Prime::Util::RandomPrimes::random_maurer_prime_with_cert($bits);
482             }
483              
484             sub random_shawe_taylor_prime_with_cert {
485 1     1 1 667 my($bits) = @_;
486 1         7 _validate_integer_nonneg($bits);
487 1 50       4 croak "random_shawe_taylor_prime bits must be >= 2" unless $bits >= 2;
488              
489 1 50       5 if ($Math::Prime::Util::_GMPfunc{"random_shawe_taylor_prime_with_cert"}) {
490 0         0 my($n,$cert) =Math::Prime::Util::GMP::random_shawe_taylor_prime_with_cert($bits);
491 0         0 return (Math::Prime::Util::_reftyped($_[0],$n), $cert);
492             }
493              
494 1         14 require Math::Prime::Util::RandomPrimes;
495 1         9 return Math::Prime::Util::RandomPrimes::random_shawe_taylor_prime_with_cert($bits);
496             }
497              
498             sub random_proven_prime_with_cert {
499 1     1 1 835 my($bits) = @_;
500 1         11 _validate_integer_nonneg($bits);
501 1 50       6 croak "random_proven_prime bits must be >= 2" unless $bits >= 2;
502              
503             # Go to Maurer with GMP
504 1 50       5 if ($Math::Prime::Util::_GMPfunc{"random_maurer_prime_with_cert"}) {
505 0         0 my($n,$cert) = Math::Prime::Util::GMP::random_maurer_prime_with_cert($bits);
506 0         0 return (Math::Prime::Util::_reftyped($_[0],$n), $cert);
507             }
508              
509 1         14 require Math::Prime::Util::RandomPrimes;
510 1         8 return Math::Prime::Util::RandomPrimes::random_proven_prime_with_cert($bits);
511             }
512              
513             #############################################################################
514              
515             sub formultiperm (&$) { ## no critic qw(ProhibitSubroutinePrototypes)
516 5     5 1 62618 my($sub, $iref) = @_;
517 5 50       27 croak("formultiperm first argument must be an array reference") unless ref($iref) eq 'ARRAY';
518              
519 5         13 my($sum, %h, @n) = (0);
520 5         52 $h{$_}++ for @$iref;
521 5         25 @n = map { [$_, $h{$_}] } sort(keys(%h));
  11         37  
522 5         19 $sum += $_->[1] for @n;
523              
524 5         1793 require Math::Prime::Util::PP;
525 5         25 my $oldforexit = Math::Prime::Util::_start_for_loop();
526 5         50 Math::Prime::Util::PP::_multiset_permutations( $sub, [], \@n, $sum );
527 5         37 Math::Prime::Util::_end_for_loop($oldforexit);
528             }
529              
530             #############################################################################
531             # Iterators
532              
533             sub prime_iterator {
534 26     26 1 60555 my($start) = @_;
535 26 100       90 $start = 0 unless defined $start;
536 26         142 _validate_integer_nonneg($start);
537 23 100       855 my $p = ($start > 0) ? $start-1 : 0;
538             # This works fine:
539             # return sub { $p = next_prime($p); return $p; };
540             # but we can optimize a little
541 23 100 66     852 if (!ref($p) && $p <= $_XS_MAXVAL) {
    50          
542             # This is simple and low memory, but slower than segments:
543             # return sub { $p = next_prime($p); return $p; };
544 22         42 my $pr = [];
545             return sub {
546 88 100   88   681 if (scalar(@$pr) == 0) {
547             # Once we're into bigints, just use next_prime
548 22 50       56 return $p=next_prime($p) if $p >= MPU_MAXPRIME;
549             # Get about 10k primes
550 22 100       64 my $segment = ($p <= 1e4) ? 10_000 : int(10000*log($p)+1);
551 22 50 33     72 $segment = ~0-$p if $p+$segment > ~0 && $p+1 < ~0;
552 22         9291 $pr = primes($p+1, $p+$segment);
553             }
554 88         317 return $p = shift(@$pr);
555 22         147 };
556             } elsif ($_HAVE_GMP) {
557 0     0   0 return sub { $p = addint(0,Math::Prime::Util::GMP::next_prime($p)); return $p;};
  0         0  
  0         0  
558             } else {
559 1         9 require Math::Prime::Util::PP;
560 3     3   23 return sub { $p = Math::Prime::Util::PP::next_prime($p); return $p; }
  3         21  
561 1         11 }
562             }
563              
564             sub prime_iterator_object {
565 11     11 1 6943 my($start) = @_;
566 11         1667 require Math::Prime::Util::PrimeIterator;
567 11         49 return Math::Prime::Util::PrimeIterator->new($start);
568             }
569              
570             #############################################################################
571             # Front ends to functions.
572             #
573             # These will do input validation, then call the appropriate internal function
574             # based on the input (XS, GMP, PP).
575             #############################################################################
576              
577             #############################################################################
578              
579             # Return just the cert portion.
580             sub prime_certificate {
581 4     4 1 14 my($n) = @_;
582 4         19 my ($is_prime, $cert) = is_provable_prime_with_cert($n);
583 4         19 return $cert;
584             }
585              
586              
587             sub is_provable_prime_with_cert {
588 53     53 1 5658 my($n) = @_;
589 53         543 _validate_integer($n);
590 53 50       3660 return 0 if $n < 2;
591 53         1021 my $header = "[MPU - Primality Certificate]\nVersion 1.0\n\nProof for:\nN $n\n\n";
592              
593 53 100       406 if ($n <= $_XS_MAXVAL) {
594 37         319 my $isp = is_prime($n);
595 37 100       165 return ($isp, '') unless $isp == 2;
596 36         239 return (2, $header . "Type Small\nN $n\n");
597             }
598              
599 16 50 33     758 if ($_HAVE_GMP && defined &Math::Prime::Util::GMP::is_provable_prime_with_cert) {
600 0         0 my ($isp, $cert) = Math::Prime::Util::GMP::is_provable_prime_with_cert($n);
601             # New version that returns string format.
602             #return ($isp, $cert) if ref($cert) ne 'ARRAY';
603 0 0       0 if (ref($cert) ne 'ARRAY') {
604             # Fix silly 0.13 mistake (TODO: deprecate this)
605 0         0 $cert =~ s/^Type Small\n(\d+)/Type Small\nN $1/smg;
606 0         0 return ($isp, $cert);
607             }
608             # Old version. Convert.
609 0         0 require Math::Prime::Util::PrimalityProving;
610 0         0 return ($isp, Math::Prime::Util::PrimalityProving::convert_array_cert_to_string($cert));
611             }
612              
613             {
614 16         33 my $isp = is_prob_prime($n);
  16         83  
615 16 50       68 return ($isp, '') if $isp == 0;
616 16 100       139 return (2, $header . "Type Small\nN $n\n") if $isp == 2;
617             }
618              
619             # Choice of methods for proof:
620             # ECPP needs a fair bit of programming work
621             # APRCL needs a lot of programming work
622             # BLS75 combo Corollary 11 of BLS75. Trial factor n-1 and n+1 to B, find
623             # factors F1 of n-1 and F2 of n+1. Quit when:
624             # B > (N/(F1*F1*(F2/2)))^1/3 or B > (N/((F1/2)*F2*F2))^1/3
625             # BLS75 n+1 Requires factoring n+1 to (n/2)^1/3 (theorem 19)
626             # BLS75 n-1 Requires factoring n-1 to (n/2)^1/3 (theorem 5 or 7)
627             # Pocklington Requires factoring n-1 to n^1/2 (BLS75 theorem 4)
628             # Lucas Easy, requires factoring of n-1 (BLS75 theorem 1)
629             # AKS horribly slow
630             # See http://primes.utm.edu/prove/merged.html or other sources.
631              
632 4         23 require Math::Prime::Util::PrimalityProving;
633             #my ($isp, $pref) = Math::Prime::Util::PrimalityProving::primality_proof_lucas($n);
634 4         25 my ($isp, $pref) = Math::Prime::Util::PrimalityProving::primality_proof_bls75($n);
635 4 50       41 carp "proved $n is not prime\n" if !$isp;
636 4         61 return ($isp, $pref);
637             }
638              
639              
640             sub verify_prime {
641 60     60 1 30974 require Math::Prime::Util::PrimalityProving;
642 60         393 return Math::Prime::Util::PrimalityProving::verify_cert(@_);
643             }
644              
645             #############################################################################
646              
647             sub RiemannZeta {
648 18     18 1 14372 my($n) = @_;
649 18 50       114 croak("Invalid input to RiemannZeta: x must be > 0") if $n <= 0;
650              
651 18 50       2334 return $n-$n if $n > 10_000_000; # Over 3M leading zeros
652              
653 18 100 100     3052 return _XS_RiemannZeta($n) if !ref($n) && $_Config{'xs'};
654              
655 12         179 require Math::Prime::Util::PP;
656 12         78 return Math::Prime::Util::PP::RiemannZeta($n);
657             }
658              
659             sub RiemannR {
660 20     20 1 21064 my($n) = @_;
661 20 100       370 croak("Invalid input to RiemannR: x must be > 0") if $n <= 0;
662              
663 18 100 66     548 return _XS_RiemannR($n) if !ref($n) && $_Config{'xs'};
664              
665 9         69 require Math::Prime::Util::PP;
666 9         38 return Math::Prime::Util::PP::RiemannR($n);
667             }
668              
669             sub ExponentialIntegral {
670 79     79 1 40027 my($n) = @_;
671 79 100       314 return $_Neg_Infinity if $n == 0;
672 78 100       212 return 0 if $n == $_Neg_Infinity;
673 77 100       255 return $_Infinity if $n == $_Infinity;
674              
675 76 100 66     858 return _XS_ExponentialIntegral($n) if !ref($n) && $_Config{'xs'};
676              
677 57         550 require Math::Prime::Util::PP;
678 57         213 return Math::Prime::Util::PP::ExponentialIntegral($n);
679             }
680              
681             sub LogarithmicIntegral {
682 128     128 1 288906 my($n) = @_;
683 128 100       485 return 0 if $n == 0;
684 125 100       11882 return $_Neg_Infinity if $n == 1;
685 124 100       11367 return $_Infinity if $n == $_Infinity;
686              
687 123 100       10368 croak("Invalid input to LogarithmicIntegral: x must be >= 0") if $n <= 0;
688              
689 122 100 100     12260 if (!ref($n) && $_Config{'xs'}) {
690 66 100       173 return 1.045163780117492784844588889194613136522615578151 if $n == 2;
691 65         650 return _XS_LogarithmicIntegral($n);
692             }
693              
694 56         594 require Math::Prime::Util::PP;
695 56         349 return Math::Prime::Util::PP::LogarithmicIntegral(@_);
696             }
697              
698             sub LambertW {
699 10     10 1 8521 my($x) = @_;
700              
701 10 100 66     223 return _XS_LambertW($x) if !ref($x) && $_Config{'xs'};
702              
703 1         8 require Math::Prime::Util::PP;
704 1         26 return Math::Prime::Util::PP::LambertW($x);
705             }
706              
707             sub bernreal {
708 27     27 1 68587 my($n, $precision) = @_;
709 27 100       90 do { require Math::BigFloat; Math::BigFloat->import(); } unless defined $Math::BigFloat::VERSION;
  1         2726  
  1         45074  
710              
711 27 50       207 if ($Math::Prime::Util::_GMPfunc{"bernreal"}) {
712 0 0       0 return Math::BigFloat->new(Math::Prime::Util::GMP::bernreal($n)) if !defined $precision;
713 0         0 return Math::BigFloat->new(Math::Prime::Util::GMP::bernreal($n,$precision),$precision);
714             }
715              
716 27         248 my($num,$den) = map { _to_bigint($_) } bernfrac($n);
  54         161  
717 27 100       117 return Math::BigFloat->bzero if $num == 0;
718 16         3471 scalar Math::BigFloat->new($num)->bdiv($den, $precision);
719             }
720              
721             sub harmreal {
722 23     23 1 42184 my($n, $precision) = @_;
723 23         105 _validate_integer_nonneg($n);
724 23 50       66 do { require Math::BigFloat; Math::BigFloat->import(); } unless defined $Math::BigFloat::VERSION;
  0         0  
  0         0  
725 23 100       52 return Math::BigFloat->bzero if $n <= 0;
726              
727 22 50       83 if ($Math::Prime::Util::_GMPfunc{"harmreal"}) {
728 0 0       0 return Math::BigFloat->new(Math::Prime::Util::GMP::harmreal($n)) if !defined $precision;
729 0         0 return Math::BigFloat->new(Math::Prime::Util::GMP::harmreal($n,$precision),$precision);
730             }
731              
732             # If low enough precision, use native floating point. Fast.
733 22 50 33     62 if (defined $precision && $precision <= 13) {
734             return Math::BigFloat->new(
735 0 0       0 ($n < 80) ? do { my $h = 0; $h += 1/$_ for 1..$n; $h; }
  0         0  
  0         0  
  0         0  
736             : log($n) + 0.57721566490153286060651209 + 1/(2*$n) - 1/(12*$n*$n) + 1/(120*$n*$n*$n*$n)
737             ,$precision
738             );
739             }
740              
741 22 50       40 if ($Math::Prime::Util::_GMPfunc{"harmfrac"}) {
742 0         0 my($num,$den) = map { _to_bigint($_) } Math::Prime::Util::GMP::harmfrac($n);
  0         0  
743 0         0 return scalar Math::BigFloat->new($num)->bdiv($den, $precision);
744             }
745              
746 22         117 require Math::Prime::Util::PP;
747 22         85 Math::Prime::Util::PP::harmreal($n, $precision);
748             }
749              
750              
751              
752             #############################################################################
753              
754             1;
755              
756             __END__