1 // -*- C++ -*-
2 //==============================================================================================
3 //
4 // This file is part of LiDIA --- a library for computational number theory
5 //
6 // Copyright (c) 1994--2001 the LiDIA Group. All rights reserved.
7 //
8 // See http://www.informatik.tu-darmstadt.de/TI/LiDIA/
9 //
10 //----------------------------------------------------------------------------------------------
11 //
12 // $Id$
13 //
14 // Author : Markus Maurer (MM)
15 // Changes : See CVS log
16 //
17 //==============================================================================================
18
19
20 #ifndef LIDIA_BIGMOD_H_GUARD_
21 #define LIDIA_BIGMOD_H_GUARD_
22
23
24
25 #ifndef LIDIA_UDIGIT_H_GUARD_
26 # include "LiDIA/udigit.h"
27 #endif
28 #ifndef LIDIA_BASE_BIGMOD_H_GUARD_
29 # include "LiDIA/base/base_bigmod.h"
30 #endif
31
32
33
34 #ifdef LIDIA_NAMESPACE
35 namespace LiDIA {
36 # define IN_NAMESPACE_LIDIA
37 #endif
38
39
40
41 class multi_bigmod;
42
43
44
45 class bigmod : public base_bigmod
46 {
47 private :
48
49 #ifndef HEADBANGER
50 static LiDIA::residue_class< bigint > *Mp;
51 #endif
52 static bigint M;
53
54 public :
55
56 //
57 // class modifiers and accessors
58 //
59
60 static void set_modulus (const bigint & m);
61 static const bigint & modulus ();
62 static LiDIA::residue_class< bigint > * residue_class();
63
64
65 //
66 // class properties
67 //
68
69 static const bigint & characteristic ();
70
71
72
73 //
74 // c'tors and d'tor
75 //
76
77 bigmod ();
78 bigmod (int i);
79 bigmod (long l);
80 bigmod (unsigned long ul);
81 bigmod (double d);
82 bigmod (const bigint & i);
83 bigmod (const bigmod & a);
84 virtual ~bigmod ();
85
86
87
88 #ifndef HEADBANGER
89
90 //
91 // assigners
92 //
93
94 void assign_zero ();
95 void assign_one ();
96
97 void assign (int i);
98 void assign (long l);
99 void assign (unsigned long ul);
100 void assign (double d);
101 void assign (const bigint & a);
102 void assign (const bigmod & a);
103
104 #endif // HEADBANGER
105
106 bigmod & operator = (int i);
107 bigmod & operator = (long l);
108 bigmod & operator = (unsigned long ul);
109 bigmod & operator = (double d);
110 bigmod & operator = (const bigint & a);
111 bigmod & operator = (const bigmod & a);
112
113
114
115 //
116 // comparators
117 //
118
119 bool is_equal(const bigmod &) const;
120 bool is_equal(const bigint &) const;
121 bool is_equal(long) const;
122 bool is_equal(unsigned long) const;
123
124
125
126 //
127 // modifiers
128 //
129
130 bigint invert (int verbose = 0);
131 void negate ();
132 void normalize ();
133
134 void inc();
135 void dec();
136
137 void multiply_by_2 ();
138 void divide_by_2 ();
139
140 void randomize ();
141
142 void swap(bigmod & a);
143
144
145
146 //
147 // I/O
148 //
149
150 friend std::istream & operator >> (std::istream & in, bigmod & a);
151 friend std::ostream & operator << (std::ostream & out, const bigmod & a);
152
153 friend int string_to_bigmod (char * s, bigmod & a);
154 friend int bigmod_to_string (const bigmod & a, char * s);
155
156 #ifdef C_STDIO
157
158 void read_from_file (FILE * fp);
159 void write_to_file (FILE * fp);
160 void scan_from_file (FILE * fp);
161 void print_to_file (FILE * fp);
162
163 #endif // C_STDIO
164
165 };
166
167
168 //
169 // I/O
170 //
171
172 std::istream & operator >> (std::istream & in, bigmod & a);
173 std::ostream & operator << (std::ostream & out, const bigmod & a);
174
175 int string_to_bigmod (char * s, bigmod & a);
176 int bigmod_to_string (const bigmod & a, char * s);
177
178 //
179 // class accessors
180 //
181
182 inline const bigint &
modulus()183 bigmod::modulus ()
184 {
185 return bigmod::M;
186 }
187
188
189
190 inline
191 LiDIA::residue_class< bigint > *
residue_class()192 bigmod::residue_class ()
193 {
194 return bigmod::Mp;
195 }
196
197
198
199 //
200 // normalizer (inline definition must precede c'tors and assigners)
201 //
202
203 inline void
normalize()204 bigmod::normalize ()
205 {
206 base_bigmod::normalize(bigmod::M);
207 }
208
209
210
211 //
212 // c'tors and d'tor
213 //
214
215 inline
bigmod()216 bigmod::bigmod ()
217 : base_bigmod()
218 {
219 // nothing to do
220 }
221
222
223
224 inline
bigmod(int i)225 bigmod::bigmod (int i)
226 : base_bigmod(i)
227 {
228 normalize();
229 }
230
231
232
233 inline
bigmod(long l)234 bigmod::bigmod (long l)
235 : base_bigmod(l)
236 {
237 normalize();
238 }
239
240
241
242 inline
bigmod(unsigned long ul)243 bigmod::bigmod (unsigned long ul)
244 : base_bigmod(ul)
245 {
246 normalize();
247 }
248
249
250
251 inline
bigmod(double d)252 bigmod::bigmod (double d)
253 : base_bigmod(d)
254 {
255 normalize();
256 }
257
258
259
260 inline
bigmod(const bigint & i)261 bigmod::bigmod (const bigint & i)
262 : base_bigmod(i)
263 {
264 normalize();
265 }
266
267
268
269 inline
bigmod(const bigmod & a)270 bigmod::bigmod (const bigmod & a)
271 : base_bigmod(a.I)
272 {
273 // nothing to do
274 }
275
276
277
278 inline
~bigmod()279 bigmod::~bigmod ()
280 {
281 }
282
283
284
285 //
286 // assigners
287 //
288
289 inline void
assign_zero()290 bigmod::assign_zero ()
291 {
292 I.assign_zero();
293 }
294
295
296
297 inline void
assign_one()298 bigmod::assign_one ()
299 {
300 I.assign_one();
301 }
302
303
304
305 inline void
assign(int i)306 bigmod::assign (int i)
307 {
308 I.assign(i);
309 normalize();
310 }
311
312
313
314
315 inline void
assign(long l)316 bigmod::assign (long l)
317 {
318 I.assign(l);
319 normalize();
320 }
321
322
323
324 inline void
assign(unsigned long ul)325 bigmod::assign (unsigned long ul)
326 {
327 I.assign(ul);
328 normalize();
329 }
330
331
332
333 inline void
assign(double d)334 bigmod::assign (double d)
335 {
336 I.assign(d);
337 normalize();
338 }
339
340
341
342 inline void
assign(const bigint & a)343 bigmod::assign (const bigint & a)
344 {
345 I.assign(a);
346 normalize();
347 }
348
349
350
351 inline void
assign(const bigmod & a)352 bigmod::assign (const bigmod & a)
353 {
354 if (&a != this) {
355 I.assign(a.I);
356 }
357 }
358
359
360
361 inline bigmod &
362 bigmod::operator = (int i)
363 {
364 assign(i);
365 return *this;
366 }
367
368
369
370 inline bigmod &
371 bigmod::operator = (long l)
372 {
373 assign(l);
374 return *this;
375 }
376
377
378
379 inline bigmod &
380 bigmod::operator = (unsigned long ul)
381 {
382 assign(ul);
383 return *this;
384 }
385
386
387
388 inline bigmod &
389 bigmod::operator = (double d)
390 {
391 assign(d);
392 return *this;
393 }
394
395
396
397 inline bigmod &
398 bigmod::operator = (const bigint & a)
399 {
400 assign(a);
401 return *this;
402 }
403
404
405
406 inline bigmod &
407 bigmod::operator = (const bigmod & a)
408 {
409 assign(a);
410 return *this;
411 }
412
413
414
415 //
416 // comparators
417 //
418
419 inline bool
is_equal(const bigmod & a)420 bigmod::is_equal (const bigmod & a) const
421 {
422 return (&a == this || I.compare(a.I) == 0);
423 }
424
425
426
427 inline bool
is_equal(const bigint & a)428 bigmod::is_equal (const bigint & a) const
429 {
430 return a.is_ge_zero() ?
431 (I.compare(a) == 0) : (I.compare(M + a) == 0);
432 }
433
434
435
436 inline bool
is_equal(long a)437 bigmod::is_equal (long a) const
438 {
439 return a >= 0 ?
440 (I.compare(a) == 0) : (I.compare(M + a) == 0);
441 }
442
443
444
445 inline bool
is_equal(unsigned long a)446 bigmod::is_equal (unsigned long a) const
447 {
448 return I.compare(a) == 0;
449 }
450
451
452
453 inline bool
454 operator == (const bigmod & a, const bigmod & b)
455 {
456 return a.is_equal(b);
457 }
458
459
460
461 inline bool
462 operator == (const bigmod & a, const bigint & b)
463 {
464 return a.is_equal(b);
465 }
466
467
468
469 inline bool
470 operator == (const bigmod & a, long b)
471 {
472 return a.is_equal(b);
473 }
474
475
476
477 inline bool
478 operator == (const bigmod & a, unsigned long b)
479 {
480 return a.is_equal(b);
481 }
482
483
484
485 inline bool
486 operator == (const bigmod & a, int b)
487 {
488 return a.is_equal(static_cast<long>(b));
489 }
490
491
492
493 inline bool
494 operator == (const bigint & a, const bigmod & b)
495 {
496 return b.is_equal(a);
497 }
498
499
500
501 inline bool
502 operator == (long a, const bigmod & b)
503 {
504 return b.is_equal(a);
505 }
506
507
508
509 inline bool
510 operator == (unsigned long a, const bigmod & b)
511 {
512 return b.is_equal(a);
513 }
514
515
516
517 inline bool
518 operator == (int a, const bigmod & b)
519 {
520 return b.is_equal(static_cast<long>(a));
521 }
522
523
524
525 inline bool
526 operator != (const bigmod & a, const bigmod & b)
527 {
528 return !a.is_equal(b);
529 }
530
531
532
533 inline bool
534 operator != (const bigmod & a, const bigint & b)
535 {
536 return !a.is_equal(b);
537 }
538
539
540
541 inline bool
542 operator != (const bigmod & a, long b)
543 {
544 return !a.is_equal(b);
545 }
546
547
548
549 inline bool
550 operator != (const bigmod & a, unsigned long b)
551 {
552 return !a.is_equal(b);
553 }
554
555
556
557 inline bool
558 operator != (const bigmod & a, int b)
559 {
560 return !a.is_equal(static_cast<long>(b));
561 }
562
563
564
565 inline bool
566 operator != (const bigint & a, const bigmod & b)
567 {
568 return !b.is_equal(a);
569 }
570
571
572
573 inline bool
574 operator != (long a, const bigmod & b)
575 {
576 return !b.is_equal(a);
577 }
578
579
580
581 inline bool
582 operator != (unsigned long a, const bigmod & b)
583 {
584 return !b.is_equal(a);
585 }
586
587
588
589 inline bool
590 operator != (int a, const bigmod & b)
591 {
592 return !b.is_equal(static_cast<long>(a));
593 }
594
595
596
597 //
598 // modifiers
599 //
600
601 inline bigint
invert(int verbose)602 bigmod::invert (int verbose)
603 {
604 return base_bigmod::invert(bigmod::M, verbose);
605 }
606
607
608
609 inline void
negate()610 bigmod::negate ()
611 {
612 base_bigmod::negate(bigmod::M);
613 }
614
615
616
617 inline void
inc()618 bigmod::inc ()
619 {
620 base_bigmod::inc(bigmod::M);
621 }
622
623
624
625 inline void
dec()626 bigmod::dec ()
627 {
628 base_bigmod::dec(bigmod::M);
629 }
630
631
632
633 inline void
multiply_by_2()634 bigmod::multiply_by_2 ()
635 {
636 base_bigmod::multiply_by_2(bigmod::M);
637 }
638
639
640
641 inline void
divide_by_2()642 bigmod::divide_by_2 ()
643 {
644 base_bigmod::divide_by_2(bigmod::M);
645 }
646
647
648
649 inline void
swap(bigmod & a)650 bigmod::swap (bigmod & a)
651 {
652 I.swap(a.I);
653 }
654
655
656
657 //
658 // arithmetic procedures
659 //
660
661 inline void
normalize(bigmod & a,const bigmod & b)662 normalize (bigmod & a, const bigmod & b)
663 {
664 a.assign(b);
665 a.normalize();
666 }
667
668
669
670 inline void
invert(bigmod & a,const bigmod & b)671 invert (bigmod & a, const bigmod & b)
672 {
673 a.assign(b);
674 a.invert();
675 }
676
677
678
679 inline void
negate(bigmod & a,const bigmod & b)680 negate (bigmod & a, const bigmod & b)
681 {
682 a.assign(b);
683 a.negate();
684 }
685
686
687
688 inline void
add(bigmod & c,const bigmod & a,const bigmod & b)689 add (bigmod & c, const bigmod & a, const bigmod & b)
690 {
691 add(c, a, b, bigmod::modulus());
692 }
693
694
695
696 inline void
add(bigmod & c,const bigmod & a,const bigint & b)697 add (bigmod & c, const bigmod & a, const bigint & b)
698 {
699 add(c, a, b, bigmod::modulus());
700 }
701
702
703
704 inline void
add(bigmod & c,const bigmod & a,long b)705 add (bigmod & c, const bigmod & a, long b)
706 {
707 add(c, a, b, bigmod::modulus());
708 }
709
710
711
712 inline void
add(bigmod & c,const bigmod & a,unsigned long b)713 add (bigmod & c, const bigmod & a, unsigned long b)
714 {
715 add(c, a, b, bigmod::modulus());
716 }
717
718
719
720 inline void
add(bigmod & c,const bigmod & a,int b)721 add (bigmod & c, const bigmod & a, int b)
722 {
723 add(c, a, static_cast<long>(b));
724 }
725
726
727
728 inline void
subtract(bigmod & c,const bigmod & a,const bigmod & b)729 subtract (bigmod & c, const bigmod & a, const bigmod & b)
730 {
731 subtract(c, a, b, bigmod::modulus());
732 }
733
734
735
736 inline void
subtract(bigmod & c,const bigmod & a,const bigint & b)737 subtract (bigmod & c, const bigmod & a, const bigint & b)
738 {
739 subtract(c, a, b, bigmod::modulus());
740 }
741
742
743
744 inline void
subtract(bigmod & c,const bigmod & a,long b)745 subtract (bigmod & c, const bigmod & a, long b)
746 {
747 subtract(c, a, b, bigmod::modulus());
748 }
749
750
751
752 inline void
subtract(bigmod & c,const bigmod & a,unsigned long b)753 subtract (bigmod & c, const bigmod & a, unsigned long b)
754 {
755 subtract(c, a, b, bigmod::modulus());
756 }
757
758
759
760 inline void
subtract(bigmod & c,const bigmod & a,int b)761 subtract (bigmod & c, const bigmod & a, int b)
762 {
763 subtract(c, a, static_cast<long>(b));
764 }
765
766
767
768 inline void
multiply(bigmod & c,const bigmod & a,const bigmod & b)769 multiply (bigmod & c, const bigmod & a, const bigmod & b)
770 {
771 multiply(c, a, b, bigmod::modulus());
772 }
773
774
775
776 inline void
multiply(bigmod & c,const bigmod & a,const bigint & b)777 multiply (bigmod & c, const bigmod & a, const bigint & b)
778 {
779 multiply(c, a, b, bigmod::modulus());
780 }
781
782
783
784 inline void
multiply(bigmod & c,const bigmod & a,long b)785 multiply (bigmod & c, const bigmod & a, long b)
786 {
787 multiply(c, a, b, bigmod::modulus());
788 }
789
790
791
792 inline void
multiply(bigmod & c,const bigmod & a,unsigned long b)793 multiply (bigmod & c, const bigmod & a, unsigned long b)
794 {
795 multiply(c, a, b, bigmod::modulus());
796 }
797
798
799
800 inline void
multiply(bigmod & c,const bigmod & a,int b)801 multiply (bigmod & c, const bigmod & a, int b)
802 {
803 multiply(c, a, static_cast<long>(b));
804 }
805
806
807
808 inline void
square(bigmod & c,const bigmod & a)809 square (bigmod & c, const bigmod & a)
810 {
811 square(c, a, bigmod::modulus());
812 }
813
814
815
816 inline void
square(bigmod & c,const bigint & a)817 square (bigmod & c, const bigint & a)
818 {
819 square(c, a, bigmod::modulus());
820 }
821
822
823
824 inline void
divide(bigmod & c,const bigmod & a,const bigmod & b)825 divide (bigmod & c, const bigmod & a, const bigmod & b)
826 {
827 divide(c, a, b, bigmod::modulus());
828 }
829
830
831
832 inline void
divide(bigmod & c,const bigmod & a,const bigint & b)833 divide (bigmod & c, const bigmod & a, const bigint & b)
834 {
835 divide(c, a, b, bigmod::modulus());
836 }
837
838
839
840 inline void
divide(bigmod & c,const bigmod & a,long b)841 divide (bigmod & c, const bigmod & a, long b)
842 {
843 divide(c, a, b, bigmod::modulus());
844 }
845
846
847
848 inline void
divide(bigmod & c,const bigmod & a,unsigned long b)849 divide (bigmod & c, const bigmod & a, unsigned long b)
850 {
851 divide(c, a, b, bigmod::modulus());
852 }
853
854
855
856 inline void
divide(bigmod & c,const bigmod & a,int b)857 divide (bigmod & c, const bigmod & a, int b)
858 {
859 divide(c, a, static_cast<long>(b));
860 }
861
862
863
864 inline void
power(bigmod & c,const bigmod & a,const bigint & b)865 power (bigmod & c, const bigmod & a, const bigint & b)
866 {
867 power(c, a, b, bigmod::modulus());
868 }
869
870
871
872 inline void
power(bigmod & c,const bigmod & a,long b)873 power (bigmod & c, const bigmod & a, long b)
874 {
875 power(c, a, b, bigmod::modulus());
876 }
877
878
879
880 inline void
inc(bigmod & c)881 inc (bigmod & c)
882 {
883 c.inc();
884 }
885
886
887
888 inline void
dec(bigmod & c)889 dec (bigmod & c)
890 {
891 c.dec();
892 }
893
894
895
896 //
897 // arithmetic operators
898 //
899
900 inline bigmod
901 operator - (const bigmod & a)
902 {
903 bigmod c(a);
904
905 c.negate();
906 return c;
907 }
908
909
910
911 inline bigmod
912 operator + (const bigmod & a, const bigmod & b)
913 {
914 bigmod c;
915
916 add(c, a, b);
917 return c;
918 }
919
920
921
922 inline bigmod
923 operator + (const bigmod & a, const bigint & b)
924 {
925 bigmod c;
926
927 add(c, a, b);
928 return c;
929 }
930
931
932
933 inline bigmod
934 operator + (const bigmod & a, int b)
935 {
936 bigmod c;
937
938 add(c, a, static_cast<long>(b));
939 return c;
940 }
941
942
943
944 inline bigmod
945 operator + (const bigmod & a, long b)
946 {
947 bigmod c;
948
949 add(c, a, b);
950 return c;
951 }
952
953
954
955 inline bigmod
956 operator + (const bigmod & a, unsigned long b)
957 {
958 bigmod c;
959
960 add(c, a, b);
961 return c;
962 }
963
964
965
966 inline bigmod
967 operator + (const bigint & a, const bigmod & b)
968 {
969 bigmod c;
970
971 add(c, b, a);
972 return c;
973 }
974
975
976
977 inline bigmod
978 operator + (int a, const bigmod & b)
979 {
980 bigmod c;
981
982 add(c, b, static_cast<long>(a));
983 return c;
984 }
985
986
987
988 inline bigmod
989 operator + (long a, const bigmod & b)
990 {
991 bigmod c;
992
993 add(c, b, a);
994 return c;
995 }
996
997
998
999 inline bigmod
1000 operator + (unsigned long a, const bigmod & b)
1001 {
1002 bigmod c;
1003
1004 add(c, b, a);
1005 return c;
1006 }
1007
1008
1009
1010 inline bigmod
1011 operator - (const bigmod & a, const bigmod & b)
1012 {
1013 bigmod c;
1014
1015 subtract(c, a, b);
1016 return c;
1017 }
1018
1019
1020
1021 inline bigmod
1022 operator - (const bigmod & a, const bigint & b)
1023 {
1024 bigmod c;
1025
1026 subtract(c, a, b);
1027 return c;
1028 }
1029
1030
1031
1032 inline bigmod
1033 operator - (const bigmod & a, int b)
1034 {
1035 bigmod c;
1036
1037 subtract(c, a, static_cast<long>(b));
1038 return c;
1039 }
1040
1041
1042
1043 inline bigmod
1044 operator - (const bigmod & a, long b)
1045 {
1046 bigmod c;
1047
1048 subtract(c, a, b);
1049 return c;
1050 }
1051
1052
1053
1054 inline bigmod
1055 operator - (const bigmod & a, unsigned long b)
1056 {
1057 bigmod c;
1058
1059 subtract(c, a, b);
1060 return c;
1061 }
1062
1063
1064
1065 inline bigmod
1066 operator - (const bigint & a, const bigmod & b)
1067 {
1068 bigmod c;
1069
1070 subtract(c, b, a);
1071 c.negate();
1072 return c;
1073 }
1074
1075
1076
1077 inline bigmod
1078 operator - (int a, const bigmod & b)
1079 {
1080 bigmod c;
1081
1082 subtract(c, b, static_cast<long>(a));
1083 c.negate();
1084 return c;
1085 }
1086
1087
1088
1089 inline bigmod
1090 operator - (long a, const bigmod & b)
1091 {
1092 bigmod c;
1093
1094 subtract(c, b, a);
1095 c.negate();
1096 return c;
1097 }
1098
1099
1100
1101 inline bigmod
1102 operator - (unsigned long a, const bigmod & b)
1103 {
1104 bigmod c;
1105
1106 subtract(c, b, a);
1107 c.negate();
1108 return c;
1109 }
1110
1111
1112
1113 inline bigmod
1114 operator * (const bigmod & a, const bigmod & b)
1115 {
1116 bigmod c;
1117
1118 multiply(c, a, b);
1119 return c;
1120 }
1121
1122
1123
1124 inline bigmod
1125 operator * (const bigmod & a, const bigint & b)
1126 {
1127 bigmod c;
1128
1129 multiply(c, a, b);
1130 return c;
1131 }
1132
1133
1134
1135 inline bigmod
1136 operator * (const bigmod & a, int b)
1137 {
1138 bigmod c;
1139
1140 multiply(c, a, static_cast<long>(b));
1141 return c;
1142 }
1143
1144
1145
1146 inline bigmod
1147 operator * (const bigmod & a, long b)
1148 {
1149 bigmod c;
1150
1151 multiply(c, a, b);
1152 return c;
1153 }
1154
1155
1156
1157 inline bigmod
1158 operator * (const bigmod & a, unsigned long b)
1159 {
1160 bigmod c;
1161
1162 multiply(c, a, b);
1163 return c;
1164 }
1165
1166
1167
1168 inline bigmod
1169 operator * (const bigint & a, const bigmod & b)
1170 {
1171 bigmod c;
1172
1173 multiply(c, b, a);
1174 return c;
1175 }
1176
1177
1178
1179 inline bigmod
1180 operator * (int a, const bigmod & b)
1181 {
1182 bigmod c;
1183
1184 multiply(c, b, static_cast<long>(a));
1185 return c;
1186 }
1187
1188
1189
1190 inline bigmod
1191 operator * (long a, const bigmod & b)
1192 {
1193 bigmod c;
1194
1195 multiply(c, b, a);
1196 return c;
1197 }
1198
1199
1200
1201 inline bigmod
1202 operator * (unsigned long a, const bigmod & b)
1203 {
1204 bigmod c;
1205
1206 multiply(c, b, a);
1207 return c;
1208 }
1209
1210
1211
1212 inline bigmod
1213 operator / (const bigmod & a, const bigmod & b)
1214 {
1215 bigmod c;
1216
1217 divide(c, a, b);
1218 return c;
1219 }
1220
1221
1222
1223 inline bigmod
1224 operator / (const bigmod & a, const bigint & b)
1225 {
1226 bigmod c;
1227
1228 divide(c, a, b);
1229 return c;
1230 }
1231
1232
1233
1234 inline bigmod
1235 operator / (const bigmod & a, int b)
1236 {
1237 bigmod c;
1238
1239 divide(c, a, static_cast<long>(b));
1240 return c;
1241 }
1242
1243
1244
1245 inline bigmod
1246 operator / (const bigmod & a, long b)
1247 {
1248 bigmod c;
1249
1250 divide(c, a, b);
1251 return c;
1252 }
1253
1254
1255
1256 inline bigmod
1257 operator / (const bigmod & a, unsigned long b)
1258 {
1259 bigmod c;
1260
1261 divide(c, a, b);
1262 return c;
1263 }
1264
1265
1266
1267 inline bigmod
1268 operator / (const bigint & a, const bigmod & b)
1269 {
1270 bigmod c;
1271
1272 divide(c, b, a);
1273 c.invert();
1274 return c;
1275 }
1276
1277
1278
1279 inline bigmod
1280 operator / (int a, const bigmod & b)
1281 {
1282 bigmod c;
1283
1284 divide(c, b, static_cast<long>(a));
1285 c.invert();
1286 return c;
1287 }
1288
1289
1290
1291 inline bigmod
1292 operator / (long a, const bigmod & b)
1293 {
1294 bigmod c;
1295
1296 divide(c, b, a);
1297 c.invert();
1298 return c;
1299 }
1300
1301
1302
1303 inline bigmod
1304 operator / (unsigned long a, const bigmod & b)
1305 {
1306 bigmod c;
1307
1308 divide(c, b, a);
1309 c.invert();
1310 return c;
1311 }
1312
1313
1314
1315 inline bigmod &
1316 operator += (bigmod & a, const bigmod & b)
1317 {
1318 add(a, a, b);
1319 return a;
1320 }
1321
1322
1323
1324 inline bigmod &
1325 operator += (bigmod & a, const bigint & b)
1326 {
1327 add(a, a, b);
1328 return a;
1329 }
1330
1331
1332
1333 inline bigmod &
1334 operator += (bigmod & a, int b)
1335 {
1336 add(a, a, static_cast<long>(b));
1337 return a;
1338 }
1339
1340
1341
1342 inline bigmod &
1343 operator += (bigmod & a, long b)
1344 {
1345 add(a, a, b);
1346 return a;
1347 }
1348
1349
1350
1351 inline bigmod &
1352 operator += (bigmod & a, unsigned long b)
1353 {
1354 add(a, a, b);
1355 return a;
1356 }
1357
1358
1359
1360 inline bigmod &
1361 operator -= (bigmod & a, const bigmod & b)
1362 {
1363 subtract(a, a, b);
1364 return a;
1365 }
1366
1367
1368
1369 inline bigmod &
1370 operator -= (bigmod & a, const bigint & b)
1371 {
1372 subtract(a, a, b);
1373 return a;
1374 }
1375
1376
1377
1378 inline bigmod &
1379 operator -= (bigmod & a, int b)
1380 {
1381 subtract(a, a, static_cast<long>(b));
1382 return a;
1383 }
1384
1385
1386
1387 inline bigmod &
1388 operator -= (bigmod & a, long b)
1389 {
1390 subtract(a, a, b);
1391 return a;
1392 }
1393
1394
1395
1396 inline bigmod &
1397 operator -= (bigmod & a, unsigned long b)
1398 {
1399 subtract(a, a, b);
1400 return a;
1401 }
1402
1403
1404
1405 inline bigmod &
1406 operator *= (bigmod & a, const bigmod & b)
1407 {
1408 multiply(a, a, b);
1409 return a;
1410 }
1411
1412
1413
1414 inline bigmod &
1415 operator *= (bigmod & a, const bigint & b)
1416 {
1417 multiply(a, a, b);
1418 return a;
1419 }
1420
1421
1422
1423 inline bigmod &
1424 operator *= (bigmod & a, int b)
1425 {
1426 multiply(a, a, static_cast<long>(b));
1427 return a;
1428 }
1429
1430
1431
1432 inline bigmod &
1433 operator *= (bigmod & a, long b)
1434 {
1435 multiply(a, a, b);
1436 return a;
1437 }
1438
1439
1440
1441 inline bigmod &
1442 operator *= (bigmod & a, unsigned long b)
1443 {
1444 multiply(a, a, b);
1445 return a;
1446 }
1447
1448
1449
1450 inline bigmod &
1451 operator /= (bigmod & a, const bigmod & b)
1452 {
1453 divide(a, a, b);
1454 return a;
1455 }
1456
1457
1458
1459 inline bigmod &
1460 operator /= (bigmod & a, const bigint & b)
1461 {
1462 divide(a, a, b);
1463 return a;
1464 }
1465
1466
1467
1468 inline bigmod &
1469 operator /= (bigmod & a, int b)
1470 {
1471 divide(a, a, static_cast<long>(b));
1472 return a;
1473 }
1474
1475
1476
1477 inline bigmod &
1478 operator /= (bigmod & a, long b)
1479 {
1480 divide(a, a, b);
1481 return a;
1482 }
1483
1484
1485
1486 inline bigmod &
1487 operator /= (bigmod & a, unsigned long b)
1488 {
1489 divide(a, a, b);
1490 return a;
1491 }
1492
1493
1494
1495 inline bigmod &
1496 operator ++ (bigmod & a)
1497 {
1498 a.inc();
1499 return a;
1500 }
1501
1502
1503
1504 inline bigmod
1505 operator ++ (bigmod & a, int)
1506 {
1507 bigmod c(a);
1508
1509 a.inc();
1510 return c;
1511 }
1512
1513
1514
1515 inline bigmod &
1516 operator -- (bigmod & a)
1517 {
1518 a.dec();
1519 return a;
1520 }
1521
1522
1523
1524 inline bigmod
1525 operator -- (bigmod & a, int)
1526 {
1527 bigmod c(a);
1528
1529 a.dec();
1530 return c;
1531 }
1532
1533
1534
1535 inline bool
1536 operator ! (const bigmod & a)
1537 {
1538 return a.is_zero();
1539 }
1540
1541
1542
1543 //
1544 // functions
1545 //
1546
1547 inline bigmod
inverse(const bigmod & a)1548 inverse (const bigmod & a)
1549 {
1550 bigmod c(a);
1551
1552 c.invert();
1553 return c;
1554 }
1555
1556
1557
1558 inline bigmod
randomize(const bigmod & a)1559 randomize (const bigmod & a)
1560 {
1561 bigmod c(randomize(a.mantissa()));
1562
1563 return c;
1564 }
1565
1566
1567
1568 //
1569 // misc. procedures
1570 //
1571
1572 inline void
swap(bigmod & a,bigmod & b)1573 swap (bigmod & a, bigmod & b)
1574 {
1575 a.swap(b);
1576 }
1577
1578
1579
1580 inline const bigint &
characteristic()1581 bigmod::characteristic ()
1582 {
1583 return bigmod::M;
1584 }
1585
1586
1587
1588 //
1589 // I/O
1590 //
1591
1592 std::istream & operator >> (std::istream & in, bigmod & a);
1593 std::ostream & operator << (std::ostream & out, const bigmod & a);
1594
1595 int string_to_bigmod (char * s, bigmod & a);
1596 int bigmod_to_string (const bigmod & a, char * s);
1597
1598
1599
1600 //
1601 // bigmod_lib functions
1602 //
1603
1604 //**** relative degree of element over prime field *************
1605
1606 inline unsigned int
get_relative_degree(const bigmod &)1607 get_relative_degree(const bigmod &)
1608 {
1609 return 1;
1610 }
1611
1612
1613 //**** absolute degree over prime field ************************
1614
1615 inline unsigned int
get_absolute_degree(const bigmod &)1616 get_absolute_degree(const bigmod &)
1617 {
1618 return 1;
1619 }
1620
1621
1622 //**** get generator of finite field ***************************
1623
1624 bigmod get_generator(const bigmod & x);
1625
1626
1627 //**** hash functions ******************************************
1628
1629 udigit hash(const bigmod & x);
1630
1631
1632 //**** is_square ***********************************************
1633
1634 bool is_square(const bigmod & a);
1635
1636
1637 //**** sqrt ****************************************************
1638
1639 bigmod sqrt(const bigmod & a);
1640
1641
1642 //**** solve_quadratic *****************************************
1643
1644 bool solve_quadratic(bigmod & root, const bigmod & a1,
1645 const bigmod & a0);
1646
1647
1648 //**** characteristic ******************************************
1649
1650 bigint characteristic(const bigmod & a);
1651
1652
1653 //**** number_of_elements **************************************
1654
1655 bigint number_of_elements(const bigmod & a);
1656
1657
1658
1659 #ifdef LIDIA_NAMESPACE
1660 } // end of namespace LiDIA
1661 # undef IN_NAMESPACE_LIDIA
1662 #endif
1663
1664
1665
1666 #define LIDIA_CLASS_BIGMOD
1667
1668
1669 #include "LiDIA/specialization/bigmod.special"
1670
1671
1672
1673 #endif // LIDIA_BIGMOD_H_GUARD_
1674