Orbiter 2022
Combinatorial Objects
a_domain.cpp
Go to the documentation of this file.
1// a_domain.cpp
2//
3// Anton Betten
4// March 14, 2015
5//
6//
7//
8//
9//
10
11
12
13#include "foundations.h"
14
15using namespace std;
16
17namespace orbiter {
18namespace layer1_foundations {
19namespace algebra {
20
21
23{
24 null();
25}
26
28{
29 freeself();
30}
31
33{
35}
36
38{
39
40}
41
42void a_domain::init_integers(int verbose_level)
43{
44 int f_v = (verbose_level >= 1);
45
46 if (f_v) {
47 cout << "a_domain::init_integers" << endl;
48 }
51}
52
53void a_domain::init_integer_fractions(int verbose_level)
54{
55 int f_v = (verbose_level >= 1);
56
57 if (f_v) {
58 cout << "a_domain::init_integer_fractions" << endl;
59 }
62}
63
64
65int a_domain::as_int(int *elt, int verbose_level)
66{
67 int f_v = (verbose_level >= 1);
69
70 if (f_v) {
71 cout << "a_domain::as_int" << endl;
72 }
74 return elt[0];
75 }
76 else if (kind == domain_integer_fractions) {
77 long int at, ab, g;
78
79 at = elt[0];
80 ab = elt[1];
81 if (at == 0) {
82 return 0;
83 }
84 g = NT.gcd_lint(at, ab);
85 at /= g;
86 ab /= g;
87 if (ab != 1 && ab != -1) {
88 cout << "a_domain::as_int the number is not an integer" << endl;
89 exit(1);
90 }
91 if (ab == -1) {
92 at *= -1;
93 }
94 return at;
95 }
96 else {
97 cout << "a_domain::as_int unknown domain kind" << endl;
98 exit(1);
99 }
100}
101
102void a_domain::make_integer(int *elt, int n, int verbose_level)
103{
104 int f_v = (verbose_level >= 1);
105
106 if (f_v) {
107 cout << "a_domain::make_integer" << endl;
108 }
109 if (kind == domain_the_integers) {
110 elt[0] = n;
111 }
112 else if (kind == domain_integer_fractions) {
113 elt[0] = n;
114 elt[1] = 1;
115 }
116 else {
117 cout << "a_domain::make_integer unknown domain kind" << endl;
118 exit(1);
119 }
120}
121
122void a_domain::make_zero(int *elt, int verbose_level)
123{
124 int f_v = (verbose_level >= 1);
125
126 if (f_v) {
127 cout << "a_domain::make_zero" << endl;
128 }
129 if (kind == domain_the_integers) {
130 elt[0] = 0;
131 }
132 else if (kind == domain_integer_fractions) {
133 elt[0] = 0;
134 elt[1] = 1;
135 }
136 else {
137 cout << "a_domain::make_zero unknown domain kind" << endl;
138 exit(1);
139 }
140}
141
142void a_domain::make_zero_vector(int *elt, int len, int verbose_level)
143{
144 int f_v = (verbose_level >= 1);
145 int i;
146
147 if (f_v) {
148 cout << "a_domain::make_zero_vector" << endl;
149 }
150 for (i = 0; i < len; i++) {
152 }
153}
154
155int a_domain::is_zero_vector(int *elt, int len, int verbose_level)
156{
157 int f_v = (verbose_level >= 1);
158 int i;
159
160 if (f_v) {
161 cout << "a_domain::is_zero_vector" << endl;
162 }
163 for (i = 0; i < len; i++) {
164 if (!is_zero(offset(elt, i), 0)) {
165
166 //cout << "a_domain::is_zero_vector element "
167 // << i << " is nonzero" << endl;
168
169 return FALSE;
170 }
171 }
172 return TRUE;
173}
174
175
176int a_domain::is_zero(int *elt, int verbose_level)
177{
178 int f_v = (verbose_level >= 1);
179 int ret;
180
181 if (f_v) {
182 cout << "a_domain::is_zero" << endl;
183 }
184 if (kind == domain_the_integers) {
185 if (elt[0] == 0) {
186 ret = TRUE;
187 }
188 else {
189 ret = FALSE;
190 }
191 }
192 else if (kind == domain_integer_fractions) {
193 if (elt[0] == 0) {
194 ret = TRUE;
195 }
196 else {
197 ret = FALSE;
198 }
199 }
200 else {
201 cout << "a_domain::is_zero unknown domain kind" << endl;
202 exit(1);
203 }
204 return ret;
205}
206
207void a_domain::make_one(int *elt, int verbose_level)
208{
209 int f_v = (verbose_level >= 1);
210
211 if (f_v) {
212 cout << "a_domain::make_one" << endl;
213 }
214 if (kind == domain_the_integers) {
215 elt[0] = 1;
216 }
217 else if (kind == domain_integer_fractions) {
218 elt[0] = 1;
219 elt[1] = 1;
220 }
221 else {
222 cout << "a_domain::make_one unknown domain kind" << endl;
223 exit(1);
224 }
225}
226
227int a_domain::is_one(int *elt, int verbose_level)
228{
229 int f_v = (verbose_level >= 1);
230 int ret = FALSE;
232
233 if (f_v) {
234 cout << "a_domain::is_one" << endl;
235 }
236 if (kind == domain_the_integers) {
237 if (elt[0] == 1) {
238 ret = TRUE;
239 }
240 else {
241 ret = FALSE;
242 }
243 }
244 else if (kind == domain_integer_fractions) {
245 long int at, ab, g;
246
247 at = elt[0];
248 ab = elt[1];
249 if (at == 0) {
250 ret = FALSE;
251 }
252 else {
253 g = NT.gcd_lint(at, ab);
254 at = at / g;
255 ab = ab / g;
256 if (ab < 0) {
257 ab *= -1;
258 at *= -1;
259 }
260 if (at == 1) {
261 ret = TRUE;
262 }
263 else {
264 ret = FALSE;
265 }
266 }
267 }
268 else {
269 cout << "a_domain::is_one unknown domain kind" << endl;
270 exit(1);
271 }
272 return ret;
273}
274
275void a_domain::copy(int *elt_from, int *elt_to, int verbose_level)
276{
277 int f_v = (verbose_level >= 1);
278
279 if (f_v) {
280 cout << "a_domain::copy" << endl;
281 }
282 if (kind == domain_the_integers) {
283 elt_to[0] = elt_from[0];
284 }
285 else if (kind == domain_integer_fractions) {
286 elt_to[0] = elt_from[0];
287 elt_to[1] = elt_from[1];
288 }
289 else {
290 cout << "a_domain::copy unknown domain kind" << endl;
291 exit(1);
292 }
293}
294
295void a_domain::copy_vector(int *elt_from, int *elt_to,
296 int len, int verbose_level)
297{
298 int f_v = (verbose_level >= 1);
299 int i;
300
301 if (f_v) {
302 cout << "a_domain::copy_vector" << endl;
303 }
304 for (i = 0; i < len; i++) {
305 copy(offset(elt_from, i), offset(elt_to, i), 0);
306 }
307}
308
309
310void a_domain::swap_vector(int *elt1, int *elt2,
311 int n, int verbose_level)
312{
313 int f_v = (verbose_level >= 1);
314 int i;
315
316 if (f_v) {
317 cout << "a_domain::swap_vector" << endl;
318 }
319 for (i = 0; i < n; i++) {
320 swap(elt1 + i * size_of_instance_in_int,
321 elt2 + i * size_of_instance_in_int, 0);
322 }
323}
324
325void a_domain::swap(int *elt1, int *elt2, int verbose_level)
326{
327 int f_v = (verbose_level >= 1);
328
329 if (f_v) {
330 cout << "a_domain::swap" << endl;
331 }
332 if (kind == domain_the_integers) {
333 int a;
334 a = elt2[0];
335 elt2[0] = elt1[0];
336 elt1[0] = a;
337 }
338 else if (kind == domain_integer_fractions) {
339 int a;
340 a = elt2[0];
341 elt2[0] = elt1[0];
342 elt1[0] = a;
343 a = elt2[1];
344 elt2[1] = elt1[1];
345 elt1[1] = a;
346 }
347 else {
348 cout << "a_domain::copy unknown domain kind" << endl;
349 exit(1);
350 }
351}
352
353void a_domain::add(int *elt_a, int *elt_b, int *elt_c, int verbose_level)
354{
355 int f_v = (verbose_level >= 1);
357
358 if (f_v) {
359 cout << "a_domain::add" << endl;
360 }
361 if (kind == domain_the_integers) {
362 elt_c[0] = elt_a[0] + elt_b[0];
363 }
364 else if (kind == domain_integer_fractions) {
365 int at, ab, bt, bb, ct, cb;
366
367 at = elt_a[0];
368 ab = elt_a[1];
369 bt = elt_b[0];
370 bb = elt_b[1];
371
372 NT.int_add_fractions(at, ab, bt, bb, ct, cb, 0 /* verbose_level */);
373
374 elt_c[0] = ct;
375 elt_c[1] = cb;
376 }
377 else {
378 cout << "a_domain::add unknown domain kind" << endl;
379 exit(1);
380 }
381}
382
383void a_domain::add_apply(int *elt_a, int *elt_b, int verbose_level)
384{
385 int f_v = (verbose_level >= 1);
387
388 if (f_v) {
389 cout << "a_domain::add_apply" << endl;
390 }
391 if (kind == domain_the_integers) {
392 elt_a[0] = elt_a[0] + elt_b[0];
393 }
394 else if (kind == domain_integer_fractions) {
395 int at, ab, bt, bb, ct, cb;
396
397 at = elt_a[0];
398 ab = elt_a[1];
399 bt = elt_b[0];
400 bb = elt_b[1];
401
402 NT.int_add_fractions(at, ab, bt, bb, ct, cb, 0 /* verbose_level */);
403
404 elt_a[0] = ct;
405 elt_a[1] = cb;
406 }
407 else {
408 cout << "a_domain::add_apply unknown domain kind" << endl;
409 exit(1);
410 }
411}
412
413void a_domain::subtract(int *elt_a, int *elt_b, int *elt_c, int verbose_level)
414{
415 int f_v = (verbose_level >= 1);
417
418 if (f_v) {
419 cout << "a_domain::subtract" << endl;
420 }
421 if (kind == domain_the_integers) {
422 elt_c[0] = elt_a[0] + elt_b[0];
423 }
424 else if (kind == domain_integer_fractions) {
425 long int at, ab, bt, bb, g, a1, b1, ct, cb;
426
427 at = elt_a[0];
428 ab = elt_a[1];
429 bt = elt_b[0];
430 bb = elt_b[1];
431 g = NT.gcd_lint(ab, bb);
432 a1 = ab / g;
433 b1 = bb / g;
434 cb = a1 * g;
435 ct = at * b1 - bt * a1;
436 elt_c[0] = ct;
437 elt_c[1] = cb;
438 }
439 else {
440 cout << "a_domain::subtract unknown domain kind" << endl;
441 exit(1);
442 }
443}
444
445void a_domain::negate(int *elt, int verbose_level)
446{
447 int f_v = (verbose_level >= 1);
448
449 if (f_v) {
450 cout << "a_domain::negate" << endl;
451 }
452 if (kind == domain_the_integers) {
453 elt[0] = - elt[0];
454 }
455 else if (kind == domain_integer_fractions) {
456 elt[0] = - elt[0];
457 }
458 else {
459 cout << "a_domain::negate unknown domain kind" << endl;
460 exit(1);
461 }
462}
463
464void a_domain::negate_vector(int *elt, int len, int verbose_level)
465{
466 int f_v = (verbose_level >= 1);
467 int i;
468
469 if (f_v) {
470 cout << "a_domain::negate" << endl;
471 }
472 for (i = 0; i < len; i++) {
473 negate(offset(elt, i), 0);
474 }
475}
476
477void a_domain::mult(int *elt_a, int *elt_b, int *elt_c, int verbose_level)
478{
479 int f_v = (verbose_level >= 1);
481
482 if (f_v) {
483 cout << "a_domain::mult" << endl;
484 }
485 if (kind == domain_the_integers) {
486 elt_c[0] = elt_a[0] * elt_b[0];
487 }
488 else if (kind == domain_integer_fractions) {
489 int at, ab, bt, bb, ct, cb;
490
491 at = elt_a[0];
492 ab = elt_a[1];
493 bt = elt_b[0];
494 bb = elt_b[1];
495
496
497 NT.int_mult_fractions(at, ab, bt, bb, ct, cb, 0 /* verbose_level */);
498
499 elt_c[0] = ct;
500 elt_c[1] = cb;
501 }
502 else {
503 cout << "a_domain::mult unknown domain kind" << endl;
504 exit(1);
505 }
506}
507
508void a_domain::mult_apply(int *elt_a, int *elt_b, int verbose_level)
509{
510 int f_v = (verbose_level >= 1);
512
513 if (f_v) {
514 cout << "a_domain::mult_apply" << endl;
515 }
516 if (kind == domain_the_integers) {
517 elt_a[0] = elt_a[0] * elt_b[0];
518 }
519 else if (kind == domain_integer_fractions) {
520 int at, ab, bt, bb, ct, cb;
521
522 at = elt_a[0];
523 ab = elt_a[1];
524 bt = elt_b[0];
525 bb = elt_b[1];
526
527
528 NT.int_mult_fractions(at, ab, bt, bb, ct, cb, 0 /* verbose_level */);
529
530 //cout << "a_domain::mult_apply " << at << "/" << ab
531 //<< " * " << bt << "/" << bb << " = " << ct << "/" << bb << endl;
532
533 elt_a[0] = ct;
534 elt_a[1] = cb;
535 }
536 else {
537 cout << "a_domain::mult_apply unknown domain kind" << endl;
538 exit(1);
539 }
540}
541
542void a_domain::power(int *elt_a, int *elt_b, int n, int verbose_level)
543{
544 int f_v = (verbose_level >= 1);
545 int *tmp1;
546 int *tmp2;
547 int *tmp3;
548
549
550 if (f_v) {
551 cout << "a_domain::power" << endl;
552 }
556
557 if (n < 0) {
558 cout << "a_domain::power exponent is negative" << endl;
559 exit(1);
560 }
561 make_one(tmp1, 0);
562 copy(elt_a, tmp3, 0);
563 while (TRUE) {
564 if (n % 2) {
565 mult(tmp3, tmp1, tmp2, 0);
566 copy(tmp2, tmp1, 0);
567 }
568 n >>= 1;
569 if (n == 0) {
570 break;
571 }
572 mult(tmp3, tmp3, tmp2, 0);
573 copy(tmp2, tmp3, 0);
574 }
575 copy(tmp1, elt_b, 0);
576 FREE_int(tmp1);
577 FREE_int(tmp2);
578 FREE_int(tmp3);
579 if (f_v) {
580 cout << "a_domain::power done" << endl;
581 }
582}
583
584void a_domain::mult_by_integer(int *elt, int n, int verbose_level)
585{
586 int f_v = (verbose_level >= 1);
587
588 if (f_v) {
589 cout << "a_domain::mult_by_integer" << endl;
590 }
591 if (kind == domain_the_integers) {
592 elt[0] *= n;
593 }
594 else if (kind == domain_integer_fractions) {
595 elt[0] *= n;
596 }
597 else {
598 cout << "a_domain::mult_by_integer unknown domain kind" << endl;
599 exit(1);
600 }
601}
602
603void a_domain::divide_by_integer(int *elt, int n, int verbose_level)
604{
605 int f_v = (verbose_level >= 1);
607
608 if (f_v) {
609 cout << "a_domain::divide_by_integer" << endl;
610 }
611 if (kind == domain_the_integers) {
612 int a;
613
614 a = elt[0];
615 if (a % n) {
616 cout << "a_domain::divide_by_integer n does not divide" << endl;
617 exit(1);
618 }
619 elt[0] /= n;
620 }
621 else if (kind == domain_integer_fractions) {
622 long int a, b, g, n1;
623
624 a = elt[0];
625 b = elt[1];
626 g = NT.gcd_lint(a, n);
627 a /= g;
628 n1 = n / g;
629 b *= n1;
630 elt[0] = a;
631 elt[1] = b;
632 }
633 else {
634 cout << "a_domain::divide_by_integer unknown domain kind" << endl;
635 exit(1);
636 }
637}
638
639
640void a_domain::divide(int *elt_a, int *elt_b, int *elt_c, int verbose_level)
641{
642 int f_v = (verbose_level >= 1);
644
645 if (f_v) {
646 cout << "a_domain::divide" << endl;
647 }
648 if (kind == domain_the_integers) {
649 long int g;
650
651 if (elt_b[0] == 0) {
652 cout << "a_domain::divide division by zero" << endl;
653 exit(1);
654 }
655 g = NT.gcd_lint(elt_a[0], elt_b[0]);
656 elt_c[0] = elt_a[0] / g;
657 }
658 else if (kind == domain_integer_fractions) {
659 int at, ab, bt, bb, ct, cb;
660
661 at = elt_a[0];
662 ab = elt_a[1];
663 bt = elt_b[0];
664 bb = elt_b[1];
665
666 if (bt == 0) {
667 cout << "a_domain::divide division by zero" << endl;
668 exit(1);
669 }
670
671 NT.int_mult_fractions(at, ab, bb, bt, ct, cb, 0 /* verbose_level */);
672
673 elt_c[0] = ct;
674 elt_c[1] = cb;
675 }
676 else {
677 cout << "a_domain::divide unknown domain kind" << endl;
678 exit(1);
679 }
680}
681
682void a_domain::inverse(int *elt_a, int *elt_b, int verbose_level)
683{
684 int f_v = (verbose_level >= 1);
685
686 if (f_v) {
687 cout << "a_domain::inverse" << endl;
688 }
689 if (kind == domain_the_integers) {
690 int a, av;
691
692 a = elt_a[0];
693 if (a == 1) {
694 av = 1;
695 }
696 else if (a == -1) {
697 av = -1;
698 }
699 else {
700 cout << "a_domain::inverse cannot invert" << endl;
701 exit(1);
702 }
703 elt_b[0] = av;
704 }
705 else if (kind == domain_integer_fractions) {
706 int at, ab;
707
708
709 at = elt_a[0];
710 ab = elt_a[1];
711 if (at == 0) {
712 cout << "a_domain::inverse cannot invert" << endl;
713 exit(1);
714 }
715 elt_b[0] = ab;
716 elt_b[1] = at;
717 }
718 else {
719 cout << "a_domain::inverse unknown domain kind" << endl;
720 exit(1);
721 }
722}
723
724
725void a_domain::print(int *elt)
726{
727 if (kind == domain_the_integers) {
728 cout << elt[0];
729 }
730 else if (kind == domain_integer_fractions) {
731 int at, ab;
732
733 at = elt[0];
734 ab = elt[1];
735
736#if 1
737 if (ab == -1) {
738 at *= -1;
739 ab = 1;
740 }
741 if (at == 0) {
742 cout << 0;
743 }
744 else if (ab == 1) {
745 cout << at;
746 }
747 else {
748 cout << at << "/" << ab;
749 }
750#else
751 cout << at << "/" << ab;
752#endif
753 }
754 else {
755 cout << "a_domain::divide unknown domain kind" << endl;
756 exit(1);
757 }
758}
759
760void a_domain::print_vector(int *elt, int n)
761{
762 int i;
763
764 cout << "(";
765 for (i = 0; i < n; i++) {
766 print(offset(elt, i));
767 if (i < n - 1) {
768 cout << ", ";
769 }
770 }
771 cout << ")";
772}
773
774void a_domain::print_matrix(int *A, int m, int n)
775{
776 int i, j;
777
778 for (i = 0; i < m; i++) {
779 for (j = 0; j < n; j++) {
780 print(offset(A, i * n + j));
781 if (j < n - 1) {
782 cout << ", ";
783 }
784 }
785 cout << endl;
786 }
787}
788
789void a_domain::print_matrix_for_maple(int *A, int m, int n)
790{
791 int i, j;
792
793 cout << "[";
794 for (i = 0; i < m; i++) {
795 cout << "[";
796 for (j = 0; j < n; j++) {
797 print(offset(A, i * n + j));
798 if (j < n - 1) {
799 cout << ", ";
800 }
801 }
802 cout << "]";
803 if (i < m - 1) {
804 cout << "," << endl;
805 }
806 else {
807 cout << "];" << endl;
808 }
809 }
810}
811
812void a_domain::make_element_from_integer(int *elt, int n, int verbose_level)
813{
814 int f_v = (verbose_level >= 1);
815
816 if (f_v) {
817 cout << "a_domain::make_element_from_integer" << endl;
818 }
819
820 if (kind == domain_the_integers) {
821 elt[0] = n;
822 }
823 else if (kind == domain_integer_fractions) {
824 elt[0] = n;
825 elt[1] = 1;
826 }
827 else {
828 cout << "a_domain::make_element_from_integer "
829 "unknown domain kind" << endl;
830 exit(1);
831 }
832 if (f_v) {
833 cout << "a_domain::make_element_from_integer done" << endl;
834 }
835}
836
837int *a_domain::offset(int *A, int i)
838{
839 return A + i * size_of_instance_in_int;
840}
841
843 int f_special, int f_complete, int *base_cols,
844 int f_P, int *P, int m, int n, int Pn, int verbose_level)
845// returns the rank which is the number of entries in base_cols
846// A is a m x n matrix,
847// P is a m x Pn matrix (if f_P is TRUE)
848{
849 int f_v = (verbose_level >= 1);
850 int f_vv = (verbose_level >= 2);
851 int f_vvv = (verbose_level >= 3);
852 int rank, i, j, k, jj;
853 int *pivot, *pivot_inv;
854 int *a, *b, *c, *z, *f;
855
856 if (f_v) {
857 cout << "Gauss algorithm for matrix:" << endl;
858 //print_integer_matrix_width(cout, A, m, n, n, 5);
859 //print_tables();
860 print_matrix(A, m, n);
861 }
862
864 pivot_inv = NEW_int(size_of_instance_in_int);
870
871 i = 0;
872 for (j = 0; j < n; j++) {
873 if (f_vv) {
874 cout << "j=" << j << endl;
875 }
876 /* search for pivot element: */
877 for (k = i; k < m; k++) {
878 if (!is_zero(offset(A, k * n + j), 0)) {
879 if (f_vv) {
880 cout << "i=" << i << " pivot found in "
881 << k << "," << j << endl;
882 }
883 // pivot element found:
884 if (k != i) {
885 swap_vector(offset(A, i * n),
886 offset(A, k * n), n, 0);
887 if (f_P) {
888 swap_vector(offset(P, i * Pn),
889 offset(P, k * Pn), Pn, 0);
890 }
891 }
892 break;
893 } // if != 0
894 } // next k
895
896 if (k == m) { // no pivot found
897 if (f_vv) {
898 cout << "no pivot found" << endl;
899 }
900 continue; // increase j, leave i constant
901 }
902
903 if (f_vv) {
904 cout << "row " << i << " pivot in row " << k
905 << " colum " << j << endl;
906 }
907
908 base_cols[i] = j;
909 //if (FALSE) {
910 // cout << "."; cout.flush();
911 // }
912
913
914 copy(offset(A, i * n + j), pivot, 0);
915 if (f_vv) {
916 cout << "pivot=";
917 print(pivot);
918 cout << endl;
919 }
920 inverse(pivot, pivot_inv, 0);
921
922 if (f_vv) {
923 cout << "pivot=";
924 print(pivot);
925 cout << " pivot_inv=";
926 print(pivot_inv);
927 cout << endl;
928 }
929 if (!f_special) {
930 // make pivot to 1:
931 for (jj = j; jj < n; jj++) {
932 mult_apply(offset(A, i * n + jj), pivot_inv, 0);
933 }
934 if (f_P) {
935 for (jj = 0; jj < Pn; jj++) {
936 mult_apply(offset(P, i * Pn + jj), pivot_inv, 0);
937 }
938 }
939 if (f_vv) {
940 cout << "pivot=";
941 print(pivot);
942 cout << " pivot_inv=";
943 print(pivot_inv);
944 cout << " made to one: ";
945 print(offset(A, i * n + j));
946 cout << endl;
947 }
948 if (f_vvv) {
949 print_matrix(A, m, n);
950 }
951 }
952
953 // do the gaussian elimination:
954
955 if (f_vv) {
956 cout << "doing elimination in column " << j
957 << " from row " << i + 1 << " to row "
958 << m - 1 << ":" << endl;
959 }
960 for (k = i + 1; k < m; k++) {
961 if (f_vv) {
962 cout << "looking at row k=" << k << endl;
963 }
964 copy(offset(A, k * n + j), z, 0);
965 if (is_zero(z, 0)) {
966 continue;
967 }
968 if (f_special) {
969 mult(z, pivot_inv, f, 0);
970 //f = mult(z, pivot_inv);
971 }
972 else {
973 copy(z, f, 0);
974 //f = z;
975 }
976 negate(f, 0);
977 //f = negate(f);
978 make_zero(offset(A, k * n + j), 0);
979 //A[k * n + j] = 0;
980 if (f_vv) {
981 cout << "eliminating row " << k << endl;
982 }
983 for (jj = j + 1; jj < n; jj++) {
984 if (f_vv) {
985 cout << "eliminating row " << k
986 << " column " << jj << endl;
987 }
988 copy(offset(A, i * n + jj), a, 0);
989 //a = A[i * n + jj];
990 copy(offset(A, k * n + jj), b, 0);
991 //b = A[k * n + jj];
992 // c := b + f * a
993 // = b - z * a if !f_special
994 // b - z * pivot_inv * a if f_special
995 mult(f, a, c, 0);
996 //c = mult(f, a);
997 add_apply(c, b, 0);
998 //c = add(c, b);
999 copy(c, offset(A, k * n + jj), 0);
1000 //A[k * n + jj] = c;
1001 if (f_vv) {
1002 cout << "A=" << endl;
1003 print_matrix(A, m, n);
1004 //print(offset(A, k * n + jj));
1005 //cout << " ";
1006 }
1007 }
1008 if (f_P) {
1009 for (jj = 0; jj < Pn; jj++) {
1010 copy(offset(P, i * Pn + jj), a, 0);
1011 //a = P[i * Pn + jj];
1012 copy(offset(P, k * Pn + jj), b, 0);
1013 //b = P[k * Pn + jj];
1014 // c := b - z * a
1015 mult(f, a, c, 0);
1016 //c = mult(f, a);
1017 add_apply(c, b, 0);
1018 //c = add(c, b);
1019 copy(c, offset(P, k * Pn + jj), 0);
1020 //P[k * Pn + jj] = c;
1021 }
1022 }
1023 if (f_vv) {
1024 cout << endl;
1025 }
1026 if (f_vvv) {
1027 cout << "A=" << endl;
1028 print_matrix(A, m, n);
1029 }
1030 }
1031 i++;
1032 if (f_vv) {
1033 cout << "A=" << endl;
1034 print_matrix(A, m, n);
1035 if (f_P) {
1036 cout << "P=" << endl;
1037 print_matrix(P, m, Pn);
1038 }
1039 }
1040 } // next j
1041 rank = i;
1042 if (f_complete) {
1043 //if (FALSE) {
1044 // cout << ";"; cout.flush();
1045 // }
1046 for (i = rank - 1; i >= 0; i--) {
1047 if (f_v) {
1048 cout << "."; cout.flush();
1049 }
1050 j = base_cols[i];
1051 if (!f_special) {
1052 copy(offset(A, i * n + j), a, 0);
1053 //a = A[i * n + j];
1054 }
1055 else {
1056 copy(offset(A, i * n + j), pivot, 0);
1057 //pivot = A[i * n + j];
1058 inverse(pivot, pivot_inv, 0);
1059 //pivot_inv = inverse(pivot);
1060 }
1061 // do the gaussian elimination in the upper part:
1062 for (k = i - 1; k >= 0; k--) {
1063 copy(offset(A, k * n + j), z, 0);
1064 //z = A[k * n + j];
1065 if (z == 0) {
1066 continue;
1067 }
1068 make_zero(offset(A, k * n + j), 0);
1069 //A[k * n + j] = 0;
1070 for (jj = j + 1; jj < n; jj++) {
1071 copy(offset(A, i * n + jj), a, 0);
1072 //a = A[i * n + jj];
1073 copy(offset(A, k * n + jj), b, 0);
1074 //b = A[k * n + jj];
1075 if (f_special) {
1076 mult_apply(a, pivot_inv, 0);
1077 //a = mult(a, pivot_inv);
1078 }
1079 mult(z, a, c, 0);
1080 //c = mult(z, a);
1081 negate(c, 0);
1082 //c = negate(c);
1083 add_apply(c, b, 0);
1084 //c = add(c, b);
1085 copy(c, offset(A, k * n + jj), 0);
1086 //A[k * n + jj] = c;
1087 }
1088 if (f_P) {
1089 for (jj = 0; jj < Pn; jj++) {
1090 copy(offset(P, i * Pn + jj), a, 0);
1091 //a = P[i * Pn + jj];
1092 copy(offset(P, k * Pn + jj), b, 0);
1093 //b = P[k * Pn + jj];
1094 if (f_special) {
1095 mult_apply(a, pivot_inv, 0);
1096 //a = mult(a, pivot_inv);
1097 }
1098 mult(z, a, c, 0);
1099 //c = mult(z, a);
1100 negate(c, 0);
1101 //c = negate(c);
1102 add_apply(c, b, 0);
1103 //c = add(c, b);
1104 copy(c, offset(P, k * Pn + jj), 0);
1105 //P[k * Pn + jj] = c;
1106 }
1107 }
1108 } // next k
1109 } // next i
1110 }
1111
1112 FREE_int(pivot);
1113 FREE_int(pivot_inv);
1114 FREE_int(a);
1115 FREE_int(b);
1116 FREE_int(c);
1117 FREE_int(z);
1118 FREE_int(f);
1119
1120 if (f_v) {
1121 cout << endl;
1122 print_matrix(A, m, n);
1123 cout << "the rank is " << rank << endl;
1124 }
1125 return rank;
1126}
1127
1128
1129void a_domain::Gauss_step(int *v1, int *v2,
1130 int len, int idx, int verbose_level)
1131// afterwards: v2[idx] = 0 and v1,v2 span the same space as before
1132// v1 is not changed if v1[idx] is nonzero
1133{
1134 int i;
1135 int f_v = (verbose_level >= 1);
1136 int *tmp1;
1137 int *tmp2;
1138
1139 if (f_v) {
1140 cout << "Gauss_step" << endl;
1141 }
1142
1145
1146 if (is_zero(offset(v2, idx), 0)) {
1147 goto after;
1148 }
1149 if (is_zero(offset(v1, idx), 0)) {
1150 // do a swap:
1151 for (i = 0; i < len; i++) {
1152 swap(offset(v1, i), offset(v2, i), 0);
1153 }
1154 goto after;
1155 }
1156
1157 copy(offset(v1, idx), tmp1, 0);
1158 inverse(tmp1, tmp2, 0);
1159 mult(tmp2, offset(v2, idx), tmp1, 0);
1160 negate(tmp1, 0);
1161
1162 //cout << "Gauss_step a=" << a << endl;
1163 for (i = 0; i < len; i++) {
1164 mult(tmp1, offset(v1, i), tmp2, 0);
1165 add_apply(offset(v2, i), tmp2, 0);
1166 }
1167
1168after:
1169 if (f_v) {
1170 cout << "Gauss_step done" << endl;
1171 }
1172
1173 FREE_int(tmp1);
1174 FREE_int(tmp2);
1175}
1176
1178 int m, int n, int *base_cols, int nb_base_cols,
1179 int &kernel_m, int &kernel_n, int *kernel, int verbose_level)
1180// kernel must point to the appropriate amount of memory!
1181// (at least n * (n - nb_base_cols) int's)
1182// kernel is stored as column vectors,
1183// i.e. kernel_m = n and kernel_n = n - nb_base_cols.
1184{
1185 int f_v = (verbose_level >= 1);
1186 int r, k, i, j, ii, jj;
1187 int *kernel_cols;
1188 int *zero;
1189 int *m_one;
1190
1191 if (f_v) {
1192 cout << "a_domain::matrix_get_kernel" << endl;
1193 }
1196
1197 make_zero(zero, 0);
1198 make_one(m_one, 0);
1199 negate(m_one, 0);
1200
1201
1202 r = nb_base_cols;
1203 k = n - r;
1204 kernel_m = n;
1205 kernel_n = k;
1206
1207 kernel_cols = NEW_int(k);
1208
1209 orbiter_kernel_system::Orbiter->Int_vec->complement(base_cols, kernel_cols, n, nb_base_cols);
1210
1211
1212 for (i = 0; i < r; i++) {
1213 ii = base_cols[i];
1214 for (j = 0; j < k; j++) {
1215 jj = kernel_cols[j];
1216
1217 copy(offset(M, i * n + jj),
1218 offset(kernel, ii * kernel_n + j), 0);
1219 }
1220 }
1221 for (i = 0; i < k; i++) {
1222 ii = kernel_cols[i];
1223 for (j = 0; j < k; j++) {
1224 if (i == j) {
1225 copy(m_one, offset(kernel, ii * kernel_n + j), 0);
1226 }
1227 else {
1228 copy(zero, offset(kernel, ii * kernel_n + j), 0);
1229 }
1230 }
1231 }
1232
1233
1234 FREE_int(kernel_cols);
1235 FREE_int(zero);
1236 FREE_int(m_one);
1237 if (f_v) {
1238 cout << "a_domain::matrix_get_kernel done" << endl;
1239 }
1240}
1241
1243 int *M, int m, int n, int *base_cols, int nb_base_cols,
1244 int &kernel_m, int &kernel_n, int *kernel, int verbose_level)
1245// kernel must point to the appropriate amount of memory!
1246// (at least n * (n - nb_base_cols) int's)
1247// kernel is stored as row vectors,
1248// i.e. kernel_m = n - nb_base_cols and kernel_n = n.
1249{
1250 int f_v = (verbose_level >= 1);
1251 int r, k, i, j, ii, jj;
1252 int *kernel_cols;
1253 int *zero;
1254 int *m_one;
1255
1256 if (f_v) {
1257 cout << "a_domain::matrix_get_kernel_as_row_vectors" << endl;
1258 }
1261
1262 make_zero(zero, 0);
1263 make_one(m_one, 0);
1264 negate(m_one, 0);
1265
1266
1267 r = nb_base_cols;
1268 k = n - r;
1269 kernel_m = k;
1270 kernel_n = n;
1271
1272 kernel_cols = NEW_int(k);
1273
1274 orbiter_kernel_system::Orbiter->Int_vec->complement(base_cols, kernel_cols, n, nb_base_cols);
1275
1276
1277 for (i = 0; i < r; i++) {
1278 ii = base_cols[i];
1279 for (j = 0; j < k; j++) {
1280 jj = kernel_cols[j];
1281
1282 copy(offset(M, i * n + jj),
1283 offset(kernel, j * kernel_n + ii), 0);
1284 }
1285 }
1286 for (i = 0; i < k; i++) {
1287 ii = kernel_cols[i];
1288 for (j = 0; j < k; j++) {
1289 if (i == j) {
1290 copy(m_one, offset(kernel, j * kernel_n + ii), 0);
1291 }
1292 else {
1293 copy(zero, offset(kernel, j * kernel_n + ii), 0);
1294 }
1295 }
1296 }
1297
1298
1299 FREE_int(kernel_cols);
1300 FREE_int(zero);
1301 FREE_int(m_one);
1302 if (f_v) {
1303 cout << "a_domain::matrix_get_kernel_as_row_vectors done" << endl;
1304 }
1305}
1306
1308 int n, int &rk, int verbose_level)
1309{
1310 int f_v = (verbose_level >= 1);
1311 int f_special = FALSE;
1312 int f_complete = TRUE;
1313 int *base_cols;
1314 int f_P = FALSE;
1315 int kernel_m, kernel_n;
1316
1317 if (f_v) {
1318 cout << "a_domain::get_image_and_kernel" << endl;
1319 }
1320
1321 base_cols = NEW_int(n);
1322 rk = Gauss_echelon_form(M, f_special, f_complete, base_cols,
1323 f_P, NULL, n, n, n, verbose_level);
1324
1325 matrix_get_kernel_as_row_vectors(M, n, n, base_cols, rk,
1326 kernel_m, kernel_n, offset(M, rk * n), verbose_level);
1327
1328 if (f_v) {
1329 cout << "a_domain::get_image_and_kernel M=" << endl;
1330 print_matrix(M, n, n);
1331 }
1332
1333 FREE_int(base_cols);
1334 if (f_v) {
1335 cout << "a_domain::get_image_and_kernel done" << endl;
1336 }
1337}
1338
1339void a_domain::complete_basis(int *M, int m, int n, int verbose_level)
1340{
1341 int f_v = (verbose_level >= 1);
1342 int f_special = FALSE;
1343 int f_complete = TRUE;
1344 int f_P = FALSE;
1345 int *M1;
1346 int *base_cols;
1347 int *kernel_cols;
1348 int i, j, k, a, rk;
1349
1350 if (f_v) {
1351 cout << "a_domain::complete_basis" << endl;
1352 }
1353
1354 M1 = NEW_int(m * n * size_of_instance_in_int);
1355 copy_vector(M, M1, m * n, 0);
1356
1357 base_cols = NEW_int(n);
1358
1359 rk = Gauss_echelon_form(M1, f_special, f_complete, base_cols,
1360 f_P, NULL, m, n, n, verbose_level);
1361
1362 if (rk != m) {
1363 cout << "a_domain::complete_basis rk != m" << endl;
1364 exit(1);
1365 }
1366
1367 k = n - rk;
1368
1369 kernel_cols = NEW_int(k);
1370
1371 orbiter_kernel_system::Orbiter->Int_vec->complement(base_cols, kernel_cols, n, rk);
1372 for (i = rk; i < n; i++) {
1373 for (j = 0; j < n; j++) {
1374 make_zero(offset(M, i * n + j), 0);
1375 }
1376 }
1377 for (i = 0; i < k; i++) {
1378 a = kernel_cols[i];
1379 make_one(offset(M, (rk + i) * n + a), 0);
1380 }
1381
1382 if (f_v) {
1383 cout << "a_domain::complete_basis M=" << endl;
1384 print_matrix(M, n, n);
1385 }
1386
1387 FREE_int(base_cols);
1388 FREE_int(kernel_cols);
1389 FREE_int(M1);
1390 if (f_v) {
1391 cout << "a_domain::complete_basis done" << endl;
1392 }
1393}
1394
1395void a_domain::mult_matrix(int *A, int *B, int *C,
1396 int ma, int na, int nb, int verbose_level)
1397{
1398 int f_v = (verbose_level >= 1);
1399 int f_vv = (verbose_level >= 2);
1400 int i, j, k;
1401 int *D, *E;
1402
1403 if (f_v) {
1404 cout << "a_domain::mult_matrix" << endl;
1405 }
1406 if (f_vv) {
1407 cout << "a_domain::mult_matrix A=" << endl;
1408 print_matrix(A, ma, na);
1409 cout << "a_domain::mult_matrix B=" << endl;
1410 print_matrix(B, na, nb);
1411 }
1414 for (i = 0; i < ma; i++) {
1415 for (k = 0; k < nb; k++) {
1416 make_zero(D, 0);
1417 for (j = 0; j < na; j++) {
1418 mult(offset(A, i * na + j),
1419 offset(B, j * nb + k), E, 0);
1420 add_apply(D, E, 0);
1421 }
1422 copy(D, offset(C, i * nb + k), 0);
1423 }
1424 }
1425 FREE_int(D);
1426 FREE_int(E);
1427 if (f_vv) {
1428 cout << "a_domain::mult_matrix C=" << endl;
1429 print_matrix(C, ma, nb);
1430 }
1431 if (f_v) {
1432 cout << "a_domain::mult_matrix done" << endl;
1433 }
1434}
1435
1436void a_domain::mult_matrix3(int *A, int *B, int *C, int *D,
1437 int n, int verbose_level)
1438{
1439 int f_v = (verbose_level >= 1);
1440 int *T;
1441
1442 if (f_v) {
1443 cout << "a_domain::mult_matrix3" << endl;
1444 }
1445 T = NEW_int(n * n * size_of_instance_in_int);
1446 mult_matrix(A, B, T, n, n, n, 0);
1447 mult_matrix(T, C, D, n, n, n, 0);
1448 FREE_int(T);
1449 if (f_v) {
1450 cout << "a_domain::mult_matrix3 done" << endl;
1451 }
1452}
1453
1454void a_domain::add_apply_matrix(int *A, int *B,
1455 int m, int n, int verbose_level)
1456{
1457 int f_v = (verbose_level >= 1);
1458 int i, j;
1459
1460 if (f_v) {
1461 cout << "a_domain::add_apply_matrix" << endl;
1462 }
1463 for (i = 0; i < m; i++) {
1464 for (j = 0; j < n; j++) {
1465 add_apply(offset(A, i * n + j), offset(B, i * n + j), 0);
1466 }
1467 }
1468 if (f_v) {
1469 cout << "a_domain::add_apply_matrix done" << endl;
1470 }
1471}
1472
1474 int *s, int m, int n, int verbose_level)
1475{
1476 int f_v = (verbose_level >= 1);
1477 int i, j;
1478
1479 if (f_v) {
1480 cout << "a_domain::matrix_mult_apply_scalar" << endl;
1481 }
1482 for (i = 0; i < m; i++) {
1483 for (j = 0; j < n; j++) {
1484 mult_apply(offset(A, i * n + j), s, 0);
1485 }
1486 }
1487 if (f_v) {
1488 cout << "a_domain::matrix_mult_apply_scalar done" << endl;
1489 }
1490}
1491
1493 int n, int k, int *A, int *B, int *C, int *D,
1494 int verbose_level)
1495// A is k x k,
1496// B is k x (n - k),
1497// C is (n - k) x k,
1498// D is (n - k) x (n - k),
1499// Mtx is n x n
1500{
1501 int f_v = (verbose_level >= 1);
1502 int i, j, r;
1503
1504 if (f_v) {
1505 cout << "a_domain::make_block_matrix_2x2" << endl;
1506 }
1507 r = n - k;
1508 for (i = 0; i < k; i++) {
1509 for (j = 0; j < k; j++) {
1510 copy(offset(A, i * k + j), offset(Mtx, i * n + j), 0);
1511 }
1512 }
1513 for (i = 0; i < k; i++) {
1514 for (j = 0; j < r; j++) {
1515 copy(offset(B, i * r + j), offset(Mtx, i * n + k + j), 0);
1516 }
1517 }
1518 for (i = 0; i < r; i++) {
1519 for (j = 0; j < k; j++) {
1520 copy(offset(C, i * k + j), offset(Mtx, (k + i) * n + j), 0);
1521 }
1522 }
1523 for (i = 0; i < r; i++) {
1524 for (j = 0; j < r; j++) {
1525 copy(offset(D, i * r + j), offset(Mtx, (k + i) * n + k + j), 0);
1526 }
1527 }
1528
1529 if (f_v) {
1530 cout << "a_domain::make_block_matrix_2x2 done" << endl;
1531 }
1532}
1533
1535 int n, int verbose_level)
1536{
1537 int f_v = (verbose_level >= 1);
1538 int i;
1539
1540 if (f_v) {
1541 cout << "a_domain::make_identity_matrix" << endl;
1542 }
1543 make_zero_vector(A, n * n, 0);
1544 for (i = 0; i < n; i++) {
1545 make_one(offset(A, i * n + i), 0);
1546 }
1547 if (f_v) {
1548 cout << "a_domain::make_identity_matrix done" << endl;
1549 }
1550}
1551
1552void a_domain::matrix_inverse(int *A, int *Ainv,
1553 int n, int verbose_level)
1554{
1555 int *T, *basecols;
1556
1557 T = NEW_int(n * n * size_of_instance_in_int);
1558 basecols = NEW_int(n * size_of_instance_in_int);
1559
1560 matrix_invert(A, T, basecols, Ainv, n, verbose_level);
1561
1562 FREE_int(T);
1563 FREE_int(basecols);
1564}
1565
1567 int *T, int *basecols, int *Ainv, int n,
1568 int verbose_level)
1569// T[n * n]
1570// basecols[n]
1571{
1572 int rk;
1573 int f_v = (verbose_level >= 1);
1574 //int f_vv = (verbose_level >= 2);
1575
1576 if (f_v) {
1577 cout << "a_domain::matrix_invert" << endl;
1578 }
1579 copy_vector(A, T, n * n, 0);
1580 make_identity_matrix(Ainv, n, 0);
1581 rk = Gauss_echelon_form(T,
1582 FALSE /* f_special */,
1583 TRUE /* f_complete */,
1584 basecols,
1585 TRUE /* f_P */, Ainv, n, n, n,
1586 verbose_level - 2);
1587 if (rk < n) {
1588 cout << "a_domain::matrix_invert not invertible" << endl;
1589 exit(1);
1590 }
1591 if (f_v) {
1592 cout << "a_domain::matrix_invert done" << endl;
1593 }
1594}
1595
1596}}}
1597
1598
void Gauss_step(int *v1, int *v2, int len, int idx, int verbose_level)
Definition: a_domain.cpp:1129
void copy(int *elt_from, int *elt_to, int verbose_level)
Definition: a_domain.cpp:275
int Gauss_echelon_form(int *A, int f_special, int f_complete, int *base_cols, int f_P, int *P, int m, int n, int Pn, int verbose_level)
Definition: a_domain.cpp:842
void add_apply_matrix(int *A, int *B, int m, int n, int verbose_level)
Definition: a_domain.cpp:1454
void divide_by_integer(int *elt, int n, int verbose_level)
Definition: a_domain.cpp:603
void make_element_from_integer(int *elt, int n, int verbose_level)
Definition: a_domain.cpp:812
void add(int *elt_a, int *elt_b, int *elt_c, int verbose_level)
Definition: a_domain.cpp:353
void mult_matrix(int *A, int *B, int *C, int ma, int na, int nb, int verbose_level)
Definition: a_domain.cpp:1395
void matrix_get_kernel(int *M, int m, int n, int *base_cols, int nb_base_cols, int &kernel_m, int &kernel_n, int *kernel, int verbose_level)
Definition: a_domain.cpp:1177
void matrix_invert(int *A, int *T, int *basecols, int *Ainv, int n, int verbose_level)
Definition: a_domain.cpp:1566
void make_one(int *elt, int verbose_level)
Definition: a_domain.cpp:207
void print_matrix_for_maple(int *A, int m, int n)
Definition: a_domain.cpp:789
void make_zero_vector(int *elt, int len, int verbose_level)
Definition: a_domain.cpp:142
void subtract(int *elt_a, int *elt_b, int *elt_c, int verbose_level)
Definition: a_domain.cpp:413
void init_integer_fractions(int verbose_level)
Definition: a_domain.cpp:53
void swap_vector(int *elt1, int *elt2, int n, int verbose_level)
Definition: a_domain.cpp:310
void complete_basis(int *M, int m, int n, int verbose_level)
Definition: a_domain.cpp:1339
void make_integer(int *elt, int n, int verbose_level)
Definition: a_domain.cpp:102
void add_apply(int *elt_a, int *elt_b, int verbose_level)
Definition: a_domain.cpp:383
void matrix_mult_apply_scalar(int *A, int *s, int m, int n, int verbose_level)
Definition: a_domain.cpp:1473
int is_zero(int *elt, int verbose_level)
Definition: a_domain.cpp:176
void mult_apply(int *elt_a, int *elt_b, int verbose_level)
Definition: a_domain.cpp:508
void negate(int *elt, int verbose_level)
Definition: a_domain.cpp:445
void make_identity_matrix(int *A, int n, int verbose_level)
Definition: a_domain.cpp:1534
void make_zero(int *elt, int verbose_level)
Definition: a_domain.cpp:122
void mult(int *elt_a, int *elt_b, int *elt_c, int verbose_level)
Definition: a_domain.cpp:477
void inverse(int *elt_a, int *elt_b, int verbose_level)
Definition: a_domain.cpp:682
void mult_by_integer(int *elt, int n, int verbose_level)
Definition: a_domain.cpp:584
void get_image_and_kernel(int *M, int n, int &rk, int verbose_level)
Definition: a_domain.cpp:1307
void copy_vector(int *elt_from, int *elt_to, int len, int verbose_level)
Definition: a_domain.cpp:295
void make_block_matrix_2x2(int *Mtx, int n, int k, int *A, int *B, int *C, int *D, int verbose_level)
Definition: a_domain.cpp:1492
int as_int(int *elt, int verbose_level)
Definition: a_domain.cpp:65
void matrix_inverse(int *A, int *Ainv, int n, int verbose_level)
Definition: a_domain.cpp:1552
void mult_matrix3(int *A, int *B, int *C, int *D, int n, int verbose_level)
Definition: a_domain.cpp:1436
void divide(int *elt_a, int *elt_b, int *elt_c, int verbose_level)
Definition: a_domain.cpp:640
int is_one(int *elt, int verbose_level)
Definition: a_domain.cpp:227
int is_zero_vector(int *elt, int len, int verbose_level)
Definition: a_domain.cpp:155
void matrix_get_kernel_as_row_vectors(int *M, int m, int n, int *base_cols, int nb_base_cols, int &kernel_m, int &kernel_n, int *kernel, int verbose_level)
Definition: a_domain.cpp:1242
void power(int *elt_a, int *elt_b, int n, int verbose_level)
Definition: a_domain.cpp:542
void negate_vector(int *elt, int len, int verbose_level)
Definition: a_domain.cpp:464
void swap(int *elt1, int *elt2, int verbose_level)
Definition: a_domain.cpp:325
void print_matrix(int *A, int m, int n)
Definition: a_domain.cpp:774
void int_mult_fractions(int at, int ab, int bt, int bb, int &ct, int &cb, int verbose_level)
void int_add_fractions(int at, int ab, int bt, int bb, int &ct, int &cb, int verbose_level)
#define FREE_int(p)
Definition: foundations.h:640
#define NEW_int(n)
Definition: foundations.h:625
#define TRUE
Definition: foundations.h:231
#define FALSE
Definition: foundations.h:234
orbiter_kernel_system::orbiter_session * Orbiter
global Orbiter session
the orbiter library for the classification of combinatorial objects