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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
+ }