Orbiter 2022
Combinatorial Objects
integer.cpp
Go to the documentation of this file.
1// integer.cpp
2//
3// Anton Betten
4// 18.12.1998
5// moved from D2 to ORBI Nov 15, 2007
6
8#include "discreta.h"
9
10using namespace std;
11
12
13namespace orbiter {
14namespace layer2_discreta {
15
16#undef INTEGER_M_I_VERBOSE
17
19{
20 k = INTEGER;
21 clearself();
22}
23
25{
26 int i = atoi(p);
27
28 k = INTEGER;
29 clearself();
30 m_i((int) i);
31}
32
34{
35 k = INTEGER;
36 clearself();
37 m_i((int) i);
38}
39
41 // copy constructor: this := x
42{
43 // cout << "integer::copy constructor for object: "
44 //<< const_cast<discreta_base &>(x) << "\n";
45 clearself();
46 const_cast<discreta_base &>(x).copyobject_to(*this);
47}
48
50 // copy assignment
51{
52 // cout << "integer::operator = (copy assignment)" << endl;
53 copyobject(const_cast<discreta_base &>(x));
54 return *this;
55}
56
58{
59 // cout << "integer::settype_integer()\n";
60 new(this) integer;
61 k = INTEGER;
62}
63
65{
66 // cout << "~integer()\n";
68}
69
71{
72 // cout << "integer::freeself_integer()\n";
73 clearself();
74}
75
77{
78 return INTEGER;
79}
80
82{
83 // cout << "integer::copyobject_to()\n";
84 x.freeself();
85 integer &xx = x.change_to_integer();
86 xx.m_i( (int) s_i() );
87}
88
89ostream& integer::print(ostream& ost)
90{
91 domain *dom;
92#ifdef PRINT_WITH_TYPE
93 ost << "(INTEGER, ";
94#endif
95#if 0
96 if (dom && dom->type == GFp) {
97 ost << " mod " << dom->p.s_i_i();
98 }
99#endif
100 if (is_GFq_domain(dom)) {
101 unipoly a;
102 domain *sub_domain;
103 int p;
104
105 sub_domain = dom->sub_domain();
106 with w(sub_domain);
107 p = sub_domain->order_int();
108
109 a.numeric_polynomial(s_i(), p);
110 ost << a;
111 }
112 else {
113 ost << s_i();
114 }
115
116#ifdef PRINT_WITH_TYPE
117 ost << ")";
118#endif
119 return ost;
120}
121
123{
124 if (s_kind() != INTEGER) {
125 cout << "error: integer::m_i "
126 "this not an integer, converting\n";
127 exit(1);
128 // settype_integer();
129 }
131 return *this;
132}
133
135{
136 int i, j;
137 //domain *dom;
138
139 if (s_kind() != INTEGER) {
140 return compare_with(a);
141 }
142 if (a.s_kind() != INTEGER) {
143 if (a.s_kind() == LONGINTEGER) {
144 int r = a.as_longinteger().compare_with(*this);
145 return -r;
146 }
147 cout << "integer::compare_with "
148 "a is neither integer nor longinteger\n";
149 exit(1);
150 }
151#if 0
152 if (is_GFp_domain(dom)) {
153 m_i( remainder_mod(s_i(), dom->order_int()) );
154 a.m_i_i( remainder_mod(a.s_i_i(), dom->order_int()) );
155 }
156#endif
157 i = s_i();
158 j = a.s_i_i();
159 if (i < j)
160 return -1;
161 if (i > j)
162 return 1;
163 return 0;
164}
165
166
168{
169 domain *dom;
170
171 if (x.s_kind() == INTEGER) {
172
173 if (is_GFq_domain(dom)) {
174 unipoly a, b, c;
175 domain *sub_domain;
176 int p, res;
177
178 sub_domain = dom->sub_domain();
179 with w(sub_domain);
180 p = sub_domain->order_int();
181
182 a.numeric_polynomial(s_i(), p);
183 b.numeric_polynomial(x.s_i_i(), p);
184 c.mult_mod(a, b, *dom->factor_poly());
185 res = c.polynomial_numeric(p);
186 y.m_i_i(res);
187 }
188
189 else if (is_Orbiter_finite_field_domain(dom)) {
190 y.m_i_i(dom->get_F()->mult(s_i(), x.s_i_i()));
191 }
192 else {
193
194
195 int l1, l2, l3;
196
197 l1 = log2();
198 l2 = x.as_integer().log2();
199 l3 = l1 + l2;
200 if (l3 >= BITS_OF_int) {
201 longinteger a, b, c;
202
203 a.homo_z(s_i());
204 b.homo_z(x.s_i_i());
205 a.mult_to(b, c);
206 y = c;
207 return;
208 }
209 else {
210 if (is_GFp_domain(dom)) {
211 // cout << "integer::mult() GFp domain" << endl;
212 y.m_i_i( remainder_mod(s_i() * x.s_i_i(), dom->order_int()) );
213 }
214 else {
215 y.m_i_i( s_i() * x.s_i_i() );
216 }
217 }
218 }
219 }
220 else if (x.s_kind() == LONGINTEGER) {
221 longinteger a, b, c;
222
223 a.homo_z(s_i());
224 b = x;
225 a.mult_to(b, c);
226 y = c;
227 return;
228 }
229 else {
230 cout << "integer::mult_to() objectkind of x:";
231 x.printobjectkind(cout);
232 cout << endl;
233 exit(1);
234 }
235}
236
238{
239 int verbose_level = 1;
240 int f_v = (verbose_level >= 1);
241 int i;
242 domain *dom;
243
244 if (f_v) {
245 cout << "integer::invert_to" << endl;
246 }
247 if (s_kind() != INTEGER) {
248 cout << "integer::invert_to() this not an integer" << endl;
249 exit(1);
250 }
251 if (is_zero())
252 return FALSE;
253 i = s_i();
254 if (is_GFp_domain(dom)) {
255 if (f_v) {
256 cout << "integer::invert_to is_GFp_domain" << endl;
257 }
258 int a, p, av;
259
260 a = s_i();
261 if (f_v) {
262 cout << "integer::invert_to a=" << a << endl;
263 }
264 p = dom->order_int();
265 if (f_v) {
266 cout << "integer::invert_to p=" << p << endl;
267 }
268 av = invert_mod_integer(a, p);
269 if (f_v) {
270 cout << "integer::invert_to av=" << av << endl;
271 }
272 x.m_i_i( av );
273 return TRUE;
274 }
275 else if (is_GFq_domain(dom)) {
276 if (f_v) {
277 cout << "integer::invert_to is_GFq_domain" << endl;
278 }
279 unipoly a;
280 domain *sub_domain;
281 int p, res;
282
283 sub_domain = dom->sub_domain();
284 with w(sub_domain);
285 p = sub_domain->order_int();
286
287 a.numeric_polynomial(s_i(), p);
288#if 0
289 // cout << "integer::invert_to() a=" << a << endl;
290 // a.printobjectkind(cout);
291 // cout << endl;
292 a.invert_mod(*dom->factor_poly());
293#else
294 int q, l;
295
296 q = dom->order_int();
297 l = q - 2;
298 a.power_int_mod(l, *dom->factor_poly());
299#endif
300 res = a.polynomial_numeric(p);
301 x.m_i_i(res);
302 return TRUE;
303 }
304 else if (is_Orbiter_finite_field_domain(dom)) {
305 if (f_v) {
306 cout << "integer::invert_to Orbiter_finite_field domain" << endl;
307 }
308 int a, av;
309 a = s_i();
310 av = dom->get_F()->inverse(a);
311 x.m_i_i(av);
312 return TRUE;
313 }
314 if (i == 1 || i == -1) {
315 x.m_i_i( i );
316 return TRUE;
317 }
318 else {
319 cout << "integer::invert_to cannot invert " << *this << endl;
320 exit(1);
321 }
322 return FALSE;
323}
324
326{
327 domain *dom;
328
329 if (x.s_kind() == INTEGER) {
330
331
332 if (is_GFq_domain(dom)) {
333 unipoly a, b, c;
334 domain *sub_domain;
335 int p, res;
336
337 sub_domain = dom->sub_domain();
338 with w(sub_domain);
339 p = sub_domain->order_int();
340
341 a.numeric_polynomial(s_i(), p);
342 b.numeric_polynomial(x.s_i_i(), p);
343 c.add(a, b);
344 res = c.polynomial_numeric(p);
345 y.m_i_i(res);
346 }
347 else if (is_Orbiter_finite_field_domain(dom)) {
348 y.m_i_i(dom->get_F()->add(s_i(), x.s_i_i()));
349 }
350 else {
351 int l1, l2, l3;
352
353 l1 = log2();
354 l2 = x.as_integer().log2();
355 l3 = MAXIMUM(l1, l2) + 1;;
356 if (l3 >= BITS_OF_int) {
357 longinteger a, b, c;
358
359 a.homo_z(s_i());
360 b.homo_z(x.s_i_i());
361 a.add_to(b, c);
362 y = c;
363 return;
364 }
365 else {
366 if (is_GFp_domain(dom)) {
367 // cout << "integer::add_to() GFp domain" << endl;
368 y.m_i_i( remainder_mod(s_i() + x.s_i_i(), dom->order_int()) );
369 }
370 else {
371 y.m_i_i( s_i() + x.s_i_i() );
372 }
373 }
374 }
375 }
376 else if (x.s_kind() == LONGINTEGER) {
377 longinteger a, b, c;
378
379 a.homo_z(s_i());
380 b = x;
381 a.add_to(b, c);
382 y = c;
383 return;
384 }
385 else {
386 cout << "integer::add_to() objectkind of x:";
387 x.printobjectkind(cout);
388 cout << endl;
389 exit(1);
390 }
391}
392
394{
395 int i;
396 domain *dom;
397
398 if (s_kind() != INTEGER) {
399 cout << "integer::negate_to() this not an integer\n";
400 exit(1);
401 }
402 if (is_GFq_domain(dom)) {
403 unipoly a;
404 domain *sub_domain;
405 int p, res;
406
407 sub_domain = dom->sub_domain();
408 with w(sub_domain);
409 p = sub_domain->order_int();
410
411 a.numeric_polynomial(s_i(), p);
412 a.negate();
413 res = a.polynomial_numeric(p);
414 x.m_i_i(res);
415 return;
416 }
417 else if (is_Orbiter_finite_field_domain(dom)) {
418 x.m_i_i(dom->get_F()->negate(s_i()));
419 return;
420 }
421 i = s_i();
422 if (is_GFp_domain(dom)) {
423 x.m_i_i( remainder_mod(-i, dom->order_int()));
424 }
425 else {
426 x.m_i_i( - i );
427 }
428}
429
431{
432 int i, pp;
433
434 i = s_i();
435 pp = p.s_i_i();
436 if (i < 0) {
437 i *= -1;
438 i %= pp;
439 if (i == 0)
440 m_i(0);
441 else
442 m_i((int)(pp - i));
443 return;
444 }
445 i %= pp;
446 m_i((int) i);
447 return;
448
449}
450
452{
453 domain *dom;
454
455 if (is_GFp_domain(dom)) {
456 m_i( 0 );
457 }
458 else if (is_GFq_domain(dom)) {
459 m_i( 0 );
460 }
461 else if (is_Orbiter_finite_field_domain(dom)) {
462 m_i( 0 );
463 }
464 else {
465 m_i(0);
466 }
467}
468
470{
471 domain *dom;
472
473 if (is_GFp_domain(dom)) {
474 m_i( 1 );
475 }
476 else if (is_GFq_domain(dom)) {
477 m_i( 1 );
478 }
479 else if (is_Orbiter_finite_field_domain(dom)) {
480 m_i( 1 );
481 }
482 else {
483 m_i(1);
484 }
485}
486
488{
489 one();
490 negate();
491}
492
494{
495 domain *dom;
496
497 if (is_GFp_domain(dom)) {
498 m_i( remainder_mod(z, dom->order_int()));
499 }
500 else if (is_GFq_domain(dom)) {
502 cout << "homo_z in GFq, characteristic = " << p << endl;
503 m_i( remainder_mod(z, p));
504 // cout << "integer::homo_z() not allowed for GF(q) domain" << endl;
505 // exit(1);
506 }
507 else if (is_Orbiter_finite_field_domain(dom)) {
509 m_i( remainder_mod(z, p));
510 }
511 else {
512 m_i(z);
513 }
514}
515
517{
518 domain *dom;
519
520 if (is_GFp_domain(dom)) {
521 m_i( remainder_mod(s_i() + 1, dom->order_int()));
522 }
523 else if (is_GFq_domain(dom)) {
524 cout << "integer::inc() not allowed for GF(q) domain" << endl;
525 exit(1);
526 }
527 else if (is_Orbiter_finite_field_domain(dom)) {
528 cout << "integer::inc() not allowed for finite_field domain" << endl;
529 exit(1);
530 }
531 else {
532 m_i( s_i() + 1);
533 }
534}
535
537{
538 domain *dom;
539
540 if (is_GFp_domain(dom)) {
541 m_i( remainder_mod(s_i() - 1, dom->order_int()));
542 }
543 else if (is_GFq_domain(dom)) {
544 cout << "integer::dec() not allowed for GF(q) domain" << endl;
545 exit(1);
546 }
547 else if (is_Orbiter_finite_field_domain(dom)) {
548 cout << "integer::dec() not allowed for finite_field domain" << endl;
549 exit(1);
550 }
551 else {
552 m_i( s_i() - 1);
553 }
554}
555
557{
558 integer a;
559
560 a.zero();
561 if (compare_with(a) == 0)
562 return TRUE;
563 else
564 return FALSE;
565}
566
568{
569 integer a;
570
571 a.one();
572 if (compare_with(a) == 0)
573 return TRUE;
574 else
575 return FALSE;
576}
577
579{
580 integer a;
581
582 a.m_one();
583 if (compare_with(a) == 0)
584 return TRUE;
585 else
586 return FALSE;
587}
588
590{
591 int i, j;
592
593 if (s_kind() != INTEGER) {
594 return compare_with_euclidean(a);
595 }
596 if (a.s_kind() != INTEGER) {
597 cout << "integer::compare_with_euclidean() a is not an integer\n";
598 exit(1);
599 }
600 i = ABS(s_i());
601 j = ABS(a.s_i_i());
602 if (i < j)
603 return -1;
604 if (i > j)
605 return 1;
606 return 0;
607}
608
610 discreta_base &q, discreta_base &r, int verbose_level)
611{
612 int a, b, qq, rr;
613
614 if (s_kind() != INTEGER) {
615 cout << "integer::integral_division() this not an integer\n";
616 exit(1);
617 }
618 if (x.s_kind() != INTEGER) {
619 if (x.s_kind() == LONGINTEGER) {
620 integer y;
622 cout << "integer::integral_division() "
623 "longinteger x cannot be retracted to integer\n";
624 cout << "x=" << x << endl;
625 exit(1);
626 }
627 integral_division(y, q, r, verbose_level);
628 return;
629 }
630 else {
631 cout << "integer::integral_division() "
632 "x is neither integer nor longinteger\n";
633 exit(1);
634 }
635 }
636 a = s_i();
637 b = x.s_i_i();
638 // cout << "integer::integral_division() a = " << a << ", b = " << b << "\n";
639 if (b <= 0) {
640 cout << "integer::integral_division() b = " << b << "\n";
641 exit(1);
642 }
643 qq = a / b;
644 rr = a - qq * b;
645 q.m_i_i(qq);
646 r.m_i_i(rr);
647}
648
649void integer::rand(int low, int high)
650{
651 int l = high + 1 - low;
652 double r = (double) ::rand() * (double)l / RAND_MAX;
653
654 m_i(low + (int) r);
655}
656
658{
659 int a = ABS(s_i());
660 int l = 0;
661
662 while (a) {
663 l++;
664 a >>= 1;
665 }
666 return l;
667}
668
669
670
671}}
672
673
674
DISCRETA base class. All DISCRETA classes are derived from this class.
Definition: discreta.h:382
int invert_mod(discreta_base &p)
Definition: base.cpp:407
std::ostream & printobjectkind(std::ostream &)
Definition: base.cpp:246
void add(discreta_base &x, discreta_base &y)
Definition: base.cpp:674
discreta_base & power_int_mod(int l, discreta_base &p)
Definition: base.cpp:499
void copyobject(discreta_base &x)
Definition: base.cpp:194
void mult_mod(discreta_base &x, discreta_base &y, discreta_base &p)
Definition: base.cpp:372
DISCRETA class for influencing arithmetic operations.
Definition: discreta.h:1360
layer1_foundations::field_theory::finite_field * get_F()
Definition: domain.cpp:72
DISCRETA integer class.
Definition: discreta.h:667
void add_to(discreta_base &x, discreta_base &y)
Definition: integer.cpp:325
std::ostream & print(std::ostream &)
Definition: integer.cpp:89
int invert_to(discreta_base &x)
Definition: integer.cpp:237
void rand(int low, int high)
Definition: integer.cpp:649
void negate_to(discreta_base &x)
Definition: integer.cpp:393
void copyobject_to(discreta_base &x)
Definition: integer.cpp:81
void normalize(discreta_base &p)
Definition: integer.cpp:430
integer & operator=(const discreta_base &x)
Definition: integer.cpp:49
int compare_with_euclidean(discreta_base &a)
Definition: integer.cpp:589
int compare_with(discreta_base &a)
Definition: integer.cpp:134
void integral_division(discreta_base &x, discreta_base &q, discreta_base &r, int verbose_level)
Definition: integer.cpp:609
void mult_to(discreta_base &x, discreta_base &y)
Definition: integer.cpp:167
DISCRETA class for integers of arbitrary magnitude.
Definition: discreta.h:727
void mult_to(discreta_base &x, discreta_base &y)
void add_to(discreta_base &x, discreta_base &y)
DISCRETA class for polynomials in one variable.
Definition: discreta.h:1236
void numeric_polynomial(int n, int q)
Definition: unipoly.cpp:537
DISCRETA class related to class domain.
Definition: discreta.h:1413
#define BITS_OF_int
Definition: discreta.h:39
#define ABS(x)
Definition: foundations.h:220
#define TRUE
Definition: foundations.h:231
#define FALSE
Definition: foundations.h:234
#define MAXIMUM(x, y)
Definition: foundations.h:217
int is_Orbiter_finite_field_domain(domain *&d)
Definition: domain.cpp:229
int finite_field_domain_characteristic(domain *d)
Definition: domain.cpp:263
int is_GFq_domain(domain *&d)
Definition: domain.cpp:216
@ LONGINTEGER
LONGINTEGER.
Definition: discreta.h:65
int is_GFp_domain(domain *&d)
Definition: domain.cpp:203
int remainder_mod(int i, int n)
Definition: global.cpp:317
int invert_mod_integer(int i, int p)
Definition: global.cpp:285
the orbiter library for the classification of combinatorial objects