Upload Tizen:Base source
[external/gmp.git] / tests / mpz / t-jac.c
1 /* Exercise mpz_*_kronecker_*() and mpz_jacobi() functions.
2
3 Copyright 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
4
5 This file is part of the GNU MP Library.
6
7 The GNU MP Library is free software; you can redistribute it and/or modify
8 it under the terms of the GNU Lesser General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or (at your
10 option) any later version.
11
12 The GNU MP Library is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
15 License for more details.
16
17 You should have received a copy of the GNU Lesser General Public License
18 along with the GNU MP Library.  If not, see http://www.gnu.org/licenses/.  */
19
20
21 /* With no arguments the various Kronecker/Jacobi symbol routines are
22    checked against some test data and a lot of derived data.
23
24    To check the test data against PARI-GP, run
25
26            t-jac -p | gp -q
27
28    It takes a while because the output from "t-jac -p" is big.
29
30
31    Enhancements:
32
33    More big test cases than those given by check_squares_zi would be good.  */
34
35
36 #include <stdio.h>
37 #include <stdlib.h>
38 #include <string.h>
39
40 #include "gmp.h"
41 #include "gmp-impl.h"
42 #include "tests.h"
43
44
45 #ifdef _LONG_LONG_LIMB
46 #define LL(l,ll)  ll
47 #else
48 #define LL(l,ll)  l
49 #endif
50
51
52 int option_pari = 0;
53
54
55 unsigned long
56 mpz_mod4 (mpz_srcptr z)
57 {
58   mpz_t          m;
59   unsigned long  ret;
60
61   mpz_init (m);
62   mpz_fdiv_r_2exp (m, z, 2);
63   ret = mpz_get_ui (m);
64   mpz_clear (m);
65   return ret;
66 }
67
68 int
69 mpz_fits_ulimb_p (mpz_srcptr z)
70 {
71   return (SIZ(z) == 1 || SIZ(z) == 0);
72 }
73
74 mp_limb_t
75 mpz_get_ulimb (mpz_srcptr z)
76 {
77   if (SIZ(z) == 0)
78     return 0;
79   else
80     return PTR(z)[0];
81 }
82
83
84 void
85 try_base (mp_limb_t a, mp_limb_t b, int answer)
86 {
87   int  got;
88
89   if ((b & 1) == 0 || b == 1 || a > b)
90     return;
91
92   got = mpn_jacobi_base (a, b, 0);
93   if (got != answer)
94     {
95       printf (LL("mpn_jacobi_base (%lu, %lu) is %d should be %d\n",
96                  "mpn_jacobi_base (%llu, %llu) is %d should be %d\n"),
97               a, b, got, answer);
98       abort ();
99     }
100 }
101
102
103 void
104 try_zi_ui (mpz_srcptr a, unsigned long b, int answer)
105 {
106   int  got;
107
108   got = mpz_kronecker_ui (a, b);
109   if (got != answer)
110     {
111       printf ("mpz_kronecker_ui (");
112       mpz_out_str (stdout, 10, a);
113       printf (", %lu) is %d should be %d\n", b, got, answer);
114       abort ();
115     }
116 }
117
118
119 void
120 try_zi_si (mpz_srcptr a, long b, int answer)
121 {
122   int  got;
123
124   got = mpz_kronecker_si (a, b);
125   if (got != answer)
126     {
127       printf ("mpz_kronecker_si (");
128       mpz_out_str (stdout, 10, a);
129       printf (", %ld) is %d should be %d\n", b, got, answer);
130       abort ();
131     }
132 }
133
134
135 void
136 try_ui_zi (unsigned long a, mpz_srcptr b, int answer)
137 {
138   int  got;
139
140   got = mpz_ui_kronecker (a, b);
141   if (got != answer)
142     {
143       printf ("mpz_ui_kronecker (%lu, ", a);
144       mpz_out_str (stdout, 10, b);
145       printf (") is %d should be %d\n", got, answer);
146       abort ();
147     }
148 }
149
150
151 void
152 try_si_zi (long a, mpz_srcptr b, int answer)
153 {
154   int  got;
155
156   got = mpz_si_kronecker (a, b);
157   if (got != answer)
158     {
159       printf ("mpz_si_kronecker (%ld, ", a);
160       mpz_out_str (stdout, 10, b);
161       printf (") is %d should be %d\n", got, answer);
162       abort ();
163     }
164 }
165
166
167 /* Don't bother checking mpz_jacobi, since it only differs for b even, and
168    we don't have an actual expected answer for it.  tests/devel/try.c does
169    some checks though.  */
170 void
171 try_zi_zi (mpz_srcptr a, mpz_srcptr b, int answer)
172 {
173   int  got;
174
175   got = mpz_kronecker (a, b);
176   if (got != answer)
177     {
178       printf ("mpz_kronecker (");
179       mpz_out_str (stdout, 10, a);
180       printf (", ");
181       mpz_out_str (stdout, 10, b);
182       printf (") is %d should be %d\n", got, answer);
183       abort ();
184     }
185 }
186
187
188 void
189 try_pari (mpz_srcptr a, mpz_srcptr b, int answer)
190 {
191   printf ("try(");
192   mpz_out_str (stdout, 10, a);
193   printf (",");
194   mpz_out_str (stdout, 10, b);
195   printf (",%d)\n", answer);
196 }
197
198
199 void
200 try_each (mpz_srcptr a, mpz_srcptr b, int answer)
201 {
202   if (option_pari)
203     {
204       try_pari (a, b, answer);
205       return;
206     }
207
208   if (mpz_fits_ulimb_p (a) && mpz_fits_ulimb_p (b))
209     try_base (mpz_get_ulimb (a), mpz_get_ulimb (b), answer);
210
211   if (mpz_fits_ulong_p (b))
212     try_zi_ui (a, mpz_get_ui (b), answer);
213
214   if (mpz_fits_slong_p (b))
215     try_zi_si (a, mpz_get_si (b), answer);
216
217   if (mpz_fits_ulong_p (a))
218     try_ui_zi (mpz_get_ui (a), b, answer);
219
220   if (mpz_fits_sint_p (a))
221     try_si_zi (mpz_get_si (a), b, answer);
222
223   try_zi_zi (a, b, answer);
224 }
225
226
227 /* Try (a/b) and (a/-b). */
228 void
229 try_pn (mpz_srcptr a, mpz_srcptr b_orig, int answer)
230 {
231   mpz_t  b;
232
233   mpz_init_set (b, b_orig);
234   try_each (a, b, answer);
235
236   mpz_neg (b, b);
237   if (mpz_sgn (a) < 0)
238     answer = -answer;
239
240   try_each (a, b, answer);
241
242   mpz_clear (b);
243 }
244
245
246 /* Try (a+k*p/b) for various k, using the fact (a/b) is periodic in a with
247    period p.  For b>0, p=b if b!=2mod4 or p=4*b if b==2mod4. */
248
249 void
250 try_periodic_num (mpz_srcptr a_orig, mpz_srcptr b, int answer)
251 {
252   mpz_t  a, a_period;
253   int    i;
254
255   if (mpz_sgn (b) <= 0)
256     return;
257
258   mpz_init_set (a, a_orig);
259   mpz_init_set (a_period, b);
260   if (mpz_mod4 (b) == 2)
261     mpz_mul_ui (a_period, a_period, 4);
262
263   /* don't bother with these tests if they're only going to produce
264      even/even */
265   if (mpz_even_p (a) && mpz_even_p (b) && mpz_even_p (a_period))
266     goto done;
267
268   for (i = 0; i < 6; i++)
269     {
270       mpz_add (a, a, a_period);
271       try_pn (a, b, answer);
272     }
273
274   mpz_set (a, a_orig);
275   for (i = 0; i < 6; i++)
276     {
277       mpz_sub (a, a, a_period);
278       try_pn (a, b, answer);
279     }
280
281  done:
282   mpz_clear (a);
283   mpz_clear (a_period);
284 }
285
286
287 /* Try (a/b+k*p) for various k, using the fact (a/b) is periodic in b of
288    period p.
289
290                                period p
291            a==0,1mod4             a
292            a==2mod4              4*a
293            a==3mod4 and b odd    4*a
294            a==3mod4 and b even   8*a
295
296    In Henri Cohen's book the period is given as 4*a for all a==2,3mod4, but
297    a counterexample would seem to be (3/2)=-1 which with (3/14)=+1 doesn't
298    have period 4*a (but rather 8*a with (3/26)=-1).  Maybe the plain 4*a is
299    to be read as applying to a plain Jacobi symbol with b odd, rather than
300    the Kronecker extension to b even. */
301
302 void
303 try_periodic_den (mpz_srcptr a, mpz_srcptr b_orig, int answer)
304 {
305   mpz_t  b, b_period;
306   int    i;
307
308   if (mpz_sgn (a) == 0 || mpz_sgn (b_orig) == 0)
309     return;
310
311   mpz_init_set (b, b_orig);
312
313   mpz_init_set (b_period, a);
314   if (mpz_mod4 (a) == 3 && mpz_even_p (b))
315     mpz_mul_ui (b_period, b_period, 8L);
316   else if (mpz_mod4 (a) >= 2)
317     mpz_mul_ui (b_period, b_period, 4L);
318
319   /* don't bother with these tests if they're only going to produce
320      even/even */
321   if (mpz_even_p (a) && mpz_even_p (b) && mpz_even_p (b_period))
322     goto done;
323
324   for (i = 0; i < 6; i++)
325     {
326       mpz_add (b, b, b_period);
327       try_pn (a, b, answer);
328     }
329
330   mpz_set (b, b_orig);
331   for (i = 0; i < 6; i++)
332     {
333       mpz_sub (b, b, b_period);
334       try_pn (a, b, answer);
335     }
336
337  done:
338   mpz_clear (b);
339   mpz_clear (b_period);
340 }
341
342
343 static const unsigned long  ktable[] = {
344   0, 1, 2, 3, 4, 5, 6, 7,
345   GMP_NUMB_BITS-1, GMP_NUMB_BITS, GMP_NUMB_BITS+1,
346   2*GMP_NUMB_BITS-1, 2*GMP_NUMB_BITS, 2*GMP_NUMB_BITS+1,
347   3*GMP_NUMB_BITS-1, 3*GMP_NUMB_BITS, 3*GMP_NUMB_BITS+1
348 };
349
350
351 /* Try (a/b*2^k) for various k. */
352 void
353 try_2den (mpz_srcptr a, mpz_srcptr b_orig, int answer)
354 {
355   mpz_t  b;
356   int    kindex;
357   int    answer_a2, answer_k;
358   unsigned long k;
359
360   /* don't bother when b==0 */
361   if (mpz_sgn (b_orig) == 0)
362     return;
363
364   mpz_init_set (b, b_orig);
365
366   /* (a/2) is 0 if a even, 1 if a==1 or 7 mod 8, -1 if a==3 or 5 mod 8 */
367   answer_a2 = (mpz_even_p (a) ? 0
368                : (((SIZ(a) >= 0 ? PTR(a)[0] : -PTR(a)[0]) + 2) & 7) < 4 ? 1
369                : -1);
370
371   for (kindex = 0; kindex < numberof (ktable); kindex++)
372     {
373       k = ktable[kindex];
374
375       /* answer_k = answer*(answer_a2^k) */
376       answer_k = (answer_a2 == 0 && k != 0 ? 0
377                   : (k & 1) == 1 && answer_a2 == -1 ? -answer
378                   : answer);
379
380       mpz_mul_2exp (b, b_orig, k);
381       try_pn (a, b, answer_k);
382     }
383
384   mpz_clear (b);
385 }
386
387
388 /* Try (a*2^k/b) for various k.  If it happens mpz_ui_kronecker() gets (2/b)
389    wrong it will show up as wrong answers demanded. */
390 void
391 try_2num (mpz_srcptr a_orig, mpz_srcptr b, int answer)
392 {
393   mpz_t  a;
394   int    kindex;
395   int    answer_2b, answer_k;
396   unsigned long  k;
397
398   /* don't bother when a==0 */
399   if (mpz_sgn (a_orig) == 0)
400     return;
401
402   mpz_init (a);
403
404   /* (2/b) is 0 if b even, 1 if b==1 or 7 mod 8, -1 if b==3 or 5 mod 8 */
405   answer_2b = (mpz_even_p (b) ? 0
406                : (((SIZ(b) >= 0 ? PTR(b)[0] : -PTR(b)[0]) + 2) & 7) < 4 ? 1
407                : -1);
408
409   for (kindex = 0; kindex < numberof (ktable); kindex++)
410     {
411       k = ktable[kindex];
412
413       /* answer_k = answer*(answer_2b^k) */
414       answer_k = (answer_2b == 0 && k != 0 ? 0
415                   : (k & 1) == 1 && answer_2b == -1 ? -answer
416                   : answer);
417
418         mpz_mul_2exp (a, a_orig, k);
419       try_pn (a, b, answer_k);
420     }
421
422   mpz_clear (a);
423 }
424
425
426 /* The try_2num() and try_2den() routines don't in turn call
427    try_periodic_num() and try_periodic_den() because it hugely increases the
428    number of tests performed, without obviously increasing coverage.
429
430    Useful extra derived cases can be added here. */
431
432 void
433 try_all (mpz_t a, mpz_t b, int answer)
434 {
435   try_pn (a, b, answer);
436   try_periodic_num (a, b, answer);
437   try_periodic_den (a, b, answer);
438   try_2num (a, b, answer);
439   try_2den (a, b, answer);
440 }
441
442
443 void
444 check_data (void)
445 {
446   static const struct {
447     const char  *a;
448     const char  *b;
449     int         answer;
450
451   } data[] = {
452
453     /* Note that the various derived checks in try_all() reduce the cases
454        that need to be given here.  */
455
456     /* some zeros */
457     {  "0",  "0", 0 },
458     {  "0",  "2", 0 },
459     {  "0",  "6", 0 },
460     {  "5",  "0", 0 },
461     { "24", "60", 0 },
462
463     /* (a/1) = 1, any a
464        In particular note (0/1)=1 so that (a/b)=(a mod b/b). */
465     { "0", "1", 1 },
466     { "1", "1", 1 },
467     { "2", "1", 1 },
468     { "3", "1", 1 },
469     { "4", "1", 1 },
470     { "5", "1", 1 },
471
472     /* (0/b) = 0, b != 1 */
473     { "0",  "3", 0 },
474     { "0",  "5", 0 },
475     { "0",  "7", 0 },
476     { "0",  "9", 0 },
477     { "0", "11", 0 },
478     { "0", "13", 0 },
479     { "0", "15", 0 },
480
481     /* (1/b) = 1 */
482     { "1",  "1", 1 },
483     { "1",  "3", 1 },
484     { "1",  "5", 1 },
485     { "1",  "7", 1 },
486     { "1",  "9", 1 },
487     { "1", "11", 1 },
488
489     /* (-1/b) = (-1)^((b-1)/2) which is -1 for b==3 mod 4 */
490     { "-1",  "1",  1 },
491     { "-1",  "3", -1 },
492     { "-1",  "5",  1 },
493     { "-1",  "7", -1 },
494     { "-1",  "9",  1 },
495     { "-1", "11", -1 },
496     { "-1", "13",  1 },
497     { "-1", "15", -1 },
498     { "-1", "17",  1 },
499     { "-1", "19", -1 },
500
501     /* (2/b) = (-1)^((b^2-1)/8) which is -1 for b==3,5 mod 8.
502        try_2num() will exercise multiple powers of 2 in the numerator.  */
503     { "2",  "1",  1 },
504     { "2",  "3", -1 },
505     { "2",  "5", -1 },
506     { "2",  "7",  1 },
507     { "2",  "9",  1 },
508     { "2", "11", -1 },
509     { "2", "13", -1 },
510     { "2", "15",  1 },
511     { "2", "17",  1 },
512
513     /* (-2/b) = (-1)^((b^2-1)/8)*(-1)^((b-1)/2) which is -1 for b==5,7mod8.
514        try_2num() will exercise multiple powers of 2 in the numerator, which
515        will test that the shift in mpz_si_kronecker() uses unsigned not
516        signed.  */
517     { "-2",  "1",  1 },
518     { "-2",  "3",  1 },
519     { "-2",  "5", -1 },
520     { "-2",  "7", -1 },
521     { "-2",  "9",  1 },
522     { "-2", "11",  1 },
523     { "-2", "13", -1 },
524     { "-2", "15", -1 },
525     { "-2", "17",  1 },
526
527     /* (a/2)=(2/a).
528        try_2den() will exercise multiple powers of 2 in the denominator. */
529     {  "3",  "2", -1 },
530     {  "5",  "2", -1 },
531     {  "7",  "2",  1 },
532     {  "9",  "2",  1 },
533     {  "11", "2", -1 },
534
535     /* Harriet Griffin, "Elementary Theory of Numbers", page 155, various
536        examples.  */
537     {   "2", "135",  1 },
538     { "135",  "19", -1 },
539     {   "2",  "19", -1 },
540     {  "19", "135",  1 },
541     { "173", "135",  1 },
542     {  "38", "135",  1 },
543     { "135", "173",  1 },
544     { "173",   "5", -1 },
545     {   "3",   "5", -1 },
546     {   "5", "173", -1 },
547     { "173",   "3", -1 },
548     {   "2",   "3", -1 },
549     {   "3", "173", -1 },
550     { "253",  "21",  1 },
551     {   "1",  "21",  1 },
552     {  "21", "253",  1 },
553     {  "21",  "11", -1 },
554     {  "-1",  "11", -1 },
555
556     /* Griffin page 147 */
557     {  "-1",  "17",  1 },
558     {   "2",  "17",  1 },
559     {  "-2",  "17",  1 },
560     {  "-1",  "89",  1 },
561     {   "2",  "89",  1 },
562
563     /* Griffin page 148 */
564     {  "89",  "11",  1 },
565     {   "1",  "11",  1 },
566     {  "89",   "3", -1 },
567     {   "2",   "3", -1 },
568     {   "3",  "89", -1 },
569     {  "11",  "89",  1 },
570     {  "33",  "89", -1 },
571
572     /* H. Davenport, "The Higher Arithmetic", page 65, the quadratic
573        residues and non-residues mod 19.  */
574     {  "1", "19",  1 },
575     {  "4", "19",  1 },
576     {  "5", "19",  1 },
577     {  "6", "19",  1 },
578     {  "7", "19",  1 },
579     {  "9", "19",  1 },
580     { "11", "19",  1 },
581     { "16", "19",  1 },
582     { "17", "19",  1 },
583     {  "2", "19", -1 },
584     {  "3", "19", -1 },
585     {  "8", "19", -1 },
586     { "10", "19", -1 },
587     { "12", "19", -1 },
588     { "13", "19", -1 },
589     { "14", "19", -1 },
590     { "15", "19", -1 },
591     { "18", "19", -1 },
592
593     /* Residues and non-residues mod 13 */
594     {  "0",  "13",  0 },
595     {  "1",  "13",  1 },
596     {  "2",  "13", -1 },
597     {  "3",  "13",  1 },
598     {  "4",  "13",  1 },
599     {  "5",  "13", -1 },
600     {  "6",  "13", -1 },
601     {  "7",  "13", -1 },
602     {  "8",  "13", -1 },
603     {  "9",  "13",  1 },
604     { "10",  "13",  1 },
605     { "11",  "13", -1 },
606     { "12",  "13",  1 },
607
608     /* various */
609     {  "5",   "7", -1 },
610     { "15",  "17",  1 },
611     { "67",  "89",  1 },
612
613     /* special values inducing a==b==1 at the end of jac_or_kron() */
614     { "0x10000000000000000000000000000000000000000000000001",
615       "0x10000000000000000000000000000000000000000000000003", 1 },
616   };
617
618   int    i;
619   mpz_t  a, b;
620
621   mpz_init (a);
622   mpz_init (b);
623
624   for (i = 0; i < numberof (data); i++)
625     {
626       mpz_set_str_or_abort (a, data[i].a, 0);
627       mpz_set_str_or_abort (b, data[i].b, 0);
628       try_all (a, b, data[i].answer);
629     }
630
631   mpz_clear (a);
632   mpz_clear (b);
633 }
634
635
636 /* (a^2/b)=1 if gcd(a,b)=1, or (a^2/b)=0 if gcd(a,b)!=1.
637    This includes when a=0 or b=0. */
638 void
639 check_squares_zi (void)
640 {
641   gmp_randstate_ptr rands = RANDS;
642   mpz_t  a, b, g;
643   int    i, answer;
644   mp_size_t size_range, an, bn;
645   mpz_t bs;
646
647   mpz_init (bs);
648   mpz_init (a);
649   mpz_init (b);
650   mpz_init (g);
651
652   for (i = 0; i < 50; i++)
653     {
654       mpz_urandomb (bs, rands, 32);
655       size_range = mpz_get_ui (bs) % 10 + 2;
656
657       mpz_urandomb (bs, rands, size_range);
658       an = mpz_get_ui (bs);
659       mpz_rrandomb (a, rands, an);
660
661       mpz_urandomb (bs, rands, size_range);
662       bn = mpz_get_ui (bs);
663       mpz_rrandomb (b, rands, bn);
664
665       mpz_gcd (g, a, b);
666       if (mpz_cmp_ui (g, 1L) == 0)
667         answer = 1;
668       else
669         answer = 0;
670
671       mpz_mul (a, a, a);
672
673       try_all (a, b, answer);
674     }
675
676   mpz_clear (bs);
677   mpz_clear (a);
678   mpz_clear (b);
679   mpz_clear (g);
680 }
681
682
683 /* Check the handling of asize==0, make sure it isn't affected by the low
684    limb. */
685 void
686 check_a_zero (void)
687 {
688   mpz_t  a, b;
689
690   mpz_init_set_ui (a, 0);
691   mpz_init (b);
692
693   mpz_set_ui (b, 1L);
694   PTR(a)[0] = 0;
695   try_all (a, b, 1);   /* (0/1)=1 */
696   PTR(a)[0] = 1;
697   try_all (a, b, 1);   /* (0/1)=1 */
698
699   mpz_set_si (b, -1L);
700   PTR(a)[0] = 0;
701   try_all (a, b, 1);   /* (0/-1)=1 */
702   PTR(a)[0] = 1;
703   try_all (a, b, 1);   /* (0/-1)=1 */
704
705   mpz_set_ui (b, 0);
706   PTR(a)[0] = 0;
707   try_all (a, b, 0);   /* (0/0)=0 */
708   PTR(a)[0] = 1;
709   try_all (a, b, 0);   /* (0/0)=0 */
710
711   mpz_set_ui (b, 2);
712   PTR(a)[0] = 0;
713   try_all (a, b, 0);   /* (0/2)=0 */
714   PTR(a)[0] = 1;
715   try_all (a, b, 0);   /* (0/2)=0 */
716
717   mpz_clear (a);
718   mpz_clear (b);
719 }
720
721
722 int
723 main (int argc, char *argv[])
724 {
725   tests_start ();
726
727   if (argc >= 2 && strcmp (argv[1], "-p") == 0)
728     {
729       option_pari = 1;
730
731       printf ("\
732 try(a,b,answer) =\n\
733 {\n\
734   if (kronecker(a,b) != answer,\n\
735     print(\"wrong at \", a, \",\", b,\n\
736       \" expected \", answer,\n\
737       \" pari says \", kronecker(a,b)))\n\
738 }\n");
739     }
740
741   check_data ();
742   check_squares_zi ();
743   check_a_zero ();
744
745   tests_end ();
746   exit (0);
747 }