ruby-numtheory 0.0.3-x86-linux → 0.0.4-x86-linux

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. data/ext/numtheory/numtheory.c +1726 -0
  2. data/lib/numtheory.so +0 -0
  3. metadata +6 -5
@@ -0,0 +1,1726 @@
1
+ #include <ruby.h>
2
+ #include <stdio.h>
3
+ #include <math.h>
4
+
5
+ #include "primes.h"
6
+ #include "queue.h"
7
+ #include "numtheory_macros.c"
8
+ #include "constants.h"
9
+
10
+ static VALUE numtheory_powermod(int argc, VALUE *argv);
11
+ static VALUE numtheory_int_powermod(VALUE b, VALUE p, VALUE m);
12
+ static VALUE numtheory_miller_rabin_pseudoprime_p(VALUE n);
13
+ static VALUE numtheory_nextprime(VALUE n);
14
+ static VALUE numtheory_precompute_primes_upto(VALUE obj, VALUE n);
15
+ static VALUE numtheory_prime(VALUE obj, VALUE i);
16
+ static VALUE numtheory_prime_p(VALUE n);
17
+ static VALUE numtheory_primepi(VALUE obj, VALUE n);
18
+ static VALUE numtheory_fibonacci(int argc, VALUE *argv);
19
+ static VALUE numtheory_sigma(int argc, VALUE *argv);
20
+ static VALUE numtheory_eulerphi(VALUE obj, VALUE n);
21
+ static VALUE numtheory_moebius(VALUE obj, VALUE n);
22
+ static VALUE numtheory_prime_division(VALUE n);
23
+ static VALUE numtheory_product(VALUE obj, VALUE arr);
24
+ static VALUE numtheory_primes_upto(VALUE min, VALUE max);
25
+ static VALUE numtheory_factorial_primeswing(VALUE n);
26
+ static VALUE numtheory_extended_gcd(VALUE x, VALUE y);
27
+ static VALUE numtheory_modular_inverse(VALUE x, VALUE y);
28
+ static VALUE numtheory_multiplicative_order(VALUE a, VALUE m);
29
+ static VALUE numtheory_pythagorean_triples(VALUE obj, VALUE max_l);
30
+ static VALUE numtheory_popcount(VALUE n);
31
+ static VALUE numtheory_bitlength(VALUE n);
32
+ static VALUE numtheory_jacobi(VALUE a, VALUE n);
33
+ static VALUE numtheory_sqrtmod(VALUE a, VALUE p);
34
+ static VALUE numtheory_isqrt(VALUE n);
35
+ static VALUE numtheory_perfect_square_p(VALUE n);
36
+ static VALUE numtheory_bpsw_pseudoprime_p(VALUE n);
37
+
38
+ static VALUE mNumTheory;
39
+ static ID primality_tests_ID;
40
+
41
+ static ID id_rand, id_mod, id_divmod,
42
+ id_gcd, id_lcm, id_pow, id_mul;
43
+
44
+ static unsigned long PRIMES_UPPER_LIMIT = 3141592;
45
+ static unsigned long NUM_OF_PRIMES;
46
+
47
+ static const VALUE zero = INT2FIX(0);
48
+ static const VALUE one = INT2FIX(1);
49
+ static const VALUE two = INT2FIX(2);
50
+ static const VALUE three = INT2FIX(3);
51
+ static const VALUE four = INT2FIX(4);
52
+ static const VALUE five = INT2FIX(5);
53
+ static const VALUE six = INT2FIX(6);
54
+ static const VALUE seven = INT2FIX(7);
55
+ static const VALUE eight = INT2FIX(8);
56
+
57
+ /*
58
+ * The <code>NumTheory</code> module contains basic number-theoretical
59
+ * functions.
60
+ */
61
+
62
+ void
63
+ Init_numtheory()
64
+ {
65
+ #if 0
66
+ VALUE rb_cInteger = rb_define_class("Integer", rb_cObject);
67
+ VALUE rb_cFixnum = rb_define_class("Fixnum", rb_cObject);
68
+ #endif
69
+ VALUE rb_mNumTheory = rb_define_module("NumTheory");
70
+ mNumTheory = rb_mNumTheory;
71
+
72
+ id_rand = rb_intern("rand");
73
+ id_mod = rb_intern("modulo");
74
+ id_divmod = rb_intern("divmod");
75
+ id_gcd = rb_intern("gcd");
76
+ id_lcm = rb_intern("lcm");
77
+ id_pow = rb_intern("**");
78
+ id_mul = rb_intern("*");
79
+
80
+ primality_tests_ID = rb_intern("PrimalityTests");
81
+ /* PrimalityTests: the number of rounds in Miller-Rabin test for primality. */
82
+ rb_define_const(rb_mNumTheory, "PrimalityTests", INT2FIX(20));
83
+
84
+ rb_define_module_function(rb_mNumTheory, "powermod",
85
+ numtheory_powermod, -1);
86
+ rb_define_module_function(rb_mNumTheory, "fibonacci",
87
+ numtheory_fibonacci, -1);
88
+ rb_define_module_function(rb_mNumTheory, "precompute_primes_upto",
89
+ numtheory_precompute_primes_upto, 1);
90
+ rb_define_module_function(rb_mNumTheory, "prime",
91
+ numtheory_prime, 1);
92
+ rb_define_module_function(rb_mNumTheory, "primepi",
93
+ numtheory_primepi, 1);
94
+ rb_define_module_function(rb_mNumTheory, "sigma",
95
+ numtheory_sigma, -1);
96
+ rb_define_module_function(rb_mNumTheory, "eulerphi",
97
+ numtheory_eulerphi, 1);
98
+ rb_define_module_function(rb_mNumTheory, "moebius",
99
+ numtheory_moebius, 1);
100
+ rb_define_module_function(rb_mNumTheory, "product",
101
+ numtheory_product, 1);
102
+
103
+ rb_define_module_function(rb_mNumTheory, "triples",
104
+ numtheory_pythagorean_triples, 1);
105
+
106
+ rb_define_method(rb_cInteger, "powermod",
107
+ numtheory_int_powermod, 2);
108
+ rb_define_method(rb_cInteger, "prime?",
109
+ numtheory_prime_p, 0);
110
+ rb_define_method(rb_cInteger, "MR_pseudoprime?",
111
+ numtheory_miller_rabin_pseudoprime_p, 0);
112
+ rb_define_method(rb_cInteger, "BPSW_pseudoprime?",
113
+ numtheory_bpsw_pseudoprime_p, 0);
114
+ rb_define_method(rb_cInteger, "nextprime",
115
+ numtheory_nextprime, 0);
116
+ rb_define_method(rb_cInteger, "prime_division",
117
+ numtheory_prime_division, 0);
118
+ rb_define_method(rb_cFixnum, "factorial",
119
+ numtheory_factorial_primeswing, 0);
120
+ rb_define_method(rb_cInteger, "primes_upto",
121
+ numtheory_primes_upto, 1);
122
+ rb_define_method(rb_cInteger, "extended_gcd",
123
+ numtheory_extended_gcd, 1);
124
+ rb_define_method(rb_cInteger, "inverse",
125
+ numtheory_modular_inverse, 1);
126
+ rb_define_method(rb_cInteger, "znorder",
127
+ numtheory_multiplicative_order, 1);
128
+ rb_define_method(rb_cInteger, "popcount",
129
+ numtheory_popcount, 0);
130
+ rb_define_method(rb_cInteger, "bitlength",
131
+ numtheory_bitlength, 0);
132
+ rb_define_method(rb_cInteger, "jacobi",
133
+ numtheory_jacobi, 1);
134
+ rb_define_method(rb_cInteger, "sqrt_mod",
135
+ numtheory_sqrtmod, 1);
136
+ rb_define_method(rb_cInteger, "isqrt",
137
+ numtheory_isqrt, 0);
138
+ rb_define_method(rb_cInteger, "square?",
139
+ numtheory_perfect_square_p, 0);
140
+
141
+ NUM_OF_PRIMES = init_sieve(PRIMES_UPPER_LIMIT);
142
+ /* PRECOMPUTED_PRIMES: the number of precomputed primes. */
143
+ rb_define_const(rb_mNumTheory, "PRECOMPUTED_PRIMES",
144
+ INT2NUM(NUM_OF_PRIMES));
145
+
146
+ }
147
+
148
+ /*
149
+ * call-seq:
150
+ * NumTheory.precompute_primes_upto(n)
151
+ *
152
+ * Precomputes primes up to the <i>n</i> via Eratosthenes' sieve method.
153
+ *
154
+ * NumTheory.precompute_primes_upto(20000000)
155
+ */
156
+ static VALUE
157
+ numtheory_precompute_primes_upto(VALUE obj, VALUE n)
158
+ {
159
+ if (FIXNUM_P(n))
160
+ {
161
+ unsigned long t = FIX2LONG(n);
162
+ if (t < PRIMES_UPPER_LIMIT || FIX2LONG(n) < 0)
163
+ {
164
+ rb_warn("new size should be more than old one; prime table is unchanged");
165
+ return Qnil;
166
+ }
167
+ PRIMES_UPPER_LIMIT = FIX2LONG(n);
168
+
169
+ free(numtheory_is_prime);
170
+ free(numtheory_primes);
171
+
172
+ NUM_OF_PRIMES = init_sieve(PRIMES_UPPER_LIMIT);
173
+ rb_const_set(mNumTheory, rb_intern("PRECOMPUTED_PRIMES"),
174
+ INT2NUM(NUM_OF_PRIMES));
175
+ }
176
+ else
177
+ {
178
+ rb_raise(rb_eArgError, "The number is too big!");
179
+ }
180
+ return Qnil;
181
+ }
182
+
183
+
184
+ inline static VALUE TO_BIGNUM(VALUE x) {
185
+ return FIXNUM_P(x) ? rb_int2big(FIX2LONG(x)) : x;
186
+ }
187
+
188
+ inline static unsigned long TO_ULONG(VALUE x) {
189
+ if (!FIXNUM_P(x))
190
+ {
191
+ if (rb_big_cmp(x, ULONG2NUM(ULONG_MAX)) != one)
192
+ return rb_big2ulong(x);
193
+ else
194
+ rb_raise(rb_eNotImpError, "Not implemented for numbers >= 2**32");
195
+ }
196
+ return FIX2ULONG(x);
197
+ }
198
+
199
+ inline static int EVEN_P(VALUE x) {
200
+ return FIXNUM_P(x) ? !(FIX2ULONG(x)&1) : !(RBIGNUM_DIGITS(x)[0]&1);
201
+ }
202
+
203
+ inline static int ZERO_P(VALUE x) {
204
+ return FIXNUM_P(x) ? FIX2LONG(x) == 0 : rb_bigzero_p(x);
205
+ }
206
+
207
+ inline static VALUE ADD(VALUE x, VALUE y) {
208
+ return FIXNUM_P(x) ? FIXNUM_P(y) ?
209
+ LONG2NUM(FIX2LONG(x) + FIX2LONG(y)) :
210
+ rb_big_plus(y, x) :
211
+ rb_big_plus(x, y);
212
+ }
213
+
214
+ inline static VALUE SUB(VALUE x, VALUE y) {
215
+ return (FIXNUM_P(x) && FIXNUM_P(y)) ?
216
+ LONG2NUM(FIX2LONG(x) - FIX2LONG(y)) :
217
+ rb_big_minus(TO_BIGNUM(x), y);
218
+ }
219
+
220
+ inline static VALUE MUL(VALUE x, VALUE y) {
221
+ return rb_funcall(x, id_mul, 1, y);
222
+ }
223
+
224
+ inline static VALUE POW(VALUE b, VALUE p) {
225
+ return rb_funcall(b, id_pow, 1, p);
226
+ }
227
+
228
+ inline static VALUE DIV(VALUE x, VALUE y) {
229
+ if (ZERO_P(y))
230
+ {
231
+ rb_raise(rb_eZeroDivError, "divided by 0");
232
+ }
233
+ return FIXNUM_P(x) ? FIXNUM_P(y) ?
234
+ INT2FIX( FIX2LONG(x) / FIX2LONG(y)) :
235
+ zero :
236
+ rb_big_div(x, y);
237
+ }
238
+
239
+ inline static VALUE DIVMOD(VALUE x, VALUE y) {
240
+ return rb_funcall(x, id_divmod, 1, y);
241
+ }
242
+
243
+ inline static VALUE MOD(VALUE x, VALUE y) {
244
+ return rb_funcall(x, id_mod, 1, y);
245
+ }
246
+
247
+ inline static int EQL(VALUE x, VALUE y) {
248
+ return (FIXNUM_P(x) && FIXNUM_P(y)) ?
249
+ x == y :
250
+ rb_big_eq(TO_BIGNUM(x), y) == Qtrue;
251
+ }
252
+
253
+ inline static int MORE(VALUE x, VALUE y) {
254
+ return (FIXNUM_P(x) && FIXNUM_P(y)) ?
255
+ FIX2LONG(x) > FIX2LONG(y) :
256
+ rb_big_cmp(TO_BIGNUM(x), y) == one;
257
+ }
258
+
259
+ inline static int LESS(VALUE x, VALUE y) {
260
+ return (FIXNUM_P(x) && FIXNUM_P(y)) ?
261
+ FIX2LONG(x) < FIX2LONG(y) :
262
+ rb_big_cmp(TO_BIGNUM(x), y) == INT2FIX(-1);
263
+ }
264
+
265
+ inline static int MORE_EQL(VALUE x, VALUE y) {
266
+ return (FIXNUM_P(x) && FIXNUM_P(y)) ?
267
+ FIX2LONG(x) >= FIX2LONG(y) :
268
+ rb_big_cmp(TO_BIGNUM(x), y) != INT2FIX(-1);
269
+ }
270
+
271
+ inline static VALUE ABS(VALUE x) {
272
+ if (FIXNUM_P(x))
273
+ return INT2FIX(abs(FIX2LONG(x)));
274
+ VALUE v = rb_big_clone(x);
275
+ RBIGNUM_SET_SIGN(v, 1);
276
+ return v;
277
+ }
278
+
279
+ inline static int NEGATIVE_P(VALUE x) {
280
+ return FIXNUM_P(x) ? FIX2LONG(x) < 0 : RBIGNUM_NEGATIVE_P(x);
281
+ }
282
+
283
+ inline static VALUE CLONE(VALUE x) {
284
+ return FIXNUM_P(x) ? x : rb_big_clone(x);
285
+ }
286
+
287
+ inline static int INTEGER_P(VALUE x) {
288
+ return (TYPE(x) == T_FIXNUM) || (TYPE(x) == T_BIGNUM);
289
+ }
290
+
291
+ inline static VALUE DOUBLED(VALUE x) {
292
+ return FIXNUM_P(x) ? LONG2NUM(FIX2LONG(x) << 1) :
293
+ rb_big_lshift(x, one);
294
+ }
295
+
296
+ inline static VALUE HALF(VALUE x) {
297
+ return FIXNUM_P(x) ? INT2FIX(FIX2LONG(x) >> 1) :
298
+ rb_big_rshift(x, one);
299
+ }
300
+
301
+ inline static VALUE RIGHT_SHIFT(VALUE x, int s) {
302
+ return FIXNUM_P(x) ? INT2FIX(FIX2LONG(x) >> s) :
303
+ rb_big_rshift(x, INT2FIX(s));
304
+ }
305
+
306
+ #ifdef min
307
+ #undef min
308
+ #endif
309
+ inline static int min(int a, int b) { return a < b ? a : b; }
310
+
311
+ /*
312
+ * call-seq:
313
+ * NumTheory.powermod(base, power, [modulo, one]) -> obj
314
+ *
315
+ * Returns (<code>base ** power) % modulo</code> if modulo is not nil.
316
+ * Otherwise returns <code>base ** power</code>. Parameter <i>one</i>
317
+ * can be used to provide the identity of the multiplicative group containing
318
+ * <i>base</i>.
319
+ *
320
+ * NumTheory.powermod(2, 20) #=> 1048576
321
+ * NumTheory.powermod(2, 20, 1000) #=> 576
322
+ *
323
+ * require 'matrix'
324
+ * NumTheory.powermod(Matrix[[1,1],[1,0]], 20, nil,
325
+ * Matrix.identity(2))
326
+ * #=> Matrix[[10946, 6765], [6765, 4181]]
327
+ */
328
+ static VALUE
329
+ numtheory_powermod(int argc, VALUE *argv)
330
+ {
331
+ VALUE base, pow, modulo, one;
332
+ rb_scan_args(argc, argv, "22", &base, &pow, &modulo, &one);
333
+
334
+ ID id_mul = rb_intern("*");
335
+ ID id_mod = rb_intern("%");
336
+
337
+ VALUE result = NIL_P(one) ? rb_uint2big(1) : one;
338
+ FOR_BITS(pow, result = rb_funcall(result, id_mul, 1, result),
339
+ {},
340
+ result = rb_funcall(result, id_mul, 1, base),
341
+ if (!NIL_P(modulo))
342
+ {
343
+ result = rb_funcall(result, id_mod, 1, modulo);
344
+ });
345
+ return result;
346
+ }
347
+
348
+ /*
349
+ * call-seq:
350
+ * integer.powermod(power, modulo) -> integer
351
+ *
352
+ * Returns (+self+ ** <i>power</i>) % <i>modulo</i>.
353
+ * Both <i>power</i> and <i>modulo</i> must be integer.
354
+ *
355
+ * 172.powermod(238, 239) #=> 1
356
+ */
357
+ static VALUE
358
+ numtheory_int_powermod(VALUE b, VALUE p, VALUE m){
359
+ VALUE result = one;
360
+ if (!INTEGER_P(p))
361
+ {
362
+ rb_raise(rb_eArgError, "power must be integer");
363
+ }
364
+ if (!INTEGER_P(m))
365
+ {
366
+ rb_raise(rb_eTypeError, "modulo must be integer");
367
+ }
368
+ if (NEGATIVE_P(p))
369
+ {
370
+ b = numtheory_modular_inverse(b, m);
371
+ p = ABS(p);
372
+ }
373
+ FOR_BITS(p, result = MUL(result, result),
374
+ {},
375
+ result = MUL(result, b),
376
+ result = MOD(result, m));
377
+ return result;
378
+ }
379
+
380
+ static int tail_zeros(VALUE n)
381
+ {
382
+ if (FIXNUM_P(n))
383
+ {
384
+ int t = FIX2LONG(n);
385
+ int s = 0;
386
+ while (!(t & 1))
387
+ t >>= 1, ++s;
388
+ return s;
389
+ }
390
+ else
391
+ {
392
+ BDIGIT* digit = RBIGNUM_DIGITS(n);
393
+ unsigned int L = RBIGNUM_LEN(n);
394
+ unsigned int i, j, s, z;
395
+ const unsigned long MAX = 1 << (SIZEOF_BDIGITS * 8 - 1);
396
+ for (i = s = 0, z = 1; i < L; ++i, ++digit)
397
+ {
398
+ for (j = 1; j <= MAX; j <<= 1)
399
+ if ((*digit & j) || j == MAX)
400
+ {
401
+ z = 0;
402
+ break;
403
+ }
404
+ else
405
+ {
406
+ ++s;
407
+ }
408
+ if (z == 0) break;
409
+ }
410
+ return s;
411
+ }
412
+ }
413
+
414
+ /*
415
+ * call-seq:
416
+ * integer.MR_pseudoprime? -> true or false
417
+ *
418
+ * Returns <code>true</code> if +self+ is pseudoprime
419
+ * accordingly to Miller-Rabin test with <i>NumTheory::PrimalityTests</i>
420
+ * rounds. Otherwise returns <code>false</code>.
421
+ */
422
+ static VALUE
423
+ numtheory_miller_rabin_pseudoprime_p(VALUE n)
424
+ {
425
+ long PRIMALITY_TESTS = FIX2LONG(rb_const_get(mNumTheory, primality_tests_ID));
426
+
427
+ if (FIXNUM_P(n))
428
+ {
429
+ long t = FIX2LONG(n);
430
+ if (t < 0) t = -t;
431
+ if (t == 2) return Qtrue;
432
+ if (!(t & 1)) return Qfalse;
433
+ if (t < 2) return Qfalse;
434
+ }
435
+
436
+ VALUE num;
437
+ if (NEGATIVE_P(n))
438
+ {
439
+ num = ABS(n);
440
+ }
441
+ else
442
+ {
443
+ num = n; // keeps just a reference instead of clone
444
+ }
445
+
446
+ if (EVEN_P(num))
447
+ {
448
+ return Qfalse;
449
+ }
450
+
451
+ VALUE num_minus_one = SUB(num, one);
452
+ VALUE d = CLONE(num_minus_one);
453
+ VALUE num_minus_four = SUB(num, four);
454
+
455
+ int s = tail_zeros(d);
456
+ d = RIGHT_SHIFT(d, s);
457
+
458
+ int i,j;
459
+ for (i = 0; i < PRIMALITY_TESTS; ++i)
460
+ {
461
+
462
+ VALUE a = rb_funcall(rb_cRandom,
463
+ id_rand,
464
+ 1,
465
+ num_minus_four);
466
+ a = ADD(a, two);
467
+
468
+ VALUE x = numtheory_int_powermod(a, d, num);
469
+ if (EQL(x, one) ||
470
+ EQL(x, num_minus_one))
471
+ {
472
+ continue;
473
+ }
474
+ for(j = 0; j < s; ++j)
475
+ {
476
+ x = MOD(MUL(x, x), num);
477
+ if (EQL(x, one))
478
+ {
479
+ return Qfalse;
480
+ }
481
+ if (EQL(x, num_minus_one))
482
+ {
483
+ break;
484
+ }
485
+ }
486
+ if (!EQL(x, num_minus_one))
487
+ {
488
+ return Qfalse;
489
+ }
490
+ }
491
+ return Qtrue;
492
+ }
493
+
494
+ inline static int
495
+ prime_p(unsigned long t)
496
+ {
497
+ return (t & 1) ? t == 3 ? 1 :
498
+ ((t % 6 == 1) || (t % 6 == 5)) ?
499
+ t < PRIMES_UPPER_LIMIT ?
500
+ is_set(numtheory_is_prime, t) ? 1 : 0 :
501
+ numtheory_bpsw_pseudoprime_p(ULL2NUM(t)) :
502
+ 0
503
+ : t == 2 ? 1 : 0;
504
+ }
505
+
506
+ /*
507
+ * call-seq:
508
+ * integer.prime? -> true or false
509
+ *
510
+ * Returns exact result for values which are precomputed, and result
511
+ * of standard Baillie-Pomerance-Selfridge-Wagstaff test for larger values.
512
+ *
513
+ * 29.prime? #=> true
514
+ */
515
+ static VALUE
516
+ numtheory_prime_p(VALUE n)
517
+ {
518
+ unsigned long t;
519
+ if (FIXNUM_P(n) && (t = abs(FIX2LONG(n)), t < PRIMES_UPPER_LIMIT))
520
+ {
521
+ return prime_p(t) ? Qtrue : Qfalse;
522
+ }
523
+ else
524
+ {
525
+ return numtheory_bpsw_pseudoprime_p(n);
526
+ }
527
+ }
528
+
529
+ /*
530
+ * call-seq:
531
+ * integer.nextprime -> integer
532
+ *
533
+ * Returns the least (pseudo)prime > +self+.
534
+ *
535
+ * (10**28).nextprime #=> 10000000000000000000000000331
536
+ */
537
+ static VALUE
538
+ numtheory_nextprime(VALUE n)
539
+ {
540
+ VALUE p = n;
541
+ for(;;)
542
+ {
543
+ p = ADD(p, one);
544
+ if (numtheory_prime_p(p))
545
+ return p;
546
+ }
547
+ }
548
+
549
+ inline static void raise_not_enough_exception()
550
+ {
551
+ rb_raise(rb_eArgError, "Not enough precomputed primes");
552
+ }
553
+
554
+ inline static unsigned long
555
+ nth_prime(long n)
556
+ {
557
+ return numtheory_primes[n-1];
558
+ }
559
+
560
+ /*
561
+ * call-seq:
562
+ * NumTheory.prime(integer) -> integer
563
+ *
564
+ * Returns prime with corresponding index.
565
+ * The prime 2 is assumed to have index 1.
566
+ *
567
+ * NumTheory.prime 1 #=> 2
568
+ * NumTheory.prime 1000 #=> 7919
569
+ */
570
+ static VALUE
571
+ numtheory_prime(VALUE obj, VALUE i)
572
+ {
573
+ long t;
574
+ if (FIXNUM_P(i))
575
+ {
576
+ t = FIX2LONG(i);
577
+ if (t < 1)
578
+ {
579
+ rb_raise(rb_eArgError, "the argument must be positive");
580
+ }
581
+ if ((unsigned long)t > NUM_OF_PRIMES)
582
+ {
583
+ raise_not_enough_exception();
584
+ }
585
+ return ULONG2NUM(nth_prime((unsigned long)t));
586
+ }
587
+ raise_not_enough_exception();
588
+ return Qnil;
589
+ }
590
+
591
+ long
592
+ primepi(unsigned long t)
593
+ {
594
+ if (t < 2) return 0;
595
+
596
+ unsigned long l, m, r;
597
+ l = 0;
598
+ r = NUM_OF_PRIMES - 1;
599
+
600
+ if (numtheory_primes[r] <= t)
601
+ {
602
+ return r + 1;
603
+ }
604
+
605
+ while (l < r-1)
606
+ {
607
+ m = (l + r) >> 1;
608
+ if (numtheory_primes[m] > t)
609
+ r = m;
610
+ else if (numtheory_primes[m] < t)
611
+ l = m;
612
+ else return m + 1;
613
+ }
614
+ return r;
615
+ }
616
+
617
+ /*
618
+ * call-seq:
619
+ * NumTheory.primepi(integer) -> integer
620
+ *
621
+ * Returns the number of primes less or equal than a given value.
622
+ *
623
+ * NumTheory.primepi 10 #=> 4
624
+ * NumTheory.primepi -10 #=> 0
625
+ */
626
+ static VALUE
627
+ numtheory_primepi(VALUE obj, VALUE n)
628
+ {
629
+ if (NEGATIVE_P(n))
630
+ {
631
+ return zero;
632
+ }
633
+ unsigned long t = TO_ULONG(n);
634
+ if (t <= PRIMES_UPPER_LIMIT)
635
+ {
636
+ return ULONG2NUM(primepi(t));
637
+ }
638
+ raise_not_enough_exception();
639
+ return Qnil;
640
+ }
641
+
642
+ /*
643
+ * call-seq:
644
+ * NumTheory.fibonacci(n, [modulo]) -> integer
645
+ *
646
+ * Returns <i>n</i>-th fibonacci number (<code>% modulo</code>
647
+ * if the <i>modulo</i> is given).
648
+ * 0-th fibonacci number is assumed to be zero.
649
+ *
650
+ * NumTheory.fibonacci 10 #=> 55
651
+ * NumTheory.fibonacci 10**30, 1234567890 #=> 862134135
652
+ */
653
+ static VALUE
654
+ numtheory_fibonacci(int argc, VALUE* argv)
655
+ {
656
+ VALUE n, modulo;
657
+ rb_scan_args(argc, argv, "11", &n, &modulo);
658
+
659
+ if (FIXNUM_P(n) && FIX2LONG(n) < 2)
660
+ {
661
+ return n;
662
+ }
663
+
664
+ if (!INTEGER_P(n) || NEGATIVE_P(n))
665
+ {
666
+ rb_raise(rb_eArgError, "n must be nonnegative integer");
667
+ }
668
+ if (!NIL_P(modulo) && !INTEGER_P(modulo))
669
+ {
670
+ rb_raise(rb_eTypeError, "modulo must be integer");
671
+ }
672
+
673
+ VALUE a, b, c, old_a, old_b, old_c, old_b_sq;
674
+ a = c = one;
675
+ b = zero;
676
+
677
+ n = SUB(n, one);
678
+
679
+ FOR_BITS(n, { old_a = a; old_b = b; old_c = c;
680
+ old_b_sq = MUL(b, b);
681
+
682
+ a = ADD(MUL(a, a), old_b_sq);
683
+ c = ADD(MUL(c, c), old_b_sq);
684
+ b = MUL(b, ADD(old_a, old_c));
685
+ },
686
+ {
687
+ },
688
+ { c = b;
689
+ b = a;
690
+ a = ADD(b, c);
691
+ },
692
+ if (!NIL_P(modulo))
693
+ {
694
+ a = MOD(a, modulo);
695
+ b = MOD(b, modulo);
696
+ c = MOD(c, modulo);
697
+ });
698
+ return a;
699
+ }
700
+
701
+ /*
702
+ * call-seq:
703
+ * NumTheory.sigma(n, [pow=1]) -> integer
704
+ *
705
+ * Returns sum of <i>pow</i>-th powers of
706
+ * divisors of <code>|n|</code>. <i>pow</i> must be
707
+ * nonnegative integer.
708
+ *
709
+ * NumTheory.sigma 1234567890, 0 #=> 48
710
+ * NumTheory.sigma 1234567890, 1 #=> 3211610688
711
+ */
712
+ static VALUE
713
+ numtheory_sigma(int argc, VALUE* argv)
714
+ {
715
+ VALUE n, pow;
716
+ rb_scan_args(argc, argv, "11", &n, &pow);
717
+
718
+ if (!INTEGER_P(n))
719
+ {
720
+ rb_raise(rb_eTypeError, "n must be integer");
721
+ }
722
+ n = ABS(n);
723
+
724
+ if (NIL_P(pow))
725
+ {
726
+ pow = one;
727
+ }
728
+ else if (!INTEGER_P(pow))
729
+ {
730
+ rb_raise(rb_eTypeError, "power must be integer");
731
+ }
732
+ if (NEGATIVE_P(pow))
733
+ {
734
+ rb_raise(rb_eArgError, "power must be >= 0");
735
+ }
736
+ if (ZERO_P(n))
737
+ {
738
+ rb_raise(rb_eArgError, "n can't be zero");
739
+ }
740
+ VALUE result = one;
741
+ VALUE tmp1, tmp2;
742
+ int i;
743
+ FOR_PRIME_FACTORS(n, p, d,
744
+ { tmp1 = one;
745
+ tmp2 = rb_big_pow(TO_BIGNUM(p), pow);
746
+ for (i = FIX2LONG(d); i; --i)
747
+ {
748
+ tmp1 = MUL(tmp1, tmp2);
749
+ tmp1 = ADD(tmp1, one);
750
+ }
751
+ result = MUL(result, tmp1);
752
+ });
753
+ return result;
754
+ }
755
+
756
+ /*
757
+ * call-seq:
758
+ * NumTheory.eulerphi(n) -> integer
759
+ *
760
+ * Returns the number of positive integers less than <code>|n|</code>
761
+ * and coprime with <code>n</code>.
762
+ *
763
+ * NumTheory.eulerphi(1234567890) #=> 329040288
764
+ */
765
+ static VALUE
766
+ numtheory_eulerphi(VALUE obj, VALUE n)
767
+ {
768
+ if (!INTEGER_P(n))
769
+ {
770
+ rb_raise(rb_eTypeError, "n must be integer");
771
+ }
772
+ VALUE num = ABS(n);
773
+ if (ZERO_P(num))
774
+ {
775
+ rb_raise(rb_eArgError, "the number must be nonzero");
776
+ }
777
+ VALUE result = CLONE(num);
778
+ FOR_PRIME_FACTORS(num, p, d,
779
+ {
780
+ result = MUL(result, SUB(p, one));
781
+ result = DIV(result, p);
782
+ });
783
+ return result;
784
+ }
785
+
786
+ /*
787
+ * call-seq:
788
+ * integer.prime_division -> ary
789
+ *
790
+ * Returns factorization of the number in the form of
791
+ * array of pairs <code>[prime, power]</code>.
792
+ *
793
+ * 1234567890.prime_division
794
+ * #=> [[2, 1], [3, 2], [5, 1], [3607, 1], [3803, 1]]
795
+ * (-987654321).prime_division
796
+ * #=> [[-1, 1], [3, 2], [17, 2], [379721, 1]]
797
+ */
798
+ static VALUE
799
+ numtheory_prime_division(VALUE n)
800
+ {
801
+ VALUE pd[2];
802
+ VALUE pds = rb_ary_new();
803
+ if (NEGATIVE_P(n))
804
+ {
805
+ pd[0] = INT2FIX(-1); pd[1] = one;
806
+ rb_ary_push(pds, rb_ary_new4(2,pd));
807
+ }
808
+ VALUE num = ABS(n);
809
+ if (ZERO_P(n))
810
+ {
811
+ pd[0] = zero; pd[1] = one;
812
+ rb_ary_push(pds, rb_ary_new4(2,pd));
813
+ }
814
+ else
815
+ {
816
+ FOR_PRIME_FACTORS(num, p, d,
817
+ {
818
+ pd[0] = p; pd[1] = d;
819
+ rb_ary_push(pds, rb_ary_new4(2,pd));
820
+ });
821
+ }
822
+ return pds;
823
+ }
824
+
825
+ /*
826
+ * call-seq:
827
+ * NumTheory.moebius(integer) -> -1, 0 or 1
828
+ *
829
+ * Returns moebius function of argument.
830
+ *
831
+ * NumTheory.moebius(4) #=> 0
832
+ * NumTheory.moebius(35) #=> 1
833
+ */
834
+ static VALUE
835
+ numtheory_moebius(VALUE obj, VALUE n)
836
+ {
837
+ if (!INTEGER_P(n))
838
+ {
839
+ rb_raise(rb_eTypeError, "n must be integer");
840
+ }
841
+ VALUE num = ABS(n);
842
+ if (ZERO_P(num))
843
+ {
844
+ rb_raise(rb_eArgError, "the number must be nonzero");
845
+ }
846
+ char result = 1;
847
+ FOR_PRIME_FACTORS(num, p, d,
848
+ {
849
+ if (FIX2LONG(d) > 1)
850
+ {
851
+ return zero;
852
+ }
853
+ else
854
+ {
855
+ result *= -1;
856
+ }
857
+ });
858
+ return INT2FIX(result);
859
+ }
860
+
861
+ static VALUE
862
+ product(VALUE* beg, VALUE* end)
863
+ {
864
+ long len = end - beg;
865
+ if (!len)
866
+ {
867
+ return one;
868
+ }
869
+ if (len < 4)
870
+ {
871
+ VALUE t = *(--end);
872
+ while (beg != end)
873
+ t = MUL(t, *(--end));
874
+ return t;
875
+ }
876
+ long half_len = len >> 1;
877
+ VALUE* mid= beg + half_len;
878
+ return MUL(product(beg, mid),
879
+ product(mid, end));
880
+ }
881
+
882
+ static VALUE
883
+ product_of_ulongs(unsigned long* beg, unsigned long* end)
884
+ {
885
+ long len = end - beg;
886
+ unsigned long tmp;
887
+ if (len < 4)
888
+ {
889
+ tmp = *(--end);
890
+ VALUE t = ULONG2NUM(tmp);
891
+ while (beg != end)
892
+ tmp = *(--end),
893
+ t = MUL(t, ULONG2NUM(tmp));
894
+ return t;
895
+ }
896
+ long half_len = len >> 1;
897
+ unsigned long* mid = beg + half_len;
898
+ return MUL(product_of_ulongs(beg, mid),
899
+ product_of_ulongs(mid, end));
900
+ }
901
+
902
+ static VALUE
903
+ primorial(unsigned long min, unsigned long max)
904
+ {
905
+ unsigned long *l;
906
+ long m_pi = primepi(min);
907
+ if (m_pi == 0)
908
+ {
909
+ m_pi = 1;
910
+ }
911
+ l = numtheory_primes + m_pi - 1;
912
+ if (nth_prime(m_pi) < min)
913
+ {
914
+ ++m_pi;
915
+ ++l;
916
+ }
917
+ return product_of_ulongs(l, numtheory_primes + primepi(max));
918
+ }
919
+
920
+ /*
921
+ * call-seq:
922
+ * NumTheory.product(ary) -> integer
923
+ *
924
+ * Returns product of integer values stored in <i>ary</i>.
925
+ * Returns 1 if <i>ary</i> is empty.
926
+ *
927
+ * NumTheory.product([1,2,3,4,5,6]) #=> 720
928
+ */
929
+ static VALUE
930
+ numtheory_product(VALUE obj, VALUE arr)
931
+ {
932
+ if (!RB_TYPE_P(arr, T_ARRAY))
933
+ {
934
+ rb_raise(rb_eTypeError, "the argument must be an array");
935
+ }
936
+ return product(RARRAY_PTR(arr), RARRAY_PTR(arr) + RARRAY_LEN(arr));
937
+ }
938
+
939
+ /*
940
+ * call-seq:
941
+ * integer.primes_upto(limit) {|i| block } -> self
942
+ * integer.primes_upto(limit) -> enumerator
943
+ *
944
+ * Yields primes in interval from +self+ to <i>limit</i> inclusively.
945
+ *
946
+ * 2.primes_upto(17).to_a #=> [2, 3, 5, 7, 11, 13, 17]
947
+ */
948
+ static VALUE
949
+ numtheory_primes_upto(VALUE min, VALUE _max)
950
+ {
951
+ VALUE max = _max;
952
+ if (!INTEGER_P(max))
953
+ {
954
+ if (TYPE(max) == T_FLOAT)
955
+ {
956
+ max = rb_to_int(max);
957
+ }
958
+ else
959
+ {
960
+ rb_raise(rb_eTypeError, "upper bound must be a number");
961
+ }
962
+ }
963
+ if (NEGATIVE_P(SUB(max,min)))
964
+ {
965
+ rb_raise(rb_eArgError, "upper bound must be more than lower");
966
+ }
967
+ if (NEGATIVE_P(SUB(max, two)))
968
+ {
969
+ return rb_ary_new2(0);
970
+ }
971
+ if (NEGATIVE_P(SUB(min, two)))
972
+ {
973
+ min = two;
974
+ }
975
+ unsigned long m = TO_ULONG(min);
976
+ unsigned long M = TO_ULONG(max);
977
+ if (M > PRIMES_UPPER_LIMIT)
978
+ {
979
+ raise_not_enough_exception();
980
+ // TODO: allow for bignums
981
+ }
982
+
983
+ RETURN_ENUMERATOR(min, 1, &max);
984
+
985
+ long m_pi = primepi(m);
986
+ long M_pi = primepi(M);
987
+
988
+ unsigned long* p_c = numtheory_primes + m_pi - 1;
989
+ if (*p_c < m)
990
+ ++m_pi, ++p_c;
991
+
992
+ for ( ; m_pi <= M_pi; ++m_pi)
993
+ {
994
+ rb_yield(ULONG2NUM(*p_c));
995
+ ++p_c;
996
+ }
997
+ return min;
998
+ }
999
+
1000
+ static VALUE
1001
+ odd_swing(long n)
1002
+ {
1003
+ if (n < 65)
1004
+ {
1005
+ return ULL2NUM(numtheory_small_odd_swings[n]);
1006
+ }
1007
+ unsigned long root_n = (int)(floor(sqrt((double)n))+0.5);
1008
+ unsigned long n3 = n / 3;
1009
+ long pi_n3 = primepi(n3);
1010
+ long count = 0;
1011
+ long q;
1012
+ VALUE* prime_list = malloc(sizeof(VALUE) * pi_n3);
1013
+ unsigned long* ptr = numtheory_primes + 1; // initially points to 3
1014
+ unsigned long prime;
1015
+ unsigned long prod;
1016
+ for ( ; *ptr <= root_n; ++ptr)
1017
+ {
1018
+ prod = 1;
1019
+ q = n;
1020
+ prime = *ptr;
1021
+ while (q /= prime)
1022
+ if (q & 1)
1023
+ prod *= prime;
1024
+
1025
+ if (prod > 1)
1026
+ prime_list[count++] = INT2FIX(prod);
1027
+ }
1028
+ for ( ; *ptr <= n3; ++ptr)
1029
+ {
1030
+ prime = *ptr;
1031
+ if ((n / prime) & 1)
1032
+ prime_list[count++] = INT2FIX(prime);
1033
+ }
1034
+ VALUE r = product(prime_list, prime_list + count);
1035
+ free(prime_list);
1036
+ return MUL(r, primorial(n/2 + 1, n));
1037
+ }
1038
+
1039
+
1040
+ static VALUE
1041
+ rec_factorial(long n)
1042
+ {
1043
+ if (n < 2) return one;
1044
+ VALUE n2fac = rec_factorial(n >> 1);
1045
+ n2fac = MUL(n2fac, n2fac);
1046
+ return MUL(n2fac, odd_swing(n));
1047
+ }
1048
+
1049
+ /*
1050
+ * call-seq:
1051
+ * integer.factorial -> integer
1052
+ *
1053
+ * Returns factorial of the number.
1054
+ *
1055
+ * 50.factorial.to_s(31) #=> "283sp352ltrc9csg1398f0dt7dg067g15ikr4b6spf70"
1056
+ */
1057
+ static VALUE
1058
+ numtheory_factorial_primeswing(VALUE n)
1059
+ {
1060
+ long t;
1061
+ if ((t = FIX2LONG(n)) >= 10000000)
1062
+ {
1063
+ rb_raise(rb_eArgError, "the argument is too big!");
1064
+ }
1065
+ if (t < 0)
1066
+ {
1067
+ rb_raise(rb_eArgError, "factorial of negative number is undefined");
1068
+ }
1069
+ if (t <= 20)
1070
+ {
1071
+ return ULL2NUM(numtheory_small_factorials[t]);
1072
+ }
1073
+ if ((unsigned long)t > PRIMES_UPPER_LIMIT)
1074
+ {
1075
+ raise_not_enough_exception();
1076
+ }
1077
+ long shift = 0;
1078
+ long q = t;
1079
+ while (q > 0)
1080
+ {
1081
+ q >>= 1;
1082
+ shift += q;
1083
+ }
1084
+ return rb_big_lshift(rec_factorial(t), LONG2NUM(shift));
1085
+ }
1086
+
1087
+ struct Egcd {
1088
+ VALUE d, a, b;
1089
+ };
1090
+
1091
+ static struct Egcd
1092
+ extended_gcd(VALUE x, VALUE y)
1093
+ {
1094
+ struct Egcd egcd_old, egcd_new;
1095
+ if (ZERO_P(y))
1096
+ {
1097
+ egcd_new.d = x;
1098
+ egcd_new.a = one;
1099
+ egcd_new.b = zero;
1100
+ return egcd_new;
1101
+ }
1102
+ VALUE divmod = DIVMOD(x, y);
1103
+ egcd_old = extended_gcd(y, rb_ary_entry(divmod, 1));
1104
+ egcd_new.d = egcd_old.d;
1105
+ egcd_new.a = egcd_old.b;
1106
+ egcd_new.b = SUB(egcd_old.a, MUL(rb_ary_entry(divmod, 0),
1107
+ egcd_old.b));
1108
+ return egcd_new;
1109
+ }
1110
+
1111
+ /*
1112
+ * call-seq:
1113
+ * Integer.extended_gcd(y) -> Integer
1114
+ *
1115
+ * Returns array <code>[d, [a, b]]</code> where
1116
+ * <i>d</i> is +self+.gcd(<i>y</i>) and <code>a*self + b*y = d</code>
1117
+ *
1118
+ * 0.extended_gcd(0) #=> [0, [0, 0]]
1119
+ * 239.extended_gcd(932) #=> [1, [39, -10]]
1120
+ */
1121
+ static VALUE
1122
+ numtheory_extended_gcd(VALUE x, VALUE y)
1123
+ {
1124
+ if (!INTEGER_P(y))
1125
+ {
1126
+ rb_raise(rb_eTypeError, "not an integer");
1127
+ }
1128
+ struct Egcd egcd;
1129
+ if (ZERO_P(x) && ZERO_P(y))
1130
+ {
1131
+ egcd.d = egcd.a = egcd.b = zero;
1132
+ }
1133
+ else
1134
+ {
1135
+ egcd = extended_gcd(x, y);
1136
+ }
1137
+ VALUE ary = rb_ary_new2(2);
1138
+ rb_ary_store(ary, 0, egcd.d);
1139
+ VALUE coeffs = rb_ary_new2(2);
1140
+ rb_ary_store(coeffs, 0, egcd.a);
1141
+ rb_ary_store(coeffs, 1, egcd.b);
1142
+ rb_ary_store(ary, 1, coeffs);
1143
+ return ary;
1144
+ }
1145
+
1146
+ /*
1147
+ * call-seq:
1148
+ * integer.inverse(m) -> integer
1149
+ *
1150
+ * Returns modular inverse modulo <i>m</i> of +self+.
1151
+ *
1152
+ * 1234.inverse(12345) #=> 9874
1153
+ */
1154
+ static VALUE
1155
+ numtheory_modular_inverse(VALUE x, VALUE y)
1156
+ {
1157
+ struct Egcd egcd = extended_gcd(x, y);
1158
+ if (egcd.d != one)
1159
+ {
1160
+ rb_raise(rb_eArgError, "modular inverse doesn't exist");
1161
+ }
1162
+ VALUE result = egcd.a;
1163
+ if (NEGATIVE_P(result))
1164
+ {
1165
+ result = ADD(result, y);
1166
+ }
1167
+ return result;
1168
+ }
1169
+
1170
+ /*
1171
+ * call-seq:
1172
+ * integer.znorder(modulo) -> integer
1173
+ *
1174
+ * Returns minimal positive integer <i>n</i> such that
1175
+ * <code>+self+.powermod(n, modulo) == 1</code>
1176
+ *
1177
+ * 20.znorder(11) => 5
1178
+ */
1179
+ static VALUE
1180
+ numtheory_multiplicative_order(VALUE a, VALUE m)
1181
+ {
1182
+ if (rb_funcall(a, id_gcd, 1, m) != one)
1183
+ {
1184
+ rb_raise(rb_eArgError, "not in (Z/nZ)*");
1185
+ }
1186
+ VALUE result = one;
1187
+ VALUE pd, phi, o, x;
1188
+ FOR_PRIME_FACTORS(ABS(m), p, d,
1189
+ {
1190
+ o = one;
1191
+ pd = POW(p, SUB(d, o));
1192
+ phi = MUL(SUB(p, o), pd);
1193
+ pd = MUL(pd, p);
1194
+ FOR_PRIME_FACTORS(phi, q, e,
1195
+ {
1196
+ x = numtheory_int_powermod(a,
1197
+ DIV(phi, POW(q, e)),
1198
+ pd);
1199
+ while (x != one)
1200
+ {
1201
+ o = MUL(o, q);
1202
+ x = numtheory_int_powermod(x, q, pd);
1203
+ }
1204
+ });
1205
+ result = rb_funcall(result, id_lcm, 1, o);
1206
+ });
1207
+ return result;
1208
+ }
1209
+
1210
+ inline VALUE* triple_new(VALUE v1, VALUE v2, VALUE v3)
1211
+ {
1212
+ VALUE* v = malloc(sizeof(VALUE)*3);
1213
+ v[0] = v1; v[1] = v2; v[2] = v3;
1214
+ return v;
1215
+ }
1216
+
1217
+ #define TRIPLE_SUM(triple) \
1218
+ (ADD(triple[0], ADD(triple[1], triple[2])))
1219
+
1220
+
1221
+ /*
1222
+ * call-seq:
1223
+ * NumTheory.triples(max_perimeter) -> enumerator
1224
+ *
1225
+ * Yields primitive pythagorean triples with perimeter less
1226
+ * or equal to <i>max_perimeter</i>.
1227
+ */
1228
+ static VALUE
1229
+ numtheory_pythagorean_triples(VALUE obj, VALUE max_l)
1230
+ {
1231
+ RETURN_ENUMERATOR(obj, 1, &max_l);
1232
+
1233
+ Queue* q = queue_new();
1234
+
1235
+ VALUE* triple;
1236
+
1237
+ queue_push(q, triple_new(three, four, five));
1238
+
1239
+ VALUE a, b, c, a2, b2, c2, c3;
1240
+ VALUE t1,t2,t3;
1241
+
1242
+ while (q -> first)
1243
+ {
1244
+ triple = queue_pop(q);
1245
+ if (MORE(TRIPLE_SUM(triple), max_l))
1246
+ {
1247
+ free(triple);
1248
+ continue;
1249
+ }
1250
+
1251
+ a = triple[0]; b = triple[1]; c = triple[2];
1252
+ rb_yield_values2(3, triple);
1253
+
1254
+ // uses ternary pythagorean tree
1255
+ a2 = DOUBLED(a);
1256
+ b2 = DOUBLED(b);
1257
+ c2 = DOUBLED(c);
1258
+ c3 = ADD(c, c2);
1259
+
1260
+ t1 = ADD(a,c2); t2 = ADD(a2,c2); t3 = ADD(a2,c3);
1261
+
1262
+ queue_push(q, triple_new(SUB(t1, b2),
1263
+ SUB(t2, b),
1264
+ SUB(t3, b2)));
1265
+
1266
+ queue_push(q, triple_new(SUB(ADD(b2, c2), a),
1267
+ SUB(ADD(b, c2), a2),
1268
+ SUB(ADD(b2, c3), a2)));
1269
+
1270
+ queue_push(q, triple_new(ADD(t1, b2),
1271
+ ADD(t2, b),
1272
+ ADD(t3, b2)));
1273
+ free(triple);
1274
+ }
1275
+ free(q);
1276
+ return Qnil;
1277
+ }
1278
+
1279
+ /*
1280
+ * call-seq:
1281
+ * integer.popcount -> integer
1282
+ *
1283
+ * Returns the number of set bits.
1284
+ */
1285
+ static VALUE
1286
+ numtheory_popcount(VALUE n)
1287
+ {
1288
+ if (NEGATIVE_P(n))
1289
+ {
1290
+ rb_raise(rb_eArgError, "popcount is undefined for negative numbers");
1291
+ }
1292
+ unsigned long k = 0;
1293
+ FOR_BITS(n, {}, {}, { ++k; }, {});
1294
+ return ULONG2NUM(k);
1295
+ }
1296
+
1297
+ static int
1298
+ int_bitlength(unsigned int v)
1299
+ {
1300
+ // taken from http://graphics.stanford.edu/~seander/bithacks.html
1301
+ const unsigned int b[] = {0x2, 0xC, 0xF0, 0xFF00, 0xFFFF0000};
1302
+ const unsigned int S[] = {1, 2, 4, 8, 16};
1303
+ int i;
1304
+
1305
+ register unsigned int r = 0;
1306
+ for (i = 4; i >= 0; --i)
1307
+ {
1308
+ if (v & b[i])
1309
+ {
1310
+ v >>= S[i];
1311
+ r |= S[i];
1312
+ }
1313
+ }
1314
+ return ++r;
1315
+ }
1316
+
1317
+ /*
1318
+ * call-seq:
1319
+ * integer.bitlength -> integer
1320
+ *
1321
+ * Returns the length in bits. Defined for positive integers only.
1322
+ * 0 is assumed to have length 1.
1323
+ */
1324
+ static VALUE
1325
+ numtheory_bitlength(VALUE n)
1326
+ {
1327
+ if (NEGATIVE_P(n))
1328
+ {
1329
+ rb_raise(rb_eArgError, "n must be positive");
1330
+ }
1331
+ long bit_len, half_k;
1332
+ if (FIXNUM_P(n))
1333
+ {
1334
+ return INT2FIX(int_bitlength(FIX2LONG(n)));
1335
+ }
1336
+ else
1337
+ {
1338
+ long len = RBIGNUM_LEN(n);
1339
+ bit_len = (len - 1) * SIZEOF_BDIGITS * 8;
1340
+ return INT2FIX(bit_len + int_bitlength(RBIGNUM_DIGITS(n)[len - 1]));
1341
+ }
1342
+ }
1343
+
1344
+ static int
1345
+ ull_jacobi(long long a, unsigned long long n)
1346
+ {
1347
+ /* it's assumed that n is odd and > 0 */
1348
+ int t = 1;
1349
+ long long tmp;
1350
+ while (a) {
1351
+ if (a < 0) {
1352
+ a = -a; if ((n & 3) == 3) t = -t;
1353
+ }
1354
+ switch (n & 7) {
1355
+ case 1: case 7:
1356
+ while (!(a&1)) a >>= 1; break;
1357
+ case 3: case 5:
1358
+ while (!(a&1)) a >>= 1, t = -t; break;
1359
+ }
1360
+ tmp = a; a = n; n = tmp;
1361
+ if ((a & 3) == 3 && (n & 3) == 3) t = -t;
1362
+ a %= n;
1363
+ if (a > (long long)(n >> 1)) a -= n;
1364
+ }
1365
+ return n == 1 ? t : 0;
1366
+ }
1367
+
1368
+ /*
1369
+ * call-seq:
1370
+ * integer.jacobi(n) -> -1, 0 or 1
1371
+ *
1372
+ * Returns jacobi symbol (a|n) where n must be odd positive
1373
+ */
1374
+ static VALUE
1375
+ numtheory_jacobi(VALUE a, VALUE n)
1376
+ {
1377
+ if (EVEN_P(n) || NEGATIVE_P(n))
1378
+ {
1379
+ rb_raise(rb_eArgError, "n must be odd positive");
1380
+ }
1381
+ int t = 1;
1382
+ VALUE tmp;
1383
+ while (!ZERO_P(a))
1384
+ {
1385
+ a = MOD(a, n);
1386
+ if (MORE(a, HALF(n)))
1387
+ {
1388
+ a = SUB(a, n);
1389
+ }
1390
+ if (FIXNUM_P(n))
1391
+ {
1392
+ return INT2FIX(ull_jacobi(FIX2LONG(a), FIX2LONG(n)));
1393
+ }
1394
+ if (RBIGNUM_LEN(n) <= 2) // unsigned long long is used
1395
+ {
1396
+ return INT2FIX(ull_jacobi(FIXNUM_P(a) ? FIX2LONG(a) : rb_big2ll(a),
1397
+ rb_big2ull(n)));
1398
+ }
1399
+ if (NEGATIVE_P(a))
1400
+ {
1401
+ a = SUB(zero, a);
1402
+ if (MOD(n, four) == three)
1403
+ t = -t;
1404
+ }
1405
+ switch (FIX2LONG(MOD(n, eight)))
1406
+ {
1407
+ case 1:
1408
+ case 7:
1409
+ while (EVEN_P(a))
1410
+ a = HALF(a);
1411
+ break;
1412
+ case 3:
1413
+ case 5:
1414
+ while (EVEN_P(a))
1415
+ a = HALF(a), t = -t;
1416
+ break;
1417
+ }
1418
+ tmp = a;
1419
+ a = n;
1420
+ n = tmp;
1421
+ if (MOD(a, four) == three && MOD(n, four) == three)
1422
+ t = -t;
1423
+ }
1424
+ if (n == one)
1425
+ {
1426
+ return INT2FIX(t);
1427
+ }
1428
+ else
1429
+ {
1430
+ return zero;
1431
+ }
1432
+ }
1433
+
1434
+ /*
1435
+ * call-seq:
1436
+ * a.sqrt_mod(p) -> integer or nil
1437
+ *
1438
+ * If (a|p) = 1 returns the square root of a in Z/pZ
1439
+ * from the interval [0, p/2]. Otherwise returns +nil+.
1440
+ */
1441
+ static VALUE
1442
+ numtheory_sqrtmod(VALUE a, VALUE p)
1443
+ {
1444
+ if (!INTEGER_P(p))
1445
+ {
1446
+ rb_raise(rb_eArgError, "the parameters must be integer");
1447
+ }
1448
+ else if (!numtheory_prime_p(p))
1449
+ {
1450
+ rb_raise(rb_eArgError, "p must be prime");
1451
+ }
1452
+ p = ABS(p);
1453
+ if (p == two)
1454
+ {
1455
+ return EVEN_P(a) ? zero : one;
1456
+ }
1457
+ if (numtheory_jacobi(a, p) != one)
1458
+ {
1459
+ return Qnil;
1460
+ }
1461
+
1462
+ VALUE t = SUB(p, one);
1463
+ VALUE p_minus_one = CLONE(t);
1464
+
1465
+ int e = tail_zeros(t);
1466
+ VALUE r;
1467
+
1468
+ t = RIGHT_SHIFT(t, e);
1469
+
1470
+ if (e == 1)
1471
+ {
1472
+ r = numtheory_int_powermod(a, ADD(HALF(t), one), p);
1473
+ }
1474
+ else if (e == 2)
1475
+ {
1476
+ if (numtheory_int_powermod(a, t, p) == one)
1477
+ {
1478
+ r = numtheory_int_powermod(a, ADD(HALF(t), one), p);
1479
+ }
1480
+ else
1481
+ {
1482
+ a = DOUBLED(a);
1483
+ r = MOD(MUL(a, numtheory_int_powermod(DOUBLED(a), HALF(t), p)), p);
1484
+ }
1485
+ }
1486
+ else
1487
+ {
1488
+ // Tonelli-Shanks algorithm
1489
+ // implemented as described in "Handbook of Applied Cryptography"
1490
+ int b = 14;
1491
+ while(1)
1492
+ {
1493
+ if (numtheory_jacobi(INT2FIX(b), p) == INT2FIX(-1))
1494
+ break;
1495
+ ++b;
1496
+ }
1497
+
1498
+ VALUE a_inv = numtheory_modular_inverse(a, p);
1499
+ VALUE D = numtheory_int_powermod(INT2FIX(b), t, p);
1500
+ r = numtheory_int_powermod(a, ADD(HALF(t), one), p);
1501
+
1502
+ int i;
1503
+ VALUE d;
1504
+ VALUE power_of_two = rb_big_lshift(TO_BIGNUM(one), INT2FIX(e - 2));
1505
+ for (i = 1; i < e; ++i)
1506
+ {
1507
+ d = numtheory_int_powermod(MUL(MUL(r, r), a_inv),
1508
+ power_of_two, p);
1509
+ power_of_two = HALF(power_of_two);
1510
+ if (EQL(d, p_minus_one))
1511
+ {
1512
+ r = MOD(MUL(r, D), p);
1513
+ }
1514
+ D = MOD(MUL(D, D), p);
1515
+ }
1516
+ }
1517
+ if (MORE(r, HALF(p)))
1518
+ {
1519
+ r = SUB(p, r);
1520
+ }
1521
+ return r;
1522
+ }
1523
+
1524
+ /*
1525
+ * call-seq:
1526
+ * integer.isqrt -> integer
1527
+ *
1528
+ * Returns the square root integer part.
1529
+ */
1530
+ static VALUE
1531
+ numtheory_isqrt(VALUE n)
1532
+ {
1533
+ if (NEGATIVE_P(n))
1534
+ {
1535
+ rb_raise(rb_eArgError, "can't take square root from negative number");
1536
+ }
1537
+ if (ZERO_P(n))
1538
+ {
1539
+ return zero;
1540
+ }
1541
+ VALUE x, y;
1542
+ if (FIXNUM_P(n))
1543
+ {
1544
+ x = n;
1545
+ }
1546
+ else
1547
+ {
1548
+ x = rb_big_lshift(TO_BIGNUM(one), ADD(HALF(numtheory_bitlength(n)), one));
1549
+ }
1550
+ for ( ; ; )
1551
+ {
1552
+ y = HALF(ADD(x, DIV(n, x)));
1553
+ if (LESS(y, x))
1554
+ x = y;
1555
+ else
1556
+ break;
1557
+ }
1558
+ return x;
1559
+ }
1560
+
1561
+ static int MOD_255(VALUE n)
1562
+ {
1563
+ if (FIXNUM_P(n))
1564
+ {
1565
+ return FIX2LONG(n) % 255;
1566
+ }
1567
+ unsigned long long m = 0;
1568
+ BDIGIT* digit = RBIGNUM_DIGITS(n);
1569
+ int i;
1570
+ for (i = 0; i < RBIGNUM_LEN(n); ++i, ++digit)
1571
+ {
1572
+ m += *digit & 0xFF;
1573
+ m += (*digit & 0xFF00) >> 8;
1574
+ m += (*digit & 0xFF0000) >> 16;
1575
+ m += (*digit & 0xFF000000UL) >> 24;
1576
+ }
1577
+ return m % 255;
1578
+ }
1579
+
1580
+ /*
1581
+ * call-seq:
1582
+ * integer.square? -> true or false
1583
+ *
1584
+ * Checks whether the integer is a perfect square or not.
1585
+ */
1586
+ static VALUE
1587
+ numtheory_perfect_square_p(VALUE n)
1588
+ {
1589
+ if (NEGATIVE_P(n))
1590
+ {
1591
+ return Qfalse;
1592
+ }
1593
+
1594
+ if ( !issquare_mod256[ (FIXNUM_P(n) ? FIX2ULONG(n) : RBIGNUM_DIGITS(n)[0]) & 0xFF ]
1595
+ ||
1596
+ !issquare_mod255[ MOD_255(n) ])
1597
+ {
1598
+ // only 44 residues mod 256 are squares, and only 54 residues mod 255.
1599
+ // 44/256 * 54/255 = 0.0364 so in 96.4% of cases there's no need to
1600
+ // check anything else
1601
+ return Qfalse;
1602
+ }
1603
+
1604
+ VALUE r = numtheory_isqrt(n);
1605
+ return EQL(MUL(r, r), n) ? Qtrue : Qfalse;
1606
+ }
1607
+
1608
+ static VALUE
1609
+ lucas_pseudoprime_p(VALUE n, VALUE a, VALUE b)
1610
+ {
1611
+ // for internal use only
1612
+
1613
+ // the details about the algorithm can be found in the book
1614
+ // "Prime numbers. A computational perspective."
1615
+
1616
+ VALUE d = SUB(MUL(a, a), MUL(b, four));
1617
+ // it's assumed here that d is not a full square and gcd(2abd, n) = 1
1618
+
1619
+ VALUE A = MOD(SUB(MUL(MUL(a, a),
1620
+ numtheory_modular_inverse(b, n)),
1621
+ two),
1622
+ n);
1623
+
1624
+ VALUE m = HALF(SUB(n, numtheory_jacobi(d, n)));
1625
+
1626
+ VALUE u = two;
1627
+ VALUE v = CLONE(A);
1628
+ FOR_BITS(m, {},
1629
+ {
1630
+ v = MOD(SUB(MUL(u, v), A), n);
1631
+ u = MOD(SUB(MUL(u, u), two), n);
1632
+ },
1633
+ {
1634
+ u = MOD(SUB(MUL(u, v), A), n);
1635
+ v = MOD(SUB(MUL(v, v), two), n);
1636
+ },
1637
+ {});
1638
+ if (EQL( MOD(MUL(A, u), n),
1639
+ MOD(MUL(two, v), n)))
1640
+ {
1641
+ return Qtrue;
1642
+ }
1643
+ return Qfalse;
1644
+ }
1645
+
1646
+ static VALUE power_of_2_mod(VALUE p, VALUE m){
1647
+ // Used internally in base-2 Miller-Rabin test.
1648
+ // Uses left shift instead of multiplication.
1649
+ VALUE result = one;
1650
+ FOR_BITS(p, result = MUL(result, result),
1651
+ {},
1652
+ result = DOUBLED(result),
1653
+ result = MOD(result, m));
1654
+ return result;
1655
+ }
1656
+
1657
+ static VALUE miller_rabin_base2_pseudoprime_p(VALUE n)
1658
+ {
1659
+ // for internal use only
1660
+ VALUE num = rb_big_clone(TO_BIGNUM(n));
1661
+ VALUE num_minus_one = SUB(num, one);
1662
+ VALUE d = rb_big_clone(TO_BIGNUM(num_minus_one));
1663
+
1664
+ int s = tail_zeros(d);
1665
+ d = RIGHT_SHIFT(d, s);
1666
+
1667
+ VALUE x = power_of_2_mod(d, num);
1668
+ if (EQL(x, one) || EQL(x, num_minus_one)) return Qtrue;
1669
+
1670
+ while (s--) {
1671
+ x = MOD(MUL(x, x), num);
1672
+ if (EQL(x, one)) return Qfalse;
1673
+ if (EQL(x, num_minus_one)) break;
1674
+ }
1675
+ if (!EQL(x, num_minus_one)) {
1676
+ return Qfalse;
1677
+ }
1678
+ return Qtrue;
1679
+ }
1680
+
1681
+ /*
1682
+ * call-seq:
1683
+ * integer.BPSW_pseudoprime? -> true or false
1684
+ *
1685
+ * Standard BPSW primality test.
1686
+ */
1687
+ static VALUE
1688
+ numtheory_bpsw_pseudoprime_p(VALUE n)
1689
+ {
1690
+ VALUE num = ABS(n);
1691
+
1692
+ if (EQL(num, two))
1693
+ {
1694
+ return Qtrue;
1695
+ }
1696
+ if (LESS(num, two) || EVEN_P(num) ||
1697
+ (numtheory_perfect_square_p(num) == Qtrue))
1698
+ {
1699
+ return Qfalse;
1700
+ }
1701
+
1702
+ // Miller-Rabin test with base 2
1703
+ if (miller_rabin_base2_pseudoprime_p(num) == Qfalse)
1704
+ {
1705
+ return Qfalse;
1706
+ }
1707
+
1708
+ // standard Lucas-Selfridge test. Based on the description from
1709
+ // http://www.e-maxx.ru/algo/bpsw
1710
+ int d_abs, d_sign, d;
1711
+ for (d_abs = 5, d_sign = 1; ; d_abs += 2, d_sign = -d_sign)
1712
+ {
1713
+ d = d_abs * d_sign;
1714
+ VALUE G = rb_funcall(num, id_gcd, 1, INT2FIX(d));
1715
+ if (MORE(G, one) && LESS(G, num))
1716
+ {
1717
+ return Qfalse;
1718
+ }
1719
+ if (numtheory_jacobi(INT2FIX(d), num) == INT2FIX(-1))
1720
+ {
1721
+ break;
1722
+ }
1723
+ }
1724
+
1725
+ return lucas_pseudoprime_p(num, one, RIGHT_SHIFT(SUB(one, INT2FIX(d)), 2));
1726
+ }