File Coverage

blib/lib/Math/Prime/Util/PP.pm
Criterion Covered Total %
statement 2981 4370 68.2
branch 1653 3276 50.4
condition 522 1224 42.6
subroutine 185 266 69.5
pod 4 161 2.4
total 5345 9297 57.4


line stmt bran cond sub pod time code
1             package Math::Prime::Util::PP;
2 40     40   1256442 use strict;
  40         98  
  40         1406  
3 40     40   224 use warnings;
  40         95  
  40         1451  
4 40     40   223 use Carp qw/carp croak confess/;
  40         84  
  40         3608  
5              
6             BEGIN {
7 40     40   185 $Math::Prime::Util::PP::AUTHORITY = 'cpan:DANAJ';
8 40         2088 $Math::Prime::Util::PP::VERSION = '0.73';
9             }
10              
11             BEGIN {
12 40 100   40   669 do { require Math::BigInt; Math::BigInt->import(try=>"GMP,Pari"); }
  28         31244  
  28         708043  
13             unless defined $Math::BigInt::VERSION;
14             }
15              
16             # The Pure Perl versions of all the Math::Prime::Util routines.
17             #
18             # Some of these will be relatively similar in performance, some will be
19             # very slow in comparison.
20             #
21             # Most of these are pretty simple. Also, you really should look at the C
22             # code for more detailed comments, including references to papers.
23              
24 0         0 BEGIN {
25 40     40   715535 use constant OLD_PERL_VERSION=> $] < 5.008;
  40         106  
  40         3114  
26 40     40   262 use constant MPU_MAXBITS => (~0 == 4294967295) ? 32 : 64;
  40         87  
  40         2091  
27 40     40   248 use constant MPU_64BIT => MPU_MAXBITS == 64;
  40         94  
  40         2024  
28 40     40   241 use constant MPU_32BIT => MPU_MAXBITS == 32;
  40         98  
  40         1921  
29             #use constant MPU_MAXPARAM => MPU_32BIT ? 4294967295 : 18446744073709551615;
30             #use constant MPU_MAXDIGITS => MPU_32BIT ? 10 : 20;
31 40     40   255 use constant MPU_MAXPRIME => MPU_32BIT ? 4294967291 : 18446744073709551557;
  40         96  
  40         1918  
32 40     40   255 use constant MPU_MAXPRIMEIDX => MPU_32BIT ? 203280221 : 425656284035217743;
  40         79  
  40         1971  
33 40     40   250 use constant MPU_HALFWORD => MPU_32BIT ? 65536 : OLD_PERL_VERSION ? 33554432 : 4294967296;
  40         119  
  40         2176  
34 40     40   285 use constant UVPACKLET => MPU_32BIT ? 'L' : 'Q';
  40         98  
  40         2729  
35 40     40   256 use constant MPU_INFINITY => (65535 > 0+'inf') ? 20**20**20 : 0+'inf';
  40         91  
  40         2216  
36 40     40   250 use constant BZERO => Math::BigInt->bzero;
  40         88  
  40         347  
37 40     40   6953 use constant BONE => Math::BigInt->bone;
  40         146  
  40         334  
38 40     40   4740 use constant BTWO => Math::BigInt->new(2);
  40         182  
  40         412  
39 40     40   5232 use constant INTMAX => (!OLD_PERL_VERSION || MPU_32BIT) ? ~0 : 562949953421312;
  40         269  
  40         2659  
40 40     40   706 use constant BMAX => Math::BigInt->new('' . INTMAX);
  40         190  
  40         313  
41 40     40   5232 use constant B_PRIM767 => Math::BigInt->new("261944051702675568529303");
  40         94  
  40         205  
42 40     40   4622 use constant B_PRIM235 => Math::BigInt->new("30");
  40         85  
  40         169  
43 40     40   3929 use constant PI_TIMES_8 => 25.13274122871834590770114707;
  40     0   105  
  40         772863  
44             }
45              
46             my $_precalc_size = 0;
47             sub prime_precalc {
48 0     0 0 0 my($n) = @_;
49 0 0       0 croak "Parameter '$n' must be a positive integer" unless _is_positive_int($n);
50 0 0       0 $_precalc_size = $n if $n > $_precalc_size;
51             }
52             sub prime_memfree {
53 10     10 0 45 $_precalc_size = 0;
54 10 50 33     54 eval { Math::Prime::Util::GMP::_GMP_memfree(); }
  0         0  
55             if defined $Math::Prime::Util::GMP::VERSION && $Math::Prime::Util::GMP::VERSION >= 0.49;
56             }
57 5     5   17 sub _get_prime_cache_size { $_precalc_size }
58 0     0   0 sub _prime_memfreeall { prime_memfree; }
59              
60              
61             sub _is_positive_int {
62 0 0 0 0   0 ((defined $_[0]) && $_[0] ne '' && ($_[0] !~ tr/0123456789//c));
63             }
64              
65             sub _bigint_to_int {
66             #if (OLD_PERL_VERSION) {
67             # my $pack = ($_[0] < 0) ? lc(UVPACKLET) : UVPACKLET;
68             # return unpack($pack,pack($pack,"$_[0]"));
69             #}
70 16602     16602   1388287 int("$_[0]");
71             }
72              
73             sub _upgrade_to_float {
74 1012 100   1012   5147 do { require Math::BigFloat; Math::BigFloat->import(); }
  1         1011  
  1         23737  
75             if !defined $Math::BigFloat::VERSION;
76 1012         4871 Math::BigFloat->new(@_);
77             }
78              
79             # Get the accuracy of variable x, or the max default from BigInt/BigFloat
80             # One might think to use ref($x)->accuracy() but numbers get upgraded and
81             # downgraded willy-nilly, and it will do the wrong thing from the user's
82             # perspective.
83             sub _find_big_acc {
84 34     34   95 my($x) = @_;
85 34         67 my $b;
86              
87 34 50       219 $b = $x->accuracy() if ref($x) =~ /^Math::Big/;
88 34 100       415 return $b if defined $b;
89              
90 15         75 my ($i,$f) = (Math::BigInt->accuracy(), Math::BigFloat->accuracy());
91 15 0 33     356 return (($i > $f) ? $i : $f) if defined $i && defined $f;
    50          
92 15 50       62 return $i if defined $i;
93 15 50       53 return $f if defined $f;
94              
95 15         79 ($i,$f) = (Math::BigInt->div_scale(), Math::BigFloat->div_scale());
96 15 50 33     460 return (($i > $f) ? $i : $f) if defined $i && defined $f;
    50          
97 15 0       0 return $i if defined $i;
98 15 0       0 return $f if defined $f;
99 15         0 return 18;
100             }
101              
102             sub _bfdigits {
103 0     0   0 my($wantbf, $xdigits) = (0, 17);
104 0 0 0     0 if (defined $bignum::VERSION || ref($_[0]) =~ /^Math::Big/) {
105 0 0       0 do { require Math::BigFloat; Math::BigFloat->import(); }
  0         0  
  0         0  
106             if !defined $Math::BigFloat::VERSION;
107 0 0       0 if (ref($_[0]) eq 'Math::BigInt') {
108 0         0 my $xacc = ($_[0])->accuracy();
109 0         0 $_[0] = Math::BigFloat->new($_[0]);
110 0 0       0 ($_[0])->accuracy($xacc) if $xacc;
111             }
112 0 0       0 $_[0] = Math::BigFloat->new("$_[0]") if ref($_[0]) ne 'Math::BigFloat';
113 0         0 $wantbf = _find_big_acc($_[0]);
114 0         0 $xdigits = $wantbf;
115             }
116 0         0 ($wantbf, $xdigits);
117             }
118              
119              
120             sub _validate_num {
121 269     269   725 my($n, $min, $max) = @_;
122 269 50       890 croak "Parameter must be defined" if !defined $n;
123 269 100       886 return 0 if ref($n);
124 236 50 33     1227 croak "Parameter '$n' must be a positive integer"
      33        
125             if $n eq '' || ($n =~ tr/0123456789//c && $n !~ /^\+\d+$/);
126 236 50 33     864 croak "Parameter '$n' must be >= $min" if defined $min && $n < $min;
127 236 50 33     654 croak "Parameter '$n' must be <= $max" if defined $max && $n > $max;
128 236 50       769 substr($_[0],0,1,'') if substr($n,0,1) eq '+';
129 236 100 66     819 return 0 unless $n < ~0 || int($n) eq ''.~0;
130 232         598 1;
131             }
132              
133             sub _validate_positive_integer {
134 16409     16409   28525 my($n, $min, $max) = @_;
135 16409 50       32271 croak "Parameter must be defined" if !defined $n;
136 16409 50       32541 if (ref($n) eq 'CODE') {
137 0         0 $_[0] = $_[0]->();
138 0         0 $n = $_[0];
139             }
140 16409 100       38008 if (ref($n) eq 'Math::BigInt') {
    50          
141 727 50 33     2675 croak "Parameter '$n' must be a positive integer"
142             if $n->sign() ne '+' || !$n->is_int();
143 727 100       13838 $_[0] = _bigint_to_int($_[0]) if $n <= BMAX;
144             } elsif (ref($n) eq 'Math::GMPz') {
145 0 0       0 croak "Parameter '$n' must be a positive integer" if Math::GMPz::Rmpz_sgn($n) < 0;
146 0 0       0 $_[0] = _bigint_to_int($_[0]) if $n <= INTMAX;
147             } else {
148 15682         26454 my $strn = "$n";
149 15682 50       28925 if ($strn eq '-0') { $_[0] = 0; $strn = '0'; }
  0         0  
  0         0  
150 15682 100 66     50020 croak "Parameter '$strn' must be a positive integer"
      66        
151             if $strn eq '' || ($strn =~ tr/0123456789//c && $strn !~ /^\+?\d+$/);
152 15681 100       30124 if ($n <= INTMAX) {
153 15547 50       30846 $_[0] = $strn if ref($n);
154             } else {
155 134         589 $_[0] = Math::BigInt->new($strn)
156             }
157             }
158 16408 50 66     72447 $_[0]->upgrade(undef) if ref($_[0]) eq 'Math::BigInt' && $_[0]->upgrade();
159 16408 50 66     42134 croak "Parameter '$_[0]' must be >= $min" if defined $min && $_[0] < $min;
160 16408 50 33     31728 croak "Parameter '$_[0]' must be <= $max" if defined $max && $_[0] > $max;
161 16408         23009 1;
162             }
163              
164             sub _validate_integer {
165 1215     1215   2333 my($n) = @_;
166 1215 50       2583 croak "Parameter must be defined" if !defined $n;
167 1215 50       2990 if (ref($n) eq 'CODE') {
168 0         0 $_[0] = $_[0]->();
169 0         0 $n = $_[0];
170             }
171 1215         2244 my $poscmp = OLD_PERL_VERSION ? 562949953421312 : ''.~0;
172 1215         1771 my $negcmp = OLD_PERL_VERSION ? -562949953421312 : -(~0 >> 1);
173 1215 100       2872 if (ref($n) eq 'Math::BigInt') {
174 1185 50       3288 croak "Parameter '$n' must be an integer" if !$n->is_int();
175 1185 100 100     10189 $_[0] = _bigint_to_int($_[0]) if $n <= $poscmp && $n >= $negcmp;
176             } else {
177 30         61 my $strn = "$n";
178 30 50       72 if ($strn eq '-0') { $_[0] = 0; $strn = '0'; }
  0         0  
  0         0  
179 30 50 33     150 croak "Parameter '$strn' must be an integer"
      33        
180             if $strn eq '' || ($strn =~ tr/-0123456789//c && $strn !~ /^[-+]?\d+$/);
181 30 100 100     146 if ($n <= $poscmp && $n >= $negcmp) {
182 27 50       73 $_[0] = $strn if ref($n);
183             } else {
184 3         19 $_[0] = Math::BigInt->new($strn)
185             }
186             }
187 1215 50 66     131299 $_[0]->upgrade(undef) if ref($_[0]) && $_[0]->upgrade();
188 1215         9156 1;
189             }
190              
191             sub _binary_search {
192 0     0   0 my($n, $lo, $hi, $sub, $exitsub) = @_;
193 0         0 while ($lo < $hi) {
194 0         0 my $mid = $lo + int(($hi-$lo) >> 1);
195 0 0 0     0 return $mid if defined $exitsub && $exitsub->($n,$lo,$hi);
196 0 0       0 if ($sub->($mid) < $n) { $lo = $mid+1; }
  0         0  
197 0         0 else { $hi = $mid; }
198             }
199 0         0 return $lo-1;
200             }
201              
202             my @_primes_small = (0,2);
203             {
204             my($n, $s, $sieveref) = (7-2, 3, _sieve_erat_string(5003));
205             push @_primes_small, 2*pos($$sieveref)-1 while $$sieveref =~ m/0/g;
206             }
207             my @_prime_next_small = (
208             2,2,3,5,5,7,7,11,11,11,11,13,13,17,17,17,17,19,19,23,23,23,23,
209             29,29,29,29,29,29,31,31,37,37,37,37,37,37,41,41,41,41,43,43,47,
210             47,47,47,53,53,53,53,53,53,59,59,59,59,59,59,61,61,67,67,67,67,67,67,71);
211              
212             # For wheel-30
213             my @_prime_indices = (1, 7, 11, 13, 17, 19, 23, 29);
214             my @_nextwheel30 = (1,7,7,7,7,7,7,11,11,11,11,13,13,17,17,17,17,19,19,23,23,23,23,29,29,29,29,29,29,1);
215             my @_prevwheel30 = (29,29,1,1,1,1,1,1,7,7,7,7,11,11,13,13,13,13,17,17,19,19,19,19,23,23,23,23,23,23);
216             my @_wheeladvance30 = (1,6,5,4,3,2,1,4,3,2,1,2,1,4,3,2,1,2,1,4,3,2,1,6,5,4,3,2,1,2);
217             my @_wheelretreat30 = (1,2,1,2,3,4,5,6,1,2,3,4,1,2,1,2,3,4,1,2,1,2,3,4,1,2,3,4,5,6);
218              
219             sub _tiny_prime_count {
220 2     2   4 my($n) = @_;
221 2 50       6 return if $n >= $_primes_small[-1];
222 2         6 my $j = $#_primes_small;
223 2         5 my $i = 1 + ($n >> 4);
224 2         8 while ($i < $j) {
225 18         25 my $mid = ($i+$j)>>1;
226 18 100       34 if ($_primes_small[$mid] <= $n) { $i = $mid+1; }
  8         16  
227 10         18 else { $j = $mid; }
228             }
229 2         10 return $i-1;
230             }
231              
232             sub _is_prime7 { # n must not be divisible by 2, 3, or 5
233 9711     9711   21787 my($n) = @_;
234              
235 9711 50 66     21073 $n = _bigint_to_int($n) if ref($n) eq 'Math::BigInt' && $n <= BMAX;
236 9711 100       26925 if (ref($n) eq 'Math::BigInt') {
237 280 100       1047 return 0 unless Math::BigInt::bgcd($n, B_PRIM767)->is_one;
238 217 100       793228 return 0 unless _miller_rabin_2($n);
239 103         5123 my $is_esl_prime = is_extra_strong_lucas_pseudoprime($n);
240 103 50       22582 return ($is_esl_prime) ? (($n <= "18446744073709551615") ? 2 : 1) : 0;
    100          
241             }
242              
243 9431 100       16979 if ($n < 61*61) {
244 3295         6145 foreach my $i (qw/7 11 13 17 19 23 29 31 37 41 43 47 53 59/) {
245 19679 100       35253 return 2 if $i*$i > $n;
246 17757 100       32670 return 0 if !($n % $i);
247             }
248 111         431 return 2;
249             }
250              
251 6136 100 100     74794 return 0 if !($n % 7) || !($n % 11) || !($n % 13) || !($n % 17) ||
      100        
      100        
      100        
      100        
      100        
      100        
      100        
      100        
      100        
      100        
      100        
      100        
252             !($n % 19) || !($n % 23) || !($n % 29) || !($n % 31) ||
253             !($n % 37) || !($n % 41) || !($n % 43) || !($n % 47) ||
254             !($n % 53) || !($n % 59);
255              
256             # We could do:
257             # return is_strong_pseudoprime($n, (2,299417)) if $n < 19471033;
258             # or:
259             # foreach my $p (@_primes_small[18..168]) {
260             # last if $p > $limit;
261             # return 0 unless $n % $p;
262             # }
263             # return 2;
264              
265 3683 100       7249 if ($n <= 1_500_000) {
266 373         859 my $limit = int(sqrt($n));
267 373         522 my $i = 61;
268 373         886 while (($i+30) <= $limit) {
269 667 100 100     4798 return 0 unless ($n% $i ) && ($n%($i+ 6)) &&
      100        
      100        
      100        
      100        
      100        
      100        
270             ($n%($i+10)) && ($n%($i+12)) &&
271             ($n%($i+16)) && ($n%($i+18)) &&
272             ($n%($i+22)) && ($n%($i+28));
273 624         914 $i += 30;
274             }
275 330         655 for my $inc (6,4,2,4,2,4,6,2) {
276 921 100       1728 last if $i > $limit;
277 629 100       1189 return 0 if !($n % $i);
278 596         857 $i += $inc;
279             }
280 297         1037 return 2;
281             }
282              
283 3310 100       5966 if ($n < 47636622961201) { # BPSW seems to be faster after this
284             # Deterministic set of Miller-Rabin tests. If the MR routines can handle
285             # bases greater than n, then this can be simplified.
286 3255         4172 my @bases;
287             # n > 1_000_000 because of the previous block.
288 3255 100       5635 if ($n < 19471033) { @bases = ( 2, 299417); }
  3169 100       5159  
    100          
    100          
    100          
    50          
    0          
289 4         6 elsif ($n < 38010307) { @bases = ( 2, 9332593); }
290 12         24 elsif ($n < 316349281) { @bases = ( 11000544, 31481107); }
291 29         54 elsif ($n < 4759123141) { @bases = ( 2, 7, 61); }
292 40         120 elsif ($n < 154639673381) { @bases = ( 15, 176006322, 4221622697); }
293 1         4 elsif ($n < 47636622961201) { @bases = ( 2, 2570940, 211991001, 3749873356); }
294 0         0 elsif ($n < 3770579582154547) { @bases = ( 2, 2570940, 880937, 610386380, 4130785767); }
295 0         0 else { @bases = ( 2, 325, 9375, 28178, 450775, 9780504, 1795265022); }
296 3255 100       5869 return is_strong_pseudoprime($n, @bases) ? 2 : 0;
297             }
298              
299             # Inlined BPSW
300 55 100       234 return 0 unless _miller_rabin_2($n);
301 46 100       257 return is_almost_extra_strong_lucas_pseudoprime($n) ? 2 : 0;
302             }
303              
304             sub is_prime {
305 6808     6808 0 65488 my($n) = @_;
306 6808 50 33     22428 return 0 if defined($n) && int($n) < 0;
307 6808         77349 _validate_positive_integer($n);
308              
309 6808 100       11319 if (ref($n) eq 'Math::BigInt') {
310 323 100       1081 return 0 unless Math::BigInt::bgcd($n, B_PRIM235)->is_one;
311             } else {
312 6485 100 100     10769 if ($n < 7) { return ($n == 2) || ($n == 3) || ($n == 5) ? 2 : 0; }
  68 100       264  
313 6417 100 100     28299 return 0 if !($n % 2) || !($n % 3) || !($n % 5);
      100        
314             }
315 3338         55289 return _is_prime7($n);
316             }
317              
318             # is_prob_prime is the same thing for us.
319             *is_prob_prime = \&is_prime;
320              
321             # BPSW probable prime. No composites are known to have passed this test
322             # since it was published in 1980, though we know infinitely many exist.
323             # It has also been verified that no 64-bit composite will return true.
324             # Slow since it's all in PP and uses bigints.
325             sub is_bpsw_prime {
326 32     32 0 106 my($n) = @_;
327 32 50 33     179 return 0 if defined($n) && int($n) < 0;
328 32         7354 _validate_positive_integer($n);
329 32 100       110 return 0 unless _miller_rabin_2($n);
330 7 50       368 if ($n <= 18446744073709551615) {
331 0 0       0 return is_almost_extra_strong_lucas_pseudoprime($n) ? 2 : 0;
332             }
333 7 100       1256 return is_extra_strong_lucas_pseudoprime($n) ? 1 : 0;
334             }
335              
336             sub is_provable_prime {
337 5     5 0 119 my($n) = @_;
338 5 50 33     62 return 0 if defined $n && $n < 2;
339 5         57 _validate_positive_integer($n);
340 5 50       34 if ($n <= 18446744073709551615) {
341 0 0       0 return 0 unless _miller_rabin_2($n);
342 0 0       0 return 0 unless is_almost_extra_strong_lucas_pseudoprime($n);
343 0         0 return 2;
344             }
345 5         687 my($is_prime, $cert) = Math::Prime::Util::is_provable_prime_with_cert($n);
346 5         65 $is_prime;
347             }
348              
349             # Possible sieve storage:
350             # 1) vec with mod-30 wheel: 8 bits / 30
351             # 2) vec with mod-2 wheel : 15 bits / 30
352             # 3) str with mod-30 wheel: 8 bytes / 30
353             # 4) str with mod-2 wheel : 15 bytes / 30
354             #
355             # It looks like using vecs is about 2x slower than strs, and the strings also
356             # let us do some fast operations on the results. E.g.
357             # Count all primes:
358             # $count += $$sieveref =~ tr/0//;
359             # Loop over primes:
360             # foreach my $s (split("0", $$sieveref, -1)) {
361             # $n += 2 + 2 * length($s);
362             # .. do something with the prime $n
363             # }
364             #
365             # We're using method 4, though sadly it is memory intensive relative to the
366             # other methods. I will point out that it is 30-60x less memory than sieves
367             # using an array, and the performance of this function is over 10x that
368             # of naive sieves.
369              
370             sub _sieve_erat_string {
371 56     56   181 my($end) = @_;
372 56 100       300 $end-- if ($end & 1) == 0;
373 56         155 my $s_end = $end >> 1;
374              
375 56         286 my $whole = int( $s_end / 15); # Prefill with 3 and 5 already marked.
376 56 50       220 croak "Sieve too large" if $whole > 1_145_324_612; # ~32 GB string
377 56         4823 my $sieve = '100010010010110' . '011010010010110' x $whole;
378 56         258 substr($sieve, $s_end+1) = ''; # Ensure we don't make too many entries
379 56         220 my ($n, $limit) = ( 7, int(sqrt($end)) );
380 56         294 while ( $n <= $limit ) {
381 1622         3250 for (my $s = ($n*$n) >> 1; $s <= $s_end; $s += $n) {
382 2487327         3994527 substr($sieve, $s, 1) = '1';
383             }
384 1622         2197 do { $n += 2 } while substr($sieve, $n>>1, 1);
  3912         7689  
385             }
386 56         2067 return \$sieve;
387             }
388              
389             # TODO: this should be plugged into precalc, memfree, etc. just like the C code
390             {
391             my $primary_size_limit = 15000;
392             my $primary_sieve_size = 0;
393             my $primary_sieve_ref;
394             sub _sieve_erat {
395 620     620   1035 my($end) = @_;
396              
397 620 100       1190 return _sieve_erat_string($end) if $end > $primary_size_limit;
398              
399 606 100       1209 if ($primary_sieve_size == 0) {
400 2         4 $primary_sieve_size = $primary_size_limit;
401 2         6 $primary_sieve_ref = _sieve_erat_string($primary_sieve_size);
402             }
403 606         1426 my $sieve = substr($$primary_sieve_ref, 0, ($end+1)>>1);
404 606         1398 return \$sieve;
405             }
406             }
407              
408              
409             sub _sieve_segment {
410 547     547   1051 my($beg,$end,$limit) = @_;
411 547 50 33     1129 ($beg, $end) = map { _bigint_to_int($_) } ($beg, $end)
  0         0  
412             if ref($end) && $end <= BMAX;
413 547 50       1174 croak "Internal error: segment beg is even" if ($beg % 2) == 0;
414 547 50       1013 croak "Internal error: segment end is even" if ($end % 2) == 0;
415 547 50       944 croak "Internal error: segment end < beg" if $end < $beg;
416 547 50       914 croak "Internal error: segment beg should be >= 3" if $beg < 3;
417 547         1086 my $range = int( ($end - $beg) / 2 ) + 1;
418              
419             # Prefill with 3 and 5 already marked, and offset to the segment start.
420 547         895 my $whole = int( ($range+14) / 15);
421 547         908 my $startp = ($beg % 30) >> 1;
422 547         3306 my $sieve = substr('011010010010110', $startp) . '011010010010110' x $whole;
423             # Set 3 and 5 to prime if we're sieving them.
424 547 100       1181 substr($sieve,0,2) = '00' if $beg == 3;
425 547 100       916 substr($sieve,0,1) = '0' if $beg == 5;
426             # Get rid of any extra we added.
427 547         1015 substr($sieve, $range) = '';
428              
429             # If the end value is below 7^2, then the pre-sieve is all we needed.
430 547 100       971 return \$sieve if $end < 49;
431              
432 536 50       1149 my $sqlimit = ref($end) ? $end->copy->bsqrt() : int(sqrt($end)+0.0000001);
433 536 50 33     1204 $limit = $sqlimit if !defined $limit || $sqlimit < $limit;
434             # For large value of end, it's a huge win to just walk primes.
435              
436 536         1084 my($p, $s, $primesieveref) = (7-2, 3, _sieve_erat($limit));
437 536         1469 while ( (my $nexts = 1 + index($$primesieveref, '0', $s)) > 0 ) {
438 40025         51445 $p += 2 * ($nexts - $s);
439 40025         46200 $s = $nexts;
440 40025         48583 my $p2 = $p*$p;
441 40025 100       58545 if ($p2 < $beg) {
442 39327         56036 my $f = 1+int(($beg-1)/$p);
443 39327 100       62634 $f++ unless $f % 2;
444 39327         47810 $p2 = $p * $f;
445             }
446             # With large bases and small segments, it's common to find we don't hit
447             # the segment at all. Skip all the setup if we find this now.
448 40025 100       71722 if ($p2 <= $end) {
449             # Inner loop marking multiples of p
450             # (everything is divided by 2 to keep inner loop simpler)
451 20147         25950 my $filter_end = ($end - $beg) >> 1;
452 20147         26352 my $filter_p2 = ($p2 - $beg) >> 1;
453 20147         31573 while ($filter_p2 <= $filter_end) {
454 726651         895908 substr($sieve, $filter_p2, 1) = "1";
455 726651         1129642 $filter_p2 += $p;
456             }
457             }
458             }
459 536         1668 \$sieve;
460             }
461              
462             sub trial_primes {
463 2     2 0 2158 my($low,$high) = @_;
464 2 100       8 if (!defined $high) {
465 1         2 $high = $low;
466 1         1 $low = 2;
467             }
468 2         8 _validate_positive_integer($low);
469 2         6 _validate_positive_integer($high);
470 2 50       6 return if $low > $high;
471 2         46 my @primes;
472              
473             # For a tiny range, just use next_prime calls
474 2 50       9 if (($high-$low) < 1000) {
475 2 50       330 $low-- if $low >= 2;
476 2         191 my $curprime = next_prime($low);
477 2         19 while ($curprime <= $high) {
478 24         130 push @primes, $curprime;
479 24         33 $curprime = next_prime($curprime);
480             }
481 2         79 return \@primes;
482             }
483              
484             # Sieve to 10k then BPSW test
485 0 0 0     0 push @primes, 2 if ($low <= 2) && ($high >= 2);
486 0 0 0     0 push @primes, 3 if ($low <= 3) && ($high >= 3);
487 0 0 0     0 push @primes, 5 if ($low <= 5) && ($high >= 5);
488 0 0       0 $low = 7 if $low < 7;
489 0 0       0 $low++ if ($low % 2) == 0;
490 0 0       0 $high-- if ($high % 2) == 0;
491 0         0 my $sieveref = _sieve_segment($low, $high, 10000);
492 0         0 my $n = $low-2;
493 0         0 while ($$sieveref =~ m/0/g) {
494 0         0 my $p = $n+2*pos($$sieveref);
495 0 0 0     0 push @primes, $p if _miller_rabin_2($p) && is_extra_strong_lucas_pseudoprime($p);
496             }
497 0         0 return \@primes;
498             }
499              
500             sub primes {
501 169     169 0 16026 my($low,$high) = @_;
502 169 100       503 if (scalar @_ > 1) {
503 65         224 _validate_positive_integer($low);
504 65         235 _validate_positive_integer($high);
505 65 100       203 $low = 2 if $low < 2;
506             } else {
507 104         224 ($low,$high) = (2, $low);
508 104         260 _validate_positive_integer($high);
509             }
510 169         453 my $sref = [];
511 169 100 66     771 return $sref if ($low > $high) || ($high < 2);
512 163 100       1302 return [grep { $_ >= $low && $_ <= $high } @_primes_small]
  270187 100       650791  
513             if $high <= $_primes_small[-1];
514              
515             return [ Math::Prime::Util::GMP::sieve_primes($low, $high, 0) ]
516 13 50 33     173 if $Math::Prime::Util::_GMPfunc{"sieve_primes"} && $Math::Prime::Util::GMP::VERSION >= 0.34;
517              
518             # At some point even the pretty-fast pure perl sieve is going to be a
519             # dog, and we should move to trials. This is typical with a small range
520             # on a large base. More thought on the switchover should be done.
521 13 50 66     120 return trial_primes($low, $high) if ref($low) eq 'Math::BigInt'
      33        
      66        
522             || ref($high) eq 'Math::BigInt'
523             || ($low > 1_000_000_000_000 && ($high-$low) < int($low/1_000_000));
524              
525 12 100 66     92 push @$sref, 2 if ($low <= 2) && ($high >= 2);
526 12 100 66     62 push @$sref, 3 if ($low <= 3) && ($high >= 3);
527 12 100 66     53 push @$sref, 5 if ($low <= 5) && ($high >= 5);
528 12 100       36 $low = 7 if $low < 7;
529 12 100       46 $low++ if ($low % 2) == 0;
530 12 100       39 $high-- if ($high % 2) == 0;
531 12 50       39 return $sref if $low > $high;
532              
533 12         25 my($n,$sieveref);
534 12 100       35 if ($low == 7) {
535 5         10 $n = 0;
536 5         21 $sieveref = _sieve_erat($high);
537 5         42 substr($$sieveref,0,3,'111');
538             } else {
539 7         10 $n = $low-1;
540 7         23 $sieveref = _sieve_segment($low,$high);
541             }
542 12         34551 push @$sref, $n+2*pos($$sieveref)-1 while $$sieveref =~ m/0/g;
543 12         2899 $sref;
544             }
545              
546             sub sieve_range {
547 0     0 0 0 my($n, $width, $depth) = @_;
548 0         0 _validate_positive_integer($n);
549 0         0 _validate_positive_integer($width);
550 0         0 _validate_positive_integer($depth);
551              
552 0         0 my @candidates;
553 0         0 my $start = $n;
554              
555 0 0       0 if ($n < 5) {
556 0 0 0     0 push @candidates, (2-$n) if $n <= 2 && $n+$width-1 >= 2;
557 0 0 0     0 push @candidates, (3-$n) if $n <= 3 && $n+$width-1 >= 3;
558 0 0 0     0 push @candidates, (4-$n) if $n <= 4 && $n+$width-1 >= 4 && $depth < 2;
      0        
559 0         0 $start = 5;
560 0         0 $width -= ($start - $n);
561             }
562              
563 0 0       0 return @candidates, map {$start+$_-$n } 0 .. $width-1 if $depth < 2;
  0         0  
564 0         0 return @candidates, map { $_ - $n }
565 0 0 0     0 grep { ($_ & 1) && ($depth < 3 || ($_ % 3)) }
566 0 0       0 map { $start+$_ }
  0         0  
567             0 .. $width-1 if $depth < 5;
568              
569 0 0       0 if (!($start & 1)) { $start++; $width--; }
  0         0  
  0         0  
570 0 0       0 $width-- if !($width&1);
571 0 0       0 return @candidates if $width < 1;
572              
573 0         0 my $sieveref = _sieve_segment($start, $start+$width-1, $depth);
574 0         0 my $offset = $start - $n - 2;
575 0         0 while ($$sieveref =~ m/0/g) {
576 0         0 push @candidates, $offset + (pos($$sieveref) << 1);
577             }
578 0         0 return @candidates;
579             }
580              
581             sub sieve_prime_cluster {
582 12     12 0 8097 my($lo,$hi,@cl) = @_;
583 12         67 my $_verbose = Math::Prime::Util::prime_get_config()->{'verbose'};
584 12         67 _validate_positive_integer($lo);
585 12         35 _validate_positive_integer($hi);
586              
587 12 50       54 if ($Math::Prime::Util::_GMPfunc{"sieve_prime_cluster"}) {
588 0 0       0 return map { ($_ > ''.~0) ? Math::BigInt->new(''.$_) : $_ }
  0         0  
589             Math::Prime::Util::GMP::sieve_prime_cluster($lo,$hi,@cl);
590             }
591              
592 12 50       38 return @{primes($lo,$hi)} if scalar(@cl) == 0;
  0         0  
593              
594 12         36 unshift @cl, 0;
595 12         47 for my $i (1 .. $#cl) {
596 36         77 _validate_positive_integer($cl[$i]);
597 36 50       94 croak "sieve_prime_cluster: values must be even" if $cl[$i] & 1;
598 36 50       110 croak "sieve_prime_cluster: values must be increasing" if $cl[$i] <= $cl[$i-1];
599             }
600 12         39 my($p,$sievelim,@p) = (17, 2000);
601 12 50       42 $p = 13 if ($hi-$lo) < 50_000_000;
602 12 50       2636 $p = 11 if ($hi-$lo) < 1_000_000;
603 12 100 100     2173 $p = 7 if ($hi-$lo) < 20_000 && $lo < INTMAX;
604              
605             # Add any cases under our sieving point.
606 12 100       3320 if ($lo <= $sievelim) {
607 2 50       6 $sievelim = $hi if $sievelim > $hi;
608 2         24 for my $n (@{primes($lo,$sievelim)}) {
  2         9  
609 606         791 my $ac = 1;
610 606         1014 for my $ci (1 .. $#cl) {
611 606 100       1048 if (!is_prime($n+$cl[$ci])) { $ac = 0; last; }
  484         681  
  484         636  
612             }
613 606 100       1180 push @p, $n if $ac;
614             }
615 2         32 $lo = next_prime($sievelim);
616             }
617 12 50       940 return @p if $lo > $hi;
618              
619             # Compute acceptable residues.
620 12         450 my $pr = primorial($p);
621 12         55 my $startpr = _bigint_to_int($lo % $pr);
622              
623 12 100       714 my @acc = grep { ($_ & 1) && $_%3 } ($startpr .. $startpr + $pr - 1);
  25620         41818  
624 12         415 for my $c (@cl) {
625 48 50       90 if ($p >= 7) {
626 48 100 100     94 @acc = grep { (($_+$c)%3) && (($_+$c)%5) && (($_+$c)%7) } @acc;
  16618         39272  
627             } else {
628 0 0       0 @acc = grep { (($_+$c)%3) && (($_+$c)%5) } @acc;
  0         0  
629             }
630             }
631 12         37 for my $c (@cl) {
632 48         71 @acc = grep { Math::Prime::Util::gcd($_+$c,$pr) == 1 } @acc;
  1912         3750  
633             }
634 12         31 @acc = map { $_-$startpr } @acc;
  606         717  
635              
636 12 50       49 print "cluster sieve using ",scalar(@acc)," residues mod $pr\n" if $_verbose;
637 12 50       35 return @p if scalar(@acc) == 0;
638              
639             # Prepare table for more sieving.
640 12         19 my @mprimes = @{primes( $p+1, $sievelim)};
  12         34  
641 12         95 my @vprem;
642 12         39 for my $p (@mprimes) {
643 3577         4798 for my $c (@cl) {
644 14306         35209 $vprem[$p]->[ ($p-($c%$p)) % $p ] = 1;
645             }
646             }
647              
648             # Walk the range in primorial chunks, doing primality tests.
649 12         36 my($nummr, $numlucas) = (0,0);
650 12         81 while ($lo <= $hi) {
651              
652 70         7142 my @racc = @acc;
653              
654             # Make sure we don't do anything past the limit
655 70 100       191 if (($lo+$acc[-1]) > $hi) {
656 12         1783 my $max = _bigint_to_int($hi-$lo);
657 12         271 @racc = grep { $_ <= $max } @racc;
  606         846  
658             }
659              
660             # Sieve more values using native math
661 70         6673 foreach my $p (@mprimes) {
662 12500         20373 my $rem = _bigint_to_int( $lo % $p );
663 12500         105067 @racc = grep { !$vprem[$p]->[ ($rem+$_) % $p ] } @racc;
  191619         327084  
664 12500 100       26400 last unless scalar(@racc);
665             }
666              
667             # Do final primality tests.
668 70 100       195 if ($lo < 1e13) {
669 24         45 for my $r (@racc) {
670 442         677 my($good, $p) = (1, $lo + $r);
671 442         605 for my $c (@cl) {
672 884         1067 $nummr++;
673 884 50       2064 if (!Math::Prime::Util::is_prime($p+$c)) { $good = 0; last; }
  0         0  
  0         0  
674             }
675 442 50       904 push @p, $p if $good;
676             }
677             } else {
678 46         5934 for my $r (@racc) {
679 106         526 my($good, $p) = (1, $lo + $r);
680 106         19785 for my $c (@cl) {
681 140         273 $nummr++;
682 140 100       429 if (!Math::Prime::Util::is_strong_pseudoprime($p+$c,2)) { $good = 0; last; }
  100         197  
  100         195  
683             }
684 106 100       684 next unless $good;
685 6         17 for my $c (@cl) {
686 12         1691 $numlucas++;
687 12 50       45 if (!Math::Prime::Util::is_extra_strong_lucas_pseudoprime($p+$c)) { $good = 0; last; }
  0         0  
  0         0  
688             }
689 6 50       995 push @p, $p if $good;
690             }
691             }
692              
693 70         272 $lo += $pr;
694             }
695 12 50       1662 print "cluster sieve ran $nummr MR and $numlucas Lucas tests\n" if $_verbose;
696 12         11227 @p;
697             }
698              
699              
700             sub _n_ramanujan_primes {
701 0     0   0 my($n) = @_;
702 0 0       0 return [] if $n <= 0;
703 0         0 my $max = nth_prime_upper(int(48/19*$n)+1);
704 0         0 my @L = (2, (0) x $n-1);
705 0         0 my $s = 1;
706 0         0 for (my $k = 7; $k <= $max; $k += 2) {
707 0 0       0 $s++ if is_prime($k);
708 0 0       0 $L[$s] = $k+1 if $s < $n;
709 0 0 0     0 $s-- if ($k&3) == 1 && is_prime(($k+1)>>1);
710 0 0       0 $L[$s] = $k+2 if $s < $n;
711             }
712 0         0 \@L;
713             }
714              
715             sub _ramanujan_primes {
716 0     0   0 my($low,$high) = @_;
717 0 0       0 ($low,$high) = (2, $low) unless defined $high;
718 0 0 0     0 return [] if ($low > $high) || ($high < 2);
719 0         0 my $nn = prime_count_upper($high) >> 1;
720 0         0 my $L = _n_ramanujan_primes($nn);
721 0   0     0 shift @$L while @$L && $L->[0] < $low;
722 0   0     0 pop @$L while @$L && $L->[-1] > $high;
723 0         0 $L;
724             }
725              
726             sub is_ramanujan_prime {
727 0     0 0 0 my($n) = @_;
728 0 0       0 return 1 if $n == 2;
729 0 0       0 return 0 if $n < 11;
730 0         0 my $L = _ramanujan_primes($n,$n);
731 0 0       0 return (scalar(@$L) > 0) ? 1 : 0;
732             }
733              
734             sub nth_ramanujan_prime {
735 0     0 0 0 my($n) = @_;
736 0 0       0 return undef if $n <= 0; ## no critic qw(ProhibitExplicitReturnUndef)
737 0         0 my $L = _n_ramanujan_primes($n);
738 0         0 return $L->[$n-1];
739             }
740              
741             sub next_prime {
742 4959     4959 0 245475 my($n) = @_;
743 4959         12199 _validate_positive_integer($n);
744 4958 100       15825 return $_prime_next_small[$n] if $n <= $#_prime_next_small;
745             # This turns out not to be faster.
746             # return $_primes_small[1+_tiny_prime_count($n)] if $n < $_primes_small[-1];
747              
748 933 100 100     5022 return Math::BigInt->new(MPU_32BIT ? "4294967311" : "18446744073709551629")
749             if ref($n) ne 'Math::BigInt' && $n >= MPU_MAXPRIME;
750             # n is now either 1) not bigint and < maxprime, or (2) bigint and >= uvmax
751              
752 928 50 66     2008 if ($n > 4294967295 && Math::Prime::Util::prime_get_config()->{'gmp'}) {
753 0         0 return Math::Prime::Util::_reftyped($_[0], Math::Prime::Util::GMP::next_prime($n));
754             }
755              
756 928 100       1926 if (ref($n) eq 'Math::BigInt') {
757 11   100     27 do {
      66        
758 115         199905 $n += $_wheeladvance30[$n%30];
759             } while !Math::BigInt::bgcd($n, B_PRIM767)->is_one ||
760             !_miller_rabin_2($n) || !is_extra_strong_lucas_pseudoprime($n);
761             } else {
762 917   100     1322 do {
763 4260         11581 $n += $_wheeladvance30[$n%30];
764             } while !($n%7) || !_is_prime7($n);
765             }
766 928         6779 $n;
767             }
768              
769             sub prev_prime {
770 157     157 0 3213 my($n) = @_;
771 157         345 _validate_positive_integer($n);
772 157 100       301 return (undef,undef,undef,2,3,3,5,5,7,7,7,7)[$n] if $n <= 11;
773 156 50 66     509 if ($n > 4294967295 && Math::Prime::Util::prime_get_config()->{'gmp'}) {
774 0         0 return Math::Prime::Util::_reftyped($_[0], Math::Prime::Util::GMP::prev_prime($n));
775             }
776              
777 156 100       323 if (ref($n) eq 'Math::BigInt') {
778 2   100     5 do {
      100        
779 22         44818 $n -= $_wheelretreat30[$n%30];
780             } while !Math::BigInt::bgcd($n, B_PRIM767)->is_one ||
781             !_miller_rabin_2($n) || !is_extra_strong_lucas_pseudoprime($n);
782             } else {
783 154   100     194 do {
784 3082         7214 $n -= $_wheelretreat30[$n%30];
785             } while !($n%7) || !_is_prime7($n);
786             }
787 156         1349 $n;
788             }
789              
790             sub partitions {
791 57     57 0 106 my $n = shift;
792              
793 57         161 my $d = int(sqrt($n+1));
794 57         151 my @pent = (1, map { (($_*(3*$_+1))>>1, (($_+1)*(3*$_+2))>>1) } 1 .. $d);
  422         821  
795 57 100       156 my $ZERO = ($n >= ((~0 > 4294967295) ? 400 : 270)) ? BZERO : 0;
796 57         111 my @part = ($ZERO+1);
797 57         936 foreach my $j (scalar @part .. $n) {
798 9683         1130776 my ($psum1, $psum2, $k) = ($ZERO, $ZERO, 1);
799 9683         14598 foreach my $p (@pent) {
800 474063 100       27246547 last if $p > $j;
801 464380 100       728457 if ((++$k) & 2) { $psum1 += $part[ $j - $p ] }
  237074         491790  
802 227306         472979 else { $psum2 += $part[ $j - $p ] }
803             }
804 9683         19375 $part[$j] = $psum1 - $psum2;
805             }
806 57         4146 return $part[$n];
807             }
808              
809             sub primorial {
810 67     67 0 127 my $n = shift;
811              
812 67         108 my @plist = @{primes($n)};
  67         171  
813 67         195 my $max = (MPU_32BIT) ? 29 : (OLD_PERL_VERSION) ? 43 : 53;
814              
815             # If small enough, multiply the small primes.
816 67 100       169 if ($n < $max) {
817 30         69 my $pn = 1;
818 30         114 $pn *= $_ for @plist;
819 30         168 return $pn;
820             }
821              
822             # Otherwise, combine them as UVs, then combine using product tree.
823 37         65 my $i = 0;
824 37         84 while ($i < $#plist) {
825 960         1485 my $m = $plist[$i] * $plist[$i+1];
826 960 100       1428 if ($m <= INTMAX) { splice(@plist, $i, 2, $m); }
  893         2204  
827 67         134 else { $i++; }
828             }
829 37         134 vecprod(@plist);
830             }
831              
832             sub consecutive_integer_lcm {
833 103     103 0 195 my $n = shift;
834              
835 103         159 my $max = (MPU_32BIT) ? 22 : (OLD_PERL_VERSION) ? 37 : 46;
836 103 100       408 my $pn = ref($n) ? ref($n)->new(1) : ($n >= $max) ? Math::BigInt->bone() : 1;
    50          
837 103         2925 for (my $p = 2; $p <= $n; $p = next_prime($p)) {
838 1789         4023 my($p_power, $pmin) = ($p, int($n/$p));
839 1789         3567 $p_power *= $p while $p_power <= $pmin;
840 1789         3987 $pn *= $p_power;
841             }
842 103 100       304 $pn = _bigint_to_int($pn) if $pn <= BMAX;
843 103         2626 return $pn;
844             }
845              
846             sub jordan_totient {
847 25     25 0 2682 my($k, $n) = @_;
848 25 0       74 return ($n == 1) ? 1 : 0 if $k == 0;
    50          
849 25 50       482 return euler_phi($n) if $k == 1;
850 25 0       308 return ($n == 1) ? 1 : 0 if $n <= 1;
    50          
851              
852             return Math::Prime::Util::_reftyped($_[0], Math::Prime::Util::GMP::jordan_totient($k, $n))
853 25 50       291 if $Math::Prime::Util::_GMPfunc{"jordan_totient"};
854              
855              
856 25         126 my @pe = Math::Prime::Util::factor_exp($n);
857 25 100       148 $n = Math::BigInt->new("$n") unless ref($n) eq 'Math::BigInt';
858 25         1048 my $totient = BONE->copy;
859 25         571 foreach my $f (@pe) {
860 38         187 my ($p, $e) = @$f;
861 38         109 $p = Math::BigInt->new("$p")->bpow($k);
862 38         12890 $totient->bmul($p->copy->bdec());
863 38         5079 $totient->bmul($p) for 2 .. $e;
864             }
865 25 100       477 $totient = _bigint_to_int($totient) if $totient->bacmp(BMAX) <= 0;
866 25         704 return $totient;
867             }
868              
869             sub euler_phi {
870 108 100   108 1 12537 return euler_phi_range(@_) if scalar @_ > 1;
871 105         157 my($n) = @_;
872 105 50 33     300 return 0 if defined $n && $n < 0;
873              
874             return Math::Prime::Util::_reftyped($_[0],Math::Prime::Util::GMP::totient($n))
875 105 50       407 if $Math::Prime::Util::_GMPfunc{"totient"};
876              
877 105         227 _validate_positive_integer($n);
878 105 100       184 return $n if $n <= 1;
879              
880 101         264 my $totient = $n - $n + 1;
881              
882             # Fast reduction of multiples of 2, may also reduce n for factoring
883 101 100       520 if (ref($n) eq 'Math::BigInt') {
884 1         5 my $s = 0;
885 1 50       5 if ($n->is_even) {
886 1         18 do { $n->brsft(BONE); $s++; } while $n->is_even;
  1         8  
  1         138  
887 1 50       15 $totient->blsft($s-1) if $s > 1;
888             }
889             } else {
890 100         194 while (($n % 4) == 0) { $n >>= 1; $totient <<= 1; }
  49         64  
  49         84  
891 100 100       173 if (($n % 2) == 0) { $n >>= 1; }
  50         73  
892             }
893              
894 101         355 my @pe = Math::Prime::Util::factor_exp($n);
895              
896 101 100 100     340 if ($#pe == 0 && $pe[0]->[1] == 1) {
    100          
897 49 50       94 if (ref($n) ne 'Math::BigInt') { $totient *= $n-1; }
  49         71  
898 0         0 else { $totient->bmul($n->bdec()); }
899             } elsif (ref($n) ne 'Math::BigInt') {
900 51         94 foreach my $f (@pe) {
901 83         138 my ($p, $e) = @$f;
902 83         105 $totient *= $p - 1;
903 83         165 $totient *= $p for 2 .. $e;
904             }
905             } else {
906 1         5 my $zero = $n->copy->bzero;
907 1         53 foreach my $f (@pe) {
908 10         26 my ($p, $e) = @$f;
909 10         1056 $p = $zero->copy->badd("$p");
910 10         1548 $totient->bmul($p->copy->bdec());
911 10         1279 $totient->bmul($p) for 2 .. $e;
912             }
913             }
914 101 50 66     214 $totient = _bigint_to_int($totient) if ref($totient) eq 'Math::BigInt'
915             && $totient->bacmp(BMAX) <= 0;
916 101         280 return $totient;
917             }
918              
919             sub inverse_totient {
920 0     0 0 0 my($n) = @_;
921 0         0 _validate_positive_integer($n);
922              
923 0 0       0 return wantarray ? (1,2) : 2 if $n == 1;
    0          
924 0 0 0     0 return wantarray ? () : 0 if $n < 1 || ($n & 1);
    0          
925              
926 0 0 0     0 $n = Math::Prime::Util::_to_bigint("$n") if !ref($n) && $n > 2**49;
927 0         0 my $do_bigint = ref($n);
928              
929 0 0       0 if (is_prime($n >> 1)) { # Coleman Remark 3.3 (Thm 3.1) and Prop 6.2
930 0 0       0 return wantarray ? () : 0 if !is_prime($n+1);
    0          
931 0 0       0 return wantarray ? ($n+1, 2*$n+2) : 2 if $n >= 10;
    0          
932             }
933              
934 0 0       0 if (!wantarray) {
935 0         0 my %r = ( 1 => 1 );
936 0     0   0 Math::Prime::Util::fordivisors(sub { my $d = $_;
937 0 0       0 $d = $do_bigint->new("$d") if $do_bigint;
938 0         0 my $p = $d+1;
939 0 0       0 if (Math::Prime::Util::is_prime($p)) {
940 0         0 my($dp,@sumi,@sumv) = ($d);
941 0         0 for my $v (1 .. 1 + Math::Prime::Util::valuation($n, $p)) {
942 0         0 Math::Prime::Util::fordivisors(sub { my $d2 = $_;
943 0 0       0 if (defined $r{$d2}) { push @sumi, $d2*$dp; push @sumv, $r{$d2}; }
  0         0  
  0         0  
944 0         0 }, $n / $dp);
945 0         0 $dp *= $p;
946             }
947 0         0 $r{ $sumi[$_] } += $sumv[$_] for 0 .. $#sumi;
948             }
949 0         0 }, $n);
950 0 0       0 return (defined $r{$n}) ? $r{$n} : 0;
951             } else {
952 0         0 my %r = ( 1 => [1] );
953 0     0   0 Math::Prime::Util::fordivisors(sub { my $d = $_;
954 0 0       0 $d = $do_bigint->new("$d") if $do_bigint;
955 0         0 my $p = $d+1;
956 0 0       0 if (Math::Prime::Util::is_prime($p)) {
957 0         0 my($dp,$pp,@T) = ($d,$p);
958 0         0 for my $v (1 .. 1 + Math::Prime::Util::valuation($n, $p)) {
959 0         0 Math::Prime::Util::fordivisors(sub { my $d2 = $_;
960 0 0       0 push @T, [ $d2*$dp, [map { $_ * $pp } @{ $r{$d2} }] ] if defined $r{$d2};
  0         0  
  0         0  
961 0         0 }, $n / $dp);
962 0         0 $dp *= $p;
963 0         0 $pp *= $p;
964             }
965 0         0 push @{$r{$_->[0]}}, @{$_->[1]} for @T;
  0         0  
  0         0  
966             }
967 0         0 }, $n);
968 0 0       0 return () unless defined $r{$n};
969 0         0 delete @r{ grep { $_ != $n } keys %r }; # Delete all intermediate results
  0         0  
970 0         0 my @result = sort { $a <=> $b } @{$r{$n}};
  0         0  
  0         0  
971 0         0 return @result;
972             }
973             }
974              
975             sub euler_phi_range {
976 3     3 1 11 my($lo, $hi) = @_;
977 3         13 _validate_integer($lo);
978 3         10 _validate_integer($hi);
979              
980 3         5 my @totients;
981 3   66     20 while ($lo < 0 && $lo <= $hi) {
982 5         11 push @totients, 0;
983 5         11 $lo++;
984             }
985 3 50       10 return @totients if $hi < $lo;
986              
987 3 50 33     22 if ($hi > 2**30 || $hi-$lo < 100) {
988 3         9 while ($lo <= $hi) {
989 101         195 push @totients, euler_phi($lo++);
990             }
991             } else {
992 0         0 my @tot = (0 .. $hi);
993 0         0 foreach my $i (2 .. $hi) {
994 0 0       0 next unless $tot[$i] == $i;
995 0         0 $tot[$i] = $i-1;
996 0         0 foreach my $j (2 .. int($hi / $i)) {
997 0         0 $tot[$i*$j] -= $tot[$i*$j]/$i;
998             }
999             }
1000 0 0       0 splice(@tot, 0, $lo) if $lo > 0;
1001 0         0 push @totients, @tot;
1002             }
1003 3         49 @totients;
1004             }
1005              
1006             sub moebius {
1007 102 100   102 1 9663 return moebius_range(@_) if scalar @_ > 1;
1008 99         211 my($n) = @_;
1009 99 50 33     428 $n = -$n if defined $n && $n < 0;
1010 99 100       1691 _validate_num($n) || _validate_positive_integer($n);
1011 99 0       207 return ($n == 1) ? 1 : 0 if $n <= 1;
    50          
1012 99 100 66     1435 return 0 if ($n >= 49) && (!($n % 4) || !($n % 9) || !($n % 25) || !($n%49) );
      100        
1013 98         9816 my @factors = Math::Prime::Util::factor($n);
1014 98         280 foreach my $i (1 .. $#factors) {
1015 106 100       319 return 0 if $factors[$i] == $factors[$i-1];
1016             }
1017 66 100       449 return ((scalar @factors) % 2) ? -1 : 1;
1018             }
1019             sub is_square_free {
1020 4 100   4 0 937 return (Math::Prime::Util::moebius($_[0]) != 0) ? 1 : 0;
1021             }
1022             sub is_semiprime {
1023 1     1 0 5 my($n) = @_;
1024 1         4 _validate_positive_integer($n);
1025 1 50       4 return ($n == 4) if $n < 6;
1026 1 0       143 return (Math::Prime::Util::is_prob_prime($n>>1) ? 1 : 0) if ($n % 2) == 0;
    50          
1027 1 0       414 return (Math::Prime::Util::is_prob_prime($n/3) ? 1 : 0) if ($n % 3) == 0;
    50          
1028 1 0       351 return (Math::Prime::Util::is_prob_prime($n/5) ? 1 : 0) if ($n % 5) == 0;
    50          
1029             {
1030 1         330 my @f = trial_factor($n, 4999);
  1         6  
1031 1 50       35 return 0 if @f > 2;
1032 0 0       0 return (_is_prime7($f[1]) ? 1 : 0) if @f == 2;
    0          
1033             }
1034 0 0       0 return 0 if _is_prime7($n);
1035             {
1036 0         0 my @f = pminus1_factor ($n, 250_000);
1037 0 0       0 return 0 if @f > 2;
1038 0 0       0 return (_is_prime7($f[1]) ? 1 : 0) if @f == 2;
    0          
1039             }
1040             {
1041 0         0 my @f = pbrent_factor ($n, 128*1024, 3, 1);
  0         0  
  0         0  
1042 0 0       0 return 0 if @f > 2;
1043 0 0       0 return (_is_prime7($f[1]) ? 1 : 0) if @f == 2;
    0          
1044             }
1045 0 0       0 return (scalar(Math::Prime::Util::factor($n)) == 2) ? 1 : 0;
1046             }
1047              
1048             sub _totpred {
1049 370     370   39746 my($n, $maxd) = @_;
1050 370 50 100     1865 return 0 if $maxd <= 1 || (ref($n) ? $n->is_odd() : ($n & 1));
    100          
1051 131 50 33     2233 $n = Math::BigInt->new("$n") unless ref($n) || $n < INTMAX;
1052 131         379 $n >>= 1;
1053 131 100 100     27540 return 1 if $n == 1 || ($n < $maxd && Math::Prime::Util::is_prime(2*$n+1));
      66        
1054 130         33093 for my $d (Math::Prime::Util::divisors($n)) {
1055 1001 100       81061 last if $d >= $maxd;
1056 881 100       23015 my $p = ($d < (INTMAX >> 1)) ? ($d<<1)+1 : Math::Prime::Util::vecprod(2,$d)+1;
1057 881 100       3737 next unless Math::Prime::Util::is_prime($p);
1058 335         854 my $r = int($n / $d);
1059 335         110429 while (1) {
1060 368 100 100     11144 return 1 if $r == $p || _totpred($r, $d);
1061 364 100       2041 last if $r % $p;
1062 33         7274 $r = int($r / $p);
1063             }
1064             }
1065 126         3770 0;
1066             }
1067             sub is_totient {
1068 3     3 0 36 my($n) = @_;
1069 3         11 _validate_positive_integer($n);
1070 3 50       10 return 1 if $n == 1;
1071 3 50       373 return 0 if $n <= 0;
1072 3         546 return _totpred($n,$n);
1073             }
1074              
1075              
1076             sub moebius_range {
1077 6     6 1 15 my($lo, $hi) = @_;
1078 6         18 _validate_integer($lo);
1079 6         15 _validate_integer($hi);
1080 6 50       19 return () if $hi < $lo;
1081 6 50       14 return moebius($lo) if $lo == $hi;
1082 6 100       15 if ($lo < 0) {
1083 2 100       6 if ($hi < 0) {
1084 1         7 return reverse(moebius_range(-$hi,-$lo));
1085             } else {
1086 1         3 return (reverse(moebius_range(1,-$lo)), moebius_range(0,$hi));
1087             }
1088             }
1089 4 50       12 if ($hi > 2**32) {
1090 0         0 my @mu;
1091 0         0 while ($lo <= $hi) {
1092 0         0 push @mu, moebius($lo++);
1093             }
1094 0         0 return @mu;
1095             }
1096 4         13 my @mu = map { 1 } $lo .. $hi;
  44         64  
1097 4 100       14 $mu[0] = 0 if $lo == 0;
1098 4         17 my($p, $sqrtn) = (2, int(sqrt($hi)+0.5));
1099 4         13 while ($p <= $sqrtn) {
1100 14         24 my $i = $p * $p;
1101 14 100       35 $i = $i * int($lo/$i) + (($lo % $i) ? $i : 0) if $i < $lo;
    100          
1102 14         32 while ($i <= $hi) {
1103 15         25 $mu[$i-$lo] = 0;
1104 15         27 $i += $p * $p;
1105             }
1106 14         25 $i = $p;
1107 14 100       40 $i = $i * int($lo/$i) + (($lo % $i) ? $i : 0) if $i < $lo;
    100          
1108 14         29 while ($i <= $hi) {
1109 49         63 $mu[$i-$lo] *= -$p;
1110 49         85 $i += $p;
1111             }
1112 14         38 $p = next_prime($p);
1113             }
1114 4         14 foreach my $i ($lo .. $hi) {
1115 44         57 my $m = $mu[$i-$lo];
1116 44 100       79 $m *= -1 if abs($m) != $i;
1117 44         73 $mu[$i-$lo] = ($m>0) - ($m<0);
1118             }
1119 4         55 return @mu;
1120             }
1121              
1122             sub mertens {
1123 1     1 0 3 my($n) = @_;
1124             # This is the most basic Deléglise and Rivat algorithm. u = n^1/2
1125             # and no segmenting is done. Their algorithm uses u = n^1/3, breaks
1126             # the summation into two parts, and calculates those in segments. Their
1127             # computation time growth is half of this code.
1128 1 50       4 return $n if $n <= 1;
1129 1         4 my $u = int(sqrt($n));
1130 1         19 my @mu = (0, Math::Prime::Util::moebius(1, $u)); # Hold values of mu for 0-u
1131 1         3 my $musum = 0;
1132 1         3 my @M = map { $musum += $_; } @mu; # Hold values of M for 0-u
  65         91  
1133 1         2 my $sum = $M[$u];
1134 1         4 foreach my $m (1 .. $u) {
1135 64 100       110 next if $mu[$m] == 0;
1136 39         49 my $inner_sum = 0;
1137 39         59 my $lower = int($u/$m) + 1;
1138 39         62 my $last_nmk = int($n/($m*$lower));
1139 39         63 my ($denom, $this_k, $next_k) = ($m, 0, int($n/($m*1)));
1140 39         60 for my $nmk (1 .. $last_nmk) {
1141 2048         2405 $denom += $m;
1142 2048         2627 $this_k = int($n/$denom);
1143 2048 100       3252 next if $this_k == $next_k;
1144 982         1372 ($this_k, $next_k) = ($next_k, $this_k);
1145 982         1375 $inner_sum += $M[$nmk] * ($this_k - $next_k);
1146             }
1147 39         80 $sum -= $mu[$m] * $inner_sum;
1148             }
1149 1         11 return $sum;
1150             }
1151              
1152             sub ramanujan_sum {
1153 0     0 0 0 my($k,$n) = @_;
1154 0 0 0     0 return 0 if $k < 1 || $n < 1;
1155 0         0 my $g = $k / Math::Prime::Util::gcd($k,$n);
1156 0         0 my $m = Math::Prime::Util::moebius($g);
1157 0 0 0     0 return $m if $m == 0 || $k == $g;
1158 0         0 $m * (Math::Prime::Util::euler_phi($k) / Math::Prime::Util::euler_phi($g));
1159             }
1160              
1161             sub liouville {
1162 4     4 0 1057 my($n) = @_;
1163 4         28 my $l = (-1) ** scalar Math::Prime::Util::factor($n);
1164 4         39 return $l;
1165             }
1166              
1167             # Exponential of Mangoldt function (A014963).
1168             # Return p if n = p^m [p prime, m >= 1], 1 otherwise.
1169             sub exp_mangoldt {
1170 5     5 0 12 my($n) = @_;
1171 5         8 my $p;
1172 5 100       38 return 1 unless Math::Prime::Util::is_prime_power($n,\$p);
1173 3         14 $p;
1174             }
1175              
1176             sub carmichael_lambda {
1177 3     3 0 1439 my($n) = @_;
1178 3 50       16 return euler_phi($n) if $n < 8; # = phi(n) for n < 8
1179 3 50       258 return $n >> 2 if ($n & ($n-1)) == 0; # = phi(n)/2 = n/4 for 2^k, k>2
1180              
1181 3         2323 my @pe = Math::Prime::Util::factor_exp($n);
1182 3 50 66     25 $pe[0]->[1]-- if $pe[0]->[0] == 2 && $pe[0]->[1] > 2;
1183              
1184 3         8 my $lcm;
1185 3 100       16 if (!ref($n)) {
1186             $lcm = Math::Prime::Util::lcm(
1187 1         4 map { ($_->[0] ** ($_->[1]-1)) * ($_->[0]-1) } @pe
  3         15  
1188             );
1189             } else {
1190             $lcm = Math::BigInt::blcm(
1191 14         4284 map { $_->[0]->copy->bpow($_->[1]->copy->bdec)->bmul($_->[0]->copy->bdec) }
1192 2         7 map { [ map { Math::BigInt->new("$_") } @$_ ] }
  14         423  
  28         603  
1193             @pe
1194             );
1195 2 100       2616 $lcm = _bigint_to_int($lcm) if $lcm->bacmp(BMAX) <= 0;
1196             }
1197 3         81 $lcm;
1198             }
1199              
1200             sub is_carmichael {
1201 1     1 0 5 my($n) = @_;
1202 1         6 _validate_positive_integer($n);
1203              
1204             # This works fine, but very slow
1205             # return !is_prime($n) && ($n % carmichael_lambda($n)) == 1;
1206              
1207 1 50 33     6 return 0 if $n < 561 || ($n % 2) == 0;
1208 1 50 33     682 return 0 if (!($n % 9) || !($n % 25) || !($n%49) || !($n%121));
      33        
      33        
1209              
1210             # Check Korselt's criterion for small divisors
1211 1         892 my $fn = $n;
1212 1         3 for my $a (5,7,11,13,17,19,23,29,31,37,41,43) {
1213 12 50       3802 if (($fn % $a) == 0) {
1214 0 0       0 return 0 if (($n-1) % ($a-1)) != 0; # Korselt
1215 0         0 $fn /= $a;
1216 0 0       0 return 0 unless $fn % $a; # not square free
1217             }
1218             }
1219 1 50       351 return 0 if Math::Prime::Util::powmod(2, $n-1, $n) != 1;
1220              
1221             # After pre-tests, it's reasonably likely $n is a Carmichael number or prime
1222              
1223             # Use probabilistic test if too large to reasonably factor.
1224 1 50       169 if (length($fn) > 50) {
1225 0 0       0 return 0 if Math::Prime::Util::is_prime($n);
1226 0         0 for my $t (13 .. 150) {
1227 0         0 my $a = $_primes_small[$t];
1228 0         0 my $gcd = Math::Prime::Util::gcd($a, $fn);
1229 0 0       0 if ($gcd == 1) {
1230 0 0       0 return 0 if Math::Prime::Util::powmod($a, $n-1, $n) != 1;
1231             } else {
1232 0 0       0 return 0 if $gcd != $a; # Not square free
1233 0 0       0 return 0 if (($n-1) % ($a-1)) != 0; # factor doesn't divide
1234 0         0 $fn /= $a;
1235             }
1236             }
1237 0         0 return 1;
1238             }
1239              
1240             # Verify with factoring.
1241 1         39 my @pe = Math::Prime::Util::factor_exp($n);
1242 1 50       7 return 0 if scalar(@pe) < 3;
1243 1         5 for my $pe (@pe) {
1244 3 50 33     1759 return 0 if $pe->[1] > 1 || (($n-1) % ($pe->[0]-1)) != 0;
1245             }
1246 1         756 1;
1247             }
1248              
1249             sub is_quasi_carmichael {
1250 0     0 0 0 my($n) = @_;
1251 0         0 _validate_positive_integer($n);
1252              
1253 0 0       0 return 0 if $n < 35;
1254 0 0 0     0 return 0 if (!($n % 4) || !($n % 9) || !($n % 25) || !($n%49) || !($n%121));
      0        
      0        
      0        
1255              
1256 0         0 my @pe = Math::Prime::Util::factor_exp($n);
1257             # Not quasi-Carmichael if prime
1258 0 0       0 return 0 if scalar(@pe) < 2;
1259             # Not quasi-Carmichael if not square free
1260 0         0 for my $pe (@pe) {
1261 0 0       0 return 0 if $pe->[1] > 1;
1262             }
1263 0         0 my @f = map { $_->[0] } @pe;
  0         0  
1264 0         0 my $nbases = 0;
1265 0 0       0 if ($n < 2000) {
1266             # In theory for performance, but mainly keeping to show direct method.
1267 0         0 my $lim = $f[-1];
1268 0         0 $lim = (($n-$lim*$lim) + $lim - 1) / $lim;
1269 0         0 for my $b (1 .. $f[0]-1) {
1270 0         0 my $nb = $n - $b;
1271 0 0   0   0 $nbases++ if Math::Prime::Util::vecall(sub { $nb % ($_-$b) == 0 }, @f);
  0         0  
1272             }
1273 0 0       0 if (scalar(@f) > 2) {
1274 0         0 for my $b (1 .. $lim-1) {
1275 0         0 my $nb = $n + $b;
1276 0 0   0   0 $nbases++ if Math::Prime::Util::vecall(sub { $nb % ($_+$b) == 0 }, @f);
  0         0  
1277             }
1278             }
1279             } else {
1280 0         0 my($spf,$lpf) = ($f[0], $f[-1]);
1281 0 0       0 if (scalar(@f) == 2) {
1282 0         0 foreach my $d (Math::Prime::Util::divisors($n/$spf - 1)) {
1283 0         0 my $k = $spf - $d;
1284 0         0 my $p = $n - $k;
1285 0 0       0 last if $d >= $spf;
1286 0 0   0   0 $nbases++ if Math::Prime::Util::vecall(sub { my $j = $_-$k; $j && ($p % $j) == 0 }, @f);
  0 0       0  
  0         0  
1287             }
1288             } else {
1289 0         0 foreach my $d (Math::Prime::Util::divisors($lpf * ($n/$lpf - 1))) {
1290 0         0 my $k = $lpf - $d;
1291 0         0 my $p = $n - $k;
1292 0 0 0     0 next if $k == 0 || $k >= $spf;
1293 0 0   0   0 $nbases++ if Math::Prime::Util::vecall(sub { my $j = $_-$k; $j && ($p % $j) == 0 }, @f);
  0 0       0  
  0         0  
1294             }
1295             }
1296             }
1297 0         0 $nbases;
1298             }
1299              
1300             sub is_pillai {
1301 0     0 0 0 my($p) = @_;
1302 0 0 0     0 return 0 if defined($p) && int($p) < 0;
1303 0         0 _validate_positive_integer($p);
1304 0 0       0 return 0 if $p <= 2;
1305              
1306 0         0 my $pm1 = $p-1;
1307 0         0 my $nfac = 5040 % $p;
1308 0         0 for (my $n = 8; $n < $p; $n++) {
1309 0         0 $nfac = Math::Prime::Util::mulmod($nfac, $n, $p);
1310 0 0 0     0 return $n if $nfac == $pm1 && ($p % $n) != 1;
1311             }
1312 0         0 0;
1313             }
1314              
1315             sub is_fundamental {
1316 2     2 0 23 my($n) = @_;
1317 2         11 _validate_integer($n);
1318 2         9 my $neg = ($n < 0);
1319 2 100       458 $n = -$n if $neg;
1320 2         54 my $r = $n & 15;
1321 2 50       751 if ($r) {
1322 2         64 my $r4 = $r & 3;
1323 2 100       478 if (!$neg) {
1324 1 0       4 return (($r == 4) ? 0 : is_square_free($n >> 2)) if $r4 == 0;
    50          
1325 1 50       172 return is_square_free($n) if $r4 == 1;
1326             } else {
1327 1 50       5 return (($r == 12) ? 0 : is_square_free($n >> 2)) if $r4 == 0;
    50          
1328 0 0       0 return is_square_free($n) if $r4 == 3;
1329             }
1330             }
1331 0         0 0;
1332             }
1333              
1334             my @_ds_overflow = # We'll use BigInt math if the input is larger than this.
1335             (~0 > 4294967295)
1336             ? (124, 3000000000000000000, 3000000000, 2487240, 64260, 7026)
1337             : ( 50, 845404560, 52560, 1548, 252, 84);
1338             sub divisor_sum {
1339 920     920 0 66985 my($n, $k) = @_;
1340 920 0 0     2109 return ((defined $k && $k==0) ? 2 : 1) if $n == 0;
    50          
1341 920 100       3253 return 1 if $n == 1;
1342              
1343 836 100 100     3923 if (defined $k && ref($k) eq 'CODE') {
1344 831         1275 my $sum = $n-$n;
1345 831         1481 my $refn = ref($n);
1346 831         3712 foreach my $d (Math::Prime::Util::divisors($n)) {
1347 3486 100       20699 $sum += $k->( $refn ? $refn->new("$d") : $d );
1348             }
1349 831         7205 return $sum;
1350             }
1351              
1352 5 50 100     28 croak "Second argument must be a code ref or number"
      66        
1353             unless !defined $k || _validate_num($k) || _validate_positive_integer($k);
1354 5 100       16 $k = 1 if !defined $k;
1355              
1356             return Math::Prime::Util::_reftyped($_[0], Math::Prime::Util::GMP::sigma($n, $k))
1357 5 50       18 if $Math::Prime::Util::_GMPfunc{"sigma"};
1358              
1359 5 50       36 my $will_overflow = ($k == 0) ? (length($n) >= $_ds_overflow[0])
    100          
1360             : ($k <= 5) ? ($n >= $_ds_overflow[$k])
1361             : 1;
1362              
1363             # The standard way is:
1364             # my $pk = $f ** $k; $product *= ($pk ** ($e+1) - 1) / ($pk - 1);
1365             # But we get less overflow using:
1366             # my $pk = $f ** $k; $product *= $pk**E for E in 0 .. e
1367             # Also separate BigInt and do fiddly bits for better performance.
1368              
1369 5         504 my @factors = Math::Prime::Util::factor_exp($n);
1370 5         13 my $product = 1;
1371 5         10 my @fm;
1372 5 100 33     48 if ($k == 0) {
    50          
    50          
    100          
1373 2         9 $product = Math::Prime::Util::vecprod(map { $_->[1]+1 } @factors);
  98         304  
1374             } elsif (!$will_overflow) {
1375 0         0 foreach my $f (@factors) {
1376 0         0 my ($p, $e) = @$f;
1377 0         0 my $pk = $p ** $k;
1378 0         0 my $fmult = $pk + 1;
1379 0         0 foreach my $E (2 .. $e) { $fmult += $pk**$E }
  0         0  
1380 0         0 $product *= $fmult;
1381             }
1382             } elsif (ref($n) && ref($n) ne 'Math::BigInt') {
1383             # This can help a lot for Math::GMP, etc.
1384 0         0 $product = ref($n)->new(1);
1385 0         0 foreach my $f (@factors) {
1386 0         0 my ($p, $e) = @$f;
1387 0         0 my $pk = ref($n)->new($p) ** $k;
1388 0         0 my $fmult = $pk; $fmult++;
  0         0  
1389 0 0       0 if ($e >= 2) {
1390 0         0 my $pke = $pk;
1391 0         0 for (2 .. $e) { $pke *= $pk; $fmult += $pke; }
  0         0  
  0         0  
1392             }
1393 0         0 $product *= $fmult;
1394             }
1395             } elsif ($k == 1) {
1396 2         8 foreach my $f (@factors) {
1397 52         100 my ($p, $e) = @$f;
1398 52         140 my $pk = Math::BigInt->new("$p");
1399 52 100       1979 if ($e == 1) { push @fm, $pk->binc; next; }
  37         84  
  37         1367  
1400 15         35 my $fmult = $pk->copy->binc;
1401 15         839 my $pke = $pk->copy;
1402 15         331 for my $E (2 .. $e) {
1403 214         11401 $pke->bmul($pk);
1404 214         12183 $fmult->badd($pke);
1405             }
1406 15         889 push @fm, $fmult;
1407             }
1408 2         23 $product = Math::Prime::Util::vecprod(@fm);
1409             } else {
1410 1         6 my $bik = Math::BigInt->new("$k");
1411 1         48 foreach my $f (@factors) {
1412 27         53 my ($p, $e) = @$f;
1413 27         79 my $pk = Math::BigInt->new("$p")->bpow($bik);
1414 27 50       6027 if ($e == 1) { push @fm, $pk->binc; next; }
  27         67  
  27         983  
1415 0         0 my $fmult = $pk->copy->binc;
1416 0         0 my $pke = $pk->copy;
1417 0         0 for my $E (2 .. $e) {
1418 0         0 $pke->bmul($pk);
1419 0         0 $fmult->badd($pke);
1420             }
1421 0         0 push @fm, $fmult;
1422             }
1423 1         7 $product = Math::Prime::Util::vecprod(@fm);
1424             }
1425 5         103 $product;
1426             }
1427              
1428             #############################################################################
1429             # Lehmer prime count
1430             #
1431             #my @_s0 = (0);
1432             #my @_s1 = (0,1);
1433             #my @_s2 = (0,1,1,1,1,2);
1434             my @_s3 = (0,1,1,1,1,1,1,2,2,2,2,3,3,4,4,4,4,5,5,6,6,6,6,7,7,7,7,7,7,8);
1435             my @_s4 = (0,1,1,1,1,1,1,1,1,1,1,2,2,3,3,3,3,4,4,5,5,5,5,6,6,6,6,6,6,7,7,8,8,8,8,8,8,9,9,9,9,10,10,11,11,11,11,12,12,12,12,12,12,13,13,13,13,13,13,14,14,15,15,15,15,15,15,16,16,16,16,17,17,18,18,18,18,18,18,19,19,19,19,20,20,20,20,20,20,21,21,21,21,21,21,21,21,22,22,22,22,23,23,24,24,24,24,25,25,26,26,26,26,27,27,27,27,27,27,27,27,28,28,28,28,28,28,29,29,29,29,30,30,30,30,30,30,31,31,32,32,32,32,33,33,33,33,33,33,34,34,35,35,35,35,35,35,36,36,36,36,36,36,37,37,37,37,38,38,39,39,39,39,40,40,40,40,40,40,41,41,42,42,42,42,42,42,43,43,43,43,44,44,45,45,45,45,46,46,47,47,47,47,47,47,47,47,47,47,48);
1436             sub _tablephi {
1437 1089     1089   1528 my($x, $a) = @_;
1438 1089 50       2932 if ($a == 0) { return $x; }
  0 50       0  
    50          
    100          
    100          
    50          
1439 0         0 elsif ($a == 1) { return $x-int($x/2); }
1440 0         0 elsif ($a == 2) { return $x-int($x/2) - int($x/3) + int($x/6); }
1441 3         20 elsif ($a == 3) { return 8 * int($x / 30) + $_s3[$x % 30]; }
1442 5         30 elsif ($a == 4) { return 48 * int($x / 210) + $_s4[$x % 210]; }
1443 0         0 elsif ($a == 5) { my $xp = int($x/11);
1444 0         0 return ( (48 * int($x / 210) + $_s4[$x % 210]) -
1445             (48 * int($xp / 210) + $_s4[$xp % 210]) ); }
1446 1081         1969 else { my ($xp,$x2) = (int($x/11),int($x/13));
1447 1081         1577 my $x2p = int($x2/11);
1448 1081         4144 return ( (48 * int($x / 210) + $_s4[$x % 210]) -
1449             (48 * int($xp / 210) + $_s4[$xp % 210]) -
1450             (48 * int($x2 / 210) + $_s4[$x2 % 210]) +
1451             (48 * int($x2p / 210) + $_s4[$x2p % 210]) ); }
1452             }
1453              
1454             sub legendre_phi {
1455 21     21 0 70 my ($x, $a, $primes) = @_;
1456 21 100       86 return _tablephi($x,$a) if $a <= 6;
1457 10 50       42 $primes = primes(Math::Prime::Util::nth_prime_upper($a+1)) unless defined $primes;
1458 10 0       44 return ($x > 0 ? 1 : 0) if $x < $primes->[$a];
    50          
1459              
1460 10         19 my $sum = 0;
1461 10         54 my %vals = ( $x => 1 );
1462 10         38 while ($a > 6) {
1463 71         146 my $primea = $primes->[$a-1];
1464 71         99 my %newvals;
1465 71         189 while (my($v,$c) = each %vals) {
1466 2212         3722 my $sval = int($v / $primea);
1467 2212 100       3192 if ($sval < $primea) {
1468 1011         2191 $sum -= $c;
1469             } else {
1470 1201         3722 $newvals{$sval} -= $c;
1471             }
1472             }
1473             # merge newvals into vals
1474 71         181 while (my($v,$c) = each %newvals) {
1475 1114         1638 $vals{$v} += $c;
1476 1114 50       2693 delete $vals{$v} if $vals{$v} == 0;
1477             }
1478 71         213 $a--;
1479             }
1480 10         43 while (my($v,$c) = each %vals) {
1481 1078         1727 $sum += $c * _tablephi($v, $a);
1482             }
1483 10         120 return $sum;
1484             }
1485              
1486             sub _sieve_prime_count {
1487 61     61   99 my $high = shift;
1488 61 100       138 return (0,0,1,2,2,3,3)[$high] if $high < 7;
1489 58 100       142 $high-- unless ($high & 1);
1490 58         81 return 1 + ${_sieve_erat($high)} =~ tr/0//;
  58         120  
1491             }
1492              
1493             sub _count_with_sieve {
1494 8427     8427   13259 my ($sref, $low, $high) = @_;
1495 8427 100       15198 ($low, $high) = (2, $low) if !defined $high;
1496 8427         10432 my $count = 0;
1497 8427 100       12499 if ($low < 3) { $low = 3; $count++; }
  5458         6597  
  5458         6513  
1498 2969         3748 else { $low |= 1; }
1499 8427 100       13697 $high-- unless ($high & 1);
1500 8427 50       13052 return $count if $low > $high;
1501 8427         11230 my $sbeg = $low >> 1;
1502 8427         10267 my $send = $high >> 1;
1503              
1504 8427 100 66     22390 if ( !defined $sref || $send >= length($$sref) ) {
1505             # outside our range, so call the segment siever.
1506 498         914 my $seg_ref = _sieve_segment($low, $high);
1507 498         2053 return $count + $$seg_ref =~ tr/0//;
1508             }
1509 7929         20134 return $count + substr($$sref, $sbeg, $send-$sbeg+1) =~ tr/0//;
1510             }
1511              
1512             sub _lehmer_pi {
1513 76     76   897 my $x = shift;
1514 76 100       212 return _sieve_prime_count($x) if $x < 1_000;
1515 21 50       67 do { require Math::BigFloat; Math::BigFloat->import(); }
  0         0  
  0         0  
1516             if ref($x) eq 'Math::BigInt';
1517 21 50       89 my $z = (ref($x) ne 'Math::BigInt')
1518             ? int(sqrt($x+0.5))
1519             : int(Math::BigFloat->new($x)->badd(0.5)->bsqrt->bfloor->bstr);
1520 21         102 my $a = _lehmer_pi(int(sqrt($z)+0.5));
1521 21         48 my $b = _lehmer_pi($z);
1522 21 50       148 my $c = _lehmer_pi(int( (ref($x) ne 'Math::BigInt')
1523             ? $x**(1/3)+0.5
1524             : Math::BigFloat->new($x)->broot(3)->badd(0.5)->bfloor
1525             ));
1526 21 50       61 ($z, $a, $b, $c) = map { (ref($_) =~ /^Math::Big/) ? _bigint_to_int($_) : $_ }
  84         211  
1527             ($z, $a, $b, $c);
1528              
1529             # Generate at least b primes.
1530 21 50       120 my $bth_prime_upper = ($b <= 10) ? 29 : int($b*(log($b) + log(log($b)))) + 1;
1531 21         83 my $primes = primes( $bth_prime_upper );
1532              
1533 21         92 my $sum = int(($b + $a - 2) * ($b - $a + 1) / 2);
1534 21         90 $sum += legendre_phi($x, $a, $primes);
1535              
1536             # Get a big sieve for our primecounts. The C code compromises with either
1537             # b*10 or x^3/5, as that cuts out all the inner loop sieves and about half
1538             # of the big outer loop counts.
1539             # Our sieve count isn't nearly as optimized here, so error on the side of
1540             # more primes. This uses a lot more memory but saves a lot of time.
1541 21         102 my $sref = _sieve_erat( int($x / $primes->[$a] / 5) );
1542              
1543 21         68 my ($lastw, $lastwpc) = (0,0);
1544 21         242 foreach my $i (reverse $a+1 .. $b) {
1545 2990         5427 my $w = int($x / $primes->[$i-1]);
1546 2990         4805 $lastwpc += _count_with_sieve($sref,$lastw+1, $w);
1547 2990         4111 $lastw = $w;
1548 2990         3584 $sum -= $lastwpc;
1549             #$sum -= _count_with_sieve($sref,$w);
1550 2990 100       5279 if ($i <= $c) {
1551 252         703 my $bi = _count_with_sieve($sref,int(sqrt($w)+0.5));
1552 252         673 foreach my $j ($i .. $bi) {
1553 5185         10305 $sum = $sum - _count_with_sieve($sref,int($w / $primes->[$j-1])) + $j - 1;
1554             }
1555             }
1556             }
1557 21         274 $sum;
1558             }
1559             #############################################################################
1560              
1561              
1562             sub prime_count {
1563 20     20 0 13117 my($low,$high) = @_;
1564 20 100       80 if (!defined $high) {
1565 7         15 $high = $low;
1566 7         13 $low = 2;
1567             }
1568 20         77 _validate_positive_integer($low);
1569 20         50 _validate_positive_integer($high);
1570              
1571 20         45 my $count = 0;
1572              
1573 20 100 100     89 $count++ if ($low <= 2) && ($high >= 2); # Count 2
1574 20 100       172 $low = 3 if $low < 3;
1575              
1576 20 100       176 $low++ if ($low % 2) == 0; # Make low go to odd number.
1577 20 100       602 $high-- if ($high % 2) == 0; # Make high go to odd number.
1578 20 100       492 return $count if $low > $high;
1579              
1580 18 100 66     273 if ( ref($low) eq 'Math::BigInt' || ref($high) eq 'Math::BigInt'
      100        
      66        
1581             || ($high-$low) < 10
1582             || ($high-$low) < int($low/100_000_000_000) ) {
1583             # Trial primes seems best. Needs some tuning.
1584 2         11 my $curprime = next_prime($low-1);
1585 2         13 while ($curprime <= $high) {
1586 5         113 $count++;
1587 5         18 $curprime = next_prime($curprime);
1588             }
1589 2         73 return $count;
1590             }
1591              
1592             # TODO: Needs tuning
1593 16 100       51 if ($high > 50_000) {
1594 10 100       49 if ( ($high / ($high-$low+1)) < 100 ) {
1595 5         20 $count += _lehmer_pi($high);
1596 5 100       27 $count -= ($low == 3) ? 1 : _lehmer_pi($low-1);
1597 5         56 return $count;
1598             }
1599             }
1600              
1601 11 100       42 return (_sieve_prime_count($high) - 1 + $count) if $low == 3;
1602              
1603 7         22 my $sieveref = _sieve_segment($low,$high);
1604 7         35 $count += $$sieveref =~ tr/0//;
1605 7         93 return $count;
1606             }
1607              
1608              
1609             sub nth_prime {
1610 20     20 0 7881 my($n) = @_;
1611 20         86 _validate_positive_integer($n);
1612              
1613 20 50       55 return undef if $n <= 0; ## no critic qw(ProhibitExplicitReturnUndef)
1614 20 100       104 return $_primes_small[$n] if $n <= $#_primes_small;
1615              
1616 10 50 33     42 if ($n > MPU_MAXPRIMEIDX && ref($n) ne 'Math::BigFloat') {
1617 0 0       0 do { require Math::BigFloat; Math::BigFloat->import(); }
  0         0  
  0         0  
1618             if !defined $Math::BigFloat::VERSION;
1619 0         0 $n = Math::BigFloat->new("$n")
1620             }
1621              
1622 10         21 my $prime = 0;
1623 10         19 my $count = 1;
1624 10         20 my $start = 3;
1625              
1626 10         56 my $logn = log($n);
1627 10         25 my $loglogn = log($logn);
1628 10 50       54 my $nth_prime_upper = ($n <= 10) ? 29 : int($n*($logn + $loglogn)) + 1;
1629 10 100       66 if ($nth_prime_upper > 100000) {
1630             # Use fast Lehmer prime count combined with lower bound to get close.
1631 3         14 my $nth_prime_lower = int($n * ($logn + $loglogn - 1.0 + (($loglogn-2.10)/$logn)));
1632 3 100       14 $nth_prime_lower-- unless $nth_prime_lower % 2;
1633 3         13 $count = _lehmer_pi($nth_prime_lower);
1634 3         13 $start = $nth_prime_lower + 2;
1635             }
1636              
1637             {
1638             # Make sure incr is an even number.
1639 10 100       25 my $incr = ($n < 1000) ? 1000 : ($n < 10000) ? 10000 : 100000;
  10 50       46  
1640 10         16 my $sieveref;
1641 10         15 while (1) {
1642 35         104 $sieveref = _sieve_segment($start, $start+$incr);
1643 35         409 my $segcount = $$sieveref =~ tr/0//;
1644 35 100       117 last if ($count + $segcount) >= $n;
1645 25         43 $count += $segcount;
1646 25         53 $start += $incr+2;
1647             }
1648             # Our count is somewhere in this segment. Need to look for it.
1649 10         24 $prime = $start - 2;
1650 10         60 while ($count < $n) {
1651 18451         22137 $prime += 2;
1652 18451 100       37056 $count++ if !substr($$sieveref, ($prime-$start)>>1, 1);
1653             }
1654             }
1655 10         511 $prime;
1656             }
1657              
1658             # The nth prime will be less or equal to this number
1659             sub nth_prime_upper {
1660 1     1 0 1790 my($n) = @_;
1661 1         7 _validate_positive_integer($n);
1662              
1663 1 50       4 return undef if $n <= 0; ## no critic qw(ProhibitExplicitReturnUndef)
1664 1 50       5 return $_primes_small[$n] if $n <= $#_primes_small;
1665              
1666 1 50 33     10 $n = _upgrade_to_float($n) if $n > MPU_MAXPRIMEIDX || $n > 2**45;
1667              
1668 1         82 my $flogn = log($n);
1669 1         48628 my $flog2n = log($flogn); # Note distinction between log_2(n) and log^2(n)
1670              
1671 1         36483 my $upper;
1672 1 50       4 if ($n >= 46254381) { # Axler 2017 Corollary 1.2
    0          
    0          
    0          
    0          
    0          
1673 1         262 $upper = $n * ( $flogn + $flog2n-1.0 + (($flog2n-2.00)/$flogn) - (($flog2n*$flog2n - 6*$flog2n + 10.667)/(2*$flogn*$flogn)) );
1674             } elsif ($n >= 8009824) { # Axler 2013 page viii Korollar G
1675 0         0 $upper = $n * ( $flogn + $flog2n-1.0 + (($flog2n-2.00)/$flogn) - (($flog2n*$flog2n - 6*$flog2n + 10.273)/(2*$flogn*$flogn)) );
1676             } elsif ($n >= 688383) { # Dusart 2010 page 2
1677 0         0 $upper = $n * ( $flogn + $flog2n - 1.0 + (($flog2n-2.00)/$flogn) );
1678             } elsif ($n >= 178974) { # Dusart 2010 page 7
1679 0         0 $upper = $n * ( $flogn + $flog2n - 1.0 + (($flog2n-1.95)/$flogn) );
1680             } elsif ($n >= 39017) { # Dusart 1999 page 14
1681 0         0 $upper = $n * ( $flogn + $flog2n - 0.9484 );
1682             } elsif ($n >= 6) { # Modified Robin 1983, for 6-39016 only
1683 0         0 $upper = $n * ( $flogn + 0.6000 * $flog2n );
1684             } else {
1685 0         0 $upper = $n * ( $flogn + $flog2n );
1686             }
1687              
1688 1         5951 return int($upper + 1.0);
1689             }
1690              
1691             # The nth prime will be greater than or equal to this number
1692             sub nth_prime_lower {
1693 3     3 0 2301 my($n) = @_;
1694 3 50       15 _validate_num($n) || _validate_positive_integer($n);
1695              
1696 3 50       10 return undef if $n <= 0; ## no critic qw(ProhibitExplicitReturnUndef)
1697 3 50       12 return $_primes_small[$n] if $n <= $#_primes_small;
1698              
1699 3 50 66     24 $n = _upgrade_to_float($n) if $n > MPU_MAXPRIMEIDX || $n > 2**45;
1700              
1701 3         324 my $flogn = log($n);
1702 3         145899 my $flog2n = log($flogn); # Note distinction between log_2(n) and log^2(n)
1703              
1704             # Dusart 1999 page 14, for all n >= 2
1705             #my $lower = $n * ($flogn + $flog2n - 1.0 + (($flog2n-2.25)/$flogn));
1706             # Dusart 2010 page 2, for all n >= 3
1707             #my $lower = $n * ($flogn + $flog2n - 1.0 + (($flog2n-2.10)/$flogn));
1708             # Axler 2013 page viii Korollar I, for all n >= 2
1709             #my $lower = $n * ($flogn + $flog2n-1.0 + (($flog2n-2.00)/$flogn) - (($flog2n*$flog2n - 6*$flog2n + 11.847)/(2*$flogn*$flogn)) );
1710             # Axler 2017 Corollary 1.4
1711 3         110463 my $lower = $n * ($flogn + $flog2n-1.0 + (($flog2n-2.00)/$flogn) - (($flog2n*$flog2n - 6*$flog2n + 11.508)/(2*$flogn*$flogn)) );
1712              
1713 3         17110 return int($lower + 0.999999999);
1714             }
1715              
1716             sub inverse_li {
1717 0     0 0 0 my($n) = @_;
1718 0 0       0 _validate_num($n) || _validate_positive_integer($n);
1719              
1720 0 0       0 return (0,2,3,5,6,8)[$n] if $n <= 5;
1721 0 0 0     0 $n = _upgrade_to_float($n) if $n > MPU_MAXPRIMEIDX || $n > 2**45;
1722 0         0 my $t = $n * log($n);
1723              
1724             # Iterator Halley's method until error term grows
1725 0         0 my $old_term = MPU_INFINITY;
1726 0         0 for my $iter (1 .. 10000) {
1727 0         0 my $dn = Math::Prime::Util::LogarithmicIntegral($t) - $n;
1728 0         0 my $term = $dn * log($t) / (1.0 + $dn/(2*$t));
1729 0 0       0 last if abs($term) >= abs($old_term);
1730 0         0 $old_term = $term;
1731 0         0 $t -= $term;
1732 0 0       0 last if abs($term) < 1e-6;
1733             }
1734 0 0       0 if (ref($t)) {
1735 0         0 $t = Math::BigInt->new($t->bceil->bstr);
1736 0 0       0 $t = _bigint_to_int($t) if $t->bacmp(BMAX) <= 0;
1737             } else {
1738 0         0 $t = int($t+0.999999);
1739             }
1740 0         0 $t;
1741             }
1742             sub _inverse_R {
1743 0     0   0 my($n) = @_;
1744 0 0       0 _validate_num($n) || _validate_positive_integer($n);
1745              
1746 0 0       0 return (0,2,3,5,6,8)[$n] if $n <= 5;
1747 0 0 0     0 $n = _upgrade_to_float($n) if $n > MPU_MAXPRIMEIDX || $n > 2**45;
1748 0         0 my $t = $n * log($n);
1749              
1750             # Iterator Halley's method until error term grows
1751 0         0 my $old_term = MPU_INFINITY;
1752 0         0 for my $iter (1 .. 10000) {
1753 0         0 my $dn = Math::Prime::Util::RiemannR($t) - $n;
1754 0         0 my $term = $dn * log($t) / (1.0 + $dn/(2*$t));
1755 0 0       0 last if abs($term) >= abs($old_term);
1756 0         0 $old_term = $term;
1757 0         0 $t -= $term;
1758 0 0       0 last if abs($term) < 1e-6;
1759             }
1760 0 0       0 if (ref($t)) {
1761 0         0 $t = Math::BigInt->new($t->bceil->bstr);
1762 0 0       0 $t = _bigint_to_int($t) if $t->bacmp(BMAX) <= 0;
1763             } else {
1764 0         0 $t = int($t+0.999999);
1765             }
1766 0         0 $t;
1767             }
1768              
1769             sub nth_prime_approx {
1770 1     1 0 777 my($n) = @_;
1771 1 50       5 _validate_num($n) || _validate_positive_integer($n);
1772              
1773 1 50       5 return undef if $n <= 0; ## no critic qw(ProhibitExplicitReturnUndef)
1774 1 50       5 return $_primes_small[$n] if $n <= $#_primes_small;
1775              
1776             # Once past 10^12 or so, inverse_li gives better results.
1777 1 50       4 return Math::Prime::Util::inverse_li($n) if $n > 1e12;
1778              
1779 1 50 33     8 $n = _upgrade_to_float($n)
1780             if ref($n) eq 'Math::BigInt' || $n >= MPU_MAXPRIMEIDX;
1781              
1782 1         4 my $flogn = log($n);
1783 1         2 my $flog2n = log($flogn);
1784              
1785             # Cipolla 1902:
1786             # m=0 fn * ( flogn + flog2n - 1 );
1787             # m=1 + ((flog2n - 2)/flogn) );
1788             # m=2 - (((flog2n*flog2n) - 6*flog2n + 11) / (2*flogn*flogn))
1789             # + O((flog2n/flogn)^3)
1790             #
1791             # Shown in Dusart 1999 page 12, as well as other sources such as:
1792             # http://www.emis.de/journals/JIPAM/images/153_02_JIPAM/153_02.pdf
1793             # where the main issue you run into is that you're doing polynomial
1794             # interpolation, so it oscillates like crazy with many high-order terms.
1795             # Hence I'm leaving it at m=2.
1796              
1797 1         8 my $approx = $n * ( $flogn + $flog2n - 1
1798             + (($flog2n - 2)/$flogn)
1799             - ((($flog2n*$flog2n) - 6*$flog2n + 11) / (2*$flogn*$flogn))
1800             );
1801              
1802             # Apply a correction to help keep values close.
1803 1         3 my $order = $flog2n/$flogn;
1804 1         2 $order = $order*$order*$order * $n;
1805              
1806 1 50       13 if ($n < 259) { $approx += 10.4 * $order; }
  0 50       0  
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    0          
1807 0         0 elsif ($n < 775) { $approx += 6.3 * $order; }
1808 0         0 elsif ($n < 1271) { $approx += 5.3 * $order; }
1809 0         0 elsif ($n < 2000) { $approx += 4.7 * $order; }
1810 0         0 elsif ($n < 4000) { $approx += 3.9 * $order; }
1811 0         0 elsif ($n < 12000) { $approx += 2.8 * $order; }
1812 0         0 elsif ($n < 150000) { $approx += 1.2 * $order; }
1813 1         3 elsif ($n < 20000000) { $approx += 0.11 * $order; }
1814 0         0 elsif ($n < 100000000) { $approx += 0.008 * $order; }
1815 0         0 elsif ($n < 500000000) { $approx += -0.038 * $order; }
1816 0         0 elsif ($n < 2000000000) { $approx += -0.054 * $order; }
1817 0         0 else { $approx += -0.058 * $order; }
1818             # If we want the asymptotic approximation to be >= actual, use -0.010.
1819              
1820 1         4 return int($approx + 0.5);
1821             }
1822              
1823             #############################################################################
1824              
1825             sub prime_count_approx {
1826 5     5 0 31250 my($x) = @_;
1827 5 100       28 _validate_num($x) || _validate_positive_integer($x);
1828              
1829             # Turn on high precision FP if they gave us a big number.
1830 5 100 66     37 $x = _upgrade_to_float($x) if ref($_[0]) eq 'Math::BigInt' && $x > 1e16;
1831             # Method 10^10 %error 10^19 %error
1832             # ----------------- ------------ ------------
1833             # n/(log(n)-1) .22% .058%
1834             # n/(ln(n)-1-1/ln(n)) .032% .0041%
1835             # average bounds .0005% .0000002%
1836             # asymp .0006% .00000004%
1837             # li(n) .0007% .00000004%
1838             # li(n)-li(n^.5)/2 .0004% .00000001%
1839             # R(n) .0004% .00000001%
1840             #
1841             # Also consider: http://trac.sagemath.org/sage_trac/ticket/8135
1842              
1843             # Asymp:
1844             # my $l1 = log($x); my $l2 = $l1*$l1; my $l4 = $l2*$l2;
1845             # my $result = int( $x/$l1 + $x/$l2 + 2*$x/($l2*$l1) + 6*$x/($l4) + 24*$x/($l4*$l1) + 120*$x/($l4*$l2) + 720*$x/($l4*$l2*$l1) + 5040*$x/($l4*$l4) + 40320*$x/($l4*$l4*$l1) + 0.5 );
1846             # my $result = int( (prime_count_upper($x) + prime_count_lower($x)) / 2);
1847             # my $result = int( LogarithmicIntegral($x) );
1848             # my $result = int(LogarithmicIntegral($x) - LogarithmicIntegral(sqrt($x))/2);
1849             # my $result = RiemannR($x) + 0.5;
1850              
1851             # Make sure we get enough accuracy, and also not too much more than needed
1852 5 100       485 $x->accuracy(length($x->copy->as_int->bstr())+2) if ref($x) =~ /^Math::Big/;
1853              
1854 5         1107 my $result;
1855 5 100 66     50 if ($Math::Prime::Util::_GMPfunc{"riemannr"} || !ref($x)) {
1856             # Fast if we have our GMP backend, and ok for native.
1857 1         5 $result = Math::Prime::Util::PP::RiemannR($x);
1858             } else {
1859 4 50       16 $x = _upgrade_to_float($x) unless ref($x) eq 'Math::BigFloat';
1860 4         17 $result = Math::BigFloat->new(0);
1861 4 50 33     577 $result->accuracy($x->accuracy) if ref($x) && $x->accuracy;
1862 4         350 $result += Math::BigFloat->new(LogarithmicIntegral($x));
1863 4         1544 $result -= Math::BigFloat->new(LogarithmicIntegral(sqrt($x))/2);
1864 4 50       3260 my $intx = ref($x) ? Math::BigInt->new($x->bfround(0)) : $x;
1865 4         2024 for my $k (3 .. 1000) {
1866 88         44746 my $m = moebius($k);
1867 88 100       200 next unless $m != 0;
1868             # With Math::BigFloat and the Calc backend, FP root is ungodly slow.
1869             # Use integer root instead. For more accuracy (not useful here):
1870             # my $v = Math::BigFloat->new( "" . rootint($x->as_int,$k) );
1871             # $v->accuracy(length($v)+5);
1872             # $v = $v - Math::BigFloat->new(($v**$k - $x))->bdiv($k * $v**($k-1));
1873             # my $term = LogarithmicIntegral($v)/$k;
1874 56         125 my $term = LogarithmicIntegral(rootint($intx,$k)) / $k;
1875 56 100       241 last if $term < .25;
1876 52 100       121 if ($m == 1) { $result->badd(Math::BigFloat->new($term)) }
  22         92  
1877 30         111 else { $result->bsub(Math::BigFloat->new($term)) }
1878             }
1879             }
1880              
1881 5 100       30 if (ref($result)) {
1882 4 50       16 return $result unless ref($result) eq 'Math::BigFloat';
1883             # Math::BigInt::FastCalc 0.19 implements as_int incorrectly.
1884 4         22 return Math::BigInt->new($result->bfround(0)->bstr);
1885             }
1886 1         5 int($result+0.5);
1887             }
1888              
1889             sub prime_count_lower {
1890 11     11 0 9462 my($x) = @_;
1891 11 100       55 _validate_num($x) || _validate_positive_integer($x);
1892              
1893 11 100       53 return _tiny_prime_count($x) if $x < $_primes_small[-1];
1894              
1895             return Math::Prime::Util::_reftyped($_[0], Math::Prime::Util::GMP::prime_count_lower($x))
1896 10 50       1029 if $Math::Prime::Util::_GMPfunc{"prime_count_lower"};
1897              
1898 10 100 66     80 $x = _upgrade_to_float($x)
1899             if ref($x) eq 'Math::BigInt' || ref($_[0]) eq 'Math::BigInt';
1900              
1901 10         938 my($result,$a);
1902 10         45 my $fl1 = log($x);
1903 10         757923 my $fl2 = $fl1*$fl1;
1904 10 100       2374 my $one = (ref($x) eq 'Math::BigFloat') ? $x->copy->bone : $x-$x+1.0;
1905              
1906             # Chebyshev 1*x/logx x >= 17
1907             # Rosser & Schoenfeld x/(logx-1/2) x >= 67
1908             # Dusart 1999 x/logx*(1+1/logx+1.8/logxlogx) x >= 32299
1909             # Dusart 2010 x/logx*(1+1/logx+2.0/logxlogx) x >= 88783
1910             # Axler 2014 (1.2) ""+... x >= 1332450001
1911             # Axler 2014 (1.2) x/(logx-1-1/logx-...) x >= 1332479531
1912             # Büthe 2015 (1.9) li(x)-(sqrtx/logx)*(...) x <= 10^19
1913             # Büthe 2014 Th 2 li(x)-logx*sqrtx/8Pi x > 2657, x <= 1.4*10^25
1914              
1915 10 50 66     1565 if ($x < 599) { # Decent for small numbers
    100          
    100          
1916 0         0 $result = $x / ($fl1 - 0.7);
1917             } elsif ($x < 52600000) { # Dusart 2010 tweaked
1918 1 50       15 if ($x < 2700) { $a = 0.30; }
  0 50       0  
    50          
    50          
    50          
    50          
    50          
    50          
    50          
1919 0         0 elsif ($x < 5500) { $a = 0.90; }
1920 0         0 elsif ($x < 19400) { $a = 1.30; }
1921 0         0 elsif ($x < 32299) { $a = 1.60; }
1922 0         0 elsif ($x < 88783) { $a = 1.83; }
1923 0         0 elsif ($x < 176000) { $a = 1.99; }
1924 0         0 elsif ($x < 315000) { $a = 2.11; }
1925 0         0 elsif ($x < 1100000) { $a = 2.19; }
1926 1         3 elsif ($x < 4500000) { $a = 2.31; }
1927 0         0 else { $a = 2.35; }
1928 1         4 $result = ($x/$fl1) * ($one + $one/$fl1 + $a/$fl2);
1929             } elsif ($x < 1.4e25 || Math::Prime::Util::prime_get_config()->{'assume_rh'}){
1930             # Büthe 2014/2015
1931 8         6608 my $lix = LogarithmicIntegral($x);
1932 8         41 my $sqx = sqrt($x);
1933 8 100       32750 if ($x < 1e19) {
1934 1         5 $result = $lix - ($sqx/$fl1) * (1.94 + 3.88/$fl1 + 27.57/$fl2);
1935             } else {
1936 7 50       2891 if (ref($x) eq 'Math::BigFloat') {
1937 7         35 my $xdigits = _find_big_acc($x);
1938 7         31 $result = $lix - ($fl1*$sqx / (Math::BigFloat->bpi($xdigits)*8));
1939             } else {
1940 0         0 $result = $lix - ($fl1*$sqx / PI_TIMES_8);
1941             }
1942             }
1943             } else { # Axler 2014 1.4
1944 1         5 my($fl3,$fl4) = ($fl2*$fl1,$fl2*$fl2);
1945 1         826 my($fl5,$fl6) = ($fl4*$fl1,$fl4*$fl2);
1946 1         1174 $result = $x / ($fl1 - $one - $one/$fl1 - 2.65/$fl2 - 13.35/$fl3 - 70.3/$fl4 - 455.6275/$fl5 - 3404.4225/$fl6);
1947             }
1948              
1949 10 100       43147 return Math::BigInt->new($result->bfloor->bstr()) if ref($result) eq 'Math::BigFloat';
1950 2         11 return int($result);
1951             }
1952              
1953             sub prime_count_upper {
1954 11     11 0 4317 my($x) = @_;
1955 11 100       61 _validate_num($x) || _validate_positive_integer($x);
1956              
1957             # Give an exact answer for what we have in our little table.
1958 11 100       50 return _tiny_prime_count($x) if $x < $_primes_small[-1];
1959              
1960             return Math::Prime::Util::_reftyped($_[0], Math::Prime::Util::GMP::prime_count_upper($x))
1961 10 50       1062 if $Math::Prime::Util::_GMPfunc{"prime_count_upper"};
1962              
1963 10 100 66     91 $x = _upgrade_to_float($x)
1964             if ref($x) eq 'Math::BigInt' || ref($_[0]) eq 'Math::BigInt';
1965              
1966             # Chebyshev: 1.25506*x/logx x >= 17
1967             # Rosser & Schoenfeld: x/(logx-3/2) x >= 67
1968             # Panaitopol 1999: x/(logx-1.112) x >= 4
1969             # Dusart 1999: x/logx*(1+1/logx+2.51/logxlogx) x >= 355991
1970             # Dusart 2010: x/logx*(1+1/logx+2.334/logxlogx) x >= 2_953_652_287
1971             # Axler 2014: x/(logx-1-1/logx-3.35/logxlogx...) x >= e^3.804
1972             # Büthe 2014 7.4 Schoenfeld bounds hold to x <= 1.4e25
1973             # Axler 2017 Prop 2.2 Schoenfeld bounds hold to x <= 5.5e25
1974             # Skewes li(x) x < 1e14
1975              
1976 10         942 my($result,$a);
1977 10         42 my $fl1 = log($x);
1978 10         755905 my $fl2 = $fl1 * $fl1;
1979 10 100       2360 my $one = (ref($x) eq 'Math::BigFloat') ? $x->copy->bone : $x-$x+1.0;
1980              
1981 10 50 33     1589 if ($x < 15900) { # Tweaked Rosser-type
    100          
    50          
    50          
1982 0 0       0 $a = ($x < 1621) ? 1.048 : ($x < 5000) ? 1.071 : 1.098;
    0          
1983 0         0 $result = ($x / ($fl1 - $a)) + 1.0;
1984             } elsif ($x < 821800000) { # Tweaked Dusart 2010
1985 2 50       32 if ($x < 24000) { $a = 2.30; }
  0 50       0  
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
1986 0         0 elsif ($x < 59000) { $a = 2.48; }
1987 0         0 elsif ($x < 350000) { $a = 2.52; }
1988 0         0 elsif ($x < 355991) { $a = 2.54; }
1989 0         0 elsif ($x < 356000) { $a = 2.51; }
1990 1         3 elsif ($x < 3550000) { $a = 2.50; }
1991 0         0 elsif ($x < 3560000) { $a = 2.49; }
1992 0         0 elsif ($x < 5000000) { $a = 2.48; }
1993 0         0 elsif ($x < 8000000) { $a = 2.47; }
1994 0         0 elsif ($x < 13000000) { $a = 2.46; }
1995 0         0 elsif ($x < 18000000) { $a = 2.45; }
1996 0         0 elsif ($x < 31000000) { $a = 2.44; }
1997 0         0 elsif ($x < 41000000) { $a = 2.43; }
1998 0         0 elsif ($x < 48000000) { $a = 2.42; }
1999 0         0 elsif ($x < 119000000) { $a = 2.41; }
2000 0         0 elsif ($x < 182000000) { $a = 2.40; }
2001 0         0 elsif ($x < 192000000) { $a = 2.395; }
2002 0         0 elsif ($x < 213000000) { $a = 2.390; }
2003 0         0 elsif ($x < 271000000) { $a = 2.385; }
2004 0         0 elsif ($x < 322000000) { $a = 2.380; }
2005 0         0 elsif ($x < 400000000) { $a = 2.375; }
2006 1         2 elsif ($x < 510000000) { $a = 2.370; }
2007 0         0 elsif ($x < 682000000) { $a = 2.367; }
2008 0         0 elsif ($x < 2953652287) { $a = 2.362; }
2009 0         0 else { $a = 2.334; } # Dusart 2010, page 2
2010 2         7 $result = ($x/$fl1) * ($one + $one/$fl1 + $a/$fl2) + $one;
2011             } elsif ($x < 1e19) { # Skewes number lower limit
2012 0 0       0 $a = ($x < 110e7) ? 0.032 : ($x < 1001e7) ? 0.027 : ($x < 10126e7) ? 0.021 : 0.0;
    0          
    0          
2013 0         0 $result = LogarithmicIntegral($x) - $a * $fl1*sqrt($x)/PI_TIMES_8;
2014             } elsif ($x < 5.5e25 || Math::Prime::Util::prime_get_config()->{'assume_rh'}) {
2015             # Schoenfeld / Büthe 2014 Th 7.4
2016 8         12812 my $lix = LogarithmicIntegral($x);
2017 8         49 my $sqx = sqrt($x);
2018 8 50       37251 if (ref($x) eq 'Math::BigFloat') {
2019 8         40 my $xdigits = _find_big_acc($x);
2020 8         40 $result = $lix + ($fl1*$sqx / (Math::BigFloat->bpi($xdigits)*8));
2021             } else {
2022 0         0 $result = $lix + ($fl1*$sqx / PI_TIMES_8);
2023             }
2024             } else { # Axler 2014 1.3
2025 0         0 my($fl3,$fl4) = ($fl2*$fl1,$fl2*$fl2);
2026 0         0 my($fl5,$fl6) = ($fl4*$fl1,$fl4*$fl2);
2027 0         0 $result = $x / ($fl1 - $one - $one/$fl1 - 3.35/$fl2 - 12.65/$fl3 - 71.7/$fl4 - 466.1275/$fl5 - 3489.8225/$fl6);
2028             }
2029              
2030 10 100       27636 return Math::BigInt->new($result->bfloor->bstr()) if ref($result) eq 'Math::BigFloat';
2031 2         10 return int($result);
2032             }
2033              
2034             sub twin_prime_count {
2035 1     1 0 4 my($low,$high) = @_;
2036 1 50       4 if (defined $high) { _validate_positive_integer($low); }
  0         0  
2037 1         3 else { ($low,$high) = (2, $low); }
2038 1         5 _validate_positive_integer($high);
2039 1         1 my $sum = 0;
2040 1         5 while ($low <= $high) {
2041 1         3 my $seghigh = ($high-$high) + $low + 1e7 - 1;
2042 1 50       4 $seghigh = $high if $seghigh > $high;
2043 1         3 $sum += scalar(@{Math::Prime::Util::twin_primes($low,$seghigh)});
  1         6  
2044 1         8 $low = $seghigh + 1;
2045             }
2046 1         9 $sum;
2047             }
2048             sub _semiprime_count {
2049 0     0   0 my $n = shift;
2050 0         0 my($sum,$pc) = (0,0);
2051             Math::Prime::Util::forprimes( sub {
2052 0     0   0 $sum += Math::Prime::Util::prime_count(int($n/$_))-$pc++;
2053 0         0 }, sqrtint($n));
2054 0         0 $sum;
2055             }
2056             sub semiprime_count {
2057 0     0 0 0 my($low,$high) = @_;
2058 0 0       0 if (defined $high) { _validate_positive_integer($low); }
  0         0  
2059 0         0 else { ($low,$high) = (2, $low); }
2060 0         0 _validate_positive_integer($high);
2061             # todo: threshold of fast count vs. walk
2062 0 0       0 my $sum = _semiprime_count($high) - (($low < 4) ? 0 : semiprime_count($low-1));
2063 0         0 $sum;
2064             }
2065             sub ramanujan_prime_count {
2066 0     0 0 0 my($low,$high) = @_;
2067 0 0       0 if (defined $high) { _validate_positive_integer($low); }
  0         0  
2068 0         0 else { ($low,$high) = (2, $low); }
2069 0         0 _validate_positive_integer($high);
2070 0         0 my $sum = 0;
2071 0         0 while ($low <= $high) {
2072 0         0 my $seghigh = ($high-$high) + $low + 1e9 - 1;
2073 0 0       0 $seghigh = $high if $seghigh > $high;
2074 0         0 $sum += scalar(@{Math::Prime::Util::ramanujan_primes($low,$seghigh)});
  0         0  
2075 0         0 $low = $seghigh + 1;
2076             }
2077 0         0 $sum;
2078             }
2079              
2080             sub twin_prime_count_approx {
2081 2     2 0 2875 my($n) = @_;
2082 2 50       10 return twin_prime_count(3,$n) if $n < 2000;
2083 2 50       293 $n = _upgrade_to_float($n) if ref($n);
2084 2         248 my $logn = log($n);
2085             # The loss of full Ei precision is a few orders of magnitude less than the
2086             # accuracy of the estimate, so save huge time and don't bother.
2087 2         97116 my $li2 = Math::Prime::Util::ExponentialIntegral("$logn") + 2.8853900817779268147198494 - ($n/$logn);
2088              
2089             # Empirical correction factor
2090 2         3467 my $fm;
2091 2 50       10 if ($n < 4000) { $fm = 0.2952; }
  0 50       0  
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
2092 0         0 elsif ($n < 8000) { $fm = 0.3151; }
2093 0         0 elsif ($n < 16000) { $fm = 0.3090; }
2094 0         0 elsif ($n < 32000) { $fm = 0.3096; }
2095 0         0 elsif ($n < 64000) { $fm = 0.3100; }
2096 0         0 elsif ($n < 128000) { $fm = 0.3089; }
2097 0         0 elsif ($n < 256000) { $fm = 0.3099; }
2098 0         0 elsif ($n < 600000) { my($x0, $x1, $y0, $y1) = (1e6, 6e5, .3091, .3059);
2099 0         0 $fm = $y0 + ($n - $x0) * ($y1-$y0) / ($x1 - $x0); }
2100 0         0 elsif ($n < 1000000) { my($x0, $x1, $y0, $y1) = (6e5, 1e6, .3062, .3042);
2101 0         0 $fm = $y0 + ($n - $x0) * ($y1-$y0) / ($x1 - $x0); }
2102 0         0 elsif ($n < 4000000) { my($x0, $x1, $y0, $y1) = (1e6, 4e6, .3067, .3041);
2103 0         0 $fm = $y0 + ($n - $x0) * ($y1-$y0) / ($x1 - $x0); }
2104 0         0 elsif ($n < 16000000) { my($x0, $x1, $y0, $y1) = (4e6, 16e6, .3033, .2983);
2105 0         0 $fm = $y0 + ($n - $x0) * ($y1-$y0) / ($x1 - $x0); }
2106 0         0 elsif ($n < 32000000) { my($x0, $x1, $y0, $y1) = (16e6, 32e6, .2980, .2965);
2107 0         0 $fm = $y0 + ($n - $x0) * ($y1-$y0) / ($x1 - $x0); }
2108 2 50       8389 $li2 *= $fm * log(12+$logn) if defined $fm;
2109              
2110 2         9 return int(1.32032363169373914785562422 * $li2 + 0.5);
2111             }
2112              
2113             sub semiprime_count_approx {
2114 0     0 0 0 my($n) = @_;
2115 0 0       0 return 0 if $n < 4;
2116 0         0 _validate_positive_integer($n);
2117 0         0 $n = "$n" + 0.00000001;
2118 0         0 my $l1 = log($n);
2119 0         0 my $l2 = log($l1);
2120             #my $est = $n * $l2 / $l1;
2121 0         0 my $est = $n * ($l2 + 0.302) / $l1;
2122 0         0 int(0.5+$est);
2123             }
2124              
2125             sub nth_twin_prime {
2126 1     1 0 2836 my($n) = @_;
2127 1 50       5 return undef if $n < 0; ## no critic qw(ProhibitExplicitReturnUndef)
2128 1 50       4 return (undef,3,5,11,17,29,41)[$n] if $n <= 6;
2129              
2130 1         68 my $p = Math::Prime::Util::nth_twin_prime_approx($n+200);
2131 1         7 my $tp = Math::Prime::Util::twin_primes($p);
2132 1         9 while ($n > scalar(@$tp)) {
2133 0         0 $n -= scalar(@$tp);
2134 0         0 $tp = Math::Prime::Util::twin_primes($p+1,$p+1e5);
2135 0         0 $p += 1e5;
2136             }
2137 1         24 return $tp->[$n-1];
2138             }
2139              
2140             sub nth_twin_prime_approx {
2141 0     0 0 0 my($n) = @_;
2142 0         0 _validate_positive_integer($n);
2143 0 0       0 return nth_twin_prime($n) if $n < 6;
2144 0 0 0     0 $n = _upgrade_to_float($n) if ref($n) || $n > 127e14; # TODO lower for 32-bit
2145 0         0 my $logn = log($n);
2146 0         0 my $nlogn2 = $n * $logn * $logn;
2147              
2148 0 0 0     0 return int(5.158 * $nlogn2/log(9+log($n*$n))) if $n > 59 && $n <= 1092;
2149              
2150 0         0 my $lo = int(0.7 * $nlogn2);
2151 0 0       0 my $hi = int( ($n > 1e16) ? 1.1 * $nlogn2
    0          
2152             : ($n > 480) ? 1.7 * $nlogn2
2153             : 2.3 * $nlogn2 + 3 );
2154              
2155             _binary_search($n, $lo, $hi,
2156 0     0   0 sub{Math::Prime::Util::twin_prime_count_approx(shift)},
2157 0     0   0 sub{ ($_[2]-$_[1])/$_[1] < 1e-15 } );
  0         0  
2158             }
2159              
2160             sub nth_semiprime {
2161 0     0 0 0 my $n = shift;
2162 0 0       0 return undef if $n < 0; ## no critic qw(ProhibitExplicitReturnUndef)
2163 0 0       0 return (undef,4,6,9,10,14,15,21,22)[$n] if $n <= 8;
2164 0         0 my $logn = log($n);
2165 0         0 my $est = 0.966 * $n * $logn / log($logn);
2166             1+_binary_search($n, int(0.9*$est)-1, int(1.15*$est)+1,
2167 0     0   0 sub{Math::Prime::Util::semiprime_count(shift)});
  0         0  
2168             }
2169              
2170             sub nth_semiprime_approx {
2171 0     0 0 0 my $n = shift;
2172 0 0       0 return undef if $n < 0; ## no critic qw(ProhibitExplicitReturnUndef)
2173 0         0 _validate_positive_integer($n);
2174 0 0       0 return (undef,4,6,9,10,14,15,21,22)[$n] if $n <= 8;
2175 0         0 $n = "$n" + 0.00000001;
2176 0         0 my $l1 = log($n);
2177 0         0 my $l2 = log($l1);
2178 0         0 my $est = 0.966 * $n * $l1 / $l2;
2179 0         0 int(0.5+$est);
2180             }
2181              
2182             sub nth_ramanujan_prime_upper {
2183 0     0 0 0 my $n = shift;
2184 0 0       0 return (0,2,11)[$n] if $n <= 2;
2185 0 0       0 $n = Math::BigInt->new("$n") if $n > (~0/3);
2186 0         0 my $nth = nth_prime_upper(3*$n);
2187 0 0       0 return $nth if $n < 10000;
2188 0 0       0 $nth = Math::BigInt->new("$nth") if $nth > (~0/177);
2189 0 0       0 if ($n < 1000000) { $nth = (177 * $nth) >> 8; }
  0 0       0  
2190 0         0 elsif ($n < 1e10) { $nth = (175 * $nth) >> 8; }
2191 0         0 else { $nth = (133 * $nth) >> 8; }
2192 0 0 0     0 $nth = _bigint_to_int($nth) if ref($nth) && $nth->bacmp(BMAX) <= 0;
2193 0         0 $nth;
2194             }
2195             sub nth_ramanujan_prime_lower {
2196 0     0 0 0 my $n = shift;
2197 0 0       0 return (0,2,11)[$n] if $n <= 2;
2198 0 0       0 $n = Math::BigInt->new("$n") if $n > (~0/2);
2199 0         0 my $nth = nth_prime_lower(2*$n);
2200 0 0       0 $nth = Math::BigInt->new("$nth") if $nth > (~0/275);
2201 0 0       0 if ($n < 10000) { $nth = (275 * $nth) >> 8; }
  0 0       0  
2202 0         0 elsif ($n < 1e10) { $nth = (262 * $nth) >> 8; }
2203 0 0 0     0 $nth = _bigint_to_int($nth) if ref($nth) && $nth->bacmp(BMAX) <= 0;
2204 0         0 $nth;
2205             }
2206             sub nth_ramanujan_prime_approx {
2207 0     0 0 0 my $n = shift;
2208 0 0       0 return (0,2,11)[$n] if $n <= 2;
2209 0         0 my($lo,$hi) = (nth_ramanujan_prime_lower($n),nth_ramanujan_prime_upper($n));
2210 0         0 $lo + (($hi-$lo)>>1);
2211             }
2212             sub ramanujan_prime_count_upper {
2213 0     0 0 0 my $n = shift;
2214 0 0       0 return (($n < 2) ? 0 : 1) if $n < 11;
    0          
2215 0         0 my $lo = int(prime_count_lower($n) / 3);
2216 0         0 my $hi = prime_count_upper($n) >> 1;
2217             1+_binary_search($n, $lo, $hi,
2218 0     0   0 sub{Math::Prime::Util::nth_ramanujan_prime_lower(shift)});
  0         0  
2219             }
2220             sub ramanujan_prime_count_lower {
2221 0     0 0 0 my $n = shift;
2222 0 0       0 return (($n < 2) ? 0 : 1) if $n < 11;
    0          
2223 0         0 my $lo = int(prime_count_lower($n) / 3);
2224 0         0 my $hi = prime_count_upper($n) >> 1;
2225             _binary_search($n, $lo, $hi,
2226 0     0   0 sub{Math::Prime::Util::nth_ramanujan_prime_upper(shift)});
  0         0  
2227             }
2228             sub ramanujan_prime_count_approx {
2229 0     0 0 0 my $n = shift;
2230 0 0       0 return (($n < 2) ? 0 : 1) if $n < 11;
    0          
2231             #$n = _upgrade_to_float($n) if ref($n) || $n > 2e16;
2232 0         0 my $lo = ramanujan_prime_count_lower($n);
2233 0         0 my $hi = ramanujan_prime_count_upper($n);
2234             _binary_search($n, $lo, $hi,
2235 0     0   0 sub{Math::Prime::Util::nth_ramanujan_prime_approx(shift)},
2236 0     0   0 sub{ ($_[2]-$_[1])/$_[1] < 1e-15 } );
  0         0  
2237             }
2238              
2239             sub _sum_primes_n {
2240 0     0   0 my $n = shift;
2241 0 0       0 return (0,0,2,5,5)[$n] if $n < 5;
2242 0         0 my $r = Math::Prime::Util::sqrtint($n);
2243 0         0 my $r2 = $r + int($n/($r+1));
2244 0         0 my(@V,@S);
2245 0         0 for my $k (0 .. $r2) {
2246 0 0       0 my $v = ($k <= $r) ? $k : int($n/($r2-$k+1));
2247 0         0 $V[$k] = $v;
2248 0         0 $S[$k] = (($v*($v+1)) >> 1) - 1;
2249             }
2250 0     0   0 Math::Prime::Util::forprimes( sub { my $p = $_;
2251 0         0 my $sp = $S[$p-1];
2252 0         0 my $p2 = $p*$p;
2253 0         0 for my $v (reverse @V) {
2254 0 0       0 last if $v < $p2;
2255 0         0 my($a,$b) = ($v,int($v/$p));
2256 0 0       0 $a = $r2 - int($n/$a) + 1 if $a > $r;
2257 0 0       0 $b = $r2 - int($n/$b) + 1 if $b > $r;
2258 0         0 $S[$a] -= $p * ($S[$b] - $sp);
2259             }
2260 0         0 }, 2, $r);
2261 0         0 $S[$r2];
2262             }
2263              
2264             sub sum_primes {
2265 0     0 0 0 my($low,$high) = @_;
2266 0 0       0 if (defined $high) { _validate_positive_integer($low); }
  0         0  
2267 0         0 else { ($low,$high) = (2, $low); }
2268 0         0 _validate_positive_integer($high);
2269 0         0 my $sum = 0;
2270 0 0       0 $sum = BZERO->copy if ( (MPU_32BIT && $high > 323_380) ||
2271             (MPU_64BIT && $high > 29_505_444_490) );
2272              
2273             # It's very possible we're here because they've counted too high. Skip fwd.
2274 0 0 0     0 if ($low <= 2 && $high >= 29505444491) {
2275 0         0 $low = 29505444503;
2276 0         0 $sum = Math::BigInt->new("18446744087046669523");
2277             }
2278              
2279 0 0       0 return $sum if $low > $high;
2280              
2281             # We have to make some decision about whether to use our PP prime sum or loop
2282             # doing the XS sieve. TODO: Be smarter here?
2283 0 0 0     0 if (!Math::Prime::Util::prime_get_config()->{'xs'} && !ref($sum) && !MPU_32BIT && ($high-$low) > 1000000) {
      0        
      0        
2284             # Unfortunately with bigints this is horrifically slow, but we have to do it.
2285 0 0       0 $high = BZERO->copy + $high if $high >= (1 << (MPU_MAXBITS/2))-1;
2286 0         0 $sum = _sum_primes_n($high);
2287 0 0       0 $sum -= _sum_primes_n($low-1) if $low > 2;
2288 0         0 return $sum;
2289             }
2290              
2291 0   0     0 my $xssum = (MPU_64BIT && $high < 6e14 && Math::Prime::Util::prime_get_config()->{'xs'});
2292 0 0 0     0 my $step = ($xssum && $high > 5e13) ? 1_000_000 : 11_000_000;
2293 0         0 Math::Prime::Util::prime_precalc(sqrtint($high));
2294 0         0 while ($low <= $high) {
2295 0         0 my $next = $low + $step - 1;
2296 0 0       0 $next = $high if $next > $high;
2297             $sum += ($xssum) ? Math::Prime::Util::sum_primes($low,$next)
2298 0 0       0 : Math::Prime::Util::vecsum( @{Math::Prime::Util::primes($low,$next)} );
  0         0  
2299 0 0       0 last if $next == $high;
2300 0         0 $low = $next+1;
2301             }
2302 0         0 $sum;
2303             }
2304             sub print_primes {
2305 0     0 0 0 my($low,$high,$fd) = @_;
2306 0 0       0 if (defined $high) { _validate_positive_integer($low); }
  0         0  
2307 0         0 else { ($low,$high) = (2, $low); }
2308 0         0 _validate_positive_integer($high);
2309              
2310 0 0       0 $fd = fileno(STDOUT) unless defined $fd;
2311 0         0 open(my $fh, ">>&=", $fd); # TODO .... or die
2312              
2313 0 0       0 if ($high >= $low) {
2314 0         0 my $p1 = $low;
2315 0         0 while ($p1 <= $high) {
2316 0         0 my $p2 = $p1 + 15_000_000 - 1;
2317 0 0       0 $p2 = $high if $p2 > $high;
2318 0 0       0 if ($Math::Prime::Util::_GMPfunc{"sieve_primes"}) {
2319 0         0 print $fh "$_\n" for Math::Prime::Util::GMP::sieve_primes($p1,$p2,0);
2320             } else {
2321 0         0 print $fh "$_\n" for @{primes($p1,$p2)};
  0         0  
2322             }
2323 0         0 $p1 = $p2+1;
2324             }
2325             }
2326 0         0 close($fh);
2327             }
2328              
2329              
2330             #############################################################################
2331              
2332             sub _mulmod {
2333 43023     43023   65989 my($x, $y, $n) = @_;
2334 43023 100       86564 return (($x * $y) % $n) if ($x|$y) < MPU_HALFWORD;
2335             #return (($x * $y) % $n) if ($x|$y) < MPU_HALFWORD || $y == 0 || $x < int(~0/$y);
2336 43023         52475 my $r = 0;
2337 43023 50       67979 $x %= $n if $x >= $n;
2338 43023 50       65510 $y %= $n if $y >= $n;
2339 43023 100       65313 ($x,$y) = ($y,$x) if $x < $y;
2340 43023 100       60795 if ($n <= (~0 >> 1)) {
2341 40495         66555 while ($y > 1) {
2342 1902318 100       2998351 if ($y & 1) { $r += $x; $r -= $n if $r >= $n; }
  929259 100       1126446  
  929259         1480297  
2343 1902318         2283159 $y >>= 1;
2344 1902318 100       2301183 $x += $x; $x -= $n if $x >= $n;
  1902318         3650964  
2345             }
2346 40495 100       68167 if ($y & 1) { $r += $x; $r -= $n if $r >= $n; }
  40495 50       49103  
  40495         67950  
2347             } else {
2348 2528         695 while ($y > 1) {
2349 26018 100       41151 if ($y & 1) { $r = $n-$r; $r = ($x >= $r) ? $x-$r : $n-$r+$x; }
  12752 100       15823  
  12752         19815  
2350 26018         31051 $y >>= 1;
2351 26018 100       50847 $x = ($x > ($n - $x)) ? ($x - $n) + $x : $x + $x;
2352             }
2353 2528 100       717 if ($y & 1) { $r = $n-$r; $r = ($x >= $r) ? $x-$r : $n-$r+$x; }
  424 50       532  
  424         719  
2354             }
2355 43023         71429 $r;
2356             }
2357             sub _addmod {
2358 33314     33314   297978 my($x, $y, $n) = @_;
2359 33314 50       56125 $x %= $n if $x >= $n;
2360 33314 100       73576 $y %= $n if $y >= $n;
2361 33314 100       68227 if (($n-$x) <= $y) {
2362 215 100       39068 ($x,$y) = ($y,$x) if $y > $x;
2363 215         12884 $x -= $n;
2364             }
2365 33314         114045 $x + $y;
2366             }
2367              
2368             # Note that Perl 5.6.2 with largish 64-bit numbers will break. As usual.
2369             sub _native_powmod {
2370 3602     3602   5853 my($n, $power, $m) = @_;
2371 3602         4669 my $t = 1;
2372 3602         4892 $n = $n % $m;
2373 3602         5858 while ($power) {
2374 66865 100       109097 $t = ($t * $n) % $m if ($power & 1);
2375 66865         79417 $power >>= 1;
2376 66865 100       127844 $n = ($n * $n) % $m if $power;
2377             }
2378 3602         5554 $t;
2379             }
2380              
2381             sub _powmod {
2382 186     186   449 my($n, $power, $m) = @_;
2383 186         300 my $t = 1;
2384              
2385 186 50       441 $n %= $m if $n >= $m;
2386 186 100       421 if ($m < MPU_HALFWORD) {
2387 12         46 while ($power) {
2388 219 100       336 $t = ($t * $n) % $m if ($power & 1);
2389 219         240 $power >>= 1;
2390 219 100       540 $n = ($n * $n) % $m if $power;
2391             }
2392             } else {
2393 174         455 while ($power) {
2394 7013 100       12963 $t = _mulmod($t, $n, $m) if ($power & 1);
2395 7013         9400 $power >>= 1;
2396 7013 100       13467 $n = _mulmod($n, $n, $m) if $power;
2397             }
2398             }
2399 186         482 $t;
2400             }
2401              
2402             # Make sure to work around RT71548, Math::BigInt::Lite,
2403             # and use correct lcm semantics.
2404             sub gcd {
2405             # First see if all inputs are non-bigints 5-10x faster if so.
2406 7 100   7 0 417 if (0 == scalar(grep { ref($_) } @_)) {
  16         54  
2407 1   50     7 my($x,$y) = (shift || 0, 0);
2408 1         4 while (@_) {
2409 2         5 $y = shift;
2410 2         5 while ($y) { ($x,$y) = ($y, $x % $y); }
  4         10  
2411 2 100       8 $x = -$x if $x < 0;
2412             }
2413 1         6 return $x;
2414             }
2415             my $gcd = Math::BigInt::bgcd( map {
2416 6 50 66     18 my $v = (($_ < 2147483647 && !ref($_)) || ref($_) eq 'Math::BigInt') ? $_ : "$_";
  13         54  
2417 13         1692 $v;
2418             } @_ );
2419 6 50       24513 $gcd = _bigint_to_int($gcd) if $gcd->bacmp(BMAX) <= 0;
2420 6         177 return $gcd;
2421             }
2422             sub lcm {
2423 4 50   4 0 528 return 0 unless @_;
2424             my $lcm = Math::BigInt::blcm( map {
2425 4 50 66     13 my $v = (($_ < 2147483647 && !ref($_)) || ref($_) eq 'Math::BigInt') ? $_ : "$_";
  12         44  
2426 12 50       1199 return 0 if $v == 0;
2427 12 50       1505 $v = -$v if $v < 0;
2428 12         1506 $v;
2429             } @_ );
2430 4 100       5900 $lcm = _bigint_to_int($lcm) if $lcm->bacmp(BMAX) <= 0;
2431 4         137 return $lcm;
2432             }
2433             sub gcdext {
2434 3     3 0 145 my($x,$y) = @_;
2435 3 50       16 if ($x == 0) { return (0, (-1,0,1)[($y>=0)+($y>0)], abs($y)); }
  0         0  
2436 3 50       222 if ($y == 0) { return ((-1,0,1)[($x>=0)+($x>0)], 0, abs($x)); }
  0         0  
2437              
2438 3 50       182 if ($Math::Prime::Util::_GMPfunc{"gcdext"}) {
2439 0         0 my($a,$b,$g) = Math::Prime::Util::GMP::gcdext($x,$y);
2440 0         0 $a = Math::Prime::Util::_reftyped($_[0], $a);
2441 0         0 $b = Math::Prime::Util::_reftyped($_[0], $b);
2442 0         0 $g = Math::Prime::Util::_reftyped($_[0], $g);
2443 0         0 return ($a,$b,$g);
2444             }
2445              
2446 3         12 my($a,$b,$g,$u,$v,$w);
2447 3 100 66     20 if (abs($x) < (~0>>1) && abs($y) < (~0>>1)) {
2448 1 50       6 $x = _bigint_to_int($x) if ref($x) eq 'Math::BigInt';
2449 1 50       3 $y = _bigint_to_int($y) if ref($y) eq 'Math::BigInt';
2450 1         4 ($a,$b,$g,$u,$v,$w) = (1,0,$x,0,1,$y);
2451 1         5 while ($w != 0) {
2452 10         14 my $r = $g % $w;
2453 10         17 my $q = int(($g-$r)/$w);
2454 10         27 ($a,$b,$g,$u,$v,$w) = ($u,$v,$w,$a-$q*$u,$b-$q*$v,$r);
2455             }
2456             } else {
2457 2         196 ($a,$b,$g,$u,$v,$w) = (BONE->copy,BZERO->copy,Math::BigInt->new("$x"),
2458             BZERO->copy,BONE->copy,Math::BigInt->new("$y"));
2459 2         520 while ($w != 0) {
2460             # Using the array bdiv is logical, but is the wrong sign.
2461 109         62138 my $r = $g->copy->bmod($w);
2462 109         21227 my $q = $g->copy->bsub($r)->bdiv($w);
2463 109         35198 ($a,$b,$g,$u,$v,$w) = ($u,$v,$w,$a-$q*$u,$b-$q*$v,$r);
2464             }
2465 2 100       1263 $a = _bigint_to_int($a) if $a->bacmp(BMAX) <= 0;
2466 2 100       105 $b = _bigint_to_int($b) if $b->bacmp(BMAX) <= 0;
2467 2 50       62 $g = _bigint_to_int($g) if $g->bacmp(BMAX) <= 0;
2468             }
2469 3 50       92 if ($g < 0) { ($a,$b,$g) = (-$a,-$b,-$g); }
  0         0  
2470 3         57 return ($a,$b,$g);
2471             }
2472              
2473             sub chinese {
2474 7 50   7 0 4953 return 0 unless scalar @_;
2475 7 50       23 return $_[0]->[0] % $_[0]->[1] if scalar @_ == 1;
2476 7         16 my($lcm, $sum);
2477              
2478 7 50 33     26 if ($Math::Prime::Util::_GMPfunc{"chinese"} && $Math::Prime::Util::GMP::VERSION >= 0.42) {
2479 0         0 $sum = Math::Prime::Util::GMP::chinese(@_);
2480 0 0       0 if (defined $sum) {
2481 0         0 $sum = Math::BigInt->new("$sum");
2482 0 0 0     0 $sum = _bigint_to_int($sum) if ref($sum) && $sum->bacmp(BMAX) <= 0;
2483             }
2484 0         0 return $sum;
2485             }
2486 7         32 foreach my $aref (sort { $b->[1] <=> $a->[1] } @_) {
  7         37  
2487 14         81 my($ai, $ni) = @$aref;
2488 14 50 50     73 $ai = Math::BigInt->new("$ai") if !ref($ai) && (abs($ai) > (~0>>1) || OLD_PERL_VERSION);
      66        
2489 14 100 100     56 $ni = Math::BigInt->new("$ni") if !ref($ni) && (abs($ni) > (~0>>1) || OLD_PERL_VERSION);
      66        
2490 14 100       140 if (!defined $lcm) {
2491 7         25 ($sum,$lcm) = ($ai % $ni, $ni);
2492 7         312 next;
2493             }
2494             # gcdext
2495 7         24 my($u,$v,$g,$s,$t,$w) = (1,0,$lcm,0,1,$ni);
2496 7         22 while ($w != 0) {
2497 166         19361 my $r = $g % $w;
2498 166 100       6101 my $q = ref($g) ? $g->copy->bsub($r)->bdiv($w) : int(($g-$r)/$w);
2499 166         10782 ($u,$v,$g,$s,$t,$w) = ($s,$t,$w,$u-$q*$s,$v-$q*$t,$r);
2500             }
2501 7 50       1517 ($u,$v,$g) = (-$u,-$v,-$g) if $g < 0;
2502 7 50 66     359 return if $g != 1 && ($sum % $g) != ($ai % $g); # Not co-prime
2503 7 100       543 $s = -$s if $s < 0;
2504 7 100       366 $t = -$t if $t < 0;
2505             # Convert to bigint if necessary. Performance goes to hell.
2506 7 100 100     362 if (!ref($lcm) && ($lcm*$s) > ~0) { $lcm = Math::BigInt->new("$lcm"); }
  4         20  
2507 7 100       275 if (ref($lcm)) {
2508 6         27 $lcm->bmul("$s");
2509 6         1373 my $m1 = Math::BigInt->new("$v")->bmul("$s")->bmod($lcm);
2510 6         2444 my $m2 = Math::BigInt->new("$u")->bmul("$t")->bmod($lcm);
2511 6         2246 $m1->bmul("$sum")->bmod($lcm);
2512 6         2882 $m2->bmul("$ai")->bmod($lcm);
2513 6         2937 $sum = $m1->badd($m2)->bmod($lcm);
2514             } else {
2515 1         3 $lcm *= $s;
2516 1 50       4 $u += $lcm if $u < 0;
2517 1 50       4 $v += $lcm if $v < 0;
2518 1         4 my $vs = _mulmod($v,$s,$lcm);
2519 1         4 my $ut = _mulmod($u,$t,$lcm);
2520 1         3 my $m1 = _mulmod($sum,$vs,$lcm);
2521 1         3 my $m2 = _mulmod($ut,$ai % $lcm,$lcm);
2522 1         3 $sum = _addmod($m1, $m2, $lcm);
2523             }
2524             }
2525 7 100 100     1496 $sum = _bigint_to_int($sum) if ref($sum) && $sum->bacmp(BMAX) <= 0;
2526 7         178 $sum;
2527             }
2528              
2529             sub _from_128 {
2530 0     0   0 my($hi, $lo) = @_;
2531 0 0 0     0 return 0 unless defined $hi && defined $lo;
2532             #print "hi $hi lo $lo\n";
2533 0         0 (Math::BigInt->new("$hi") << MPU_MAXBITS) + $lo;
2534             }
2535              
2536             sub vecsum {
2537 528 0   528 0 3752 return Math::Prime::Util::_reftyped($_[0], @_ ? $_[0] : 0) if @_ <= 1;
    50          
2538              
2539             return Math::Prime::Util::_reftyped($_[0], Math::Prime::Util::GMP::vecsum(@_))
2540 528 50       1527 if $Math::Prime::Util::_GMPfunc{"vecsum"};
2541 528         1064 my $sum = 0;
2542 528         964 my $neglim = -(INTMAX >> 1) - 1;
2543 528         1401 foreach my $v (@_) {
2544 2072         5939 $sum += $v;
2545 2072 100 100     63787 if ($sum > (INTMAX-250) || $sum < $neglim) {
2546 514         35437 $sum = BZERO->copy;
2547 514         14030 $sum->badd("$_") for @_;
2548 514         5038601 return $sum;
2549             }
2550             }
2551 14         75 $sum;
2552             }
2553              
2554             sub vecprod {
2555 14078 50   14078 0 65511 return 1 unless @_;
2556             return Math::Prime::Util::_reftyped($_[0], Math::Prime::Util::GMP::vecprod(@_))
2557 14078 50       36715 if $Math::Prime::Util::_GMPfunc{"vecprod"};
2558             # Product tree:
2559 14078         37262 my $prod = _product(0, $#_, [map { Math::BigInt->new("$_") } @_]);
  29884         2542544  
2560             # Linear:
2561             # my $prod = BONE->copy; $prod *= "$_" for @_;
2562 14078 100 66     6654014 $prod = _bigint_to_int($prod) if $prod->bacmp(BMAX) <= 0 && $prod->bcmp(-(BMAX>>1)) > 0;
2563 14078         324183 $prod;
2564             }
2565              
2566             sub vecmin {
2567 1 50   1 0 5 return unless @_;
2568 1         2 my $min = shift;
2569 1 50       3 for (@_) { $min = $_ if $_ < $min; }
  2         8  
2570 1         4 $min;
2571             }
2572             sub vecmax {
2573 1 50   1 0 5 return unless @_;
2574 1         3 my $max = shift;
2575 1 50       3 for (@_) { $max = $_ if $_ > $max; }
  2         7  
2576 1         5 $max;
2577             }
2578              
2579             sub vecextract {
2580 0     0 0 0 my($aref, $mask) = @_;
2581              
2582 0 0       0 return @$aref[@$mask] if ref($mask) eq 'ARRAY';
2583              
2584             # This is concise but very slow.
2585             # map { $aref->[$_] } grep { $mask & (1 << $_) } 0 .. $#$aref;
2586              
2587 0         0 my($i, @v) = (0);
2588 0         0 while ($mask) {
2589 0 0       0 push @v, $i if $mask & 1;
2590 0         0 $mask >>= 1;
2591 0         0 $i++;
2592             }
2593 0         0 @$aref[@v];
2594             }
2595              
2596             sub sumdigits {
2597 0     0 0 0 my($n,$base) = @_;
2598 0         0 my $sum = 0;
2599 0 0 0     0 $base = 2 if !defined $base && $n =~ s/^0b//;
2600 0 0 0     0 $base = 16 if !defined $base && $n =~ s/^0x//;
2601 0 0 0     0 if (!defined $base || $base == 10) {
2602 0         0 $n =~ tr/0123456789//cd;
2603 0         0 $sum += $_ for (split(//,$n));
2604             } else {
2605 0 0       0 croak "sumdigits: invalid base $base" if $base < 2;
2606 0         0 my $cmap = substr("0123456789abcdefghijklmnopqrstuvwxyz",0,$base);
2607 0         0 for my $c (split(//,lc($n))) {
2608 0         0 my $p = index($cmap,$c);
2609 0 0       0 $sum += $p if $p > 0;
2610             }
2611             }
2612 0         0 $sum;
2613             }
2614              
2615             sub invmod {
2616 4     4 0 13 my($a,$n) = @_;
2617 4 50 33     17 return if $n == 0 || $a == 0;
2618 4 50       346 return 0 if $n == 1;
2619 4 100       127 $n = -$n if $n < 0; # Pari semantics
2620 4 50       176 if ($n > ~0) {
2621 0         0 my $invmod = Math::BigInt->new("$a")->bmodinv("$n");
2622 0 0 0     0 return if !defined $invmod || $invmod->is_nan;
2623 0 0       0 $invmod = _bigint_to_int($invmod) if $invmod->bacmp(BMAX) <= 0;
2624 0         0 return $invmod;
2625             }
2626 4         171 my($t,$nt,$r,$nr) = (0, 1, $n, $a % $n);
2627 4         186 while ($nr != 0) {
2628             # Use mod before divide to force correct behavior with high bit set
2629 13         929 my $quot = int( ($r-($r % $nr))/$nr );
2630 13         1452 ($nt,$t) = ($t-$quot*$nt,$nt);
2631 13         869 ($nr,$r) = ($r-$quot*$nr,$nr);
2632             }
2633 4 100       360 return if $r > 1;
2634 3 100       121 $t += $n if $t < 0;
2635 3         171 $t;
2636             }
2637              
2638             sub _verify_sqrtmod {
2639 1     1   4 my($r,$a,$n) = @_;
2640 1 50       5 if (ref($r)) {
2641 1 50       6 return if $r->copy->bmul($r)->bmod($n)->bcmp($a);
2642 1 50       668 $r = _bigint_to_int($r) if $r->bacmp(BMAX) <= 0;
2643             } else {
2644 0 0       0 return unless (($r*$r) % $n) == $a;
2645             }
2646 1 50       29 $r = $n-$r if $n-$r < $r;
2647 1         217 $r;
2648             }
2649              
2650             sub sqrtmod {
2651 1     1 0 5 my($a,$n) = @_;
2652 1 50       7 return if $n == 0;
2653 1 50 33     9 if ($n <= 2 || $a <= 1) {
2654 0         0 $a %= $n;
2655 0 0       0 return ((($a*$a) % $n) == $a) ? $a : undef;
2656             }
2657              
2658 1 50       5 if ($n < 10000000) {
2659             # Horrible trial search
2660 0         0 $a = _bigint_to_int($a);
2661 0         0 $n = _bigint_to_int($n);
2662 0         0 $a %= $n;
2663 0 0       0 return 1 if $a == 1;
2664 0         0 my $lim = ($n+1) >> 1;
2665 0         0 for my $r (2 .. $lim) {
2666 0 0       0 return $r if (($r*$r) % $n) == $a;
2667             }
2668 0         0 undef;
2669             }
2670              
2671 1 50       9 $a = Math::BigInt->new("$a") unless ref($a) eq 'Math::BigInt';
2672 1 50       99 $n = Math::BigInt->new("$n") unless ref($n) eq 'Math::BigInt';
2673 1         57 $a->bmod($n);
2674 1         145 my $r;
2675              
2676 1 50       6 if (($n % 4) == 3) {
2677 1         341 $r = $a->copy->bmodpow(($n+1)>>2, $n);
2678 1         54893 return _verify_sqrtmod($r, $a, $n);
2679             }
2680 0 0       0 if (($n % 8) == 5) {
2681 0         0 my $q = $a->copy->bmodpow(($n-1)>>2, $n);
2682 0 0       0 if ($q->is_one) {
2683 0         0 $r = $a->copy->bmodpow(($n+3)>>3, $n);
2684             } else {
2685 0         0 my $v = $a->copy->bmul(4)->bmodpow(($n-5)>>3, $n);
2686 0         0 $r = $a->copy->bmul(2)->bmul($v)->bmod($n);
2687             }
2688 0         0 return _verify_sqrtmod($r, $a, $n);
2689             }
2690              
2691 0 0 0     0 return if $n->is_odd && !$a->copy->bmodpow(($n-1)>>1,$n)->is_one();
2692              
2693             # Horrible trial search. Need to use Tonelli-Shanks here.
2694 0         0 $r = Math::BigInt->new(2);
2695 0         0 my $lim = int( ($n+1) / 2 );
2696 0         0 while ($r < $lim) {
2697 0 0       0 return $r if $r->copy->bmul($r)->bmod($n) == $a;
2698 0         0 $r++;
2699             }
2700 0         0 undef;
2701             }
2702              
2703             sub addmod {
2704 19419     19419 0 5205013 my($a, $b, $n) = @_;
2705 19419 50       55459 return 0 if $n <= 1;
2706 19419 50 66     2243819 return _addmod($a,$b,$n) if $n < INTMAX && $a>=0 && $a=0 && $b
      66        
      33        
      33        
2707 18987         2313982 my $ret = Math::BigInt->new("$a")->badd("$b")->bmod("$n");
2708 18987 100       22754910 $ret = _bigint_to_int($ret) if $ret->bacmp(BMAX) <= 0;
2709 18987         565680 $ret;
2710             }
2711              
2712             sub mulmod {
2713 7368     7368 0 25090 my($a, $b, $n) = @_;
2714 7368 50       24538 return 0 if $n <= 1;
2715 7368 0 33     886947 return _mulmod($a,$b,$n) if $n < INTMAX && $a>0 && $a0 && $b
      33        
      0        
      0        
2716             return Math::Prime::Util::_reftyped($_[0], Math::Prime::Util::GMP::mulmod($a,$b,$n))
2717 7368 50       902575 if $Math::Prime::Util::_GMPfunc{"mulmod"};
2718 7368         22294 my $ret = Math::BigInt->new("$a")->bmod("$n")->bmul("$b")->bmod("$n");
2719 7368 100       94418968 $ret = _bigint_to_int($ret) if $ret->bacmp(BMAX) <= 0;
2720 7368         232687 $ret;
2721             }
2722             sub divmod {
2723 0     0 0 0 my($a, $b, $n) = @_;
2724 0 0       0 return 0 if $n <= 1;
2725 0         0 my $ret = Math::BigInt->new("$b")->bmodinv("$n")->bmul("$a")->bmod("$n");
2726 0 0       0 if ($ret->is_nan) {
2727 0         0 $ret = undef;
2728             } else {
2729 0 0       0 $ret = _bigint_to_int($ret) if $ret->bacmp(BMAX) <= 0;
2730             }
2731 0         0 $ret;
2732             }
2733             sub powmod {
2734 22     22 0 83 my($a, $b, $n) = @_;
2735 22 50       85 return 0 if $n <= 1;
2736 22 50       2716 if ($Math::Prime::Util::_GMPfunc{"powmod"}) {
2737 0         0 my $r = Math::Prime::Util::GMP::powmod($a,$b,$n);
2738 0 0       0 return (defined $r) ? Math::Prime::Util::_reftyped($_[0], $r) : undef;
2739             }
2740 22         72 my $ret = Math::BigInt->new("$a")->bmod("$n")->bmodpow("$b","$n");
2741 22 50       493389 if ($ret->is_nan) {
2742 0         0 $ret = undef;
2743             } else {
2744 22 100       215 $ret = _bigint_to_int($ret) if $ret->bacmp(BMAX) <= 0;
2745             }
2746 22         803 $ret;
2747             }
2748              
2749             # no validation, x is allowed to be negative, y must be >= 0
2750             sub _gcd_ui {
2751 62278     62278   99198 my($x, $y) = @_;
2752 62278 100       111751 if ($y < $x) { ($x, $y) = ($y, $x); }
  27618 100       47073  
2753 3         5 elsif ($x < 0) { $x = -$x; }
2754 62278         107308 while ($y > 0) {
2755 1136998         1986085 ($x, $y) = ($y, $x % $y);
2756             }
2757 62278         93900 $x;
2758             }
2759              
2760             sub is_power {
2761 1194     1194 0 332170 my ($n, $a, $refp) = @_;
2762 1194 50 66     4483 croak("is_power third argument not a scalar reference") if defined($refp) && !ref($refp);
2763 1194         3277 _validate_integer($n);
2764 1194 100 66     3209 return 0 if abs($n) <= 3 && !$a;
2765              
2766 1190 0 0     96651 if ($Math::Prime::Util::_GMPfunc{"is_power"} &&
      33        
2767             ($Math::Prime::Util::GMP::VERSION >= 0.42 ||
2768             ($Math::Prime::Util::GMP::VERSION >= 0.28 && $n > 0))) {
2769 0 0       0 $a = 0 unless defined $a;
2770 0         0 my $k = Math::Prime::Util::GMP::is_power($n,$a);
2771 0 0       0 return 0 unless $k > 0;
2772 0 0       0 if (defined $refp) {
2773 0 0       0 $a = $k unless $a;
2774 0         0 my $isneg = ($n < 0);
2775 0 0       0 $n =~ s/^-// if $isneg;
2776 0         0 $$refp = Math::Prime::Util::rootint($n, $a);
2777 0 0       0 $$refp = Math::Prime::Util::_reftyped($_[0], $$refp) if $$refp > INTMAX;
2778 0 0       0 $$refp = -$$refp if $isneg;
2779             }
2780 0         0 return $k;
2781             }
2782              
2783 1190 50 66     4589 if (defined $a && $a != 0) {
2784 0 0       0 return 1 if $a == 1; # Everything is a 1st power
2785 0 0 0     0 return 0 if $n < 0 && $a % 2 == 0; # Negative n never an even power
2786 0 0       0 if ($a == 2) {
2787 0 0       0 if (_is_perfect_square($n)) {
2788 0 0       0 $$refp = int(sqrt($n)) if defined $refp;
2789 0         0 return 1;
2790             }
2791             } else {
2792 0 0       0 $n = Math::BigInt->new("$n") unless ref($n) eq 'Math::BigInt';
2793 0         0 my $root = $n->copy->babs->broot($a)->bfloor;
2794 0 0       0 $root->bneg if $n->is_neg;
2795 0 0       0 if ($root->copy->bpow($a) == $n) {
2796 0 0       0 $$refp = $root if defined $refp;
2797 0         0 return 1;
2798             }
2799             }
2800             } else {
2801 1190 100       4040 $n = Math::BigInt->new("$n") unless ref($n) eq 'Math::BigInt';
2802 1190 100       23101 if ($n < 0) {
2803 256         39452 my $absn = $n->copy->babs;
2804 256         7776 my $root = is_power($absn, 0, $refp);
2805 256 50       910 return 0 unless $root;
2806 256 100       819 if ($root % 2 == 0) {
2807 128         512 my $power = valuation($root, 2);
2808 128         281 $root >>= $power;
2809 128 100       366 return 0 if $root == 1;
2810 122         374 $power = BTWO->copy->bpow($power);
2811 122 100       32198 $$refp = $$refp ** $power if defined $refp;
2812             }
2813 250 100       13836 $$refp = -$$refp if defined $refp;
2814 250         6825 return $root;
2815             }
2816 934         153933 my $e = 2;
2817 934         1383 while (1) {
2818 3768         10445 my $root = $n->copy()->broot($e)->bfloor;
2819 3768 100       6513921 last if $root->is_one();
2820 3505 100       47737 if ($root->copy->bpow($e) == $n) {
2821 671         311085 my $next = is_power($root, 0, $refp);
2822 671 100 100     2707 $$refp = $root if !$next && defined $refp;
2823 671 100       1424 $e *= $next if $next != 0;
2824 671         2152 return $e;
2825             }
2826 2834         1456033 $e = next_prime($e);
2827             }
2828             }
2829 263         3829 0;
2830             }
2831              
2832             sub is_square {
2833 1     1 0 6 my($n) = @_;
2834 1 50       8 return 0 if $n < 0;
2835             #is_power($n,2);
2836 1         5 _validate_integer($n);
2837 1         4 _is_perfect_square($n);
2838             }
2839              
2840             sub is_prime_power {
2841 0     0 0 0 my ($n, $refp) = @_;
2842 0 0 0     0 croak("is_prime_power second argument not a scalar reference") if defined($refp) && !ref($refp);
2843 0 0       0 return 0 if $n <= 1;
2844              
2845 0 0       0 if (Math::Prime::Util::is_prime($n)) { $$refp = $n if defined $refp; return 1; }
  0 0       0  
  0         0  
2846 0         0 my $r;
2847 0         0 my $k = Math::Prime::Util::is_power($n,0,\$r);
2848 0 0       0 if ($k) {
2849 0 0 0     0 $r = _bigint_to_int($r) if ref($r) && $r->bacmp(BMAX) <= 0;
2850 0 0       0 return 0 unless Math::Prime::Util::is_prime($r);
2851 0 0       0 $$refp = $r if defined $refp;
2852             }
2853 0         0 $k;
2854             }
2855              
2856             sub is_polygonal {
2857 2     2 0 21 my ($n, $k, $refp) = @_;
2858 2 50 33     8 croak("is_polygonal third argument not a scalar reference") if defined($refp) && !ref($refp);
2859 2 50       6 croak("is_polygonal: k must be >= 3") if $k < 3;
2860 2 50       9 return 0 if $n <= 0;
2861 2 0       6 if ($n == 1) { $$refp = 1 if defined $refp; return 1; }
  0 50       0  
  0         0  
2862              
2863 2 50       8 if ($Math::Prime::Util::_GMPfunc{"polygonal_nth"}) {
2864 0         0 my $nth = Math::Prime::Util::GMP::polygonal_nth($n, $k);
2865 0 0       0 return 0 unless $nth;
2866 0         0 $nth = Math::Prime::Util::_reftyped($_[0], $nth);
2867 0 0       0 $$refp = $nth if defined $refp;
2868 0         0 return 1;
2869             }
2870              
2871 2         4 my($D,$R);
2872 2 50       5 if ($k == 4) {
2873 0 0       0 return 0 unless _is_perfect_square($n);
2874 0 0       0 $$refp = sqrtint($n) if defined $refp;
2875 0         0 return 1;
2876             }
2877 2 50 33     8 if ($n <= MPU_HALFWORD && $k <= MPU_HALFWORD) {
2878 0 0       0 $D = ($k==3) ? 1+($n<<3) : (8*$k-16)*$n + ($k-4)*($k-4);
2879 0 0       0 return 0 unless _is_perfect_square($D);
2880 0         0 $D = $k-4 + Math::Prime::Util::sqrtint($D);
2881 0         0 $R = 2*$k-4;
2882             } else {
2883 2 50       4 if ($k == 3) {
2884 2         7 $D = vecsum(1, vecprod($n, 8));
2885             } else {
2886 0         0 $D = vecsum(vecprod($n, vecprod(8, $k) - 16), vecprod($k-4,$k-4));;
2887             }
2888 2 100       8 return 0 unless _is_perfect_square($D);
2889 1         54 $D = vecsum( sqrtint($D), $k-4 );
2890 1         7 $R = vecprod(2, $k) - 4;
2891             }
2892 1 50       4 return 0 if ($D % $R) != 0;
2893 1 50       365 $$refp = $D / $R if defined $refp;
2894 1         6 1;
2895             }
2896              
2897             sub valuation {
2898 132     132 0 3198 my($n, $k) = @_;
2899 132 50 33     636 $n = -$n if defined $n && $n < 0;
2900 132 100       798 _validate_num($n) || _validate_positive_integer($n);
2901 132 50 33     571 return 0 if $n < 2 || $k < 2;
2902 132         687 my $v = 0;
2903 132 100       377 if ($k == 2) { # Accelerate power of 2
2904 130 100       303 if (ref($n) eq 'Math::BigInt') { # This can pay off for big inputs
2905 1 50       5 return 0 unless $n->is_even;
2906 1         26 my $s = $n->as_bin; # We could do same for k=10
2907 1         1137 return length($s) - rindex($s,'1') - 1;
2908             }
2909 129         428 while (!($n & 0xFFFF) ) { $n >>=16; $v +=16; }
  1         3  
  1         3  
2910 129         413 while (!($n & 0x000F) ) { $n >>= 4; $v += 4; }
  19         64  
  19         58  
2911             }
2912 131         427 while ( !($n % $k) ) {
2913 198         1436 $n /= $k;
2914 198         15311 $v++;
2915             }
2916 131         502 $v;
2917             }
2918              
2919             sub hammingweight {
2920 0     0 0 0 my $n = shift;
2921 0         0 return 0 + (Math::BigInt->new("$n")->as_bin() =~ tr/1//);
2922             }
2923              
2924             my @_digitmap = (0..9, 'a'..'z');
2925             my %_mapdigit = map { $_digitmap[$_] => $_ } 0 .. $#_digitmap;
2926             sub _splitdigits {
2927 3     3   12 my($n, $base, $len) = @_; # n is num or bigint, base is in range
2928 3         9 my @d;
2929 3 50       22 if ($base == 10) {
    100          
    50          
2930 0         0 @d = split(//,"$n");
2931             } elsif ($base == 2) {
2932 2         7 @d = split(//,substr(Math::BigInt->new("$n")->as_bin,2));
2933             } elsif ($base == 16) {
2934 0         0 @d = map { $_mapdigit{$_} } split(//,substr(Math::BigInt->new("$n")->as_hex,2));
  0         0  
2935             } else {
2936 1         4 while ($n >= 1) {
2937 339         251561 my $rem = $n % $base;
2938 339         97437 unshift @d, $rem;
2939 339         958 $n = ($n-$rem)/$base; # Always an exact division
2940             }
2941             }
2942 3 50 33     12684 if ($len >= 0 && $len != scalar(@d)) {
2943 0         0 while (@d < $len) { unshift @d, 0; }
  0         0  
2944 0         0 while (@d > $len) { shift @d; }
  0         0  
2945             }
2946 3         444 @d;
2947             }
2948              
2949             sub todigits {
2950 3     3 0 334 my($n,$base,$len) = @_;
2951 3 50       15 $base = 10 unless defined $base;
2952 3 50       15 $len = -1 unless defined $len;
2953 3 50       11 die "Invalid base: $base" if $base < 2;
2954 3 50       14 return if $n == 0;
2955 3 50       554 $n = -$n if $n < 0;
2956 3 50       506 _validate_num($n) || _validate_positive_integer($n);
2957 3         16 _splitdigits($n, $base, $len);
2958             }
2959              
2960             sub todigitstring {
2961 0     0 0 0 my($n,$base,$len) = @_;
2962 0 0       0 $base = 10 unless defined $base;
2963 0 0       0 $len = -1 unless defined $len;
2964 0         0 $n =~ s/^-//;
2965 0 0 0     0 return substr(Math::BigInt->new("$n")->as_bin,2) if $base == 2 && $len < 0;
2966 0 0 0     0 return substr(Math::BigInt->new("$n")->as_oct,1) if $base == 8 && $len < 0;
2967 0 0 0     0 return substr(Math::BigInt->new("$n")->as_hex,2) if $base == 16 && $len < 0;
2968 0 0       0 my @d = ($n == 0) ? () : _splitdigits($n, $base, $len);
2969 0 0       0 return join("", @d) if $base <= 10;
2970 0 0       0 die "Invalid base for string: $base" if $base > 36;
2971 0         0 join("", map { $_digitmap[$_] } @d);
  0         0  
2972             }
2973              
2974             sub fromdigits {
2975 1     1 0 5 my($r, $base) = @_;
2976 1 50       4 $base = 10 unless defined $base;
2977 1 50 33     6 return $r if $base == 10 && ref($r) =~ /^Math::/;
2978 1         2 my $n;
2979 1 50 33     61 if (ref($r) && ref($r) !~ /^Math::/) {
    50          
    50          
    50          
2980 0 0       0 croak "fromdigits first argument must be a string or array reference"
2981             unless ref($r) eq 'ARRAY';
2982 0         0 ($n,$base) = (BZERO->copy, BZERO + $base);
2983 0         0 for my $d (@$r) {
2984 0         0 $n = $n * $base + $d;
2985             }
2986             } elsif ($base == 2) {
2987 0         0 $n = Math::BigInt->from_bin("0b$r");
2988             } elsif ($base == 8) {
2989 0         0 $n = Math::BigInt->from_oct("0$r");
2990             } elsif ($base == 16) {
2991 0         0 $n = Math::BigInt->from_hex("0x$r");
2992             } else {
2993 1         9 $r =~ s/^0*//;
2994 1         6 ($n,$base) = (BZERO->copy, BZERO + $base);
2995             #for my $d (map { $_mapdigit{$_} } split(//,$r)) {
2996             # croak "Invalid digit for base $base" unless defined $d && $d < $base;
2997             # $n = $n * $base + $d;
2998             #}
2999 1         234 for my $c (split(//, lc($r))) {
3000 16         1922 $n->bmul($base);
3001 16 50       946 if ($c ne '0') {
3002 16         32 my $d = index("0123456789abcdefghijklmnopqrstuvwxyz", $c);
3003 16 50       30 croak "Invalid digit for base $base" unless $d >= 0;
3004 16         32 $n->badd($d);
3005             }
3006             }
3007             }
3008 1 50       141 $n = _bigint_to_int($n) if $n->bacmp(BMAX) <= 0;
3009 1         53 $n;
3010             }
3011              
3012             sub sqrtint {
3013 1     1 0 5 my($n) = @_;
3014 1         3 my $sqrt = Math::BigInt->new("$n")->bsqrt;
3015 1         1343 return Math::Prime::Util::_reftyped($_[0], "$sqrt");
3016             }
3017              
3018             sub rootint {
3019 58     58 0 133 my ($n, $k, $refp) = @_;
3020 58 50       126 croak "rootint: k must be > 0" unless $k > 0;
3021             # Math::BigInt returns NaN for any root of a negative n.
3022 58         197 my $root = Math::BigInt->new("$n")->babs->broot("$k");
3023 58 50       43317 if (defined $refp) {
3024 0 0       0 croak("logint third argument not a scalar reference") unless ref($refp);
3025 0         0 $$refp = $root->copy->bpow($k);
3026             }
3027 58         177 return Math::Prime::Util::_reftyped($_[0], "$root");
3028             }
3029              
3030             sub logint {
3031 0     0 0 0 my ($n, $b, $refp) = @_;
3032 0 0 0     0 croak("logint third argument not a scalar reference") if defined($refp) && !ref($refp);
3033              
3034 0 0       0 if ($Math::Prime::Util::_GMPfunc{"logint"}) {
3035 0         0 my $e = Math::Prime::Util::GMP::logint($n, $b);
3036 0 0       0 if (defined $refp) {
3037 0         0 my $r = Math::Prime::Util::GMP::powmod($b, $e, $n);
3038 0 0       0 $r = $n if $r == 0;
3039 0         0 $$refp = Math::Prime::Util::_reftyped($_[0], $r);
3040             }
3041 0         0 return Math::Prime::Util::_reftyped($_[0], $e);
3042             }
3043              
3044 0 0       0 croak "logint: n must be > 0" unless $n > 0;
3045 0 0       0 croak "logint: missing base" unless defined $b;
3046 0 0       0 if ($b == 10) {
3047 0         0 my $e = length($n)-1;
3048 0 0       0 $$refp = Math::BigInt->new("1" . "0"x$e) if defined $refp;
3049 0         0 return $e;
3050             }
3051 0 0       0 if ($b == 2) {
3052 0         0 my $e = length(Math::BigInt->new("$n")->as_bin)-2-1;
3053 0 0       0 $$refp = Math::BigInt->from_bin("1" . "0"x$e) if defined $refp;
3054 0         0 return $e;
3055             }
3056 0 0       0 croak "logint: base must be > 1" unless $b > 1;
3057              
3058 0         0 my $e = Math::BigInt->new("$n")->blog("$b");
3059 0 0       0 $$refp = Math::BigInt->new("$b")->bpow($e) if defined $refp;
3060 0         0 return Math::Prime::Util::_reftyped($_[0], "$e");
3061             }
3062              
3063             # Seidel (Luschny), core using Trizen's simplications from Math::BigNum.
3064             # http://oeis.org/wiki/User:Peter_Luschny/ComputationAndAsymptoticsOfBernoulliNumbers#Bernoulli_numbers__after_Seidel
3065             sub _bernoulli_seidel {
3066 103     103   199 my($n) = @_;
3067 103 50       230 return (1,1) if $n == 0;
3068 103 50 33     393 return (0,1) if $n > 1 && $n % 2;
3069              
3070 103         300 my $oacc = Math::BigInt->accuracy(); Math::BigInt->accuracy(undef);
  103         1317  
3071 103         1756 my @D = (BZERO->copy, BONE->copy, map { BZERO->copy } 1 .. ($n>>1)-1);
  2374         46196  
3072 103         2296 my ($h, $w) = (1, 1);
3073              
3074 103         266 foreach my $i (0 .. $n-1) {
3075 4954 100       17472198 if ($w ^= 1) {
3076 2477         8407 $D[$_]->badd($D[$_-1]) for 1 .. $h-1;
3077             } else {
3078 2477         4066 $w = $h++;
3079 2477         7401 $D[$w]->badd($D[$w+1]) while --$w;
3080             }
3081             }
3082 103         227122 my $num = $D[$h-1];
3083 103         406 my $den = BONE->copy->blsft($n+1)->bsub(BTWO);
3084 103         53825 my $gcd = Math::BigInt::bgcd($num, $den);
3085 103         78626 $num /= $gcd;
3086 103         39588 $den /= $gcd;
3087 103 100       20936 $num->bneg() if ($n % 4) == 0;
3088 103         1028 Math::BigInt->accuracy($oacc);
3089 103         4277 ($num,$den);
3090             }
3091              
3092             sub bernfrac {
3093 111     111 0 223 my $n = shift;
3094 111 100       301 return (BONE,BONE) if $n == 0;
3095 107 100       294 return (BONE,BTWO) if $n == 1; # We're choosing 1/2 instead of -1/2
3096 105 100 66     490 return (BZERO,BONE) if $n < 0 || $n & 1;
3097              
3098             # We should have used one of the GMP functions before coming here.
3099              
3100 103         243 _bernoulli_seidel($n);
3101             }
3102              
3103             sub stirling {
3104 518     518 0 89268 my($n, $m, $type) = @_;
3105 518 50       1806 return 1 if $m == $n;
3106 518 50 33     3928 return 0 if $n == 0 || $m == 0 || $m > $n;
      33        
3107 518 100       1472 $type = 1 unless defined $type;
3108 518 50 100     2653 croak "stirling type must be 1, 2, or 3" unless $type == 1 || $type == 2 || $type == 3;
      66        
3109 518 50       1304 if ($m == 1) {
3110 0 0       0 return 1 if $type == 2;
3111 0 0       0 return factorial($n) if $type == 3;
3112 0 0       0 return factorial($n-1) if $n&1;
3113 0         0 return vecprod(-1, factorial($n-1));
3114             }
3115             return Math::Prime::Util::_reftyped($_[0], Math::Prime::Util::GMP::stirling($n,$m,$type))
3116 518 50       1494 if $Math::Prime::Util::_GMPfunc{"stirling"};
3117             # Go through vecsum with quoted negatives to make sure we don't overflow.
3118 518         910 my $s;
3119 518 100       1632 if ($type == 3) {
    100          
3120 5         377 $s = Math::Prime::Util::vecprod( Math::Prime::Util::binomial($n,$m), Math::Prime::Util::binomial($n-1,$m-1), Math::Prime::Util::factorial($n-$m) );
3121             } elsif ($type == 2) {
3122 465         923 my @terms;
3123 465         1340 for my $j (1 .. $m) {
3124 14941         561031 my $t = Math::Prime::Util::vecprod(
3125             Math::BigInt->new($j) ** $n,
3126             Math::Prime::Util::binomial($m,$j)
3127             );
3128 14941 100       726407 push @terms, (($m-$j) & 1) ? "-$t" : $t;
3129             }
3130 465         18796 $s = Math::Prime::Util::vecsum(@terms) / factorial($m);
3131             } else {
3132 48         93 my @terms;
3133 48         154 for my $k (1 .. $n-$m) {
3134 782         51488 my $t = Math::Prime::Util::vecprod(
3135             Math::Prime::Util::binomial($k + $n - 1, $k + $n - $m),
3136             Math::Prime::Util::binomial(2 * $n - $m, $n - $k - $m),
3137             Math::Prime::Util::stirling($k - $m + $n, $k, 2),
3138             );
3139 782 100       7023 push @terms, ($k & 1) ? "-$t" : $t;
3140             }
3141 48         2372 $s = Math::Prime::Util::vecsum(@terms);
3142             }
3143 518         496267 $s;
3144             }
3145              
3146             sub _harmonic_split { # From Fredrik Johansson
3147 1259     1259   34837 my($a,$b) = @_;
3148 1259 100       2814 return (BONE, $a) if $b - $a == BONE;
3149 1047 100       150502 return ($a+$a+BONE, $a*$a+$a) if $b - $a == BTWO; # Cut down recursion
3150 590         83339 my $m = $a->copy->badd($b)->brsft(BONE);
3151 590         96301 my ($p,$q) = _harmonic_split($a, $m);
3152 590         164028 my ($r,$s) = _harmonic_split($m, $b);
3153 590         217148 ($p*$s+$q*$r, $q*$s);
3154             }
3155              
3156             sub harmfrac {
3157 79     79 0 160 my($n) = @_;
3158 79 50       156 return (BZERO,BONE) if $n <= 0;
3159 79 50       372 $n = Math::BigInt->new("$n") unless ref($n) eq 'Math::BigInt';
3160 79         3778 my($p,$q) = _harmonic_split($n-$n+1, $n+1);
3161 79         27594 my $gcd = Math::BigInt::bgcd($p,$q);
3162 79         97203 ( scalar $p->bdiv($gcd), scalar $q->bdiv($gcd) );
3163             }
3164              
3165             sub harmreal {
3166 21     21 0 48 my($n, $precision) = @_;
3167              
3168 21 50       44 do { require Math::BigFloat; Math::BigFloat->import(); } unless defined $Math::BigFloat::VERSION;
  0         0  
  0         0  
3169 21 50       48 return Math::BigFloat->bzero if $n <= 0;
3170              
3171             # Use asymptotic formula for larger $n if possible. Saves lots of time if
3172             # the default Calc backend is being used.
3173             {
3174 21         33 my $sprec = $precision;
  21         33  
3175 21 50       89 $sprec = Math::BigFloat->precision unless defined $sprec;
3176 21 50       286 $sprec = 40 unless defined $sprec;
3177 21 50 33     248 if ( ($sprec <= 23 && $n > 54) ||
      33        
      33        
      33        
      33        
      33        
      33        
3178             ($sprec <= 30 && $n > 348) ||
3179             ($sprec <= 40 && $n > 2002) ||
3180             ($sprec <= 50 && $n > 12644) ) {
3181 0         0 $n = Math::BigFloat->new($n, $sprec+5);
3182 0         0 my($n2, $one, $h) = ($n*$n, Math::BigFloat->bone, Math::BigFloat->bzero);
3183 0         0 my $nt = $n2;
3184 0         0 my $eps = Math::BigFloat->new(10)->bpow(-$sprec-4);
3185 0         0 foreach my $d (-12, 120, -252, 240, -132, 32760, -12, 8160, -14364, 6600, -276, 65520, -12) { # OEIS A006593
3186 0         0 my $term = $one/($d * $nt);
3187 0 0       0 last if $term->bacmp($eps) < 0;
3188 0         0 $h += $term;
3189 0         0 $nt *= $n2;
3190             }
3191 0         0 $h->badd(scalar $one->copy->bdiv(2*$n));
3192 0         0 $h->badd(_Euler($sprec));
3193 0         0 $h->badd($n->copy->blog);
3194 0         0 $h->round($sprec);
3195 0         0 return $h;
3196             }
3197             }
3198              
3199 21         59 my($num,$den) = Math::Prime::Util::harmfrac($n);
3200             # Note, with Calc backend this can be very, very slow
3201 21         7406 scalar Math::BigFloat->new($num)->bdiv($den, $precision);
3202             }
3203              
3204             sub is_pseudoprime {
3205 10     10 0 1331 my($n, @bases) = @_;
3206 10 50       27 return 0 if int($n) < 0;
3207 10         28 _validate_positive_integer($n);
3208 10 50       20 croak("No bases given to is_pseudoprime") unless scalar(@bases) > 0;
3209 10 50       17 return 0+($n >= 2) if $n < 4;
3210              
3211 10         22 foreach my $base (@bases) {
3212 10 50       20 croak "Base $base is invalid" if $base < 2;
3213 10 50       19 $base = $base % $n if $base >= $n;
3214 10 50 33     37 if ($base > 1 && $base != $n-1) {
3215 10 50       29 my $x = (ref($n) eq 'Math::BigInt')
3216             ? $n->copy->bzero->badd($base)->bmodpow($n-1,$n)->is_one
3217             : _powmod($base, $n-1, $n);
3218 10 50       23 return 0 unless $x == 1;
3219             }
3220             }
3221 10         27 1;
3222             }
3223              
3224             sub is_euler_pseudoprime {
3225 0     0 0 0 my($n, @bases) = @_;
3226 0 0       0 return 0 if int($n) < 0;
3227 0         0 _validate_positive_integer($n);
3228 0 0       0 croak("No bases given to is_euler_pseudoprime") unless scalar(@bases) > 0;
3229 0 0       0 return 0+($n >= 2) if $n < 4;
3230              
3231 0         0 foreach my $base (@bases) {
3232 0 0       0 croak "Base $base is invalid" if $base < 2;
3233 0 0       0 $base = $base % $n if $base >= $n;
3234 0 0 0     0 if ($base > 1 && $base != $n-1) {
3235 0         0 my $j = kronecker($base, $n);
3236 0 0       0 return 0 if $j == 0;
3237 0 0       0 $j = ($j > 0) ? 1 : $n-1;
3238 0 0       0 my $x = (ref($n) eq 'Math::BigInt')
3239             ? $n->copy->bzero->badd($base)->bmodpow(($n-1)/2,$n)
3240             : _powmod($base, ($n-1)>>1, $n);
3241 0 0       0 return 0 unless $x == $j;
3242             }
3243             }
3244 0         0 1;
3245             }
3246              
3247             sub is_euler_plumb_pseudoprime {
3248 0     0 0 0 my($n) = @_;
3249 0 0       0 return 0 if int($n) < 0;
3250 0         0 _validate_positive_integer($n);
3251 0 0       0 return 0+($n >= 2) if $n < 4;
3252 0 0       0 return 0 if ($n % 2) == 0;
3253 0         0 my $nmod8 = $n % 8;
3254 0         0 my $exp = 1 + ($nmod8 == 1);
3255 0         0 my $ap = Math::Prime::Util::powmod(2, ($n-1) >> $exp, $n);
3256 0 0 0     0 if ($ap == 1) { return ($nmod8 == 1 || $nmod8 == 7); }
  0         0  
3257 0 0 0     0 if ($ap == $n-1) { return ($nmod8 == 1 || $nmod8 == 3 || $nmod8 == 5); }
  0         0  
3258 0         0 0;
3259             }
3260              
3261             sub _miller_rabin_2 {
3262 3739     3739   266677 my($n, $nm1, $s, $d) = @_;
3263              
3264 3739 100       7477 if ( ref($n) eq 'Math::BigInt' ) {
3265              
3266 476 50       1534 if (!defined $nm1) {
3267 476         1536 $nm1 = $n->copy->bdec();
3268 476         36992 $s = 0;
3269 476         1404 $d = $nm1->copy;
3270 476         9409 do {
3271 976         62218 $s++;
3272 976         3123 $d->brsft(BONE);
3273             } while $d->is_even;
3274             }
3275 476         59458 my $x = BTWO->copy->bmodpow($d,$n);
3276 476 100 100     43238431 return 1 if $x->is_one || $x->bcmp($nm1) == 0;
3277 365         22929 foreach my $r (1 .. $s-1) {
3278 356         5271 $x->bmul($x)->bmod($n);
3279 356 50       160980 last if $x->is_one;
3280 356 100       4879 return 1 if $x->bcmp($nm1) == 0;
3281             }
3282              
3283             } else {
3284              
3285 3263 50       5490 if (!defined $nm1) {
3286 3263         4250 $nm1 = $n-1;
3287 3263         4259 $s = 0;
3288 3263         4426 $d = $nm1;
3289 3263         6243 while ( ($d & 1) == 0 ) {
3290 7574         9208 $s++;
3291 7574         12994 $d >>= 1;
3292             }
3293             }
3294              
3295 3263 100       5226 if ($n < MPU_HALFWORD) {
3296 3206         6030 my $x = _native_powmod(2, $d, $n);
3297 3206 100 100     9571 return 1 if $x == 1 || $x == $nm1;
3298 3196         6334 foreach my $r (1 .. $s-1) {
3299 3807         4988 $x = ($x*$x) % $n;
3300 3807 100       6024 last if $x == 1;
3301 3804 100       7287 return 1 if $x == $n-1;
3302             }
3303             } else {
3304 57         270 my $x = _powmod(2, $d, $n);
3305 57 100 66     478 return 1 if $x == 1 || $x == $nm1;
3306 19         194 foreach my $r (1 .. $s-1) {
3307 31 50       100 $x = ($x < MPU_HALFWORD) ? ($x*$x) % $n : _mulmod($x, $x, $n);
3308 31 50       112 last if $x == 1;
3309 31 100       118 return 1 if $x == $n-1;
3310             }
3311             }
3312             }
3313 3194         18853 0;
3314             }
3315              
3316             sub is_strong_pseudoprime {
3317 3619     3619 0 33084 my($n, @bases) = @_;
3318 3619 50       7700 return 0 if int($n) < 0;
3319 3619         57384 _validate_positive_integer($n);
3320 3619 50       7193 croak("No bases given to is_strong_pseudoprime") unless scalar(@bases) > 0;
3321              
3322 3619 100       6700 return 0+($n >= 2) if $n < 4;
3323 3615 50       38544 return 0 if ($n % 2) == 0;
3324              
3325 3615 100       106955 if ($bases[0] == 2) {
3326 3365 100       5420 return 0 unless _miller_rabin_2($n);
3327 375         3184 shift @bases;
3328 375 100       1043 return 1 unless @bases;
3329             }
3330              
3331 575         1306 my @newbases;
3332 575         1169 for my $base (@bases) {
3333 718 50       1497 croak "Base $base is invalid" if $base < 2;
3334 718 100       3806 $base %= $n if $base >= $n;
3335 718 50 66     16501 return 0 if $base == 0 || ($base == $n-1 && ($base % 2) == 1);
      33        
3336 718         66873 push @newbases, $base;
3337             }
3338 575         1271 @bases = @newbases;
3339              
3340 575 100       1489 if ( ref($n) eq 'Math::BigInt' ) {
3341              
3342 152         440 my $nminus1 = $n->copy->bdec();
3343 152         11433 my $s = 0;
3344 152         412 my $d = $nminus1->copy;
3345 152         3105 do { # n is > 3 and odd, so n-1 must be even
3346 285         17942 $s++;
3347 285         921 $d->brsft(BONE);
3348             } while $d->is_even;
3349             # Different way of doing the above. Fewer function calls, slower on ave.
3350             #my $dbin = $nminus1->as_bin;
3351             #my $last1 = rindex($dbin, '1');
3352             #my $s = length($dbin)-2-$last1+1;
3353             #my $d = $nminus1->copy->brsft($s);
3354              
3355 152         18419 foreach my $ma (@bases) {
3356 194         2178 my $x = $n->copy->bzero->badd($ma)->bmodpow($d,$n);
3357 194 100 100     6808023 next if $x->is_one || $x->bcmp($nminus1) == 0;
3358 104         6418 foreach my $r (1 .. $s-1) {
3359 100         1273 $x->bmul($x); $x->bmod($n);
  100         16076  
3360 100 50       28206 return 0 if $x->is_one;
3361 100 100       1454 do { $ma = 0; last; } if $x->bcmp($nminus1) == 0;
  41         1504  
  41         104  
3362             }
3363 104 100       2195 return 0 if $ma != 0;
3364             }
3365              
3366             } else {
3367              
3368 423         639 my $s = 0;
3369 423         612 my $d = $n - 1;
3370 423         964 while ( ($d & 1) == 0 ) {
3371 1744         2102 $s++;
3372 1744         2910 $d >>= 1;
3373             }
3374              
3375 423 100       809 if ($n < MPU_HALFWORD) {
3376 382         593 foreach my $ma (@bases) {
3377 396         658 my $x = _native_powmod($ma, $d, $n);
3378 396 100 100     1372 next if ($x == 1) || ($x == ($n-1));
3379 330         632 foreach my $r (1 .. $s-1) {
3380 954         1304 $x = ($x*$x) % $n;
3381 954 100       1606 return 0 if $x == 1;
3382 953 100       1768 last if $x == $n-1;
3383             }
3384 329 100       763 return 0 if $x != $n-1;
3385             }
3386             } else {
3387 41         109 foreach my $ma (@bases) {
3388 117         322 my $x = _powmod($ma, $d, $n);
3389 117 100 100     782 next if ($x == 1) || ($x == ($n-1));
3390              
3391 6         20 foreach my $r (1 .. $s-1) {
3392 7 100       27 $x = ($x < MPU_HALFWORD) ? ($x*$x) % $n : _mulmod($x, $x, $n);
3393 7 50       17 return 0 if $x == 1;
3394 7 100       23 last if $x == $n-1;
3395             }
3396 6 100       39 return 0 if $x != $n-1;
3397             }
3398             }
3399              
3400             }
3401 502         4818 1;
3402             }
3403              
3404              
3405             # Calculate Kronecker symbol (a|b). Cohen Algorithm 1.4.10.
3406             # Extension of the Jacobi symbol, itself an extension of the Legendre symbol.
3407             sub kronecker {
3408 665     665 0 9388 my($a, $b) = @_;
3409 665 0       1667 return (abs($a) == 1) ? 1 : 0 if $b == 0;
    50          
3410 665         46655 my $k = 1;
3411 665 50       1793 if ($b % 2 == 0) {
3412 0 0       0 return 0 if $a % 2 == 0;
3413 0         0 my $v = 0;
3414 0         0 do { $v++; $b /= 2; } while $b % 2 == 0;
  0         0  
  0         0  
3415 0 0 0     0 $k = -$k if $v % 2 == 1 && ($a % 8 == 3 || $a % 8 == 5);
      0        
3416             }
3417 665 100       95949 if ($b < 0) {
3418 1         3 $b = -$b;
3419 1 50       5 $k = -$k if $a < 0;
3420             }
3421 665 100       45645 if ($a < 0) { $a = -$a; $k = -$k if $b % 4 == 3; }
  16 100       42  
  16         44  
3422 665 100 100     3773 $b = _bigint_to_int($b) if ref($b) eq 'Math::BigInt' && $b <= BMAX;
3423 665 50 66     11730 $a = _bigint_to_int($a) if ref($a) eq 'Math::BigInt' && $a <= BMAX;
3424             # Now: b > 0, b odd, a >= 0
3425 665         1945 while ($a != 0) {
3426 936 100       55681 if ($a % 2 == 0) {
3427 402         40026 my $v = 0;
3428 402         728 do { $v++; $a /= 2; } while $a % 2 == 0;
  672         24520  
  672         2053  
3429 402 100 100     72396 $k = -$k if $v % 2 == 1 && ($b % 8 == 3 || $b % 8 == 5);
      100        
3430             }
3431 936 100 100     61163 $k = -$k if $a % 4 == 3 && $b % 4 == 3;
3432 936         100865 ($a, $b) = ($b % $a, $a);
3433             # If a,b are bigints and now small enough, finish as native.
3434 936 100 100     89649 if ( ref($a) eq 'Math::BigInt' && $a <= BMAX
      100        
      66        
3435             && ref($b) eq 'Math::BigInt' && $b <= BMAX) {
3436 267         18128 return $k * kronecker(_bigint_to_int($a),_bigint_to_int($b));
3437             }
3438             }
3439 398 50       5050 return ($b == 1) ? $k : 0;
3440             }
3441              
3442             sub _binomialu {
3443 5235     5235   13350 my($r, $n, $k) = (1, @_);
3444 5235 0       10784 return ($k == $n) ? 1 : 0 if $k >= $n;
    50          
3445 5235 100       12196 $k = $n - $k if $k > ($n >> 1);
3446 5235         12756 foreach my $d (1 .. $k) {
3447 89359 100       151169 if ($r >= int(~0/$n)) {
3448 13809         19962 my($g, $nr, $dr);
3449 13809         27172 $g = _gcd_ui($n, $d); $nr = int($n/$g); $dr = int($d/$g);
  13809         23972  
  13809         20499  
3450 13809         22097 $g = _gcd_ui($r, $dr); $r = int($r/$g); $dr = int($dr/$g);
  13809         20380  
  13809         19872  
3451 13809 100       32035 return 0 if $r >= int(~0/$nr);
3452 8576         12128 $r *= $nr;
3453 8576         13110 $r = int($r/$dr);
3454             } else {
3455 75550         98518 $r *= $n;
3456 75550         102649 $r = int($r/$d);
3457             }
3458 84126         115348 $n--;
3459             }
3460 2         5 $r;
3461             }
3462              
3463             sub binomial {
3464 5235     5235 0 111599 my($n, $k) = @_;
3465              
3466             # 1. Try GMP
3467             return Math::Prime::Util::_reftyped($_[0], Math::Prime::Util::GMP::binomial($n,$k))
3468 5235 50       17069 if $Math::Prime::Util::_GMPfunc{"binomial"};
3469              
3470             # 2. Exit early for known 0 cases, and adjust k to be positive.
3471 5235 50 33     14851 if ($n >= 0) { return 0 if $k < 0 || $k > $n; }
  5234 100       24669  
3472 1 50 33     8 else { return 0 if $k < 0 && $k > $n; }
3473 5235 100       11981 $k = $n - $k if $k < 0;
3474              
3475             # 3. Try to do in integer Perl
3476 5235         9810 my $r;
3477 5235 100       12755 if ($n >= 0) {
3478 5234         13577 $r = _binomialu($n, $k);
3479 5234 100       13768 return $r if $r > 0;
3480             } else {
3481 1         4 $r = _binomialu(-$n+$k-1, $k);
3482 1 50 33     8 return $r if $r > 0 && !($k & 1);
3483 1 50 33     10 return -$r if $r > 0 && $r <= (~0>>1);
3484             }
3485              
3486             # 4. Overflow. Solve using Math::BigInt
3487 5233 50       11303 return 1 if $k == 0; # Work around bug in old
3488 5233 50       12556 return $n if $k == $n-1; # Math::BigInt (fixed in 1.90)
3489 5233 50       10275 if ($n >= 0) {
3490 5233         26044 $r = Math::BigInt->new(''.$n)->bnok($k);
3491 5233 50       14384868 $r = _bigint_to_int($r) if $r->bacmp(BMAX) <= 0;
3492             } else { # Math::BigInt is incorrect for negative n
3493 0         0 $r = Math::BigInt->new(''.(-$n+$k-1))->bnok($k);
3494 0 0       0 if ($k & 1) {
3495 0         0 $r->bneg;
3496 0 0       0 $r = _bigint_to_int($r) if $r->bacmp(''.(~0>>1)) <= 0;
3497             } else {
3498 0 0       0 $r = _bigint_to_int($r) if $r->bacmp(BMAX) <= 0;
3499             }
3500             }
3501 5233         164706 $r;
3502             }
3503              
3504             sub _product {
3505 14994     14994   845613 my($a, $b, $r) = @_;
3506 14994 100       54493 if ($b <= $a) {
    100          
    100          
3507 2         6 $r->[$a];
3508             } elsif ($b == $a+1) {
3509 13720         45554 $r->[$a] -> bmul( $r->[$b] );
3510             } elsif ($b == $a+2) {
3511 814         2984 $r->[$a] -> bmul( $r->[$a+1] ) -> bmul( $r->[$a+2] );
3512             } else {
3513 458         719 my $c = $a + (($b-$a+1)>>1);
3514 458         980 _product($a, $c-1, $r);
3515 458         30817 _product($c, $b, $r);
3516 458         33216 $r->[$a] -> bmul( $r->[$c] );
3517             }
3518             }
3519              
3520             sub factorial {
3521 768     768 0 154051 my($n) = @_;
3522 768 100       2934 return (1,1,2,6,24,120,720,5040,40320,362880,3628800,39916800,479001600)[$n] if $n <= 12;
3523 564 50       1764 return Math::GMP::bfac($n) if ref($n) eq 'Math::GMP';
3524 564 50       1523 do { my $r = Math::GMPz->new(); Math::GMPz::Rmpz_fac_ui($r,$n); return $r; }
  0         0  
  0         0  
  0         0  
3525             if ref($n) eq 'Math::GMPz';
3526 564 50       2066 if (Math::BigInt->config()->{lib} !~ /GMP|Pari/) {
3527             # It's not a GMP or GMPz object, and we have a slow bigint library.
3528 564         28781 my $r;
3529 564 50 33     2933 if (defined $Math::GMPz::VERSION) {
    50          
    50          
3530 0         0 $r = Math::GMPz->new(); Math::GMPz::Rmpz_fac_ui($r,$n);
  0         0  
3531             } elsif (defined $Math::GMP::VERSION) {
3532 0         0 $r = Math::GMP::bfac($n);
3533             } elsif (defined &Math::Prime::Util::GMP::factorial && Math::Prime::Util::prime_get_config()->{'gmp'}) {
3534 0         0 $r = Math::Prime::Util::GMP::factorial($n);
3535             }
3536 564 50       1463 return Math::Prime::Util::_reftyped($_[0], $r) if defined $r;
3537             }
3538 564         3033 my $r = Math::BigInt->new($n)->bfac();
3539 564 100       18782733 $r = _bigint_to_int($r) if $r->bacmp(BMAX) <= 0;
3540 564         14630 $r;
3541             }
3542              
3543             sub factorialmod {
3544 0     0 0 0 my($n,$m) = @_;
3545              
3546             return Math::Prime::Util::GMP::factorialmod($n,$m)
3547 0 0       0 if $Math::Prime::Util::_GMPfunc{"factorialmod"};
3548              
3549 0 0 0     0 return 0 if $n >= $m || $m == 1;
3550              
3551 0 0       0 if ($n > 10) {
3552 0         0 my($s,$t,$e) = (1);
3553             Math::Prime::Util::forprimes( sub {
3554 0     0   0 ($t,$e) = ($n,0);
3555 0         0 while ($t > 0) {
3556 0         0 $t = int($t/$_);
3557 0         0 $e += $t;
3558             }
3559 0         0 $s = Math::Prime::Util::mulmod($s, Math::Prime::Util::powmod($_,$e,$m), $m);
3560 0         0 }, 2, $n >> 1);
3561             Math::Prime::Util::forprimes( sub {
3562 0     0   0 $s = Math::Prime::Util::mulmod($s, $_, $m);
3563 0         0 }, ($n >> 1)+1, $n);
3564 0         0 return $s;
3565             }
3566              
3567 0         0 return factorial($n) % $m;
3568             }
3569              
3570             sub _is_perfect_square {
3571 212     212   56335 my($n) = @_;
3572 212 50       1011 return (1,1,0,0,1)[$n] if $n <= 4;
3573              
3574 212 100       16227 if (ref($n) eq 'Math::BigInt') {
3575 140         677 my $mc = _bigint_to_int($n & 31);
3576 140 100 66     6850 if ($mc==0||$mc==1||$mc==4||$mc==9||$mc==16||$mc==17||$mc==25) {
      66        
      100        
      66        
      100        
      100        
3577 48         191 my $sq = $n->copy->bsqrt->bfloor;
3578 48         48831 $sq->bmul($sq);
3579 48 100       5926 return 1 if $sq == $n;
3580             }
3581             } else {
3582 72         166 my $mc = $n & 31;
3583 72 100 33     870 if ($mc==0||$mc==1||$mc==4||$mc==9||$mc==16||$mc==17||$mc==25) {
      33        
      33        
      33        
      66        
      100        
3584 8         31 my $sq = int(sqrt($n));
3585 8 50       36 return 1 if ($sq*$sq) == $n;
3586             }
3587             }
3588 210         3096 0;
3589             }
3590              
3591             sub is_primitive_root {
3592 0     0 0 0 my($a, $n) = @_;
3593 0 0       0 $n = -$n if $n < 0; # Ignore sign of n
3594 0 0       0 return ($n==1) ? 1 : 0 if $n <= 1;
    0          
3595 0 0 0     0 $a %= $n if $a < 0 || $a >= $n;
3596              
3597             return Math::Prime::Util::GMP::is_primitive_root($a,$n)
3598 0 0       0 if $Math::Prime::Util::_GMPfunc{"is_primitive_root"};
3599              
3600 0 0 0     0 if ($Math::Prime::Util::_GMPfunc{"znorder"} && $Math::Prime::Util::_GMPfunc{"totient"}) {
3601 0         0 my $order = Math::Prime::Util::GMP::znorder($a,$n);
3602 0 0       0 return 0 unless defined $order;
3603 0         0 my $totient = Math::Prime::Util::GMP::totient($n);
3604 0 0       0 return ($order eq $totient) ? 1 : 0;
3605             }
3606              
3607 0 0       0 return 0 if Math::Prime::Util::gcd($a, $n) != 1;
3608 0         0 my $s = Math::Prime::Util::euler_phi($n);
3609 0 0 0     0 return 0 if ($s % 2) == 0 && Math::Prime::Util::powmod($a, $s/2, $n) == 1;
3610 0 0 0     0 return 0 if ($s % 3) == 0 && Math::Prime::Util::powmod($a, $s/3, $n) == 1;
3611 0 0 0     0 return 0 if ($s % 5) == 0 && Math::Prime::Util::powmod($a, $s/5, $n) == 1;
3612 0         0 foreach my $f (Math::Prime::Util::factor_exp($s)) {
3613 0         0 my $fp = $f->[0];
3614 0 0 0     0 return 0 if $fp > 5 && Math::Prime::Util::powmod($a, $s/$fp, $n) == 1;
3615             }
3616 0         0 1;
3617             }
3618              
3619             sub znorder {
3620 10     10 0 1602 my($a, $n) = @_;
3621 10 50       34 return if $n <= 0;
3622 10 50       728 return 1 if $n == 1;
3623 10 50       793 return if $a <= 0;
3624 10 50       555 return 1 if $a == 1;
3625              
3626             return Math::Prime::Util::_reftyped($_[0], Math::Prime::Util::GMP::znorder($a,$n))
3627 10 50       341 if $Math::Prime::Util::_GMPfunc{"znorder"};
3628              
3629             # Sadly, Calc/FastCalc are horrendously slow for this function.
3630 10 100       99 return if Math::Prime::Util::gcd($a, $n) > 1;
3631              
3632             # The answer is one of the divisors of phi(n) and lambda(n).
3633 8         201 my $lambda = Math::Prime::Util::carmichael_lambda($n);
3634 8 100       103 $a = Math::BigInt->new("$a") unless ref($a) eq 'Math::BigInt';
3635              
3636             # This is easy and usually fast, but can bog down with too many divisors.
3637 8 100       362 if ($lambda <= 2**64) {
3638 7         90 foreach my $k (Math::Prime::Util::divisors($lambda)) {
3639 54 100       2074 return $k if Math::Prime::Util::powmod($a,$k,$n) == 1;
3640             }
3641 0         0 return;
3642             }
3643              
3644             # Algorithm 1.7 from A. Das applied to Carmichael Lambda.
3645 1 50       341 $lambda = Math::BigInt->new("$lambda") unless ref($lambda) eq 'Math::BigInt';
3646 1         7 my $k = Math::BigInt->bone;
3647 1         80 foreach my $f (Math::Prime::Util::factor_exp($lambda)) {
3648 7         1104 my($pi, $ei, $enum) = (Math::BigInt->new("$f->[0]"), $f->[1], 0);
3649 7         364 my $phidiv = $lambda / ($pi**$ei);
3650 7         4150 my $b = Math::Prime::Util::powmod($a,$phidiv,$n);
3651 7         39 while ($b != 1) {
3652 10 50       1649 return if $enum++ >= $ei;
3653 10         56 $b = Math::Prime::Util::powmod($b,$pi,$n);
3654 10         342 $k *= $pi;
3655             }
3656             }
3657 1 50       230 $k = _bigint_to_int($k) if $k->bacmp(BMAX) <= 0;
3658 1         36 return $k;
3659             }
3660              
3661             sub _dlp_trial {
3662 2     2   10 my ($a,$g,$p,$limit) = @_;
3663 2 50 33     16 $limit = $p if !defined $limit || $limit > $p;
3664 2         179 my $t = $g->copy;
3665              
3666 2 50       57 if ($limit < 1_000_000_000) {
3667 2         11 for my $k (1 .. $limit) {
3668 213 100       15061 return $k if $t == $a;
3669 212         21512 $t = Math::Prime::Util::mulmod($t, $g, $p);
3670             }
3671 1         91 return 0;
3672             }
3673              
3674 0         0 for (my $k = BONE->copy; $k < $limit; $k->binc) {
3675 0 0       0 if ($t == $a) {
3676 0 0       0 $k = _bigint_to_int($k) if $k->bacmp(BMAX) <= 0;
3677 0         0 return $k;
3678             }
3679 0         0 $t->bmul($g)->bmod($p);
3680             }
3681 0         0 0;
3682             }
3683             sub _dlp_bsgs {
3684 1     1   4 my ($a,$g,$p,$n,$_verbose) = @_;
3685 1         7 my $invg = invmod($g, $p);
3686 1 50       4 return unless defined $invg;
3687 1         6 my $maxm = Math::Prime::Util::sqrtint($n)+1;
3688 1         61 my $b = ($p + $maxm - 1) / $maxm;
3689             # Limit for time and space.
3690 1 50       658 $b = ($b > 4_000_000) ? 4_000_000 : int("$b");
3691 1 50       143 $maxm = ($maxm > $b) ? $b : int("$maxm");
3692              
3693 1         4 my %hash;
3694 1         4 my $am = BONE->copy;
3695 1         28 my $gm = Math::Prime::Util::powmod($invg, $maxm, $p);
3696 1         82 my $key = $a->copy;
3697 1         24 my $r;
3698              
3699 1         5 foreach my $m (0 .. $b) {
3700             # Baby Step
3701 87 50       3655 if ($m <= $maxm) {
3702 87         146 $r = $hash{"$am"};
3703 87 50       202 if (defined $r) {
3704 0 0       0 print " bsgs found in stage 1 after $m tries\n" if $_verbose;
3705 0         0 $r = Math::Prime::Util::addmod($m, Math::Prime::Util::mulmod($r,$maxm,$p), $p);
3706 0         0 return $r;
3707             }
3708 87         276 $hash{"$am"} = $m;
3709 87         234 $am = Math::Prime::Util::mulmod($am,$g,$p);
3710 87 50       6275 if ($am == $a) {
3711 0 0       0 print " bsgs found during bs\n" if $_verbose;
3712 0         0 return $m+1;
3713             }
3714             }
3715              
3716             # Giant Step
3717 87         9255 $r = $hash{"$key"};
3718 87 100       202 if (defined $r) {
3719 1 50       5 print " bsgs found in stage 2 after $m tries\n" if $_verbose;
3720 1         5 $r = Math::Prime::Util::addmod($r, Math::Prime::Util::mulmod($m,$maxm,$p), $p);
3721 1         100 return $r;
3722             }
3723 86 50       351 $hash{"$key"} = $m if $m <= $maxm;
3724 86         305 $key = Math::Prime::Util::mulmod($key,$gm,$p);
3725             }
3726 0         0 0;
3727             }
3728              
3729             sub znlog {
3730             my ($a,$g,$p) =
3731 2 100   2 0 156 map { ref($_) eq 'Math::BigInt' ? $_ : Math::BigInt->new("$_") } @_;
  6         109  
3732 2         47 $a->bmod($p);
3733 2         281 $g->bmod($p);
3734 2 50 33     322 return 0 if $a == 1 || $g == 0 || $p < 2;
      33        
3735 2         952 my $_verbose = Math::Prime::Util::prime_get_config()->{'verbose'};
3736              
3737             # For large p, znorder can be very slow. Do trial test first.
3738 2         12 my $x = _dlp_trial($a, $g, $p, 200);
3739 2 100       56 if ($x == 0) {
3740 1         5 my $n = znorder($g, $p);
3741 1 50 33     104 if (defined $n && $n > 1000) {
3742 1 50       10 $n = Math::BigInt->new("$n") unless ref($n) eq 'Math::BigInt';
3743 1         51 $x = _dlp_bsgs($a, $g, $p, $n, $_verbose);
3744 1 50 33     8 $x = _bigint_to_int($x) if ref($x) && $x->bacmp(BMAX) <= 0;
3745 1 50 33     18 return $x if $x > 0 && $g->copy->bmodpow($x, $p) == $a;
3746 0 0 0     0 print " BSGS giving up\n" if $x == 0 && $_verbose;
3747 0 0 0     0 print " BSGS incorrect answer $x\n" if $x > 0 && $_verbose > 1;
3748             }
3749 0         0 $x = _dlp_trial($a,$g,$p);
3750             }
3751 1 50 33     7 $x = _bigint_to_int($x) if ref($x) && $x->bacmp(BMAX) <= 0;
3752 1 50       7 return ($x == 0) ? undef : $x;
3753             }
3754              
3755             sub znprimroot {
3756 8     8 0 125 my($n) = @_;
3757 8 100       22 $n = -$n if $n < 0;
3758 8 100       203 if ($n <= 4) {
3759 2 100       6 return if $n == 0;
3760 1         4 return $n-1;
3761             }
3762 6 100       128 return if $n % 4 == 0;
3763 5         354 my $a = 1;
3764 5         10 my $phi = $n-1;
3765 5 100       272 if (!is_prob_prime($n)) {
3766 2         6 $phi = euler_phi($n);
3767             # Check that a primitive root exists.
3768 2 100       18 return if $phi != Math::Prime::Util::carmichael_lambda($n);
3769             }
3770 12         775 my @exp = map { Math::BigInt->new("$_") }
3771 4         198 map { int($phi/$_->[0]) }
  12         816  
3772             Math::Prime::Util::factor_exp($phi);
3773             #print "phi: $phi factors: ", join(",",factor($phi)), "\n";
3774             #print " exponents: ", join(",", @exp), "\n";
3775 4         184 while (1) {
3776 97         136 my $fail = 0;
3777 97         125 do { $a++ } while Math::Prime::Util::kronecker($a,$n) == 0;
  98         273  
3778 97 50       180 return if $a >= $n;
3779 97         327 foreach my $f (@exp) {
3780 137 100       2118 if (Math::Prime::Util::powmod($a,$f,$n) == 1) {
3781 93         3744 $fail = 1;
3782 93         136 last;
3783             }
3784             }
3785 97 100       487 return $a if !$fail;
3786             }
3787             }
3788              
3789              
3790             # Find first D in sequence (5,-7,9,-11,13,-15,...) where (D|N) == -1
3791             sub _lucas_selfridge_params {
3792 11     11   22 my($n) = @_;
3793              
3794             # D is typically quite small: 67 max for N < 10^19. However, it is
3795             # theoretically possible D could grow unreasonably. I'm giving up at 4000M.
3796 11         18 my $d = 5;
3797 11         20 my $sign = 1;
3798 11         18 while (1) {
3799 32 100       88 my $gcd = (ref($n) eq 'Math::BigInt') ? Math::BigInt::bgcd($d, $n)
3800             : _gcd_ui($d, $n);
3801 32 50 33     1740 return (0,0,0) if $gcd > 1 && $gcd != $n; # Found divisor $d
3802 32         832 my $j = kronecker($d * $sign, $n);
3803 32 100       68 last if $j == -1;
3804 21         31 $d += 2;
3805 21 50       42 croak "Could not find Jacobi sequence for $n" if $d > 4_000_000_000;
3806 21         40 $sign = -$sign;
3807             }
3808 11         22 my $D = $sign * $d;
3809 11         16 my $P = 1;
3810 11         26 my $Q = int( (1 - $D) / 4 );
3811 11         32 ($P, $Q, $D)
3812             }
3813              
3814             sub _lucas_extrastrong_params {
3815 198     198   619 my($n, $increment) = @_;
3816 198 100       878 $increment = 1 unless defined $increment;
3817              
3818 198         591 my ($P, $Q, $D) = (3, 1, 5);
3819 198         431 while (1) {
3820 360 100       1684 my $gcd = (ref($n) eq 'Math::BigInt') ? Math::BigInt::bgcd($D, $n)
3821             : _gcd_ui($D, $n);
3822 360 50 33     67567 return (0,0,0) if $gcd > 1 && $gcd != $n; # Found divisor $d
3823 360 100       30229 last if kronecker($D, $n) == -1;
3824 162         353 $P += $increment;
3825 162 50       405 croak "Could not find Jacobi sequence for $n" if $P > 65535;
3826 162         418 $D = $P*$P - 4;
3827             }
3828 198         929 ($P, $Q, $D);
3829             }
3830              
3831             # returns U_k, V_k, Q_k all mod n
3832             sub lucas_sequence {
3833 156     156 0 743 my($n, $P, $Q, $k) = @_;
3834              
3835 156 50       549 croak "lucas_sequence: n must be >= 2" if $n < 2;
3836 156 50       16820 croak "lucas_sequence: k must be >= 0" if $k < 0;
3837 156 50       23933 croak "lucas_sequence: P out of range" if abs($P) >= $n;
3838 156 50       12257 croak "lucas_sequence: Q out of range" if abs($Q) >= $n;
3839              
3840 156 50 33     10342 if ($Math::Prime::Util::_GMPfunc{"lucas_sequence"} && $Math::Prime::Util::GMP::VERSION >= 0.30) {
3841 0 0       0 return map { ($_ > ''.~0) ? Math::BigInt->new(''.$_) : $_ }
  0         0  
3842             Math::Prime::Util::GMP::lucas_sequence($n, $P, $Q, $k);
3843             }
3844              
3845 156 100       658 $n = Math::BigInt->new("$n") unless ref($n) eq 'Math::BigInt';
3846              
3847 156         1083 my $ZERO = $n->copy->bzero;
3848 156 100       7795 $P = $ZERO+$P unless ref($P) eq 'Math::BigInt';
3849 156 100       25274 $Q = $ZERO+$Q unless ref($Q) eq 'Math::BigInt';
3850 156         22504 my $D = $P*$P - BTWO*BTWO*$Q;
3851 156 50       45740 if ($D->is_zero) {
3852 0         0 my $S = ($ZERO+$P) >> 1;
3853 0         0 my $U = $S->copy->bmodpow($k-1,$n)->bmul($k)->bmod($n);
3854 0         0 my $V = $S->copy->bmodpow($k,$n)->bmul(BTWO)->bmod($n);
3855 0         0 my $Qk = ($ZERO+$Q)->bmodpow($k, $n);
3856 0         0 return ($U, $V, $Qk);
3857             }
3858 156         2357 my $U = BONE->copy;
3859 156         3694 my $V = $P->copy;
3860 156         3230 my $Qk = $Q->copy;
3861              
3862 156 50       3298 return (BZERO->copy, BTWO->copy, $Qk) if $k == 0;
3863 156 100       24849 $k = Math::BigInt->new("$k") unless ref($k) eq 'Math::BigInt';
3864 156         1153 my $kstr = substr($k->as_bin, 2);
3865 156         51796 my $bpos = 0;
3866              
3867 156 50       531 if (($n % 2)==0) {
    100          
3868 0         0 $P->bmod($n);
3869 0         0 $Q->bmod($n);
3870 0         0 my($Uh,$Vl, $Vh, $Ql, $Qh) = (BONE->copy, BTWO->copy, $P->copy, BONE->copy, BONE->copy);
3871 0         0 my ($b,$s) = (length($kstr)-1, 0);
3872 0 0       0 if ($kstr =~ /(0+)$/) { $s = length($1); }
  0         0  
3873 0         0 for my $bpos (0 .. $b-$s-1) {
3874 0         0 $Ql->bmul($Qh)->bmod($n);
3875 0 0       0 if (substr($kstr,$bpos,1)) {
3876 0         0 $Qh = $Ql * $Q;
3877 0         0 $Uh->bmul($Vh)->bmod($n);
3878 0         0 $Vl->bmul($Vh)->bsub($P * $Ql)->bmod($n);
3879 0         0 $Vh->bmul($Vh)->bsub(BTWO * $Qh)->bmod($n);
3880             } else {
3881 0         0 $Qh = $Ql->copy;
3882 0         0 $Uh->bmul($Vl)->bsub($Ql)->bmod($n);
3883 0         0 $Vh->bmul($Vl)->bsub($P * $Ql)->bmod($n);
3884 0         0 $Vl->bmul($Vl)->bsub(BTWO * $Ql)->bmod($n);
3885             }
3886             }
3887 0         0 $Ql->bmul($Qh);
3888 0         0 $Qh = $Ql * $Q;
3889 0         0 $Uh->bmul($Vl)->bsub($Ql)->bmod($n);
3890 0         0 $Vl->bmul($Vh)->bsub($P * $Ql)->bmod($n);
3891 0         0 $Ql->bmul($Qh)->bmod($n);
3892 0         0 for (1 .. $s) {
3893 0         0 $Uh->bmul($Vl)->bmod($n);
3894 0         0 $Vl->bmul($Vl)->bsub(BTWO * $Ql)->bmod($n);
3895 0         0 $Ql->bmul($Ql)->bmod($n);
3896             }
3897 0         0 ($U, $V, $Qk) = ($Uh, $Vl, $Ql);
3898             } elsif ($Q->is_one) {
3899 142         51250 my $Dinverse = $D->copy->bmodinv($n);
3900 142 50 33     82927 if ($P > BTWO && !$Dinverse->is_nan) {
3901             # Calculate V_k with U=V_{k+1}
3902 142         6510 $U = $P->copy->bmul($P)->bsub(BTWO)->bmod($n);
3903 142         38363 while (++$bpos < length($kstr)) {
3904 11913 100       20264283 if (substr($kstr,$bpos,1)) {
3905 5892         15971 $V->bmul($U)->bsub($P )->bmod($n);
3906 5892         10226855 $U->bmul($U)->bsub(BTWO)->bmod($n);
3907             } else {
3908 6021         15821 $U->bmul($V)->bsub($P )->bmod($n);
3909 6021         9913670 $V->bmul($V)->bsub(BTWO)->bmod($n);
3910             }
3911             }
3912             # Crandall and Pomerance eq 3.13: U_n = D^-1 (2V_{n+1} - PV_n)
3913 142         80786 $U = $Dinverse * (BTWO*$U - $P*$V);
3914             } else {
3915 0         0 while (++$bpos < length($kstr)) {
3916 0         0 $U->bmul($V)->bmod($n);
3917 0         0 $V->bmul($V)->bsub(BTWO)->bmod($n);
3918 0 0       0 if (substr($kstr,$bpos,1)) {
3919 0         0 my $T1 = $U->copy->bmul($D);
3920 0         0 $U->bmul($P)->badd( $V);
3921 0 0       0 $U->badd($n) if $U->is_odd;
3922 0         0 $U->brsft(BONE);
3923 0         0 $V->bmul($P)->badd($T1);
3924 0 0       0 $V->badd($n) if $V->is_odd;
3925 0         0 $V->brsft(BONE);
3926             }
3927             }
3928             }
3929             } else {
3930 14 100       5063 my $qsign = ($Q == -1) ? -1 : 0;
3931 14         1398 while (++$bpos < length($kstr)) {
3932 427         139126 $U->bmul($V)->bmod($n);
3933 427 100       134922 if ($qsign == 1) { $V->bmul($V)->bsub(BTWO)->bmod($n); }
  19 100       41  
3934 20         77 elsif ($qsign == -1) { $V->bmul($V)->badd(BTWO)->bmod($n); }
3935 388         891 else { $V->bmul($V)->bsub($Qk->copy->blsft(BONE))->bmod($n); }
3936 427 100       226178 if (substr($kstr,$bpos,1)) {
3937 197         522 my $T1 = $U->copy->bmul($D);
3938 197         16110 $U->bmul($P)->badd( $V);
3939 197 100       23572 $U->badd($n) if $U->is_odd;
3940 197         8464 $U->brsft(BONE);
3941              
3942 197         20541 $V->bmul($P)->badd($T1);
3943 197 100       26899 $V->badd($n) if $V->is_odd;
3944 197         6618 $V->brsft(BONE);
3945              
3946 197 100       25761 if ($qsign != 0) { $qsign = -1; }
  19         64  
3947 178         492 else { $Qk->bmul($Qk)->bmul($Q)->bmod($n); }
3948             } else {
3949 230 100       495 if ($qsign != 0) { $qsign = 1; }
  20         50  
3950 210         498 else { $Qk->bmul($Qk)->bmod($n); }
3951             }
3952             }
3953 14 100       3213 if ($qsign == 1) { $Qk->bneg; }
  1 100       7  
3954 2         8 elsif ($qsign == -1) { $Qk = $n->copy->bdec; }
3955             }
3956 156         77502 $U->bmod($n);
3957 156         45895 $V->bmod($n);
3958 156         18886 return ($U, $V, $Qk);
3959             }
3960             sub _lucasuv {
3961 0     0   0 my($P, $Q, $k) = @_;
3962              
3963 0 0       0 croak "lucas_sequence: k must be >= 0" if $k < 0;
3964 0 0       0 return (0,2) if $k == 0;
3965              
3966 0 0       0 $P = Math::BigInt->new("$P") unless ref($P) eq 'Math::BigInt';
3967 0 0       0 $Q = Math::BigInt->new("$Q") unless ref($Q) eq 'Math::BigInt';
3968              
3969             # Simple way, very slow as k increases:
3970             #my($U0, $U1) = (BZERO->copy, BONE->copy);
3971             #my($V0, $V1) = (BTWO->copy, Math::BigInt->new("$P"));
3972             #for (2 .. $k) {
3973             # ($U0,$U1) = ($U1, $P*$U1 - $Q*$U0);
3974             # ($V0,$V1) = ($V1, $P*$V1 - $Q*$V0);
3975             #}
3976             #return ($U1, $V1);
3977              
3978 0         0 my($Uh,$Vl, $Vh, $Ql, $Qh) = (BONE->copy, BTWO->copy, $P->copy, BONE->copy, BONE->copy);
3979 0 0       0 $k = Math::BigInt->new("$k") unless ref($k) eq 'Math::BigInt';
3980 0         0 my $kstr = substr($k->as_bin, 2);
3981 0         0 my ($n,$s) = (length($kstr)-1, 0);
3982 0 0       0 if ($kstr =~ /(0+)$/) { $s = length($1); }
  0         0  
3983              
3984 0 0       0 if ($Q == -1) {
3985             # This could be simplified, and it's running 10x slower than it should.
3986 0         0 my ($ql,$qh) = (1,1);
3987 0         0 for my $bpos (0 .. $n-$s-1) {
3988 0         0 $ql *= $qh;
3989 0 0       0 if (substr($kstr,$bpos,1)) {
3990 0         0 $qh = -$ql;
3991 0         0 $Uh->bmul($Vh);
3992 0 0       0 if ($ql == 1) {
3993 0         0 $Vl->bmul($Vh)->bsub( $P );
3994 0         0 $Vh->bmul($Vh)->badd( BTWO );
3995             } else {
3996 0         0 $Vl->bmul($Vh)->badd( $P );
3997 0         0 $Vh->bmul($Vh)->bsub( BTWO );
3998             }
3999             } else {
4000 0         0 $qh = $ql;
4001 0 0       0 if ($ql == 1) {
4002 0         0 $Uh->bmul($Vl)->bdec;
4003 0         0 $Vh->bmul($Vl)->bsub($P);
4004 0         0 $Vl->bmul($Vl)->bsub(BTWO);
4005             } else {
4006 0         0 $Uh->bmul($Vl)->binc;
4007 0         0 $Vh->bmul($Vl)->badd($P);
4008 0         0 $Vl->bmul($Vl)->badd(BTWO);
4009             }
4010             }
4011             }
4012 0         0 $ql *= $qh;
4013 0         0 $qh = -$ql;
4014 0 0       0 if ($ql == 1) {
4015 0         0 $Uh->bmul($Vl)->bdec;
4016 0         0 $Vl->bmul($Vh)->bsub($P);
4017             } else {
4018 0         0 $Uh->bmul($Vl)->binc;
4019 0         0 $Vl->bmul($Vh)->badd($P);
4020             }
4021 0         0 $ql *= $qh;
4022 0         0 for (1 .. $s) {
4023 0         0 $Uh->bmul($Vl);
4024 0 0       0 if ($ql == 1) { $Vl->bmul($Vl)->bsub(BTWO); $ql *= $ql; }
  0         0  
  0         0  
4025 0         0 else { $Vl->bmul($Vl)->badd(BTWO); $ql *= $ql; }
  0         0  
4026             }
4027 0 0       0 return map { ($_ > ''.~0) ? Math::BigInt->new(''.$_) : $_ } ($Uh, $Vl);
  0         0  
4028             }
4029              
4030 0         0 for my $bpos (0 .. $n-$s-1) {
4031 0         0 $Ql->bmul($Qh);
4032 0 0       0 if (substr($kstr,$bpos,1)) {
4033 0         0 $Qh = $Ql * $Q;
4034             #$Uh = $Uh * $Vh;
4035             #$Vl = $Vh * $Vl - $P * $Ql;
4036             #$Vh = $Vh * $Vh - BTWO * $Qh;
4037 0         0 $Uh->bmul($Vh);
4038 0         0 $Vl->bmul($Vh)->bsub($P * $Ql);
4039 0         0 $Vh->bmul($Vh)->bsub(BTWO * $Qh);
4040             } else {
4041 0         0 $Qh = $Ql->copy;
4042             #$Uh = $Uh * $Vl - $Ql;
4043             #$Vh = $Vh * $Vl - $P * $Ql;
4044             #$Vl = $Vl * $Vl - BTWO * $Ql;
4045 0         0 $Uh->bmul($Vl)->bsub($Ql);
4046 0         0 $Vh->bmul($Vl)->bsub($P * $Ql);
4047 0         0 $Vl->bmul($Vl)->bsub(BTWO * $Ql);
4048             }
4049             }
4050 0         0 $Ql->bmul($Qh);
4051 0         0 $Qh = $Ql * $Q;
4052 0         0 $Uh->bmul($Vl)->bsub($Ql);
4053 0         0 $Vl->bmul($Vh)->bsub($P * $Ql);
4054 0         0 $Ql->bmul($Qh);
4055 0         0 for (1 .. $s) {
4056 0         0 $Uh->bmul($Vl);
4057 0         0 $Vl->bmul($Vl)->bsub(BTWO * $Ql);
4058 0         0 $Ql->bmul($Ql);
4059             }
4060 0 0       0 return map { ($_ > ''.~0) ? Math::BigInt->new(''.$_) : $_ } ($Uh, $Vl, $Ql);
  0         0  
4061             }
4062 0     0 0 0 sub lucasu { (_lucasuv(@_))[0] }
4063 0     0 0 0 sub lucasv { (_lucasuv(@_))[1] }
4064              
4065             sub is_lucas_pseudoprime {
4066 5     5 0 1665 my($n) = @_;
4067              
4068 5 50       22 return 0+($n >= 2) if $n < 4;
4069 5 50 33     50 return 0 if ($n % 2) == 0 || _is_perfect_square($n);
4070              
4071 5         13 my ($P, $Q, $D) = _lucas_selfridge_params($n);
4072 5 50       13 return 0 if $D == 0; # We found a divisor in the sequence
4073 5 50       14 die "Lucas parameter error: $D, $P, $Q\n" if ($D != $P*$P - 4*$Q);
4074              
4075 5         15 my($U, $V, $Qk) = lucas_sequence($n, $P, $Q, $n+1);
4076 5 50       21 return ($U == 0) ? 1 : 0;
4077             }
4078              
4079             sub is_strong_lucas_pseudoprime {
4080 6     6 0 999 my($n) = @_;
4081              
4082 6 50       23 return 0+($n >= 2) if $n < 4;
4083 6 50 33     158 return 0 if ($n % 2) == 0 || _is_perfect_square($n);
4084              
4085 6         23 my ($P, $Q, $D) = _lucas_selfridge_params($n);
4086 6 50       16 return 0 if $D == 0; # We found a divisor in the sequence
4087 6 50       17 die "Lucas parameter error: $D, $P, $Q\n" if ($D != $P*$P - 4*$Q);
4088              
4089 6         14 my $m = $n+1;
4090 6         185 my($s, $k) = (0, $m);
4091 6   66     26 while ( $k > 0 && !($k % 2) ) {
4092 19         975 $s++;
4093 19         55 $k >>= 1;
4094             }
4095 6         599 my($U, $V, $Qk) = lucas_sequence($n, $P, $Q, $k);
4096              
4097 6 100       24 return 1 if $U == 0;
4098 4 50       835 $V = Math::BigInt->new("$V") unless ref($V) eq 'Math::BigInt';
4099 4 50       16 $Qk = Math::BigInt->new("$Qk") unless ref($Qk) eq 'Math::BigInt';
4100 4         15 foreach my $r (0 .. $s-1) {
4101 11 100       1590 return 1 if $V->is_zero;
4102 8 100       112 if ($r < ($s-1)) {
4103 7         21 $V->bmul($V)->bsub(BTWO*$Qk)->bmod($n);
4104 7         3210 $Qk->bmul($Qk)->bmod($n);
4105             }
4106             }
4107 1         15 return 0;
4108             }
4109              
4110             sub is_extra_strong_lucas_pseudoprime {
4111 142     142 0 2940 my($n) = @_;
4112              
4113 142 50       647 return 0+($n >= 2) if $n < 4;
4114 142 50 33     21468 return 0 if ($n % 2) == 0 || _is_perfect_square($n);
4115              
4116 142         864 my ($P, $Q, $D) = _lucas_extrastrong_params($n);
4117 142 50       575 return 0 if $D == 0; # We found a divisor in the sequence
4118 142 50       579 die "Lucas parameter error: $D, $P, $Q\n" if ($D != $P*$P - 4*$Q);
4119              
4120             # We have to convert n to a bigint or Math::BigInt::GMP's stupid set_si bug
4121             # (RT 71548) will hit us and make the test $V == $n-2 always return false.
4122 142 100       632 $n = Math::BigInt->new("$n") unless ref($n) eq 'Math::BigInt';
4123              
4124 142         841 my($s, $k) = (0, $n->copy->binc);
4125 142   66     10643 while ($k->is_even && !$k->is_zero) {
4126 2772         366968 $s++;
4127 2772         5779 $k->brsft(BONE);
4128             }
4129              
4130 142         17789 my($U, $V, $Qk) = lucas_sequence($n, $P, $Q, $k);
4131              
4132 142 50       718 $V = Math::BigInt->new("$V") unless ref($V) eq 'Math::BigInt';
4133 142 50 66     661 return 1 if $U == 0 && ($V == BTWO || $V == ($n - BTWO));
      100        
4134 74         18462 foreach my $r (0 .. $s-2) {
4135 2628 100       8271756 return 1 if $V->is_zero;
4136 2570         35173 $V->bmul($V)->bsub(BTWO)->bmod($n);
4137             }
4138 16         144 return 0;
4139             }
4140              
4141             sub is_almost_extra_strong_lucas_pseudoprime {
4142 56     56 0 2284 my($n, $increment) = @_;
4143 56 100       182 $increment = 1 unless defined $increment;
4144              
4145 56 50       215 return 0+($n >= 2) if $n < 4;
4146 56 50 33     347 return 0 if ($n % 2) == 0 || _is_perfect_square($n);
4147              
4148 56         271 my ($P, $Q, $D) = _lucas_extrastrong_params($n, $increment);
4149 56 50       148 return 0 if $D == 0; # We found a divisor in the sequence
4150 56 50       218 die "Lucas parameter error: $D, $P, $Q\n" if ($D != $P*$P - 4*$Q);
4151              
4152 56 50       617 $n = Math::BigInt->new("$n") unless ref($n) eq 'Math::BigInt';
4153              
4154 56         5010 my $ZERO = $n->copy->bzero;
4155 56         3048 my $TWO = $ZERO->copy->binc->binc;
4156 56         6207 my $V = $ZERO + $P; # V_{k}
4157 56         10093 my $W = $ZERO + $P*$P-$TWO; # V_{k+1}
4158 56         16454 my $kstr = substr($n->copy->binc()->as_bin, 2);
4159 56         14076 $kstr =~ s/(0*)$//;
4160 56         210 my $s = length($1);
4161 56         130 my $bpos = 0;
4162 56         230 while (++$bpos < length($kstr)) {
4163 2468 100       985992 if (substr($kstr,$bpos,1)) {
4164 1240         3142 $V->bmul($W)->bsub($P )->bmod($n);
4165 1240         596823 $W->bmul($W)->bsub($TWO)->bmod($n);
4166             } else {
4167 1228         3119 $W->bmul($V)->bsub($P )->bmod($n);
4168 1228         592465 $V->bmul($V)->bsub($TWO)->bmod($n);
4169             }
4170             }
4171              
4172 56 100 100     22757 return 1 if $V == 2 || $V == ($n-$TWO);
4173 36         10937 foreach my $r (0 .. $s-2) {
4174 39 100       1106 return 1 if $V->is_zero;
4175 36         618 $V->bmul($V)->bsub($TWO)->bmod($n);
4176             }
4177 33         14821 return 0;
4178             }
4179              
4180             sub is_frobenius_khashin_pseudoprime {
4181 0     0 0 0 my($n) = @_;
4182 0 0       0 return 0+($n >= 2) if $n < 4;
4183 0 0       0 return 0 unless $n % 2;
4184 0 0       0 return 0 if _is_perfect_square($n);
4185              
4186 0 0       0 $n = Math::BigInt->new("$n") unless ref($n) eq 'Math::BigInt';
4187              
4188 0         0 my($k,$c) = (2,1);
4189 0 0       0 if ($n % 4 == 3) { $c = $n-1; }
  0 0       0  
4190 0         0 elsif ($n % 8 == 5) { $c = 2; }
4191             else {
4192 0         0 do {
4193 0         0 $c += 2;
4194 0         0 $k = kronecker($c, $n);
4195             } while $k == 1;
4196             }
4197 0 0 0     0 return 0 if $k == 0 || ($k == 2 && !($n % 3));;
      0        
4198              
4199 0 0       0 my $ea = ($k == 2) ? 2 : 1;
4200 0         0 my($ra,$rb,$a,$b,$d) = ($ea,1,$ea,1,$n-1);
4201 0         0 while (!$d->is_zero) {
4202 0 0       0 if ($d->is_odd()) {
4203 0         0 ($ra, $rb) = ( (($ra*$a)%$n + ((($rb*$b)%$n)*$c)%$n) % $n,
4204             (($rb*$a)%$n + ($ra*$b)%$n) % $n );
4205             }
4206 0         0 $d >>= 1;
4207 0 0       0 if (!$d->is_zero) {
4208 0         0 ($a, $b) = ( (($a*$a)%$n + ((($b*$b)%$n)*$c)%$n) % $n,
4209             (($b*$a)%$n + ($a*$b)%$n) % $n );
4210             }
4211             }
4212 0 0 0     0 return ($ra == $ea && $rb == $n-1) ? 1 : 0;
4213             }
4214              
4215             sub is_frobenius_underwood_pseudoprime {
4216 1     1 0 4 my($n) = @_;
4217 1 50       5 return 0+($n >= 2) if $n < 4;
4218 1 50       135 return 0 unless $n % 2;
4219              
4220 1         246 my($a, $temp1, $temp2);
4221 1 50       4 if ($n % 4 == 3) {
4222 1         288 $a = 0;
4223             } else {
4224 0         0 for ($a = 1; $a < 1000000; $a++) {
4225 0 0 0     0 next if $a==2 || $a==4 || $a==7 || $a==8 || $a==10 || $a==14 || $a==16 || $a==18;
      0        
      0        
      0        
      0        
      0        
      0        
4226 0         0 my $j = kronecker($a*$a - 4, $n);
4227 0 0       0 last if $j == -1;
4228 0 0 0     0 return 0 if $j == 0 || ($a == 20 && _is_perfect_square($n));
      0        
4229             }
4230             }
4231 1         16 $temp1 = Math::Prime::Util::gcd(($a+4)*(2*$a+5), $n);
4232 1 50 33     7 return 0 if $temp1 != 1 && $temp1 != $n;
4233              
4234 1 50       4 $n = Math::BigInt->new("$n") unless ref($n) eq 'Math::BigInt';
4235 1         4 my $ZERO = $n->copy->bzero;
4236 1         58 my $ONE = $ZERO->copy->binc;
4237 1         80 my $TWO = $ONE->copy->binc;
4238 1         61 my($s, $t) = ($ONE->copy, $TWO->copy);
4239              
4240 1         39 my $ap2 = $TWO + $a;
4241 1         268 my $np1string = substr( $n->copy->binc->as_bin, 2);
4242 1         480 my $np1len = length($np1string);
4243              
4244 1         4 foreach my $bit (1 .. $np1len-1) {
4245 107         276 $temp2 = $t+$t;
4246 107 50       9214 $temp2 += ($s * $a) if $a != 0;
4247 107         260 $temp1 = $temp2 * $s;
4248 107         18567 $temp2 = $t - $s;
4249 107         14514 $s += $t;
4250 107         7431 $t = ($s * $temp2) % $n;
4251 107         55123 $s = $temp1 % $n;
4252 107 100       35063 if ( substr( $np1string, $bit, 1 ) ) {
4253 51 50       121 if ($a == 0) { $temp1 = $s + $s; }
  51         129  
4254 0         0 else { $temp1 = $s * $ap2; }
4255 51         4833 $temp1 += $t;
4256 51         3275 $t->badd($t)->bsub($s); # $t = ($t+$t) - $s;
4257 51         9092 $s = $temp1;
4258             }
4259             }
4260 1         11 $temp1 = (2*$a+5) % $n;
4261 1 50 33     192 return ($s == 0 && $t == $temp1) ? 1 : 0;
4262             }
4263              
4264             sub _perrin_signature {
4265 2     2   7 my($n) = @_;
4266 2         9 my @S = (1,$n-1,3, 3,0,2);
4267 2 50       526 return @S if $n <= 1;
4268              
4269 2         244 my @nbin = todigits($n,2);
4270 2         13 shift @nbin;
4271              
4272 2         11 while (@nbin) {
4273 1254         5918 my @T = map { addmod(addmod(Math::Prime::Util::mulmod($S[$_],$S[$_],$n), $n-$S[5-$_],$n), $n-$S[5-$_],$n); } 0..5;
  7524         58724  
4274 1254         9483 my $T01 = addmod($T[2], $n-$T[1], $n);
4275 1254         13290 my $T34 = addmod($T[5], $n-$T[4], $n);
4276 1254         12461 my $T45 = addmod($T34, $T[3], $n);
4277 1254 100       12942 if (shift @nbin) {
4278 645         31101 @S = ($T[0], $T01, $T[1], $T[4], $T45, $T[5]);
4279             } else {
4280 609         2945 @S = ($T01, $T[1], addmod($T01,$T[0],$n), $T34, $T[4], $T45);
4281             }
4282             }
4283 2         16 @S;
4284             }
4285              
4286             sub is_perrin_pseudoprime {
4287 2     2 0 5148 my($n, $restrict) = @_;
4288 2 50       12 $restrict = 0 unless defined $restrict;
4289 2 50       14 return 0+($n >= 2) if $n < 4;
4290 2 50 33     12 return 0 if $restrict > 2 && ($n % 2) == 0;
4291              
4292 2 50       18 $n = Math::BigInt->new("$n") unless ref($n) eq 'Math::BigInt';
4293              
4294 2         209 my @S = _perrin_signature($n);
4295 2 50       11 return 0 unless $S[4] == 0;
4296 2 50       197 return 1 if $restrict == 0;
4297 0 0       0 return 0 unless $S[1] == $n-1;
4298 0 0       0 return 1 if $restrict == 1;
4299 0         0 my $j = kronecker(-23,$n);
4300 0 0       0 if ($j == -1) {
4301 0         0 my $B = $S[2];
4302 0         0 my $B2 = mulmod($B,$B,$n);
4303 0         0 my $A = addmod(addmod(1,mulmod(3,$B,$n),$n),$n-$B2,$n);
4304 0         0 my $C = addmod(mulmod(3,$B2,$n),$n-2,$n);
4305 0 0 0     0 return 1 if $S[0] == $A && $S[2] == $B && $S[3] == $B && $S[5] == $C && $B != 3 && addmod(mulmod($B2,$B,$n),$n-$B,$n) == 1;
      0        
      0        
      0        
      0        
4306             } else {
4307 0 0 0     0 return 0 if $j == 0 && $n != 23 && $restrict > 2;
      0        
4308 0 0 0     0 return 1 if $S[0] == 1 && $S[2] == 3 && $S[3] == 3 && $S[5] == 2;
      0        
      0        
4309 0 0 0     0 return 1 if $S[0] == 0 && $S[5] == $n-1 && $S[2] != $S[3] && addmod($S[2],$S[3],$n) == $n-3 && mulmod(addmod($S[2],$n-$S[3],$n),addmod($S[2],$n-$S[3],$n),$n) == $n-(23%$n);
      0        
      0        
      0        
4310             }
4311 0         0 0;
4312             }
4313              
4314             sub is_catalan_pseudoprime {
4315 0     0 0 0 my($n) = @_;
4316 0 0       0 return 0+($n >= 2) if $n < 4;
4317 0         0 my $m = ($n-1)>>1;
4318 0 0       0 return (binomial($m<<1,$m) % $n) == (($m&1) ? $n-1 : 1) ? 1 : 0;
    0          
4319             }
4320              
4321             sub is_frobenius_pseudoprime {
4322 1     1 0 3 my($n, $P, $Q) = @_;
4323 1 50 33     7 ($P,$Q) = (0,0) unless defined $P && defined $Q;
4324 1 50       5 return 0+($n >= 2) if $n < 4;
4325              
4326 1 50       9 $n = Math::BigInt->new("$n") unless ref($n) eq 'Math::BigInt';
4327 1 50       48 return 0 if $n->is_even;
4328              
4329 1         20 my($k, $Vcomp, $D, $Du) = (0, 4);
4330 1 50 33     6 if ($P == 0 && $Q == 0) {
4331 1         2 ($P,$Q) = (-1,2);
4332 1         4 while ($k != -1) {
4333 1         3 $P += 2;
4334 1 50       3 $P = 5 if $P == 3; # Skip 3
4335 1         3 $D = $P*$P-4*$Q;
4336 1 50       5 $Du = ($D >= 0) ? $D : -$D;
4337 1 50 33     4 last if $P >= $n || $Du >= $n; # TODO: remove?
4338 1         142 $k = kronecker($D, $n);
4339 1 50       5 return 0 if $k == 0;
4340 1 50 33     8 return 0 if $P == 10001 && _is_perfect_square($n);
4341             }
4342             } else {
4343 0         0 $D = $P*$P-4*$Q;
4344 0 0       0 $Du = ($D >= 0) ? $D : -$D;
4345 0 0       0 croak "Frobenius invalid P,Q: ($P,$Q)" if _is_perfect_square($Du);
4346             }
4347 1 0 33     3 return (is_prime($n) ? 1 : 0) if $n <= $Du || $n <= abs($Q) || $n <= abs($P);
    50 33        
4348 1 50       338 return 0 if Math::Prime::Util::gcd(abs($P*$Q*$D), $n) > 1;
4349              
4350 1 50       59 if ($k == 0) {
4351 0         0 $k = kronecker($D, $n);
4352 0 0       0 return 0 if $k == 0;
4353 0         0 my $Q2 = (2*abs($Q)) % $n;
4354 0 0       0 $Vcomp = ($k == 1) ? 2 : ($Q >= 0) ? $Q2 : $n-$Q2;
    0          
4355             }
4356              
4357 1         7 my($U, $V, $Qk) = lucas_sequence($n, $P, $Q, $n-$k);
4358 1 50 33     6 return 1 if $U == 0 && $V == $Vcomp;
4359 1         270 0;
4360             }
4361              
4362             # Since people have graciously donated millions of CPU years to doing these
4363             # tests, it would be rude of us not to use the results. This means we don't
4364             # actually use the pretest and Lucas-Lehmer test coded below for any reasonable
4365             # size number.
4366             # See: http://www.mersenne.org/report_milestones/
4367             my %_mersenne_primes;
4368             undef @_mersenne_primes{2,3,5,7,13,17,19,31,61,89,107,127,521,607,1279,2203,2281,3217,4253,4423,9689,9941,11213,19937,21701,23209,44497,86243,110503,132049,216091,756839,859433,1257787,1398269,2976221,3021377,6972593,13466917,20996011,24036583,25964951,30402457,32582657,37156667,42643801,43112609,57885161,74207281};
4369              
4370             sub is_mersenne_prime {
4371 0     0 0 0 my $p = shift;
4372              
4373             # Use the known Mersenne primes
4374 0 0       0 return 1 if exists $_mersenne_primes{$p};
4375 0 0       0 return 0 if $p < 34007399; # GIMPS has checked all below
4376             # Past this we do a generic Mersenne prime test
4377              
4378 0 0       0 return 1 if $p == 2;
4379 0 0       0 return 0 unless is_prob_prime($p);
4380 0 0 0     0 return 0 if $p > 3 && $p % 4 == 3 && $p < ((~0)>>1) && is_prob_prime($p*2+1);
      0        
      0        
4381 0         0 my $mp = BONE->copy->blsft($p)->bdec;
4382              
4383             # Definitely faster than using Math::BigInt that doesn't have GMP.
4384             return (0 == (Math::Prime::Util::GMP::lucas_sequence($mp, 4, 1, $mp+1))[0])
4385 0 0       0 if $Math::Prime::Util::_GMPfunc{"lucas_sequence"};
4386              
4387 0         0 my $V = Math::BigInt->new(4);
4388 0         0 for my $k (3 .. $p) {
4389 0         0 $V->bmul($V)->bsub(BTWO)->bmod($mp);
4390             }
4391 0         0 return $V->is_zero;
4392             }
4393              
4394              
4395             my $_poly_bignum;
4396             sub _poly_new {
4397 206     206   562 my @poly = @_;
4398 206 50       529 push @poly, 0 unless scalar @poly;
4399 206 50       516 if ($_poly_bignum) {
4400 0 0       0 @poly = map { (ref $_ eq 'Math::BigInt')
  0         0  
4401             ? $_->copy
4402             : Math::BigInt->new("$_"); } @poly;
4403             }
4404 206         521 return \@poly;
4405             }
4406              
4407             #sub _poly_print {
4408             # my($poly) = @_;
4409             # carp "poly has null top degree" if $#$poly > 0 && !$poly->[-1];
4410             # foreach my $d (reverse 1 .. $#$poly) {
4411             # my $coef = $poly->[$d];
4412             # print "", ($coef != 1) ? $coef : "", ($d > 1) ? "x^$d" : "x", " + "
4413             # if $coef;
4414             # }
4415             # my $p0 = $poly->[0] || 0;
4416             # print "$p0\n";
4417             #}
4418              
4419             sub _poly_mod_mul {
4420 1654     1654   3730 my($px, $py, $r, $n) = @_;
4421              
4422 1654         3005 my $px_degree = $#$px;
4423 1654         2570 my $py_degree = $#$py;
4424 1654 50       6224 my @res = map { $_poly_bignum ? Math::BigInt->bzero : 0 } 0 .. $r-1;
  180410         266589  
4425              
4426             # convolve(px, py) mod (X^r-1,n)
4427 1654         7175 my @indices_y = grep { $py->[$_] } (0 .. $py_degree);
  83490         107651  
4428 1654         5429 foreach my $ix (0 .. $px_degree) {
4429 78553         104461 my $px_at_ix = $px->[$ix];
4430 78553 100       124878 next unless $px_at_ix;
4431 78516 50       112927 if ($_poly_bignum) {
4432 0         0 foreach my $iy (@indices_y) {
4433 0         0 my $rindex = ($ix + $iy) % $r; # reduce mod X^r-1
4434 0         0 $res[$rindex]->badd($px_at_ix->copy->bmul($py->[$iy]))->bmod($n);
4435             }
4436             } else {
4437 78516         104167 foreach my $iy (@indices_y) {
4438 7543424         10045123 my $rindex = ($ix + $iy) % $r; # reduce mod X^r-1
4439 7543424         11452477 $res[$rindex] = ($res[$rindex] + $px_at_ix * $py->[$iy]) % $n;
4440             }
4441             }
4442             }
4443             # In case we had upper terms go to zero after modulo, reduce the degree.
4444 1654         37048 pop @res while !$res[-1];
4445 1654         9270 return \@res;
4446             }
4447              
4448             sub _poly_mod_pow {
4449 103     103   387 my($pn, $power, $r, $mod) = @_;
4450 103         338 my $res = _poly_new(1);
4451 103         696 my $p = $power;
4452              
4453 103         264 while ($p) {
4454 1037 100       3298 $res = _poly_mod_mul($res, $pn, $r, $mod) if ($p & 1);
4455 1037         1961 $p >>= 1;
4456 1037 100       3247 $pn = _poly_mod_mul($pn, $pn, $r, $mod) if $p;
4457             }
4458 103         509 return $res;
4459             }
4460              
4461             sub _test_anr {
4462 103     103   371 my($a, $n, $r) = @_;
4463 103         479 my $pp = _poly_mod_pow(_poly_new($a, 1), $n, $r, $n);
4464 103   50     729 $pp->[$n % $r] = (($pp->[$n % $r] || 0) - 1) % $n; # subtract X^(n%r)
4465 103   50     442 $pp->[ 0] = (($pp->[ 0] || 0) - $a) % $n; # subtract a
4466 103 100       393 return 0 if scalar grep { $_ } @$pp;
  5057         6721  
4467 102         549 1;
4468             }
4469              
4470             sub is_aks_prime {
4471 10     10 0 1384 my $n = shift;
4472 10 100 100     56 return 0 if $n < 2 || is_power($n);
4473              
4474 7         16 my($log2n, $limit);
4475 7 50       21 if ($n > 2**48) {
4476 0 0       0 do { require Math::BigFloat; Math::BigFloat->import(); }
  0         0  
  0         0  
4477             if !defined $Math::BigFloat::VERSION;
4478             # limit = floor( log2(n) * log2(n) ). o_r(n) must be larger than this
4479 0         0 my $floatn = Math::BigFloat->new("$n");
4480             #my $sqrtn = _bigint_to_int($floatn->copy->bsqrt->bfloor);
4481             # The following line seems to trigger a memory leak in Math::BigFloat::blog
4482             # (the part where $MBI is copied to $int) if $n is a Math::BigInt::GMP.
4483 0         0 $log2n = $floatn->copy->blog(2);
4484 0         0 $limit = _bigint_to_int( ($log2n * $log2n)->bfloor );
4485             } else {
4486 7         34 $log2n = log($n)/log(2) + 0.0001; # Error on large side.
4487 7         16 $limit = int( $log2n*$log2n + 0.0001 );
4488             }
4489              
4490 7         22 my $r = next_prime($limit);
4491 7         15 foreach my $f (@{primes(0,$r-1)}) {
  7         25  
4492 147 50       253 return 1 if $f == $n;
4493 147 100       278 return 0 if !($n % $f);
4494             }
4495              
4496 6         33 while ($r < $n) {
4497 5 100       19 return 0 if !($n % $r);
4498             #return 1 if $r >= $sqrtn;
4499 4 100       18 last if znorder($n, $r) > $limit; # Note the arguments!
4500 2         92 $r = next_prime($r);
4501             }
4502              
4503 5 100       108 return 1 if $r >= $n;
4504              
4505             # Since r is a prime, phi(r) = r-1
4506 2 50       19 my $rlimit = (ref($log2n) eq 'Math::BigFloat')
4507             ? _bigint_to_int( Math::BigFloat->new("$r")->bdec()
4508             ->bsqrt->bmul($log2n)->bfloor)
4509             : int( (sqrt(($r-1)) * $log2n) + 0.001 );
4510              
4511 2         7 $_poly_bignum = 1;
4512 2 50       9 if ( $n < (MPU_HALFWORD-1) ) {
4513 2         5 $_poly_bignum = 0;
4514             #$n = _bigint_to_int($n) if ref($n) eq 'Math::BigInt';
4515             } else {
4516 0 0       0 $n = Math::BigInt->new("$n") unless ref($n) eq 'Math::BigInt';
4517             }
4518              
4519 2         17 my $_verbose = Math::Prime::Util::prime_get_config()->{'verbose'};
4520 2 50       11 print "# aks r = $r s = $rlimit\n" if $_verbose;
4521 2 50       9 local $| = 1 if $_verbose > 1;
4522 2         9 for (my $a = 1; $a <= $rlimit; $a++) {
4523 103 100       501 return 0 unless _test_anr($a, $n, $r);
4524 102 50       615 print "." if $_verbose > 1;
4525             }
4526 1 50       8 print "\n" if $_verbose > 1;
4527              
4528 1         13 return 1;
4529             }
4530              
4531              
4532             sub _basic_factor {
4533             # MODIFIES INPUT SCALAR
4534 39 0   39   163 return ($_[0] == 1) ? () : ($_[0]) if $_[0] < 4;
    50          
4535              
4536 39         2734 my @factors;
4537 39 100       164 if (ref($_[0]) ne 'Math::BigInt') {
4538 17         56 while ( !($_[0] % 2) ) { push @factors, 2; $_[0] = int($_[0] / 2); }
  0         0  
  0         0  
4539 17         53 while ( !($_[0] % 3) ) { push @factors, 3; $_[0] = int($_[0] / 3); }
  0         0  
  0         0  
4540 17         43 while ( !($_[0] % 5) ) { push @factors, 5; $_[0] = int($_[0] / 5); }
  0         0  
  0         0  
4541             } else {
4542             # Without this, the bdivs will try to convert the results to BigFloat
4543             # and lose precision.
4544 22 100 66     164 $_[0]->upgrade(undef) if ref($_[0]) && $_[0]->upgrade();
4545 22 100       416 if (!Math::BigInt::bgcd($_[0], B_PRIM235)->is_one) {
4546 1         182 while ( $_[0]->is_even) { push @factors, 2; $_[0]->brsft(BONE); }
  7         716  
  7         14  
4547 1         115 foreach my $div (3, 5) {
4548 2         285 my ($q, $r) = $_[0]->copy->bdiv($div);
4549 2         576 while ($r->is_zero) {
4550 1         11 push @factors, $div;
4551 1         2 $_[0] = $q;
4552 1         2 ($q, $r) = $_[0]->copy->bdiv($div);
4553             }
4554             }
4555             }
4556 22 50 33     4032 $_[0] = _bigint_to_int($_[0]) if $] >= 5.008 && $_[0] <= BMAX;
4557             }
4558              
4559 39 50 33     1011 if ( ($_[0] > 1) && _is_prime7($_[0]) ) {
4560 0         0 push @factors, $_[0];
4561 0         0 $_[0] = 1;
4562             }
4563 39         3676 @factors;
4564             }
4565              
4566             sub trial_factor {
4567 251     251 0 1984 my($n, $limit) = @_;
4568              
4569             # Don't use _basic_factor here -- they want a trial forced.
4570 251         323 my @factors;
4571 251 50       463 if ($n < 4) {
4572 0 0       0 @factors = ($n == 1) ? () : ($n);
4573 0         0 return @factors;
4574             }
4575              
4576 251         8743 my $start_idx = 1;
4577             # Expand small primes if it would help.
4578 251 100 66     669 push @_primes_small, @{primes($_primes_small[-1]+1, 100_003)}
  1   66     131  
      100        
4579             if $n > 400_000_000
4580             && $_primes_small[-1] < 99_000
4581             && (!defined $limit || $limit > $_primes_small[-1]);
4582              
4583             # Do initial bigint reduction. Hopefully reducing it to native int.
4584 251 100       9511 if (ref($n) eq 'Math::BigInt') {
4585 77         296 $n = $n->copy; # Don't modify their original input!
4586 77         1834 my $newlim = $n->copy->bsqrt;
4587 77 50 33     91151 $limit = $newlim if !defined $limit || $limit > $newlim;
4588 77         6584 while ($start_idx <= $#_primes_small) {
4589 20534         4051066 my $f = $_primes_small[$start_idx++];
4590 20534 100       39337 last if $f > $limit;
4591 20514 100       42609 if ($n->copy->bmod($f)->is_zero) {
4592 287         59091 do {
4593 555         133926 push @factors, $f;
4594 555         1533 $n->bdiv($f)->bfloor();
4595             } while $n->copy->bmod($f)->is_zero;
4596 287 100       144005 last if $n < BMAX;
4597 230         8998 my $newlim = $n->copy->bsqrt;
4598 230 50       333367 $limit = $newlim if $limit > $newlim;
4599             }
4600             }
4601 77 50       2644 return @factors if $n->is_one;
4602 77 100       1670 $n = _bigint_to_int($n) if $n <= BMAX;
4603 77 50 66     3969 return (@factors,$n) if $start_idx <= $#_primes_small && $_primes_small[$start_idx] > $limit;
4604             }
4605              
4606             {
4607 251 100       374 my $newlim = (ref($n) eq 'Math::BigInt') ? $n->copy->bsqrt : int(sqrt($n) + 0.001);
  251         750  
4608 251 100 66     23401 $limit = $newlim if !defined $limit || $limit > $newlim;
4609             }
4610              
4611 251 100       2437 if (ref($n) ne 'Math::BigInt') {
4612 231         500 for my $i ($start_idx .. $#_primes_small) {
4613 51251         62253 my $p = $_primes_small[$i];
4614 51251 100       75487 last if $p > $limit;
4615 51029 100       81470 if (($n % $p) == 0) {
4616 308         383 do { push @factors, $p; $n = int($n/$p); } while ($n % $p) == 0;
  329         476  
  329         748  
4617 308 100       545 last if $n == 1;
4618 299         454 my $newlim = int( sqrt($n) + 0.001);
4619 299 100       558 $limit = $newlim if $newlim < $limit;
4620             }
4621             }
4622 231 50       556 if ($_primes_small[-1] < $limit) {
4623 0 0       0 my $inc = (($_primes_small[-1] % 6) == 1) ? 4 : 2;
4624 0         0 my $p = $_primes_small[-1] + $inc;
4625 0         0 while ($p <= $limit) {
4626 0 0       0 if (($n % $p) == 0) {
4627 0         0 do { push @factors, $p; $n = int($n/$p); } while ($n % $p) == 0;
  0         0  
  0         0  
4628 0 0       0 last if $n == 1;
4629 0         0 my $newlim = int( sqrt($n) + 0.001);
4630 0 0       0 $limit = $newlim if $newlim < $limit;
4631             }
4632 0         0 $p += ($inc ^= 6);
4633             }
4634             }
4635             } else { # n is a bigint. Use mod-210 wheel trial division.
4636             # Generating a wheel mod $w starting at $s:
4637             # mpu 'my($s,$w,$t)=(11,2*3*5); say join ",",map { ($t,$s)=($_-$s,$_); $t; } grep { gcd($_,$w)==1 } $s+1..$s+$w;'
4638             # Should start at $_primes_small[$start_idx], do 11 + next multiple of 210.
4639 20         181 my @incs = map { Math::BigInt->new($_) } (2,4,2,4,6,2,6,4,2,4,6,6,2,6,4,2,6,4,6,8,4,2,4,2,4,8,6,4,6,2,4,6,2,6,6,4,2,4,6,2,6,4,2,4,2,10,2,10);
  960         33739  
4640 20         859 my $f = 11; while ($f <= $_primes_small[$start_idx-1]-210) { $f += 210; }
  20         139  
  460         841  
4641 20         90 ($f, $limit) = map { Math::BigInt->new("$_") } ($f, $limit);
  40         966  
4642 20         854 SEARCH: while ($f <= $limit) {
4643 20         772 foreach my $finc (@incs) {
4644 960 50 33     53350 if ($n->copy->bmod($f)->is_zero && $f->bacmp($limit) <= 0) {
4645 0 0       0 my $sf = ($f <= BMAX) ? _bigint_to_int($f) : $f->copy;
4646 0         0 do {
4647 0         0 push @factors, $sf;
4648 0         0 $n->bdiv($f)->bfloor();
4649             } while $n->copy->bmod($f)->is_zero;
4650 0 0       0 last SEARCH if $n->is_one;
4651 0         0 my $newlim = $n->copy->bsqrt;
4652 0 0       0 $limit = $newlim if $limit > $newlim;
4653             }
4654 960         118353 $f->badd($finc);
4655             }
4656             }
4657             }
4658 251 100       2783 push @factors, $n if $n > 1;
4659 251         3307 @factors;
4660             }
4661              
4662             my $_holf_r;
4663             my @_fsublist = (
4664             [ "pbrent 32k", sub { pbrent_factor (shift, 32*1024, 1, 1) } ],
4665             [ "p-1 1M", sub { pminus1_factor(shift, 1_000_000, undef, 1); } ],
4666             [ "ECM 1k", sub { ecm_factor (shift, 1_000, 5_000, 15) } ],
4667             [ "pbrent 512k",sub { pbrent_factor (shift, 512*1024, 7, 1) } ],
4668             [ "p-1 4M", sub { pminus1_factor(shift, 4_000_000, undef, 1); } ],
4669             [ "ECM 10k", sub { ecm_factor (shift, 10_000, 50_000, 10) } ],
4670             [ "pbrent 512k",sub { pbrent_factor (shift, 512*1024, 11, 1) } ],
4671             [ "HOLF 256k", sub { holf_factor (shift, 256*1024, $_holf_r); $_holf_r += 256*1024; } ],
4672             [ "p-1 20M", sub { pminus1_factor(shift,20_000_000); } ],
4673             [ "ECM 100k", sub { ecm_factor (shift, 100_000, 800_000, 10) } ],
4674             [ "HOLF 512k", sub { holf_factor (shift, 512*1024, $_holf_r); $_holf_r += 512*1024; } ],
4675             [ "pbrent 2M", sub { pbrent_factor (shift, 2048*1024, 13, 1) } ],
4676             [ "HOLF 2M", sub { holf_factor (shift, 2048*1024, $_holf_r); $_holf_r += 2048*1024; } ],
4677             [ "ECM 1M", sub { ecm_factor (shift, 1_000_000, 1_000_000, 10) } ],
4678             [ "p-1 100M", sub { pminus1_factor(shift, 100_000_000, 500_000_000); } ],
4679             );
4680              
4681             sub factor {
4682 239     239 0 3963 my($n) = @_;
4683 239         560 _validate_positive_integer($n);
4684 239         333 my @factors;
4685              
4686 239 100       493 if ($n < 4) {
4687 1 50       19 @factors = ($n == 1) ? () : ($n);
4688 1         6 return @factors;
4689             }
4690 238 100       7613 $n = $n->copy if ref($n) eq 'Math::BigInt';
4691 238         1660 my $lim = 4999; # How much trial factoring to do
4692              
4693             # For native integers, we could save a little time by doing hardcoded trials
4694             # by 2-29 here. Skipping it.
4695              
4696 238         626 push @factors, trial_factor($n, $lim);
4697 238 100       837 return @factors if $factors[-1] < $lim*$lim;
4698 71         1860 $n = pop(@factors);
4699              
4700 71         355 my @nstack = ($n);
4701 71         268 while (@nstack) {
4702 132         331 $n = pop @nstack;
4703             # Don't use bignum on $n if it has gotten small enough.
4704 132 100 100     624 $n = _bigint_to_int($n) if ref($n) eq 'Math::BigInt' && $n <= BMAX;
4705             #print "Looking at $n with stack ", join(",",@nstack), "\n";
4706 132   100     1805 while ( ($n >= ($lim*$lim)) && !_is_prime7($n) ) {
4707 61         197 my @ftry;
4708 61         152 $_holf_r = 1;
4709 61         199 foreach my $sub (@_fsublist) {
4710 126 100       503 last if scalar @ftry >= 2;
4711 65 50       392 print " starting $sub->[0]\n" if Math::Prime::Util::prime_get_config()->{'verbose'} > 1;
4712 65         438 @ftry = $sub->[1]->($n);
4713             }
4714 61 50       241 if (scalar @ftry > 1) {
4715             #print " split into ", join(",",@ftry), "\n";
4716 61         168 $n = shift @ftry;
4717 61 100 66     386 $n = _bigint_to_int($n) if ref($n) eq 'Math::BigInt' && $n <= BMAX;
4718 61         906 push @nstack, @ftry;
4719             } else {
4720             #warn "trial factor $n\n";
4721 0         0 push @factors, trial_factor($n);
4722             #print " trial into ", join(",",@factors), "\n";
4723 0         0 $n = 1;
4724 0         0 last;
4725             }
4726             }
4727 132 50       6085 push @factors, $n if $n != 1;
4728             }
4729 71         1711 @factors = sort {$a<=>$b} @factors;
  514         1644  
4730 71         1021 return @factors;
4731             }
4732              
4733             sub _found_factor {
4734 96     96   545 my($f, $n, $what, @factors) = @_;
4735 96 50 33     421 if ($f == 1 || $f == $n) {
4736 0         0 push @factors, $n;
4737             } else {
4738             # Perl 5.6.2 needs things spelled out for it.
4739 96 100       6550 my $f2 = (ref($n) eq 'Math::BigInt') ? $n->copy->bdiv($f)->as_int
4740             : int($n/$f);
4741 96         10706 push @factors, $f;
4742 96         216 push @factors, $f2;
4743 96 50       373 croak "internal error in $what" unless $f * $f2 == $n;
4744             # MPU::GMP prints this type of message if verbose, so do the same.
4745 96 50       6805 print "$what found factor $f\n" if Math::Prime::Util::prime_get_config()->{'verbose'} > 0;
4746             }
4747 96         1717 @factors;
4748             }
4749              
4750             # TODO:
4751 0     0 0 0 sub squfof_factor { trial_factor(@_) }
4752              
4753             sub prho_factor {
4754 5     5 0 3702 my($n, $rounds, $pa, $skipbasic) = @_;
4755 5 100       21 $rounds = 4*1024*1024 unless defined $rounds;
4756 5 50       15 $pa = 3 unless defined $pa;
4757              
4758 5         12 my @factors;
4759 5 50       13 if (!$skipbasic) {
4760 5         19 @factors = _basic_factor($n);
4761 5 50       18 return @factors if $n < 4;
4762             }
4763              
4764 5         224 my $inloop = 0;
4765 5         11 my $U = 7;
4766 5         10 my $V = 7;
4767              
4768 5 100       22 if ( ref($n) eq 'Math::BigInt' ) {
    100          
4769              
4770 2         6 my $zero = $n->copy->bzero;
4771 2         89 $pa = $zero->badd("$pa");
4772 2         248 $U = $zero->copy->badd($U);
4773 2         252 $V = $zero->copy->badd($V);
4774 2         243 for my $i (1 .. $rounds) {
4775             # Would use bmuladd here, but old Math::BigInt's barf with scalar $pa.
4776 22         642 $U->bmul($U)->badd($pa)->bmod($n);
4777 22         6713 $V->bmul($V)->badd($pa);
4778 22         3244 $V->bmul($V)->badd($pa)->bmod($n);
4779 22         9396 my $f = Math::BigInt::bgcd($U-$V, $n);
4780 22 50       62122 if ($f->bacmp($n) == 0) {
    100          
4781 0 0       0 last if $inloop++; # We've been here before
4782             } elsif (!$f->is_one) {
4783 2         67 return _found_factor($f, $n, "prho", @factors);
4784             }
4785             }
4786              
4787             } elsif ($n < MPU_HALFWORD) {
4788              
4789 2         5 my $inner = 32;
4790 2         7 $rounds = int( ($rounds + $inner-1) / $inner );
4791 2         7 while ($rounds-- > 0) {
4792 2         5 my($m, $oldU, $oldV, $f) = (1, $U, $V);
4793 2         8 for my $i (1 .. $inner) {
4794 64         69 $U = ($U * $U + $pa) % $n;
4795 64         68 $V = ($V * $V + $pa) % $n;
4796 64         70 $V = ($V * $V + $pa) % $n;
4797 64 100       73 $f = ($U > $V) ? $U-$V : $V-$U;
4798 64         78 $m = ($m * $f) % $n;
4799             }
4800 2         6 $f = _gcd_ui( $m, $n );
4801 2 50       6 next if $f == 1;
4802 2 100       8 if ($f == $n) {
4803 1         3 ($U, $V) = ($oldU, $oldV);
4804 1         4 for my $i (1 .. $inner) {
4805 2         5 $U = ($U * $U + $pa) % $n;
4806 2         3 $V = ($V * $V + $pa) % $n;
4807 2         4 $V = ($V * $V + $pa) % $n;
4808 2 100       4 $f = ($U > $V) ? $U-$V : $V-$U;
4809 2         4 $f = _gcd_ui( $f, $n);
4810 2 100       5 last if $f != 1;
4811             }
4812 1 50 33     8 last if $f == 1 || $f == $n;
4813             }
4814 2         15 return _found_factor($f, $n, "prho", @factors);
4815             }
4816              
4817             } else {
4818              
4819 1         5 for my $i (1 .. $rounds) {
4820 5 50       12 if ($n <= (~0 >> 1)) {
4821 5 50       11 $U = _mulmod($U, $U, $n); $U += $pa; $U -= $n if $U >= $n;
  5         7  
  5         11  
4822 5         8 $V = _mulmod($V, $V, $n); $V += $pa; # Let the mulmod handle it
  5         7  
4823 5 50       7 $V = _mulmod($V, $V, $n); $V += $pa; $V -= $n if $V >= $n;
  5         7  
  5         10  
4824             } else {
4825             #$U = _mulmod($U, $U, $n); $U=$n-$U; $U = ($pa>=$U) ? $pa-$U : $n-$U+$pa;
4826             #$V = _mulmod($V, $V, $n); $V=$n-$V; $V = ($pa>=$V) ? $pa-$V : $n-$V+$pa;
4827             #$V = _mulmod($V, $V, $n); $V=$n-$V; $V = ($pa>=$V) ? $pa-$V : $n-$V+$pa;
4828 0         0 $U = _mulmod($U, $U, $n); $U = _addmod($U, $pa, $n);
  0         0  
4829 0         0 $V = _mulmod($V, $V, $n); $V = _addmod($V, $pa, $n);
  0         0  
4830 0         0 $V = _mulmod($V, $V, $n); $V = _addmod($V, $pa, $n);
  0         0  
4831             }
4832 5         11 my $f = _gcd_ui( $U-$V, $n );
4833 5 50       13 if ($f == $n) {
    100          
4834 0 0       0 last if $inloop++; # We've been here before
4835             } elsif ($f != 1) {
4836 1         3 return _found_factor($f, $n, "prho", @factors);
4837             }
4838             }
4839              
4840             }
4841 0         0 push @factors, $n;
4842 0         0 @factors;
4843             }
4844              
4845             sub pbrent_factor {
4846 78     78 0 3506 my($n, $rounds, $pa, $skipbasic) = @_;
4847 78 100       243 $rounds = 4*1024*1024 unless defined $rounds;
4848 78 100       243 $pa = 3 unless defined $pa;
4849              
4850 78         186 my @factors;
4851 78 100       238 if (!$skipbasic) {
4852 17         66 @factors = _basic_factor($n);
4853 17 50       68 return @factors if $n < 4;
4854             }
4855              
4856 78         1177 my $Xi = 2;
4857 78         157 my $Xm = 2;
4858              
4859 78 100       365 if ( ref($n) eq 'Math::BigInt' ) {
    100          
4860              
4861             # Same code as the GMP version, but runs *much* slower. Even with
4862             # Math::BigInt::GMP it's >200x slower. With the default Calc backend
4863             # it's thousands of times slower.
4864 23         50 my $inner = 32;
4865 23         122 my $zero = $n->copy->bzero;
4866 23         1330 my $saveXi;
4867             my $f;
4868 23         85 $Xi = $zero->copy->badd($Xi);
4869 23         4215 $Xm = $zero->copy->badd($Xm);
4870 23         3341 $pa = $zero->copy->badd($pa);
4871 23         3447 my $r = 1;
4872 23         120 while ($rounds > 0) {
4873 206 100       621 my $rleft = ($r > $rounds) ? $rounds : $r;
4874 206         482 while ($rleft > 0) {
4875 2334 100       45328 my $dorounds = ($rleft > $inner) ? $inner : $rleft;
4876 2334         6853 my $m = $zero->copy->bone;
4877 2334         233767 $saveXi = $Xi->copy;
4878 2334         50258 foreach my $i (1 .. $dorounds) {
4879 71659         58872634 $Xi->bmul($Xi)->badd($pa)->bmod($n);
4880 71659         33592495 $m->bmul($Xi->copy->bsub($Xm));
4881             }
4882 2334         3434761 $rleft -= $dorounds;
4883 2334         5341 $rounds -= $dorounds;
4884 2334         8745 $m->bmod($n);
4885 2334         5809515 $f = Math::BigInt::bgcd($m, $n);
4886 2334 100       9368886 last unless $f->is_one;
4887             }
4888 206 100       3905 if ($f->is_one) {
4889 185         2306 $r *= 2;
4890 185         484 $Xm = $Xi->copy;
4891 185         4327 next;
4892             }
4893 21 50       351 if ($f == $n) { # back up to determine the factor
4894 0         0 $Xi = $saveXi->copy;
4895 0   0     0 do {
4896 0         0 $Xi->bmul($Xi)->badd($pa)->bmod($n);
4897 0         0 $f = Math::BigInt::bgcd($Xm-$Xi, $n);
4898             } while ($f != 1 && $r-- != 0);
4899 0 0 0     0 last if $f == 1 || $f == $n;
4900             }
4901 21         1314 return _found_factor($f, $n, "pbrent", @factors);
4902             }
4903              
4904             } elsif ($n < MPU_HALFWORD) {
4905              
4906             # Doing the gcd batching as above works pretty well here, but it's a lot
4907             # of code for not much gain for general users.
4908 10         24 for my $i (1 .. $rounds) {
4909 1653         1757 $Xi = ($Xi * $Xi + $pa) % $n;
4910 1653 100       2411 my $f = _gcd_ui( ($Xi>$Xm) ? $Xi-$Xm : $Xm-$Xi, $n);
4911 1653 100 66     2506 return _found_factor($f, $n, "pbrent", @factors) if $f != 1 && $f != $n;
4912 1643 100       2498 $Xm = $Xi if ($i & ($i-1)) == 0; # i is a power of 2
4913             }
4914              
4915             } else {
4916              
4917 45         151 for my $i (1 .. $rounds) {
4918 32881         52431 $Xi = _addmod( _mulmod($Xi, $Xi, $n), $pa, $n);
4919 32881 100       68509 my $f = _gcd_ui( ($Xi>$Xm) ? $Xi-$Xm : $Xm-$Xi, $n);
4920 32881 100 66     63180 return _found_factor($f, $n, "pbrent", @factors) if $f != 1 && $f != $n;
4921 32836 100       66554 $Xm = $Xi if ($i & ($i-1)) == 0; # i is a power of 2
4922             }
4923              
4924             }
4925 2         8 push @factors, $n;
4926 2         23 @factors;
4927             }
4928              
4929             sub pminus1_factor {
4930 7     7 0 7104 my($n, $B1, $B2, $skipbasic) = @_;
4931              
4932 7         18 my @factors;
4933 7 100       43 if (!$skipbasic) {
4934 5         25 @factors = _basic_factor($n);
4935 5 50       25 return @factors if $n < 4;
4936             }
4937              
4938 7 100       647 if ( ref($n) ne 'Math::BigInt' ) {
4939             # Stage 1 only
4940 1 50       5 $B1 = 10_000_000 unless defined $B1;
4941 1         2 my $pa = 2;
4942 1         1 my $f = 1;
4943 1         2 my($pc_beg, $pc_end, @bprimes);
4944 1         2 $pc_beg = 2;
4945 1         2 $pc_end = $pc_beg + 100_000;
4946 1         3 my $sqrtb1 = int(sqrt($B1));
4947 1         2 while (1) {
4948 1 50       3 $pc_end = $B1 if $pc_end > $B1;
4949 1         2 @bprimes = @{ primes($pc_beg, $pc_end) };
  1         4  
4950 1         95 foreach my $q (@bprimes) {
4951 2         4 my $k = $q;
4952 2 50       8 if ($q <= $sqrtb1) {
4953 2         8 my $kmin = int($B1 / $q);
4954 2         6 while ($k <= $kmin) { $k *= $q; }
  35         48  
4955             }
4956 2         10 $pa = _powmod($pa, $k, $n);
4957 2 50       10 if ($pa == 0) { push @factors, $n; return @factors; }
  0         0  
  0         0  
4958 2         8 my $f = _gcd_ui( $pa-1, $n );
4959 2 100       10 return _found_factor($f, $n, "pminus1", @factors) if $f != 1;
4960             }
4961 0 0       0 last if $pc_end >= $B1;
4962 0         0 $pc_beg = $pc_end+1;
4963 0         0 $pc_end += 500_000;
4964             }
4965 0         0 push @factors, $n;
4966 0         0 return @factors;
4967             }
4968              
4969             # Stage 2 isn't really any faster than stage 1 for the examples I've tried.
4970             # Perl's overhead is greater than the savings of multiply vs. powmod
4971              
4972 6 100       29 if (!defined $B1) {
4973 1         7 for my $mul (1, 100, 1000, 10_000, 100_000, 1_000_000) {
4974 1         4 $B1 = 1000 * $mul;
4975 1         3 $B2 = 1*$B1;
4976             #warn "Trying p-1 with $B1 / $B2\n";
4977 1         21 my @nf = pminus1_factor($n, $B1, $B2);
4978 1 50       5 if (scalar @nf > 1) {
4979 1         4 push @factors, @nf;
4980 1         11 return @factors;
4981             }
4982             }
4983 0         0 push @factors, $n;
4984 0         0 return @factors;
4985             }
4986 5 100       23 $B2 = 1*$B1 unless defined $B2;
4987              
4988 5         22 my $one = $n->copy->bone;
4989 5         578 my ($j, $q, $saveq) = (32, 2, 2);
4990 5         19 my $t = $one->copy;
4991 5         117 my $pa = $one->copy->binc();
4992 5         441 my $savea = $pa->copy;
4993 5         110 my $f = $one->copy;
4994 5         95 my($pc_beg, $pc_end, @bprimes);
4995              
4996 5         10 $pc_beg = 2;
4997 5         17 $pc_end = $pc_beg + 100_000;
4998 5         14 while (1) {
4999 5 100       22 $pc_end = $B1 if $pc_end > $B1;
5000 5         15 @bprimes = @{ primes($pc_beg, $pc_end) };
  5         32  
5001 5         290 foreach my $q (@bprimes) {
5002 4252         13094 my($k, $kmin) = ($q, int($B1 / $q));
5003 4252         8606 while ($k <= $kmin) { $k *= $q; }
  593         1087  
5004 4252         9539 $t *= $k; # accumulate powers for a
5005 4252 100       718797 if ( ($j++ % 64) == 0) {
5006 68 50 33     522 next if $pc_beg > 2 && ($j-1) % 256;
5007 68         353 $pa->bmodpow($t, $n);
5008 68         21833104 $t = $one->copy;
5009 68 50       2878 if ($pa == 0) { push @factors, $n; return @factors; }
  0         0  
  0         0  
5010 68         21496 $f = Math::BigInt::bgcd( $pa->copy->bdec, $n );
5011 68 100       225155 last if $f == $n;
5012 66 100       2914 return _found_factor($f, $n, "pminus1", @factors) unless $f->is_one;
5013 65         1278 $saveq = $q;
5014 65         207 $savea = $pa->copy;
5015             }
5016             }
5017 4         120 $q = $bprimes[-1];
5018 4 50 66     24 last if !$f->is_one || $pc_end >= $B1;
5019 0         0 $pc_beg = $pc_end+1;
5020 0         0 $pc_end += 500_000;
5021             }
5022 4         718 undef @bprimes;
5023 4         29 $pa->bmodpow($t, $n);
5024 4 50       306229 if ($pa == 0) { push @factors, $n; return @factors; }
  0         0  
  0         0  
5025 4         1024 $f = Math::BigInt::bgcd( $pa-1, $n );
5026 4 100       7095 if ($f == $n) {
5027 2         100 $q = $saveq;
5028 2         7 $pa = $savea->copy;
5029 2         50 while ($q <= $B1) {
5030 114         328 my ($k, $kmin) = ($q, int($B1 / $q));
5031 114         264 while ($k <= $kmin) { $k *= $q; }
  0         0  
5032 114         420 $pa->bmodpow($k, $n);
5033 114         648639 my $f = Math::BigInt::bgcd( $pa-1, $n );
5034 114 100       485241 if ($f == $n) { push @factors, $n; return @factors; }
  2         96  
  2         40  
5035 112 50       4443 last if !$f->is_one;
5036 112         1628 $q = next_prime($q);
5037             }
5038             }
5039             # STAGE 2
5040 2 50 33     92 if ($f->is_one && $B2 > $B1) {
5041 2         60 my $bm = $pa->copy;
5042 2         52 my $b = $one->copy;
5043 2         49 my @precomp_bm;
5044 2         9 $precomp_bm[0] = ($bm * $bm) % $n;
5045 2         1019 foreach my $j (1..19) {
5046 38         23091 $precomp_bm[$j] = ($precomp_bm[$j-1] * $bm * $bm) % $n;
5047             }
5048 2         1313 $pa->bmodpow($q, $n);
5049 2         10213 my $j = 1;
5050 2         9 $pc_beg = $q+1;
5051 2         4 $pc_end = $pc_beg + 100_000;
5052 2         7 while (1) {
5053 2 50       9 $pc_end = $B2 if $pc_end > $B2;
5054 2         6 @bprimes = @{ primes($pc_beg, $pc_end) };
  2         15  
5055 2         32 foreach my $i (0 .. $#bprimes) {
5056 896         2170 my $diff = $bprimes[$i] - $q;
5057 896         1405 $q = $bprimes[$i];
5058 896         1527 my $qdiff = ($diff >> 1) - 1;
5059 896 100       2122 if (!defined $precomp_bm[$qdiff]) {
5060 3         18 $precomp_bm[$qdiff] = $bm->copy->bmodpow($diff, $n);
5061             }
5062 896         9104 $pa->bmul($precomp_bm[$qdiff])->bmod($n);
5063 896 50       342129 if ($pa == 0) { push @factors, $n; return @factors; }
  0         0  
  0         0  
5064 896         152753 $b->bmul($pa-1);
5065 896 100       2049562 if (($j++ % 128) == 0) {
5066 7         44 $b->bmod($n);
5067 7         53209 $f = Math::BigInt::bgcd( $b, $n );
5068 7 100       21090 last if !$f->is_one;
5069             }
5070             }
5071 2 50 33     45 last if !$f->is_one || $pc_end >= $B2;
5072 0         0 $pc_beg = $pc_end+1;
5073 0         0 $pc_end += 500_000;
5074             }
5075 2         39 $f = Math::BigInt::bgcd( $b, $n );
5076             }
5077 2         5045 return _found_factor($f, $n, "pminus1", @factors);
5078             }
5079              
5080             sub holf_factor {
5081 3     3 0 6073 my($n, $rounds, $startrounds) = @_;
5082 3 50       16 $rounds = 64*1024*1024 unless defined $rounds;
5083 3 50       13 $startrounds = 1 unless defined $startrounds;
5084 3 50       11 $startrounds = 1 if $startrounds < 1;
5085              
5086 3         12 my @factors = _basic_factor($n);
5087 3 50       13 return @factors if $n < 4;
5088              
5089 3 100       305 if ( ref($n) eq 'Math::BigInt' ) {
5090 2         9 for my $i ($startrounds .. $rounds) {
5091 2         10 my $ni = $n->copy->bmul($i);
5092 2         383 my $s = $ni->copy->bsqrt->bfloor->as_int;
5093 2 50       2495 if ($s * $s == $ni) {
5094             # s^2 = n*i, so m = s^2 mod n = 0. Hence f = GCD(n, s) = GCD(n, n*i)
5095 0         0 my $f = Math::BigInt::bgcd($ni, $n);
5096 0         0 return _found_factor($f, $n, "HOLF", @factors);
5097             }
5098 2         386 $s->binc;
5099 2         91 my $m = ($s * $s) - $ni;
5100             # Check for perfect square
5101 2         620 my $mc = _bigint_to_int($m & 31);
5102 2 0 33     92 next unless $mc==0||$mc==1||$mc==4||$mc==9||$mc==16||$mc==17||$mc==25;
      66        
      66        
      66        
      33        
      33        
5103 2         10 my $f = $m->copy->bsqrt->bfloor->as_int;
5104 2 50       216 next unless ($f*$f) == $m;
5105 2 50       218 $f = Math::BigInt::bgcd( ($s > $f) ? $s-$f : $f-$s, $n);
5106 2         905 return _found_factor($f, $n, "HOLF ($i rounds)", @factors);
5107             }
5108             } else {
5109 1         5 for my $i ($startrounds .. $rounds) {
5110 3         8 my $s = int(sqrt($n * $i));
5111 3 50       7 $s++ if ($s * $s) != ($n * $i);
5112 3 50       7 my $m = ($s < MPU_HALFWORD) ? ($s*$s) % $n : _mulmod($s, $s, $n);
5113             # Check for perfect square
5114 3         4 my $mc = $m & 31;
5115 3 50 33     29 next unless $mc==0||$mc==1||$mc==4||$mc==9||$mc==16||$mc==17||$mc==25;
      33        
      33        
      66        
      66        
      66        
5116 1         2 my $f = int(sqrt($m));
5117 1 50       67 next unless $f*$f == $m;
5118 1         6 $f = _gcd_ui($s - $f, $n);
5119 1         6 return _found_factor($f, $n, "HOLF ($i rounds)", @factors);
5120             }
5121             }
5122 0         0 push @factors, $n;
5123 0         0 @factors;
5124             }
5125              
5126             sub fermat_factor {
5127 2     2 0 2780 my($n, $rounds) = @_;
5128 2 50       10 $rounds = 64*1024*1024 unless defined $rounds;
5129              
5130 2         11 my @factors = _basic_factor($n);
5131 2 50       8 return @factors if $n < 4;
5132              
5133 2 100       126 if ( ref($n) eq 'Math::BigInt' ) {
5134 1         6 my $pa = $n->copy->bsqrt->bfloor->as_int;
5135 1 50       1407 return _found_factor($pa, $n, "Fermat", @factors) if $pa*$pa == $n;
5136 1         188 $pa++;
5137 1         55 my $b2 = $pa*$pa - $n;
5138 1         298 my $lasta = $pa + $rounds;
5139 1         177 while ($pa <= $lasta) {
5140 1         48 my $mc = _bigint_to_int($b2 & 31);
5141 1 0 33     36 if ($mc==0||$mc==1||$mc==4||$mc==9||$mc==16||$mc==17||$mc==25) {
      33        
      33        
      33        
      0        
      0        
5142 1         4 my $s = $b2->copy->bsqrt->bfloor->as_int;
5143 1 50       109 if ($s*$s == $b2) {
5144 1         106 my $i = $pa-($lasta-$rounds)+1;
5145 1         477 return _found_factor($pa - $s, $n, "Fermat ($i rounds)", @factors);
5146             }
5147             }
5148 0         0 $pa++;
5149 0         0 $b2 = $pa*$pa-$n;
5150             }
5151             } else {
5152 1         3 my $pa = int(sqrt($n));
5153 1 50       4 return _found_factor($pa, $n, "Fermat", @factors) if $pa*$pa == $n;
5154 1         2 $pa++;
5155 1         4 my $b2 = $pa*$pa - $n;
5156 1         2 my $lasta = $pa + $rounds;
5157 1         3 while ($pa <= $lasta) {
5158 2         6 my $mc = $b2 & 31;
5159 2 100 33     22 if ($mc==0||$mc==1||$mc==4||$mc==9||$mc==16||$mc==17||$mc==25) {
      33        
      33        
      33        
      66        
      66        
5160 1         2 my $s = int(sqrt($b2));
5161 1 50       3 if ($s*$s == $b2) {
5162 1         3 my $i = $pa-($lasta-$rounds)+1;
5163 1         13 return _found_factor($pa - $s, $n, "Fermat ($i rounds)", @factors);
5164             }
5165             }
5166 1         2 $pa++;
5167 1         2 $b2 = $pa*$pa-$n;
5168             }
5169             }
5170 0         0 push @factors, $n;
5171 0         0 @factors;
5172             }
5173              
5174              
5175             sub ecm_factor {
5176 7     7 0 4914 my($n, $B1, $B2, $ncurves) = @_;
5177 7         37 _validate_positive_integer($n);
5178              
5179 7         38 my @factors = _basic_factor($n);
5180 7 50       34 return @factors if $n < 4;
5181              
5182 7 50       824 if ($Math::Prime::Util::_GMPfunc{"ecm_factor"}) {
5183 0 0       0 $B1 = 0 if !defined $B1;
5184 0 0       0 $ncurves = 0 if !defined $ncurves;
5185 0         0 my @ef = Math::Prime::Util::GMP::ecm_factor($n, $B1, $ncurves);
5186 0 0       0 if (@ef > 1) {
5187 0         0 my $ecmfac = Math::Prime::Util::_reftyped($n, $ef[-1]);
5188 0         0 return _found_factor($ecmfac, $n, "ECM (GMP) B1=$B1 curves $ncurves", @factors);
5189             }
5190 0         0 push @factors, $n;
5191 0         0 return @factors;
5192             }
5193              
5194 7 100       27 $ncurves = 10 unless defined $ncurves;
5195              
5196 7 100       26 if (!defined $B1) {
5197 1         6 for my $mul (1, 10, 100, 1000, 10_000, 100_000, 1_000_000) {
5198 1         4 $B1 = 100 * $mul;
5199 1         2 $B2 = 10*$B1;
5200             #warn "Trying ecm with $B1 / $B2\n";
5201 1         17 my @nf = ecm_factor($n, $B1, $B2, $ncurves);
5202 1 50       5 if (scalar @nf > 1) {
5203 1         4 push @factors, @nf;
5204 1         10 return @factors;
5205             }
5206             }
5207 0         0 push @factors, $n;
5208 0         0 return @factors;
5209             }
5210              
5211 6 50       24 $B2 = 10*$B1 unless defined $B2;
5212 6         30 my $sqrt_b1 = int(sqrt($B1)+1);
5213              
5214             # Affine code. About 3x slower than the projective, and no stage 2.
5215             #
5216             #if (!defined $Math::Prime::Util::ECAffinePoint::VERSION) {
5217             # eval { require Math::Prime::Util::ECAffinePoint; 1; }
5218             # or do { croak "Cannot load Math::Prime::Util::ECAffinePoint"; };
5219             #}
5220             #my @bprimes = @{ primes(2, $B1) };
5221             #my $irandf = Math::Prime::Util::_get_rand_func();
5222             #foreach my $curve (1 .. $ncurves) {
5223             # my $a = $irandf->($n-1);
5224             # my $b = 1;
5225             # my $ECP = Math::Prime::Util::ECAffinePoint->new($a, $b, $n, 0, 1);
5226             # foreach my $q (@bprimes) {
5227             # my $k = $q;
5228             # if ($k < $sqrt_b1) {
5229             # my $kmin = int($B1 / $q);
5230             # while ($k <= $kmin) { $k *= $q; }
5231             # }
5232             # $ECP->mul($k);
5233             # my $f = $ECP->f;
5234             # if ($f != 1) {
5235             # last if $f == $n;
5236             # warn "ECM found factors with B1 = $B1 in curve $curve\n";
5237             # return _found_factor($f, $n, "ECM B1=$B1 curve $curve", @factors);
5238             # }
5239             # last if $ECP->is_infinity;
5240             # }
5241             #}
5242              
5243 6         1914 require Math::Prime::Util::ECProjectivePoint;
5244 6         1388 require Math::Prime::Util::RandomPrimes;
5245              
5246             # With multiple curves, it's better to get all the primes at once.
5247             # The downside is this can kill memory with a very large B1.
5248 6         18 my @bprimes = @{ primes(3, $B1) };
  6         32  
5249 6         29 foreach my $q (@bprimes) {
5250 33 100       71 last if $q > $sqrt_b1;
5251 27         71 my($k,$kmin) = ($q, int($B1/$q));
5252 27         58 while ($k <= $kmin) { $k *= $q; }
  40         76  
5253 27         43 $q = $k;
5254             }
5255 6 50       30 my @b2primes = ($B2 > $B1) ? @{primes($B1+1, $B2)} : ();
  6         21  
5256              
5257 6         143 foreach my $curve (1 .. $ncurves) {
5258 24         2377 my $sigma = Math::Prime::Util::urandomm($n-6) + 6;
5259 24         9028 my ($u, $v) = ( ($sigma*$sigma - 5) % $n, (4 * $sigma) % $n );
5260 24         23723 my ($x, $z) = ( ($u*$u*$u) % $n, ($v*$v*$v) % $n );
5261 24         31034 my $cb = (4 * $x * $v) % $n;
5262 24         13880 my $ca = ( (($v-$u)**3) * (3*$u + $v) ) % $n;
5263 24         36946 my $f = Math::BigInt::bgcd( $cb, $n );
5264 24 50       80592 $f = Math::BigInt::bgcd( $z, $n ) if $f == 1;
5265 24 50       81451 next if $f == $n;
5266 24 50       1090 return _found_factor($f,$n, "ECM B1=$B1 curve $curve", @factors) if $f != 1;
5267 24 100       2838 $cb = Math::BigInt->new("$cb") unless ref($cb) eq 'Math::BigInt';
5268 24         130 $u = $cb->copy->bmodinv($n);
5269 24         116947 $ca = (($ca*$u) - 2) % $n;
5270              
5271 24         16136 my $ECP = Math::Prime::Util::ECProjectivePoint->new($ca, $n, $x, $z);
5272 24         82 my $fm = $n-$n+1;
5273 24         6006 my $i = 15;
5274              
5275 24         123 for (my $q = 2; $q < $B1; $q *= 2) { $ECP->double(); }
  174         546  
5276 24         112 foreach my $k (@bprimes) {
5277 2857         29345 $ECP->mul($k);
5278 2857         12159 $fm = ($fm * $ECP->x() ) % $n;
5279 2857 100       1258380 if ($i++ % 32 == 0) {
5280 86         521 $f = Math::BigInt::bgcd($fm, $n);
5281 86 100       304486 last if $f != 1;
5282             }
5283             }
5284 24         290 $f = Math::BigInt::bgcd($fm, $n);
5285 24 50       81518 next if $f == $n;
5286              
5287 24 100 66     1421 if ($f == 1 && $B2 > $B1) { # BEGIN STAGE 2
5288 22 100       3388 my $D = int(sqrt($B2/2)); $D++ if $D % 2;
  22         98  
5289 22         71 my $one = $n - $n + 1;
5290 22         5986 my $g = $one;
5291              
5292 22         142 my $S2P = $ECP->copy->normalize;
5293 22         112 $f = $S2P->f;
5294 22 50       106 if ($f != 1) {
5295 0 0       0 next if $f == $n;
5296             #warn "ECM S2 normalize f=$f\n" if $f != 1;
5297 0         0 return _found_factor($f, $n, "ECM S2 B1=$B1 curve $curve");
5298             }
5299 22         2597 my $S2x = $S2P->x;
5300 22         90 my $S2d = $S2P->d;
5301 22         78 my @nqx = ($n-$n, $S2x);
5302              
5303 22         2604 foreach my $i (2 .. 2*$D) {
5304 1838         798177 my($x2, $z2);
5305 1838 100       5133 if ($i % 2) {
5306 909         5312 ($x2, $z2) = Math::Prime::Util::ECProjectivePoint::_addx($nqx[($i-1)/2], $nqx[($i+1)/2], $S2x, $n);
5307             } else {
5308 929         4320 ($x2, $z2) = Math::Prime::Util::ECProjectivePoint::_double($nqx[$i/2], $one, $n, $S2d);
5309             }
5310 1838         848511 $nqx[$i] = $x2;
5311             #($f, $u, undef) = _extended_gcd($z2, $n);
5312 1838         5370 $f = Math::BigInt::bgcd( $z2, $n );
5313 1838 100       6100658 last if $f != 1;
5314 1836         221098 $u = $z2->copy->bmodinv($n);
5315 1836         8790206 $nqx[$i] = ($x2 * $u) % $n;
5316             }
5317 22 100       9000 if ($f != 1) {
5318 2 50       191 next if $f == $n;
5319             #warn "ECM S2 1: B1 $B1 B2 $B2 curve $curve f=$f\n";
5320 2         142 return _found_factor($f, $n, "ECM S2 B1=$B1 curve $curve", @factors);
5321             }
5322              
5323 20         2449 $x = $nqx[2*$D-1];
5324 20         119 my $m = 1;
5325 20         110 while ($m < ($B2+$D)) {
5326 882 100       2405 if ($m != 1) {
5327 862         1611 my $oldx = $S2x;
5328 862         3652 my ($x1, $z1) = Math::Prime::Util::ECProjectivePoint::_addx($nqx[2*$D], $S2x, $x, $n);
5329 862         804102 $f = Math::BigInt::bgcd( $z1, $n );
5330 862 50       2880549 last if $f != 1;
5331 862         101627 $u = $z1->copy->bmodinv($n);
5332 862         4167315 $S2x = ($x1 * $u) % $n;
5333 862         377818 $x = $oldx;
5334 862 50       3394 last if $f != 1;
5335             }
5336 882 100       101016 if ($m+$D > $B1) {
5337 722 100       3142 my @p = grep { $_ >= $m-$D && $_ <= $m+$D } @b2primes;
  337305         735678  
5338 722         1941 foreach my $i (@p) {
5339 4950 100       2453819 last if $i >= $m;
5340 4245         14708 $g = ($g * ($S2x - $nqx[$m+$D-$i])) % $n;
5341             }
5342 722         11659 foreach my $i (@p) {
5343 8736 100       1628080 next unless $i > $m;
5344 4281 100 100     14161 next if $i > ($m+$m) || is_prime($m+$m-$i);
5345 3324         11117 $g = ($g * ($S2x - $nqx[$i-$m])) % $n;
5346             }
5347 722         314340 $f = Math::BigInt::bgcd($g, $n);
5348             #warn "ECM S2 3: found $f in stage 2\n" if $f != 1;
5349 722 100       2398420 last if $f != 1;
5350             }
5351 880         90624 $m += 2*$D;
5352             }
5353             } # END STAGE 2
5354              
5355 22 50       863 next if $f == $n;
5356 22 100       987 if ($f != 1) {
5357             #warn "ECM found factors with B1 = $B1 in curve $curve\n";
5358 4         500 return _found_factor($f, $n, "ECM B1=$B1 curve $curve", @factors);
5359             }
5360             # end of curve loop
5361             }
5362 0         0 push @factors, $n;
5363 0         0 @factors;
5364             }
5365              
5366             sub divisors {
5367 38     38 0 1785 my($n) = @_;
5368 38         181 _validate_positive_integer($n);
5369 38         92 my(@factors, @d, @t);
5370              
5371             # In scalar context, returns sigma_0(n). Very fast.
5372 38 50       157 return Math::Prime::Util::divisor_sum($n,0) unless wantarray;
5373 38 0       119 return ($n == 0) ? (0,1) : (1) if $n <= 1;
    50          
5374              
5375 38 50       4385 if ($Math::Prime::Util::_GMPfunc{"divisors"}) {
5376             # This trips an erroneous compile time error without the eval.
5377 0         0 eval ' @d = Math::Prime::Util::GMP::divisors($n); '; ## no critic qw(ProhibitStringyEval)
5378 0 0       0 @d = map { $_ <= ~0 ? $_ : ref($n)->new($_) } @d if ref($n);
  0 0       0  
5379 0         0 return @d;
5380             }
5381              
5382 38         208 @factors = Math::Prime::Util::factor($n);
5383 38 50       192 return (1,$n) if scalar @factors == 1;
5384              
5385 38         175 my $bigint = ref($n);
5386 38 50       150 @factors = map { $bigint->new("$_") } @factors if $bigint;
  225         9694  
5387 38 50       2494 @d = $bigint ? ($bigint->new(1)) : (1);
5388              
5389 38         1681 while (my $p = shift @factors) {
5390 191         6737 my $e = 1;
5391 191   100     677 while (@factors && $p == $factors[0]) { $e++; shift(@factors); }
  34         1413  
  34         157  
5392 191         5414 push @d, @t = map { $_ * $p } @d; # multiply through once
  2648         230570  
5393 191         18951 push @d, @t = map { $_ * $p } @t for 2 .. $e; # repeat
  34         1231  
5394             }
5395              
5396 38 100       266 @d = map { $_ <= INTMAX ? _bigint_to_int($_) : $_ } @d if $bigint;
  2720 50       86850  
5397 38         5481 @d = sort { $a <=> $b } @d;
  9181         54931  
5398 38         1108 @d;
5399             }
5400              
5401              
5402             sub chebyshev_theta {
5403 2     2 0 8 my($n,$low) = @_;
5404 2 100       9 $low = 2 unless defined $low;
5405 2         7 my($sum,$high) = (0.0, 0);
5406 2         8 while ($low <= $n) {
5407 2         6 $high = $low + 1e6;
5408 2 50       7 $high = $n if $high > $n;
5409 2         5 $sum += log($_) for @{primes($low,$high)};
  2         10  
5410 2         40 $low = $high+1;
5411             }
5412 2         10 $sum;
5413             }
5414              
5415             sub chebyshev_psi {
5416 1     1 0 4 my($n) = @_;
5417 1 50       5 return 0 if $n <= 1;
5418 1         6 my ($sum, $logn, $sqrtn) = (0.0, log($n), int(sqrt($n)));
5419              
5420             # Sum the log of prime powers first
5421 1         2 for my $p (@{primes($sqrtn)}) {
  1         3  
5422 22         40 my $logp = log($p);
5423 22         37 $sum += $logp * int($logn/$logp+1e-15);
5424             }
5425             # The rest all have exponent 1: add them in using the segmenting theta code
5426 1         9 $sum += chebyshev_theta($n, $sqrtn+1);
5427              
5428 1         15 $sum;
5429             }
5430              
5431             sub hclassno {
5432 0     0 0 0 my $n = shift;
5433              
5434 0 0       0 return -1 if $n == 0;
5435 0 0 0     0 return 0 if $n < 0 || ($n % 4) == 1 || ($n % 4) == 2;
      0        
5436 0 0       0 return 2 * (2,3,6,6,6,8,12,9,6,12,18,12,8,12,18,18,12,15,24,12,6,24,30,20,12,12,24,24,18,24)[($n>>1)-1] if $n <= 60;
5437              
5438 0         0 my ($h, $square, $b, $b2) = (0, 0, $n & 1, ($n+1) >> 2);
5439              
5440 0 0       0 if ($b == 0) {
5441 0         0 my $lim = int(sqrt($b2));
5442 0 0       0 if (_is_perfect_square($b2)) {
5443 0         0 $square = 1;
5444 0         0 $lim--;
5445             }
5446             #$h += scalar(grep { $_ <= $lim } divisors($b2));
5447 0 0       0 for my $i (1 .. $lim) { $h++ unless $b2 % $i; }
  0         0  
5448 0         0 ($b,$b2) = (2, ($n+4) >> 2);
5449             }
5450 0         0 while ($b2 * 3 < $n) {
5451 0 0       0 $h++ unless $b2 % $b;
5452 0         0 my $lim = int(sqrt($b2));
5453 0 0       0 if (_is_perfect_square($b2)) {
5454 0         0 $h++;
5455 0         0 $lim--;
5456             }
5457             #$h += 2 * scalar(grep { $_ > $b && $_ <= $lim } divisors($b2));
5458 0 0       0 for my $i ($b+1 .. $lim) { $h += 2 unless $b2 % $i; }
  0         0  
5459 0         0 $b += 2;
5460 0         0 $b2 = ($n+$b*$b) >> 2;
5461             }
5462 0 0       0 return (($b2*3 == $n) ? 2*(3*$h+1) : $square ? 3*(2*$h+1) : 6*$h) << 1;
    0          
5463             }
5464              
5465             # Sigma method for prime powers
5466             sub _taup {
5467 0     0   0 my($p, $e, $n) = @_;
5468 0         0 my($bp) = Math::BigInt->new("".$p);
5469 0 0       0 if ($e == 1) {
5470 0 0       0 return (0,1,-24,252,-1472,4830,-6048,-16744,84480)[$p] if $p <= 8;
5471 0         0 my $ds5 = $bp->copy->bpow( 5)->binc(); # divisor_sum(p,5)
5472 0         0 my $ds11 = $bp->copy->bpow(11)->binc(); # divisor_sum(p,11)
5473 0         0 my $s = Math::BigInt->new("".vecsum(map { vecprod(BTWO,Math::Prime::Util::divisor_sum($_,5), Math::Prime::Util::divisor_sum($p-$_,5)) } 1..($p-1)>>1));
  0         0  
5474 0         0 $n = ( 65*$ds11 + 691*$ds5 - (691*252)*$s ) / 756;
5475             } else {
5476 0         0 my $t = Math::BigInt->new(""._taup($p,1));
5477 0         0 $n = $t->copy->bpow($e);
5478 0 0       0 if ($e == 2) {
    0          
5479 0         0 $n -= $bp->copy->bpow(11);
5480             } elsif ($e == 3) {
5481 0         0 $n -= BTWO * $t * $bp->copy->bpow(11);
5482             } else {
5483 0 0       0 $n += vecsum( map { vecprod( ($_&1) ? - BONE : BONE,
  0         0  
5484             $bp->copy->bpow(11*$_),
5485             binomial($e-$_, $e-2*$_),
5486             $t ** ($e-2*$_) ) } 1 .. ($e>>1) );
5487             }
5488             }
5489 0 0 0     0 $n = _bigint_to_int($n) if ref($n) && $n->bacmp(BMAX) <= 0;
5490 0         0 $n;
5491             }
5492              
5493             # Cohen's method using Hurwitz class numbers
5494             # The two hclassno calls could be collapsed with some work
5495             sub _tauprime {
5496 9     9   11 my $p = shift;
5497 9 100       22 return -24 if $p == 2;
5498 8         298 my $sum = Math::BigInt->new(0);
5499 8 50       1080 if ($p < (MPU_32BIT ? 300 : 1600)) {
5500 8         267 my($p9,$pp7) = (9*$p, 7*$p*$p);
5501 8         904 for my $t (1 .. Math::Prime::Util::sqrtint($p)) {
5502 36         3428 my $t2 = $t * $t;
5503 36         55 my $v = $p - $t2;
5504 36         650 $sum += $t2**3 * (4*$t2*$t2 - $p9*$t2 + $pp7) * (Math::Prime::Util::hclassno(4*$v) + 2 * Math::Prime::Util::hclassno($v));
5505             }
5506 8         3076 $p = Math::BigInt->new("$p");
5507             } else {
5508 0         0 $p = Math::BigInt->new("$p");
5509 0         0 my($p9,$pp7) = (9*$p, 7*$p*$p);
5510 0         0 for my $t (1 .. Math::Prime::Util::sqrtint($p)) {
5511 0         0 my $t2 = Math::BigInt->new("$t") ** 2;
5512 0         0 my $v = $p - $t2;
5513 0         0 $sum += $t2**3 * (4*$t2*$t2 - $p9*$t2 + $pp7) * (Math::Prime::Util::hclassno(4*$v) + 2 * Math::Prime::Util::hclassno($v));
5514             }
5515             }
5516 8         295 28*$p**6 - 28*$p**5 - 90*$p**4 - 35*$p**3 - 1 - 32 * ($sum/3);
5517             }
5518              
5519             # Recursive method for handling prime powers
5520             sub _taupower {
5521 9     9   1160 my($p, $e) = @_;
5522 9 50       18 return 1 if $e <= 0;
5523 9 100       21 return _tauprime($p) if $e == 1;
5524 2         7 $p = Math::BigInt->new("$p");
5525 2         86 my($tp, $p11) = ( _tauprime($p), $p**11 );
5526 2 100       5108 return $tp ** 2 - $p11 if $e == 2;
5527 1 50       5 return $tp ** 3 - 2 * $tp * $p11 if $e == 3;
5528 1 50       4 return $tp ** 4 - 3 * $tp**2 * $p11 + $p11**2 if $e == 4;
5529             # Recurse -3
5530 1         4 ($tp**3 - 2*$tp*$p11) * _taupower($p,$e-3) + ($p11*$p11 - $tp*$tp*$p11) * _taupower($p,$e-4);
5531             }
5532              
5533             sub ramanujan_tau {
5534 4     4 0 4999 my $n = shift;
5535 4 50       12 return 0 if $n <= 0;
5536              
5537             # Use GMP if we have no XS or if size is small
5538 4 50 33     18 if ($n < 100000 || !Math::Prime::Util::prime_get_config()->{'xs'}) {
5539 4 50       11 if ($Math::Prime::Util::_GMPfunc{"ramanujan_tau"}) {
5540 0         0 return Math::Prime::Util::_reftyped($_[0], Math::Prime::Util::GMP::ramanujan_tau($n));
5541             }
5542             }
5543              
5544             # _taup is faster for small numbers, but gets very slow. It's not a huge
5545             # deal, and the GMP code will probably get run for small inputs anyway.
5546 4         28 vecprod(map { _taupower($_->[0],$_->[1]) } Math::Prime::Util::factor_exp($n));
  7         4822  
5547             }
5548              
5549             sub _Euler {
5550 79     79   149 my($dig) = @_;
5551             return Math::Prime::Util::GMP::Euler($dig)
5552 79 0 33     170 if $dig > 70 && $Math::Prime::Util::_GMPfunc{"Euler"};
5553 79         498 '0.57721566490153286060651209008240243104215933593992359880576723488486772677766467';
5554             }
5555             sub _Li2 {
5556 1     1   3 my($dig) = @_;
5557             return Math::Prime::Util::GMP::li(2,$dig)
5558 1 0 33     4 if $dig > 70 && $Math::Prime::Util::_GMPfunc{"li"};
5559 1         5 '1.04516378011749278484458888919461313652261557815120157583290914407501320521';
5560             }
5561              
5562             sub ExponentialIntegral {
5563 18     18 0 7685 my($x) = @_;
5564 18 50       68 return - MPU_INFINITY if $x == 0;
5565 18 50       45 return 0 if $x == - MPU_INFINITY;
5566 18 50       45 return MPU_INFINITY if $x == MPU_INFINITY;
5567              
5568 18 50       44 if ($Math::Prime::Util::_GMPfunc{"ei"}) {
5569 0 0 0     0 $x = Math::BigFloat->new("$x") if defined $bignum::VERSION && ref($x) ne 'Math::BigFloat';
5570 0 0       0 return 0.0 + Math::Prime::Util::GMP::ei($x,40) if !ref($x);
5571 0         0 my $str = Math::Prime::Util::GMP::ei($x, _find_big_acc($x));
5572 0         0 return $x->copy->bzero->badd($str);
5573             }
5574              
5575 18 50 33     49 $x = Math::BigFloat->new("$x") if defined $bignum::VERSION && ref($x) ne 'Math::BigFloat';
5576              
5577 18         26 my $tol = 1e-16;
5578 18         23 my $sum = 0.0;
5579 18         31 my($y, $t);
5580 18         25 my $c = 0.0;
5581 18         29 my $val; # The result from one of the four methods
5582              
5583 18 100       108 if ($x < -1) {
    100          
    100          
5584             # Continued fraction
5585 1         3 my $lc = 0;
5586 1         5 my $ld = 1 / (1 - $x);
5587 1         3 $val = $ld * (-exp($x));
5588 1         4 for my $n (1 .. 100000) {
5589 15         28 $lc = 1 / (2*$n + 1 - $x - $n*$n*$lc);
5590 15         29 $ld = 1 / (2*$n + 1 - $x - $n*$n*$ld);
5591 15         19 my $old = $val;
5592 15         21 $val *= $ld/$lc;
5593 15 100       33 last if abs($val - $old) <= ($tol * abs($val));
5594             }
5595             } elsif ($x < 0) {
5596             # Rational Chebyshev approximation
5597 5         12 my @C6p = ( -148151.02102575750838086,
5598             150260.59476436982420737,
5599             89904.972007457256553251,
5600             15924.175980637303639884,
5601             2150.0672908092918123209,
5602             116.69552669734461083368,
5603             5.0196785185439843791020);
5604 5         12 my @C6q = ( 256664.93484897117319268,
5605             184340.70063353677359298,
5606             52440.529172056355429883,
5607             8125.8035174768735759866,
5608             750.43163907103936624165,
5609             40.205465640027706061433,
5610             1.0000000000000000000000);
5611 5         13 my $sumn = $C6p[0]-$x*($C6p[1]-$x*($C6p[2]-$x*($C6p[3]-$x*($C6p[4]-$x*($C6p[5]-$x*$C6p[6])))));
5612 5         11 my $sumd = $C6q[0]-$x*($C6q[1]-$x*($C6q[2]-$x*($C6q[3]-$x*($C6q[4]-$x*($C6q[5]-$x*$C6q[6])))));
5613 5         16 $val = log(-$x) - ($sumn / $sumd);
5614             } elsif ($x < -log($tol)) {
5615             # Convergent series
5616 9         14 my $fact_n = 1;
5617 9         23 $y = _Euler(18)-$c; $t = $sum+$y; $c = ($t-$sum)-$y; $sum = $t;
  9         15  
  9         17  
  9         13  
5618 9         18 $y = log($x)-$c; $t = $sum+$y; $c = ($t-$sum)-$y; $sum = $t;
  9         12  
  9         12  
  9         15  
5619 9         19 for my $n (1 .. 200) {
5620 401         515 $fact_n *= $x/$n;
5621 401         513 my $term = $fact_n / $n;
5622 401         494 $y = $term-$c; $t = $sum+$y; $c = ($t-$sum)-$y; $sum = $t;
  401         501  
  401         539  
  401         475  
5623 401 100       692 last if $term < $tol;
5624             }
5625 9         18 $val = $sum;
5626             } else {
5627             # Asymptotic divergent series
5628 3         8 my $invx = 1.0 / $x;
5629 3         6 my $term = $invx;
5630 3         7 $sum = 1.0 + $term;
5631 3         9 for my $n (2 .. 200) {
5632 81         100 my $last_term = $term;
5633 81         132 $term *= $n * $invx;
5634 81 100       136 last if $term < $tol;
5635 78 50       123 if ($term < $last_term) {
5636 78         96 $y = $term-$c; $t = $sum+$y; $c = ($t-$sum)-$y; $sum = $t;
  78         99  
  78         99  
  78         110  
5637             } else {
5638 0         0 $y = (-$last_term/3)-$c; $t = $sum+$y; $c = ($t-$sum)-$y; $sum = $t;
  0         0  
  0         0  
  0         0  
5639 0         0 last;
5640             }
5641             }
5642 3         22 $val = exp($x) * $invx * $sum;
5643             }
5644 18         158 $val;
5645             }
5646              
5647             sub LogarithmicIntegral {
5648 91     91 0 21859 my($x,$opt) = @_;
5649 91 100       304 return 0 if $x == 0;
5650 90 50       14350 return - MPU_INFINITY if $x == 1;
5651 90 50       11974 return MPU_INFINITY if $x == MPU_INFINITY;
5652 90 50       11363 croak "Invalid input to LogarithmicIntegral: x must be > 0" if $x <= 0;
5653 90 50       13616 $opt = 0 unless defined $opt;
5654              
5655 90 50       293 if ($Math::Prime::Util::_GMPfunc{"li"}) {
5656 0 0 0     0 $x = Math::BigFloat->new("$x") if defined $bignum::VERSION && ref($x) ne 'Math::BigFloat';
5657 0 0       0 return 0.0 + Math::Prime::Util::GMP::li($x,40) if !ref($x);
5658 0         0 my $str = Math::Prime::Util::GMP::li($x, _find_big_acc($x));
5659 0         0 return $x->copy->bzero->badd($str);
5660             }
5661              
5662 90 100       228 if ($x == 2) {
5663 1 50       7 my $li2const = (ref($x) eq 'Math::BigFloat') ? Math::BigFloat->new(_Li2(_find_big_acc($x))) : 0.0+_Li2(30);
5664 1         9 return $li2const;
5665             }
5666              
5667 89 50       11608 if (defined $bignum::VERSION) {
    100          
5668             # If bignum is on, always use Math::BigFloat.
5669 0 0       0 $x = Math::BigFloat->new("$x") if ref($x) ne 'Math::BigFloat';
5670             } elsif (ref($x)) {
5671             # bignum is off, use native if small, BigFloat otherwise.
5672 79 100       239 if ($x <= 1e16) {
5673 60         14395 $x = _bigint_to_int($x);
5674             } else {
5675 19 50       5931 $x = _upgrade_to_float($x) if ref($x) ne 'Math::BigFloat';
5676             }
5677             }
5678             # Make sure we preserve whatever accuracy setting the input was using.
5679 89 100 66     1901 $x->accuracy($_[0]->accuracy) if ref($x) && ref($_[0]) =~ /^Math::Big/ && $_[0]->accuracy;
      100        
5680              
5681             # Do divergent series here for big inputs. Common for big pc approximations.
5682             # Why is this here?
5683             # 1) exp(log(x)) results in a lot of lost precision
5684             # 2) exp(x) with lots of precision turns out to be really slow, and in
5685             # this case it was unnecessary.
5686 89         782 my $tol = 1e-16;
5687 89         161 my $xdigits = 0;
5688 89         149 my $finalacc = 0;
5689 89 100       250 if (ref($x) =~ /^Math::Big/) {
5690 19         80 $xdigits = _find_big_acc($x);
5691 19         64 my $xlen = length($x->copy->bfloor->bstr());
5692 19 100       2553 $xdigits = $xlen if $xdigits < $xlen;
5693 19         64 $finalacc = $xdigits;
5694 19         85 $xdigits += length(int(log(0.0+"$x"))) + 1;
5695 19         1093 $tol = Math::BigFloat->new(10)->bpow(-$xdigits);
5696 19         27375 $x->accuracy($xdigits);
5697             }
5698 89 100       1562 my $logx = $xdigits ? $x->copy->blog(undef,$xdigits) : log($x);
5699              
5700             # TODO: See if we can tune this
5701 89         1741288 if (0 && $x >= 1) {
5702             _upgrade_to_float();
5703             my $sum = Math::BigFloat->new(0);
5704             my $inner_sum = Math::BigFloat->new(0);
5705             my $p = Math::BigFloat->new(-1);
5706             my $factorial = 1;
5707             my $power2 = 1;
5708             my $q;
5709             my $k = 0;
5710             my $neglogx = -$logx;
5711             for my $n (1 .. 1000) {
5712             $factorial = vecprod($factorial, $n);
5713             $q = vecprod($factorial, $power2);
5714             $power2 = vecprod(2, $power2);
5715             while ($k <= ($n-1)>>1) {
5716             $inner_sum += Math::BigFloat->new(1) / (2*$k+1);
5717             $k++;
5718             }
5719             $p *= $neglogx;
5720             my $term = ($p / $q) * $inner_sum;
5721             $sum += $term;
5722             last if abs($term) < $tol;
5723             }
5724             $sum *= sqrt($x);
5725             return 0.0+_Euler(18) + log($logx) + $sum unless ref($x)=~/^Math::Big/;
5726             my $val = Math::BigFloat->new(_Euler(40))->badd("".log($logx))->badd("$sum");
5727             $val->accuracy($finalacc) if $xdigits;
5728             return $val;
5729             }
5730              
5731 89 100       259 if ($x > 1e16) {
5732 19 50       8260 my $invx = ref($logx) ? Math::BigFloat->bone / $logx : 1.0/$logx;
5733             # n = 0 => 0!/(logx)^0 = 1/1 = 1
5734             # n = 1 => 1!/(logx)^1 = 1/logx
5735 19         20542 my $term = $invx;
5736 19         114 my $sum = 1.0 + $term;
5737 19         14619 for my $n (2 .. 1000) {
5738 947         46144 my $last_term = $term;
5739 947         2513 $term *= $n * $invx;
5740 947 50       1080833 last if $term < $tol;
5741 947 100       125697 if ($term < $last_term) {
5742 928         130210 $sum += $term;
5743             } else {
5744 19         4048 $sum -= ($last_term/3);
5745 19         32473 last;
5746             }
5747 928 50       598917 $term->bround($xdigits) if $xdigits;
5748             }
5749 19         97 $invx *= $sum;
5750 19         12196 $invx *= $x;
5751 19 50 33     8847 $invx->accuracy($finalacc) if ref($invx) && $xdigits;
5752 19         6943 return $invx;
5753             }
5754             # Convergent series.
5755 70 50       168 if ($x >= 1) {
5756 70         100 my $fact_n = 1.0;
5757 70         98 my $nfac = 1.0;
5758 70         117 my $sum = 0.0;
5759 70         149 for my $n (1 .. 200) {
5760 2909         3774 $fact_n *= $logx/$n;
5761 2909         3840 my $term = $fact_n / $n;
5762 2909         3519 $sum += $term;
5763 2909 100       4614 last if $term < $tol;
5764 2839 50       4729 $term->bround($xdigits) if $xdigits;
5765             }
5766              
5767 70 50       248 return 0.0+_Euler(18) + log($logx) + $sum unless ref($x) =~ /^Math::Big/;
5768              
5769 0         0 my $val = Math::BigFloat->new(_Euler(40))->badd("".log($logx))->badd("$sum");
5770 0 0       0 $val->accuracy($finalacc) if $xdigits;
5771 0         0 return $val;
5772             }
5773              
5774 0         0 ExponentialIntegral($logx);
5775             }
5776              
5777             # Riemann Zeta function for native integers.
5778             my @_Riemann_Zeta_Table = (
5779             0.6449340668482264364724151666460251892, # zeta(2) - 1
5780             0.2020569031595942853997381615114499908,
5781             0.0823232337111381915160036965411679028,
5782             0.0369277551433699263313654864570341681,
5783             0.0173430619844491397145179297909205279,
5784             0.0083492773819228268397975498497967596,
5785             0.0040773561979443393786852385086524653,
5786             0.0020083928260822144178527692324120605,
5787             0.0009945751278180853371459589003190170,
5788             0.0004941886041194645587022825264699365,
5789             0.0002460865533080482986379980477396710,
5790             0.0001227133475784891467518365263573957,
5791             0.0000612481350587048292585451051353337,
5792             0.0000305882363070204935517285106450626,
5793             0.0000152822594086518717325714876367220,
5794             0.0000076371976378997622736002935630292,
5795             0.0000038172932649998398564616446219397,
5796             0.0000019082127165539389256569577951013,
5797             0.0000009539620338727961131520386834493,
5798             0.0000004769329867878064631167196043730,
5799             0.0000002384505027277329900036481867530,
5800             0.0000001192199259653110730677887188823,
5801             0.0000000596081890512594796124402079358,
5802             0.0000000298035035146522801860637050694,
5803             0.0000000149015548283650412346585066307,
5804             0.0000000074507117898354294919810041706,
5805             0.0000000037253340247884570548192040184,
5806             0.0000000018626597235130490064039099454,
5807             0.0000000009313274324196681828717647350,
5808             0.0000000004656629065033784072989233251,
5809             0.0000000002328311833676505492001455976,
5810             0.0000000001164155017270051977592973835,
5811             0.0000000000582077208790270088924368599,
5812             0.0000000000291038504449709968692942523,
5813             0.0000000000145519218910419842359296322,
5814             0.0000000000072759598350574810145208690,
5815             0.0000000000036379795473786511902372363,
5816             0.0000000000018189896503070659475848321,
5817             0.0000000000009094947840263889282533118,
5818             );
5819              
5820              
5821             sub RiemannZeta {
5822 160     160 0 4940 my($x) = @_;
5823              
5824 160 100       467 my $ix = ($x == int($x)) ? "" . Math::BigInt->new($x) : 0;
5825              
5826             # Try our GMP code if possible.
5827 160 50       10527 if ($Math::Prime::Util::_GMPfunc{"zeta"}) {
5828 0         0 my($wantbf,$xdigits) = _bfdigits($x);
5829             # If we knew the *exact* number of zero digits, we could let GMP zeta
5830             # handle the correct rounding. But we don't, so we have to go over.
5831 0         0 my $zero_dig = "".int($x / 3) - 1;
5832 0         0 my $strval = Math::Prime::Util::GMP::zeta($x, $xdigits + 8 + $zero_dig);
5833 0 0       0 if ($strval =~ s/^(1\.0*)/./) {
5834 0 0       0 $strval .= "e-".(length($1)-2) if length($1) > 2;
5835             } else {
5836 0         0 $strval =~ s/^(\d+)/$1-1/e;
  0         0  
5837             }
5838              
5839 0 0       0 return ($wantbf) ? Math::BigFloat->new($strval,$wantbf) : 0.0 + $strval;
5840             }
5841              
5842             # If we need a bigfloat result, then call our PP routine.
5843 160 100 66     569 if (defined $bignum::VERSION || ref($x) =~ /^Math::Big/) {
5844 4         1379 require Math::Prime::Util::ZetaBigFloat;
5845 4         18 return Math::Prime::Util::ZetaBigFloat::RiemannZeta($x);
5846             }
5847              
5848             # Native float results
5849 156 100 100     505 return 0.0 + $_Riemann_Zeta_Table[int($x)-2]
5850             if $x == int($x) && defined $_Riemann_Zeta_Table[int($x)-2];
5851 148         225 my $tol = 1.11e-16;
5852              
5853             # Series based on (2n)! / B_2n.
5854             # This is a simplification of the Cephes zeta function.
5855 148         329 my @A = (
5856             12.0,
5857             -720.0,
5858             30240.0,
5859             -1209600.0,
5860             47900160.0,
5861             -1892437580.3183791606367583212735166426,
5862             74724249600.0,
5863             -2950130727918.1642244954382084600497650,
5864             116467828143500.67248729113000661089202,
5865             -4597978722407472.6105457273596737891657,
5866             181521054019435467.73425331153534235290,
5867             -7166165256175667011.3346447367083352776,
5868             282908877253042996618.18640556532523927,
5869             );
5870 148         196 my $s = 0.0;
5871 148         201 my $rb = 0.0;
5872 148         247 foreach my $i (2 .. 10) {
5873 533         875 $rb = $i ** -$x;
5874 533         689 $s += $rb;
5875 533 100       1193 return $s if abs($rb/$s) < $tol;
5876             }
5877 4         7 my $w = 10.0;
5878 4         12 $s = $s + $rb*$w/($x-1.0) - 0.5*$rb;
5879 4         8 my $ra = 1.0;
5880 4         9 foreach my $i (0 .. 12) {
5881 29         39 my $k = 2*$i;
5882 29         41 $ra *= $x + $k;
5883 29         35 $rb /= $w;
5884 29         49 my $t = $ra*$rb/$A[$i];
5885 29         37 $s += $t;
5886 29         37 $t = abs($t/$s);
5887 29 100       52 last if $t < $tol;
5888 25         34 $ra *= $x + $k + 1.0;
5889 25         38 $rb /= $w;
5890             }
5891 4         35 return $s;
5892             }
5893              
5894             # Riemann R function
5895             sub RiemannR {
5896 10     10 0 4449 my($x) = @_;
5897              
5898 10 50       39 croak "Invalid input to ReimannR: x must be > 0" if $x <= 0;
5899              
5900             # With MPU::GMP v0.49 this is fast.
5901 10 50       28 if ($Math::Prime::Util::_GMPfunc{"riemannr"}) {
5902 0         0 my($wantbf,$xdigits) = _bfdigits($x);
5903 0         0 my $strval = Math::Prime::Util::GMP::riemannr($x, $xdigits);
5904 0 0       0 return ($wantbf) ? Math::BigFloat->new($strval,$wantbf) : 0.0 + $strval;
5905             }
5906              
5907              
5908             # TODO: look into this as a generic solution
5909 10         16 if (0 && $Math::Prime::Util::_GMPfunc{"zeta"}) {
5910             my($wantbf,$xdigits) = _bfdigits($x);
5911             $x = _upgrade_to_float($x);
5912              
5913             my $extra_acc = 4;
5914             $xdigits += $extra_acc;
5915             $x->accuracy($xdigits);
5916              
5917             my $logx = log($x);
5918             my $part_term = $x->copy->bone;
5919             my $sum = $x->copy->bone;
5920             my $tol = $x->copy->bone->brsft($xdigits-1, 10);
5921             my $bigk = $x->copy->bone;
5922             my $term;
5923             for my $k (1 .. 10000) {
5924             $part_term *= $logx / $bigk;
5925             my $zarg = $bigk->copy->binc;
5926             my $zeta = (RiemannZeta($zarg) * $bigk) + $bigk;
5927             #my $strval = Math::Prime::Util::GMP::zeta($k+1, $xdigits + int(($k+1) / 3));
5928             #my $zeta = Math::BigFloat->new($strval)->bdec->bmul($bigk)->badd($bigk);
5929             $term = $part_term / $zeta;
5930             $sum += $term;
5931             last if $term < ($tol * $sum);
5932             $bigk->binc;
5933             }
5934             $sum->bround($xdigits-$extra_acc);
5935             my $strval = "$sum";
5936             return ($wantbf) ? Math::BigFloat->new($strval,$wantbf) : 0.0 + $strval;
5937             }
5938              
5939 10 50 33     50 if (defined $bignum::VERSION || ref($x) =~ /^Math::Big/) {
5940 0         0 require Math::Prime::Util::ZetaBigFloat;
5941 0         0 return Math::Prime::Util::ZetaBigFloat::RiemannR($x);
5942             }
5943              
5944 10         15 my $sum = 0.0;
5945 10         18 my $tol = 1e-18;
5946 10         21 my($c, $y, $t) = (0.0);
5947 10 100       26 if ($x > 10**17) {
5948 1         63 my @mob = Math::Prime::Util::moebius(0,300);
5949 1         6 for my $k (1 .. 300) {
5950 19 100       38 next if $mob[$k] == 0;
5951 13         70 my $term = $mob[$k] / $k *
5952             Math::Prime::Util::LogarithmicIntegral($x**(1.0/$k));
5953 13         19 $y = $term-$c; $t = $sum+$y; $c = ($t-$sum)-$y; $sum = $t;
  13         21  
  13         19  
  13         18  
5954 13 100       42 last if abs($term) < ($tol * abs($sum));
5955             }
5956             } else {
5957 9         16 $y = 1.0-$c; $t = $sum+$y; $c = ($t-$sum)-$y; $sum = $t;
  9         17  
  9         19  
  9         13  
5958 9         24 my $flogx = log($x);
5959 9         15 my $part_term = 1.0;
5960 9         23 for my $k (1 .. 10000) {
5961 425 100       823 my $zeta = ($k <= $#_Riemann_Zeta_Table)
5962             ? $_Riemann_Zeta_Table[$k+1-2] # Small k from table
5963             : RiemannZeta($k+1); # Large k from function
5964 425         596 $part_term *= $flogx / $k;
5965 425         644 my $term = $part_term / ($k + $k * $zeta);
5966 425         579 $y = $term-$c; $t = $sum+$y; $c = ($t-$sum)-$y; $sum = $t;
  425         508  
  425         552  
  425         555  
5967 425 100       772 last if $term < ($tol * $sum);
5968             }
5969             }
5970 10         89 return $sum;
5971             }
5972              
5973             sub LambertW {
5974 1     1 0 457 my $x = shift;
5975 1 50       6 croak "Invalid input to LambertW: x must be >= -1/e" if $x < -0.36787944118;
5976 1 50       4 $x = _upgrade_to_float($x) if ref($x) eq 'Math::BigInt';
5977 1 50       4 my $xacc = ref($x) ? _find_big_acc($x) : 0;
5978 1         3 my $w;
5979              
5980 1 50       5 if ($Math::Prime::Util::_GMPfunc{"lambertw"}) {
5981 0 0       0 my $w = (!$xacc)
5982             ? 0.0 + Math::Prime::Util::GMP::lambertw($x)
5983             : $x->copy->bzero->badd(Math::Prime::Util::GMP::lambertw($x, $xacc));
5984 0         0 return $w;
5985             }
5986              
5987             # Approximation
5988 1 50       8 if ($x < -0.06) {
    50          
    50          
5989 0         0 my $ti = $x * 2 * exp($x-$x+1) + 2;
5990 0 0       0 return -1 if $ti <= 0;
5991 0         0 my $t = sqrt($ti);
5992 0         0 $w = (-1 + 1/6*$t + (257/720)*$t*$t + (13/720)*$t*$t*$t) / (1 + (5/6)*$t + (103/720)*$t*$t);
5993             } elsif ($x < 1.363) {
5994 0         0 my $l1 = log($x + 1);
5995 0         0 $w = $l1 * (1 - log(1+$l1) / (2+$l1));
5996             } elsif ($x < 3.7) {
5997 0         0 my $l1 = log($x);
5998 0         0 my $l2 = log($l1);
5999 0         0 $w = $l1 - $l2 - log(1 - $l2/$l1)/2.0;
6000             } else {
6001 1         3 my $l1 = log($x);
6002 1         3 my $l2 = log($l1);
6003 1         4 my $d1 = 2 * $l1 * $l1;
6004 1         4 my $d2 = 3 * $l1 * $d1;
6005 1         3 my $d3 = 2 * $l1 * $d2;
6006 1         2 my $d4 = 5 * $l1 * $d3;
6007 1         10 $w = $l1 - $l2 + $l2/$l1 + $l2*($l2-2)/$d1
6008             + $l2*(6+$l2*(-9+2*$l2))/$d2
6009             + $l2*(-12+$l2*(36+$l2*(-22+3*$l2)))/$d3
6010             + $l2*(60+$l2*(-300+$l2*(350+$l2*(-125+12*$l2))))/$d4;
6011             }
6012              
6013             # Now iterate to get the answer
6014             #
6015             # Newton:
6016             # $w = $w*(log($x) - log($w) + 1) / ($w+1);
6017             # Halley:
6018             # my $e = exp($w);
6019             # my $f = $w * $e - $x;
6020             # $w -= $f / ($w*$e+$e - ($w+2)*$f/(2*$w+2));
6021              
6022             # Fritsch converges quadratically, so tolerance could be 4x smaller. Use 2x.
6023 1 50       4 my $tol = ($xacc) ? 10**(-int(1+$xacc/2)) : 1e-16;
6024 1 50       3 $w->accuracy($xacc+10) if $xacc;
6025 1         4 for (1 .. 200) {
6026 200 50       311 last if $w == 0;
6027 200         267 my $w1 = $w + 1;
6028 200         278 my $zn = log($x/$w) - $w;
6029 200         297 my $qn = $w1 * 2 * ($w1+(2*$zn/3));
6030 200         296 my $en = ($zn/$w1) * ($qn-$zn)/($qn-$zn*2);
6031 200         261 my $wen = $w * $en;
6032 200         244 $w += $wen;
6033 200 50       353 last if abs($wen) < $tol;
6034             }
6035 1 50       5 $w->accuracy($xacc) if $xacc;
6036              
6037 1         5 $w;
6038             }
6039              
6040             my $_Pi = "3.141592653589793238462643383279503";
6041             sub Pi {
6042 986     986 0 776882 my $digits = shift;
6043 986 50       2700 return 0.0+$_Pi unless $digits;
6044 986 50       2076 return 0.0+sprintf("%.*lf", $digits-1, $_Pi) if $digits < 15;
6045 986 100       2046 return _upgrade_to_float($_Pi, $digits) if $digits < 30;
6046              
6047             # Performance ranking:
6048             # MPU::GMP Uses AGM or Ramanujan/Chudnosky with binary splitting
6049             # MPFR Uses AGM, from 1x to 1/4x the above
6050             # Perl AGM w/GMP also AGM, nice growth rate, but slower than above
6051             # C pidigits much worse than above, but faster than the others
6052             # Perl AGM without Math::BigInt::GMP, it's sluggish
6053             # Math::BigFloat new versions use AGM, old ones are *very* slow
6054             #
6055             # With a few thousand digits, any of the top 4 are fine.
6056             # At 10k digits, the first two are pulling away.
6057             # At 50k digits, the first three are 5-20x faster than C pidigits, and
6058             # pray you're not having to the Perl BigFloat methods without GMP.
6059             # At 100k digits, the first two are 15x faster than the third, C pidigits
6060             # is 200x slower, and the rest thousands of times slower.
6061             # At 1M digits, the first is under 1 second, MPFR under 2 seconds,
6062             # Perl AGM (Math::BigInt::GMP) is over a minute, and C piigits at 1.5 hours.
6063             #
6064             # Interestingly, Math::BigInt::Pari, while greatly faster than Calc, is
6065             # *much* slower than GMP for these operations (both AGM and Machin). While
6066             # Perl AGM with the Math::BigInt::GMP backend will pull away from C pidigits,
6067             # using it with the other backends doesn't do so.
6068             #
6069             # The GMP program at https://gmplib.org/download/misc/gmp-chudnovsky.c
6070             # will run ~4x faster than MPFR and ~1.5x faster than MPU::GMP.
6071              
6072 972         3575 my $have_bigint_gmp = Math::BigInt->config()->{lib} =~ /GMP/;
6073 972         46154 my $have_xdigits = Math::Prime::Util::prime_get_config()->{'xs'};
6074 972         2829 my $_verbose = Math::Prime::Util::prime_get_config()->{'verbose'};
6075              
6076 972 50       3021 if ($Math::Prime::Util::_GMPfunc{"Pi"}) {
6077 0 0       0 print " using MPUGMP for Pi($digits)\n" if $_verbose;
6078 0         0 return _upgrade_to_float( Math::Prime::Util::GMP::Pi($digits) );
6079             }
6080              
6081             # We could consider looking for Math::MPFR or Math::Pari
6082              
6083             # This has a *much* better growth rate than the later solutions.
6084 972 100 33     3420 if ( !$have_xdigits || ($have_bigint_gmp && $digits > 100) ) {
      66        
6085 1 50       3 print " using Perl AGM for Pi($digits)\n" if $_verbose;
6086             # Brent-Salamin (aka AGM or Gauss-Legendre)
6087 1         2 $digits += 8;
6088 1         13 my $HALF = _upgrade_to_float(0.5);
6089 1         315 my ($an, $bn, $tn, $pn) = ($HALF->copy->bone, $HALF->copy->bsqrt($digits),
6090             $HALF->copy->bmul($HALF), $HALF->copy->bone);
6091 1         7891 while ($pn < $digits) {
6092 7         3788 my $prev_an = $an->copy;
6093 7         221 $an->badd($bn)->bmul($HALF, $digits);
6094 7         5717 $bn->bmul($prev_an)->bsqrt($digits);
6095 7         83726 $prev_an->bsub($an);
6096 7         3114 $tn->bsub($pn * $prev_an * $prev_an);
6097 7         13605 $pn->badd($pn);
6098             }
6099 1         521 $an->badd($bn);
6100 1         399 $an->bmul($an,$digits)->bdiv(4*$tn, $digits-8);
6101 1         2779 return $an;
6102             }
6103              
6104             # Spigot method in C. Low overhead but not good growth rate.
6105 971 50       1908 if ($have_xdigits) {
6106 971 50       1708 print " using XS spigot for Pi($digits)\n" if $_verbose;
6107 971         3595377 return _upgrade_to_float(Math::Prime::Util::_pidigits($digits));
6108             }
6109              
6110             # We're going to have to use the Math::BigFloat code.
6111             # 1) it rounds incorrectly (e.g. 761, 1372, 1509,...).
6112             # Fix by adding some digits and rounding.
6113             # 2) AGM is *much* faster once past ~2000 digits
6114             # 3) It is very slow without the GMP backend. The Pari backend helps
6115             # but it still pretty bad. With Calc it's glacial for large inputs.
6116              
6117             # Math::BigFloat AGM spigot AGM
6118             # Size GMP Pari Calc GMP Pari Calc C C+GMP
6119             # 500 0.04 0.60 0.30 0.08 0.10 0.47 0.09 0.06
6120             # 1000 0.04 0.11 1.82 0.09 0.14 1.82 0.09 0.06
6121             # 2000 0.07 0.37 13.5 0.09 0.34 9.16 0.10 0.06
6122             # 4000 0.14 2.17 107.8 0.12 1.14 39.7 0.20 0.06
6123             # 8000 0.52 15.7 0.22 4.63 186.2 0.56 0.08
6124             # 16000 2.73 121.8 0.52 19.2 2.00 0.08
6125             # 32000 15.4 1.42 7.78 0.12
6126             # ^ ^ ^
6127             # | use this THIRD ---+ |
6128             # use this SECOND ---+ |
6129             # use this FIRST ---+
6130             # approx
6131             # growth 5.6x 7.6x 8.0x 2.7x 4.1x 4.7x 3.9x 2.0x
6132              
6133 0 0       0 print " using BigFloat for Pi($digits)\n" if $_verbose;
6134 0         0 _upgrade_to_float(0);
6135 0         0 return Math::BigFloat::bpi($digits+10)->round($digits);
6136             }
6137              
6138             sub forpart {
6139 1     1 0 1579 my($sub, $n, $rhash) = @_;
6140 1         6 _forcompositions(1, $sub, $n, $rhash);
6141             }
6142             sub forcomp {
6143 0     0 0 0 my($sub, $n, $rhash) = @_;
6144 0         0 _forcompositions(0, $sub, $n, $rhash);
6145             }
6146             sub _forcompositions {
6147 1     1   4 my($ispart, $sub, $n, $rhash) = @_;
6148 1         4 _validate_positive_integer($n);
6149 1         6 my($mina, $maxa, $minn, $maxn, $primeq) = (1,$n,1,$n,-1);
6150 1 50       3 if (defined $rhash) {
6151 0 0       0 croak "forpart second argument must be a hash reference"
6152             unless ref($rhash) eq 'HASH';
6153 0 0       0 if (defined $rhash->{amin}) {
6154 0         0 $mina = $rhash->{amin};
6155 0         0 _validate_positive_integer($mina);
6156             }
6157 0 0       0 if (defined $rhash->{amax}) {
6158 0         0 $maxa = $rhash->{amax};
6159 0         0 _validate_positive_integer($maxa);
6160             }
6161 0 0       0 $minn = $maxn = $rhash->{n} if defined $rhash->{n};
6162 0 0       0 $minn = $rhash->{nmin} if defined $rhash->{nmin};
6163 0 0       0 $maxn = $rhash->{nmax} if defined $rhash->{nmax};
6164 0         0 _validate_positive_integer($minn);
6165 0         0 _validate_positive_integer($maxn);
6166 0 0       0 if (defined $rhash->{prime}) {
6167 0         0 $primeq = $rhash->{prime};
6168 0         0 _validate_positive_integer($primeq);
6169             }
6170 0 0       0 $mina = 1 if $mina < 1;
6171 0 0       0 $maxa = $n if $maxa > $n;
6172 0 0       0 $minn = 1 if $minn < 1;
6173 0 0       0 $maxn = $n if $maxn > $n;
6174 0 0 0     0 $primeq = 2 if $primeq != -1 && $primeq != 0;
6175             }
6176              
6177 1 50 33     5 $sub->() if $n == 0 && $minn <= 1;
6178 1 50 33     14 return if $n < $minn || $minn > $maxn || $mina > $maxa || $maxn <= 0 || $maxa <= 0;
      33        
      33        
      33        
6179              
6180 1         4 my $oldforexit = Math::Prime::Util::_start_for_loop();
6181 1         3 my ($x, $y, $r, $k);
6182 1         14 my @a = (0) x ($n);
6183 1         3 $k = 1;
6184 1         3 $a[0] = $mina - 1;
6185 1         4 $a[1] = $n - $mina + 1;
6186 1         4 while ($k != 0) {
6187 5         24 $x = $a[$k-1]+1;
6188 5         14 $y = $a[$k]-1;
6189 5         9 $k--;
6190 5 50       11 $r = $ispart ? $x : 1;
6191 5         11 while ($r <= $y) {
6192 4         6 $a[$k] = $x;
6193 4         6 $x = $r;
6194 4         5 $y -= $x;
6195 4         9 $k++;
6196             }
6197 5         7 $a[$k] = $x + $y;
6198             # Restrict size
6199 5         11 while ($k+1 > $maxn) {
6200 0         0 $a[$k-1] += $a[$k];
6201 0         0 $k--;
6202             }
6203 5 50       10 next if $k+1 < $minn;
6204             # Restrict values
6205 5 50 33     29 if ($mina > 1 || $maxa < $n) {
6206 0 0       0 last if $a[0] > $maxa;
6207 0 0       0 if ($ispart) {
6208 0 0       0 next if $a[$k] > $maxa;
6209             } else {
6210 0 0   0   0 next if Math::Prime::Util::vecany(sub{ $_ < $mina || $_ > $maxa }, @a[0..$k]);
  0 0       0  
6211             }
6212             }
6213 5 50 33 0   12 next if $primeq == 0 && Math::Prime::Util::vecany(sub{ is_prime($_) }, @a[0..$k]);
  0         0  
6214 5 50 33 0   13 next if $primeq == 2 && Math::Prime::Util::vecany(sub{ !is_prime($_) }, @a[0..$k]);
  0         0  
6215 5 50       14 last if Math::Prime::Util::_get_forexit();
6216 5         17 $sub->(@a[0 .. $k]);
6217             }
6218 1         7 Math::Prime::Util::_end_for_loop($oldforexit);
6219             }
6220             sub forcomb {
6221 1     1 0 609 my($sub, $n, $k) = @_;
6222 1         5 _validate_positive_integer($n);
6223              
6224 1         3 my($begk, $endk);
6225 1 50       13 if (defined $k) {
6226 1         6 _validate_positive_integer($k);
6227 1 50       3 return if $k > $n;
6228 1         4 $begk = $endk = $k;
6229             } else {
6230 0         0 $begk = 0;
6231 0         0 $endk = $n;
6232             }
6233              
6234 1         5 my $oldforexit = Math::Prime::Util::_start_for_loop();
6235 1         4 for my $k ($begk .. $endk) {
6236 1 50       4 if ($k == 0) {
6237 0         0 $sub->();
6238             } else {
6239 1         5 my @c = 0 .. $k-1;
6240 1         2 while (1) {
6241 3         10 $sub->(@c);
6242 3 50       15 last if Math::Prime::Util::_get_forexit();
6243 3 100       18 next if $c[-1]++ < $n-1;
6244 2         7 my $i = $k-2;
6245 2   100     20 $i-- while $i >= 0 && $c[$i] >= $n-($k-$i);
6246 2 100       11 last if $i < 0;
6247 1         3 $c[$i]++;
6248 1         4 while (++$i < $k) { $c[$i] = $c[$i-1] + 1; }
  1         4  
6249             }
6250             }
6251 1 50       14 last if Math::Prime::Util::_get_forexit();
6252             }
6253 1         4 Math::Prime::Util::_end_for_loop($oldforexit);
6254             }
6255             sub _forperm {
6256 1     1   2 my($sub, $n, $all_perm) = @_;
6257 1         3 my $k = $n;
6258 1         3 my @c = reverse 0 .. $k-1;
6259 1         14 my $inc = 0;
6260 1         4 my $send = 1;
6261 1         5 my $oldforexit = Math::Prime::Util::_start_for_loop();
6262 1         3 while (1) {
6263 6 50       15 if (!$all_perm) { # Derangements via simple filtering.
6264 0         0 $send = 1;
6265 0         0 for my $p (0 .. $#c) {
6266 0 0       0 if ($c[$p] == $k-$p-1) {
6267 0         0 $send = 0;
6268 0         0 last;
6269             }
6270             }
6271             }
6272 6 50       11 if ($send) {
6273 6         19 $sub->(reverse @c);
6274 6 50       27 last if Math::Prime::Util::_get_forexit();
6275             }
6276 6 100       20 if (++$inc & 1) {
6277 3         9 @c[0,1] = @c[1,0];
6278 3         5 next;
6279             }
6280 3         4 my $j = 2;
6281 3   100     22 $j++ while $j < $k && $c[$j] > $c[$j-1];
6282 3 100       9 last if $j >= $k;
6283 2         4 my $m = 0;
6284 2         5 $m++ while $c[$j] > $c[$m];
6285 2         5 @c[$j,$m] = @c[$m,$j];
6286 2         18 @c[0..$j-1] = reverse @c[0..$j-1];
6287             }
6288 1         8 Math::Prime::Util::_end_for_loop($oldforexit);
6289             }
6290             sub forperm {
6291 1     1 0 1114 my($sub, $n, $k) = @_;
6292 1         14 _validate_positive_integer($n);
6293 1 50       7 croak "Too many arguments for forperm" if defined $k;
6294 1 50       4 return $sub->() if $n == 0;
6295 1 50       4 return $sub->(0) if $n == 1;
6296 1         6 _forperm($sub, $n, 1);
6297             }
6298             sub forderange {
6299 0     0 0 0 my($sub, $n, $k) = @_;
6300 0         0 _validate_positive_integer($n);
6301 0 0       0 croak "Too many arguments for forderange" if defined $k;
6302 0 0       0 return $sub->() if $n == 0;
6303 0 0       0 return if $n == 1;
6304 0         0 _forperm($sub, $n, 0);
6305             }
6306              
6307             sub _multiset_permutations {
6308 78     78   127 my($sub, $prefix, $ar, $sum) = @_;
6309              
6310 78 100       129 return if $sum == 0;
6311              
6312             # Remove any values with 0 occurances
6313 77         120 my @n = grep { $_->[1] > 0 } @$ar;
  238         454  
6314              
6315 77 50       162 if ($sum == 1) { # A single value
    100          
6316 0         0 $sub->(@$prefix, $n[0]->[0]);
6317             } elsif ($sum == 2) { # Optimize the leaf case
6318 51         73 my($n0,$n1) = map { $_->[0] } @n;
  97         169  
6319 51 100       96 if (@n == 1) {
6320 5         13 $sub->(@$prefix, $n0, $n0);
6321             } else {
6322 46         111 $sub->(@$prefix, $n0, $n1);
6323 46 100       235 $sub->(@$prefix, $n1, $n0) unless Math::Prime::Util::_get_forexit();
6324             }
6325             } elsif (0 && $sum == scalar(@n)) { # All entries have 1 occurance
6326             # TODO: Figure out a way to use this safely. We need to capture any
6327             # lastfor that was seen in the forperm.
6328             my @i = map { $_->[0] } @n;
6329 0     0   0 Math::Prime::Util::forperm(sub { $sub->(@$prefix, @i[@_]) }, 1+$#i);
6330             } else { # Recurse over each leading value
6331 26         46 for my $v (@n) {
6332 73         90 $v->[1]--;
6333 73         113 push @$prefix, $v->[0];
6334 40     40   1149864 no warnings 'recursion';
  40         109  
  40         113802  
6335 73         193 _multiset_permutations($sub, $prefix, \@n, $sum-1);
6336 73         249 pop @$prefix;
6337 73         93 $v->[1]++;
6338 73 100       169 last if Math::Prime::Util::_get_forexit();
6339             }
6340             }
6341             }
6342              
6343             sub numtoperm {
6344 0     0 0 0 my($n,$k) = @_;
6345 0         0 _validate_positive_integer($n);
6346 0         0 _validate_integer($k);
6347 0 0       0 return () if $n == 0;
6348 0 0       0 return (0) if $n == 1;
6349 0         0 my $f = factorial($n-1);
6350 0 0 0     0 $k %= vecprod($f,$n) if $k < 0 || int($k/$f) >= $n;
6351 0         0 my @S = map { $_ } 0 .. $n-1;
  0         0  
6352 0         0 my @V;
6353 0         0 while ($n-- > 0) {
6354 0         0 my $i = int($k/$f);
6355 0         0 push @V, splice(@S,$i,1);
6356 0 0       0 last if $n == 0;
6357 0         0 $k -= $i*$f;
6358 0         0 $f /= $n;
6359             }
6360 0         0 @V;
6361             }
6362              
6363             sub permtonum {
6364 2     2 0 10533 my $A = shift;
6365 2 50       11 croak "permtonum argument must be an array reference"
6366             unless ref($A) eq 'ARRAY';
6367 2         5 my $n = scalar(@$A);
6368 2 100       12 return 0 if $n == 0;
6369             {
6370 1         8 my %S;
  1         2  
6371 1         4 for my $v (@$A) {
6372             croak "permtonum invalid permutation array"
6373 26 50 33     165 if !defined $v || $v < 0 || $v >= $n || $S{$v}++;
      33        
      33        
6374             }
6375             }
6376 1         7 my $f = factorial($n-1);
6377 1         3 my $rank = 0;
6378 1         7 for my $i (0 .. $n-2) {
6379 25         6218 my $k = 0;
6380 25         70 for my $j ($i+1 .. $n-1) {
6381 325 100       587 $k++ if $A->[$j] < $A->[$i];
6382             }
6383 25         152 $rank = Math::Prime::Util::vecsum($rank, Math::Prime::Util::vecprod($k,$f));
6384 25         123 $f /= $n-$i-1;
6385             }
6386 1         222 $rank;
6387             }
6388              
6389             sub randperm {
6390 0     0 0 0 my($n,$k) = @_;
6391 0         0 _validate_positive_integer($n);
6392 0 0       0 if (defined $k) {
6393 0         0 _validate_positive_integer($k);
6394             }
6395 0 0 0     0 $k = $n if !defined($k) || $k > $n;
6396 0 0       0 return () if $k == 0;
6397              
6398 0         0 my @S;
6399 0 0       0 if ("$k"/"$n" <= 0.30) {
6400 0         0 my %seen;
6401             my $v;
6402 0         0 for my $i (1 .. $k) {
6403 0         0 do { $v = Math::Prime::Util::urandomm($n); } while $seen{$v}++;
  0         0  
6404 0         0 push @S,$v;
6405             }
6406             } else {
6407 0         0 @S = map { $_ } 0..$n-1;
  0         0  
6408 0         0 for my $i (0 .. $n-2) {
6409 0 0       0 last if $i >= $k;
6410 0         0 my $j = Math::Prime::Util::urandomm($n-$i);
6411 0         0 @S[$i,$i+$j] = @S[$i+$j,$i];
6412             }
6413 0         0 $#S = $k-1;
6414             }
6415 0         0 return @S;
6416             }
6417              
6418             sub shuffle {
6419 0     0 0 0 my @S=@_;
6420             # Note: almost all the time is spent in urandomm.
6421 0         0 for (my $i = $#S; $i >= 1; $i--) {
6422 0         0 my $j = Math::Prime::Util::urandomm($i+1);
6423 0         0 @S[$i,$j] = @S[$j,$i];
6424             }
6425 0         0 @S;
6426             }
6427              
6428             ###############################################################################
6429             # Random numbers
6430             ###############################################################################
6431              
6432             # PPFE: irand irand64 drand random_bytes csrand srand _is_csprng_well_seeded
6433             sub urandomb {
6434 46     46 0 175 my($n) = @_;
6435 46 50       162 return 0 if $n <= 0;
6436 46 50       139 return ( Math::Prime::Util::irand() >> (32-$n) ) if $n <= 32;
6437 46 50       125 return ( Math::Prime::Util::irand64() >> (64-$n) ) if MPU_MAXBITS >= 64 && $n <= 64;
6438 46         874 my $bytes = Math::Prime::Util::random_bytes(($n+7)>>3);
6439 46         244 my $binary = substr(unpack("B*",$bytes),0,$n);
6440 46         294 return Math::BigInt->new("0b$binary");
6441             }
6442             sub urandomm {
6443 46     46 0 163 my($n) = @_;
6444             # _validate_positive_integer($n);
6445             return Math::Prime::Util::_reftyped($_[0], Math::Prime::Util::GMP::urandomm($n))
6446 46 50       192 if $Math::Prime::Util::_GMPfunc{"urandomm"};
6447 46 50       182 return 0 if $n <= 1;
6448 46         5815 my $r;
6449 46 50       143 if ($n <= 4294967295) {
    50          
6450 0         0 my $rmax = int(4294967295 / $n) * $n;
6451 0         0 do { $r = Math::Prime::Util::irand() } while $r >= $rmax;
  0         0  
6452             } elsif (!ref($n)) {
6453 0         0 my $rmax = int(~0 / $n) * $n;
6454 0         0 do { $r = Math::Prime::Util::irand64() } while $r >= $rmax;
  0         0  
6455             } else {
6456             # TODO: verify and try to optimize this
6457 46         6209 my $bits = length($n->as_bin) - 2;
6458 46         12656 my $bytes = 1 + (($bits+7)>>3);
6459 46         229 my $rmax = Math::BigInt->bone->blsft($bytes*8)->bdec;
6460 46         24614 my $overflow = $rmax - ($rmax % $n);
6461 46         16926 do { $r = Math::Prime::Util::urandomb($bytes*8); } while $r >= $overflow;
  46         3004  
6462             }
6463 46         23013 return $r % $n;
6464             }
6465              
6466             sub random_prime {
6467 2     2 0 133963 my($low, $high) = @_;
6468 2 50       12 if (scalar(@_) == 1) { ($low,$high) = (2,$low); }
  0         0  
6469 2         10 else { _validate_positive_integer($low); }
6470 2         11 _validate_positive_integer($high);
6471              
6472             return Math::Prime::Util::_reftyped($_[0], Math::Prime::Util::GMP::random_prime($low, $high))
6473 2 50       20 if $Math::Prime::Util::_GMPfunc{"random_prime"};
6474              
6475 2         1079 require Math::Prime::Util::RandomPrimes;
6476 2         13 return Math::Prime::Util::RandomPrimes::random_prime($low,$high);
6477             }
6478              
6479             sub random_ndigit_prime {
6480 3     3 0 2719 my($digits) = @_;
6481 3         20 _validate_positive_integer($digits, 1);
6482             return Math::Prime::Util::_reftyped($_[0], Math::Prime::Util::GMP::random_ndigit_prime($digits))
6483 3 50       13 if $Math::Prime::Util::_GMPfunc{"random_ndigit_prime"};
6484 3         957 require Math::Prime::Util::RandomPrimes;
6485 3         18 return Math::Prime::Util::RandomPrimes::random_ndigit_prime($digits);
6486             }
6487             sub random_nbit_prime {
6488 6     6 0 79294 my($bits) = @_;
6489 6         33 _validate_positive_integer($bits, 2);
6490             return Math::Prime::Util::_reftyped($_[0], Math::Prime::Util::GMP::random_nbit_prime($bits))
6491 6 50       29 if $Math::Prime::Util::_GMPfunc{"random_nbit_prime"};
6492 6         53 require Math::Prime::Util::RandomPrimes;
6493 6         36 return Math::Prime::Util::RandomPrimes::random_nbit_prime($bits);
6494             }
6495             sub random_strong_prime {
6496 1     1 0 212 my($bits) = @_;
6497 1         7 _validate_positive_integer($bits, 128);
6498             return Math::Prime::Util::_reftyped($_[0], Math::Prime::Util::GMP::random_strong_prime($bits))
6499 1 50       6 if $Math::Prime::Util::_GMPfunc{"random_strong_prime"};
6500 1         10 require Math::Prime::Util::RandomPrimes;
6501 1         8 return Math::Prime::Util::RandomPrimes::random_strong_prime($bits);
6502             }
6503              
6504             sub random_maurer_prime {
6505 3     3 0 1122 my($bits) = @_;
6506 3         19 _validate_positive_integer($bits, 2);
6507              
6508             return Math::Prime::Util::_reftyped($_[0], Math::Prime::Util::GMP::random_maurer_prime($bits))
6509 3 50       15 if $Math::Prime::Util::_GMPfunc{"random_maurer_prime"};
6510              
6511 3         29 require Math::Prime::Util::RandomPrimes;
6512 3         22 my ($n, $cert) = Math::Prime::Util::RandomPrimes::random_maurer_prime_with_cert($bits);
6513 3 50       24 croak "maurer prime $n failed certificate verification!"
6514             unless Math::Prime::Util::verify_prime($cert);
6515              
6516 3         36 return $n;
6517             }
6518              
6519             sub random_shawe_taylor_prime {
6520 1     1 0 57 my($bits) = @_;
6521 1         7 _validate_positive_integer($bits, 2);
6522              
6523             return Math::Prime::Util::_reftyped($_[0], Math::Prime::Util::GMP::random_shawe_taylor_prime($bits))
6524 1 50       7 if $Math::Prime::Util::_GMPfunc{"random_shawe_taylor_prime"};
6525              
6526 1         11 require Math::Prime::Util::RandomPrimes;
6527 1         7 my ($n, $cert) = Math::Prime::Util::RandomPrimes::random_shawe_taylor_prime_with_cert($bits);
6528 1 50       7 croak "shawe-taylor prime $n failed certificate verification!"
6529             unless Math::Prime::Util::verify_prime($cert);
6530              
6531 1         13 return $n;
6532             }
6533              
6534             sub miller_rabin_random {
6535 2     2 0 579 my($n, $k, $seed) = @_;
6536 2         10 _validate_positive_integer($n);
6537 2 50       11 if (scalar(@_) == 1 ) { $k = 1; } else { _validate_positive_integer($k); }
  0         0  
  2         7  
6538              
6539 2 50       9 return 1 if $k <= 0;
6540              
6541 2 50       11 if ($Math::Prime::Util::_GMPfunc{"miller_rabin_random"}) {
6542 0 0       0 return Math::Prime::Util::GMP::miller_rabin_random($n, $k, $seed) if defined $seed;
6543 0         0 return Math::Prime::Util::GMP::miller_rabin_random($n, $k);
6544             }
6545              
6546             # Math::Prime::Util::prime_get_config()->{'assume_rh'}) ==> 2*log(n)^2
6547 2 50       9 if ($k >= int(3*$n/4) ) {
6548 0         0 for (2 .. int(3*$n/4)+2) {
6549 0 0       0 return 0 unless Math::Prime::Util::is_strong_pseudoprime($n, $_);
6550             }
6551 0         0 return 1;
6552             }
6553 2         1344 my $brange = $n-2;
6554 2 100       457 return 0 unless Math::Prime::Util::is_strong_pseudoprime($n, Math::Prime::Util::urandomm($brange)+2 );
6555 1         4 $k--;
6556 1         7 while ($k > 0) {
6557 1 50       6 my $nbases = ($k >= 20) ? 20 : $k;
6558 1 50       5 return 0 unless is_strong_pseudoprime($n, map { urandomm($brange)+2 } 1 .. $nbases);
  19         6935  
6559 1         31 $k -= $nbases;
6560             }
6561 1         18 1;
6562             }
6563              
6564             sub random_semiprime {
6565 1     1 0 5027 my($b) = @_;
6566 1 50 33     12 return 0 if defined $b && int($b) < 0;
6567 1         7 _validate_positive_integer($b,4);
6568              
6569 1         2 my $n;
6570 1 50       7 my $min = ($b <= MPU_MAXBITS) ? (1 << ($b-1)) : BTWO->copy->bpow($b-1);
6571 1         501 my $max = $min + ($min - 1);
6572 1         313 my $L = $b >> 1;
6573 1         4 my $N = $b - $L;
6574 1 50       5 my $one = ($b <= MPU_MAXBITS) ? 1 : BONE;
6575 1   33     3 do {
6576 1         5 $n = $one * random_nbit_prime($L) * random_nbit_prime($N);
6577             } while $n < $min || $n > $max;
6578 1 50 33     329 $n = _bigint_to_int($n) if ref($n) && $n->bacmp(BMAX) <= 0;
6579 1         33 $n;
6580             }
6581              
6582             sub random_unrestricted_semiprime {
6583 1     1 0 453 my($b) = @_;
6584 1 50 33     10 return 0 if defined $b && int($b) < 0;
6585 1         6 _validate_positive_integer($b,3);
6586              
6587 1         2 my $n;
6588 1 50       7 my $min = ($b <= MPU_MAXBITS) ? (1 << ($b-1)) : BTWO->copy->bpow($b-1);
6589 1         480 my $max = $min + ($min - 1);
6590              
6591 1 50       301 if ($b <= 64) {
6592 0         0 do {
6593 0         0 $n = $min + urandomb($b-1);
6594             } while !Math::Prime::Util::is_semiprime($n);
6595             } else {
6596             # Try to get probabilities right for small divisors
6597 1         39 my %M = (
6598             2 => 1.91218397452243,
6599             3 => 1.33954826555021,
6600             5 => 0.854756717114822,
6601             7 => 0.635492301836862,
6602             11 => 0.426616792046787,
6603             13 => 0.368193843118344,
6604             17 => 0.290512701603111,
6605             19 => 0.263359264658156,
6606             23 => 0.222406328935102,
6607             29 => 0.181229250520242,
6608             31 => 0.170874199059434,
6609             37 => 0.146112155735473,
6610             41 => 0.133427839963585,
6611             43 => 0.127929010905662,
6612             47 => 0.118254609086782,
6613             53 => 0.106316418106489,
6614             59 => 0.0966989675438643,
6615             61 => 0.0938833658008547,
6616             67 => 0.0864151823151671,
6617             71 => 0.0820822953188297,
6618             73 => 0.0800964416340746,
6619             79 => 0.0747060914833344,
6620             83 => 0.0714973706654851,
6621             89 => 0.0672115468436284,
6622             97 => 0.0622818892486191,
6623             101 => 0.0600855891549939,
6624             103 => 0.0590613570015407,
6625             107 => 0.0570921135626976,
6626             109 => 0.0561691667641485,
6627             113 => 0.0544330141081874,
6628             127 => 0.0490620204315701,
6629             );
6630 1         3 my ($p,$r);
6631 1         120 $r = Math::Prime::Util::drand();
6632 1         7 for my $prime (2..127) {
6633 126 100       222 next unless defined $M{$prime};
6634 31         53 my $PR = $M{$prime} / $b + 0.19556 / $prime;
6635 31 50       57 if ($r <= $PR) {
6636 0         0 $p = $prime;
6637 0         0 last;
6638             }
6639 31         111 $r -= $PR;
6640             }
6641 1 50       4 if (!defined $p) {
6642             # Idea from Charles Greathouse IV, 2010. The distribution is right
6643             # at the high level (small primes weighted more and not far off what
6644             # we get with the uniform selection), but there is a noticeable skew
6645             # toward primes with a large gap after them. For instance 3 ends up
6646             # being weighted as much as 2, and 7 more than 5.
6647             #
6648             # Since we handled small divisors earlier, this is less bothersome.
6649 1         3 my $M = 0.26149721284764278375542683860869585905;
6650 1         8 my $weight = $M + log($b * log(2)/2);
6651 1         2 my $minr = log(log(131));
6652 1         2 do {
6653 2         8 $r = Math::Prime::Util::drand($weight) - $M;
6654             } while $r < $minr;
6655             # Using Math::BigFloat::bexp is ungodly slow, so avoid at all costs.
6656 1         11 my $re = exp($r);
6657 1 50       7 my $a = ($re < log(~0)) ? int(exp($re)+0.5)
6658             : _upgrade_to_float($re)->bexp->bround->as_int;
6659 1 50       16 $p = $a < 2 ? 2 : Math::Prime::Util::prev_prime($a+1);
6660             }
6661 1 50       11 my $ranmin = ref($min) ? $min->badd($p-1)->bdiv($p)->as_int : int(($min+$p-1)/$p);
6662 1 50       588 my $ranmax = ref($max) ? $max->bdiv($p)->as_int : int($max/$p);
6663 1         384 my $q = random_prime($ranmin, $ranmax);
6664 1         85 $n = Math::Prime::Util::vecprod($p,$q);
6665             }
6666 1 50 33     8 $n = _bigint_to_int($n) if ref($n) && $n->bacmp(BMAX) <= 0;
6667 1         26 $n;
6668             }
6669              
6670             sub random_factored_integer {
6671 0     0 0   my($n) = @_;
6672 0 0 0       return (0,[]) if defined $n && int($n) < 0;
6673 0           _validate_positive_integer($n,1);
6674              
6675 0           while (1) {
6676 0           my @S = ($n);
6677             # make s_i chain
6678 0           push @S, 1 + Math::Prime::Util::urandomm($S[-1]) while $S[-1] > 1;
6679             # first is n, last is 1
6680 0           @S = grep { is_prime($_) } @S[1 .. $#S-1];
  0            
6681 0           my $r = Math::Prime::Util::vecprod(@S);
6682 0 0 0       return ($r, [@S]) if $r <= $n && (1+urandomm($n)) <= $r;
6683             }
6684             }
6685              
6686              
6687              
6688             1;
6689              
6690             __END__