Orbiter 2022
Combinatorial Objects
combinatorics_domain.cpp
Go to the documentation of this file.
1// combinatorics_domain.cpp
2//
3// Anton Betten
4// April 3, 2003
5
6#include "foundations.h"
7
8using namespace std;
9
10
11namespace orbiter {
12namespace layer1_foundations {
13namespace combinatorics {
14
15
17{
18
19}
20
22{
23
24}
25
26
28{
29 int n, i;
30
31 n = 1;
32 for (i = 2; i <= a; i++) {
33 n *= i;
34 }
35 return n;
36}
37
38int combinatorics_domain::Kung_mue_i(int *part, int i, int m)
39{
40 int k, mue;
41
42 mue = 0;
43 for (k = 1; k <= i; k++) {
44 mue += part[k - 1] * k;
45 }
46 for (k = i + 1; k <= m; k++) {
47 mue += part[k - 1] * i;
48 }
49 return mue;
50}
51
53 int *part, int *dual_part, int n, int verbose_level)
54{
55 int f_v = (verbose_level >= 1);
56 int f_vv = (verbose_level >= 2);
57 int s, i, j, aj;
58
59 if (f_v) {
60 cout << "partition_dual" << endl;
61 cout << "input: ";
62 Int_vec_print(cout, part, n);
63 cout << endl;
64 }
65 Int_vec_zero(dual_part, n);
66 j = 0;
67 s = 0;
68 for (i = n; i >= 1; i--) {
69 if (part[i - 1] == 0) {
70 continue;
71 }
72 if (j) {
73 aj = part[j - 1];
74 s += aj;
75 dual_part[s - 1] = j - i;
76 if (f_vv) {
77 cout << "partition_dual i=" << i << " j=" << j
78 << " aj=" << aj << " s=" << s << endl;
79 }
80 }
81 j = i;
82 }
83 if (j) {
84 aj = part[j - 1];
85 s += aj;
86 dual_part[s - 1] = j;
87 if (f_vv) {
88 cout << "partition_dual j=" << j << " aj=" << aj
89 << " s=" << s << endl;
90 }
91 }
92 if (f_v) {
93 cout << "partition_dual" << endl;
94 cout << "output: ";
95 Int_vec_print(cout, dual_part, n);
96 cout << endl;
97 }
98}
99
101 int *&Table, int &nb, int verbose_level)
102{
103 int f_v = (verbose_level >= 1);
104 int *v;
105 int cnt;
106
107 if (f_v) {
108 cout << "combinatorics_domain::make_all_partitions_of_n n=" << n << endl;
109 }
111 if (f_v) {
112 cout << "combinatorics_domain::make_all_partitions_of_n nb=" << nb << endl;
113 }
114 v = NEW_int(n);
115 Table = NEW_int(nb * n);
116 cnt = 0;
117 partition_first(v, n);
118 while (TRUE) {
119 Int_vec_copy(v, Table + cnt * n, n);
120 cnt++;
121 if (!partition_next(v, n)) {
122 break;
123 }
124 }
125
126 FREE_int(v);
127 if (f_v) {
128 cout << "combinatorics_domain::make_all_partitions_of_n done" << endl;
129 }
130}
131
133{
134 int verbose_level = 0;
135 int f_v = (verbose_level >= 1);
136 int *v;
137 int cnt;
138
139 if (f_v) {
140 cout << "combinatorics_domain::count_all_partitions_of_n "
141 "n=" << n << endl;
142 }
143 v = NEW_int(n);
144 partition_first(v, n);
145 cnt = 1;
146 while (TRUE) {
147 if (!partition_next(v, n)) {
148 break;
149 }
150 cnt++;
151 }
152
153 FREE_int(v);
154 if (f_v) {
155 cout << "combinatorics_domain::count_all_partitions_of_n "
156 "done, cnt=" << cnt << endl;
157 }
158 return cnt;
159}
160
162{
163 Int_vec_zero(v, n);
164 v[n - 1] = 1;
165 return TRUE;
166}
167
169// next partition in exponential notation
170{
171 int i, j, a, s;
172
173 if (n == 1) {
174 return FALSE;
175 }
176 s = v[0];
177 for (i = 1; i < n; i++) {
178 a = v[i];
179 if (a > 0) {
180 a--;
181 s += (i + 1);
182 v[i] = a;
183 for (j = i - 1; j >= 0; j--) {
184 a = s / (j + 1);
185 s -= a * (j + 1);
186 v[j] = a;
187 }
188 return TRUE;
189 }
190 }
191 return FALSE;
192}
193
194void combinatorics_domain::partition_print(ostream &ost, int *v, int n)
195{
196 int i, a;
197 int f_first = TRUE;
198
199 ost << "[";
200 for (i = n; i >= 1; i--) {
201 a = v[i - 1];
202 if (a) {
203 if (!f_first) {
204 ost << ", ";
205 }
206 if (a > 1) {
207 ost << i << "^" << a;
208 }
209 else {
210 ost << i;
211 }
212 f_first = FALSE;
213 }
214 }
215 ost << "]";
216}
217
219// Returns TRUE if the word v of length n is regular, i.~e.
220// lies in an orbit of length $n$ under the action of the cyclic group
221// $C_n$ acting on the coordinates.
222// Lueneburg~\cite{Lueneburg87a} p. 118.
223// v is a vector over $\{0, 1, \ldots , q-1\}$
224{
225 int i, k, ipk, f_is_regular;
226
227 if (len == 1) {
228 return TRUE;
229 }
230 k = 1;
231 do {
232 i = 0;
233 ipk = i + k;
234 while (v[ipk] == v[i] && i < len - 1) {
235 i++;
236 if (ipk == len - 1) {
237 ipk = 0;
238 }
239 else {
240 ipk++;
241 }
242 }
243 f_is_regular = (v[ipk] < v[i]);
244 k++;
245 } while (f_is_regular && k <= len - 1);
246 return f_is_regular;
247}
248
250{
252
253#if 0
254 int a;
255 for (a = 0; a < Q; a++) {
256 Gg.AG_element_unrank(q, v, 1, len, a);
257 if (int_vec_is_regular_word(v, len, q)) {
258 return TRUE;
259 }
260 }
261 return FALSE;
262#else
263 int i;
264 for (i = 0; i < len; i++) {
265 v[i] = 0;
266 }
267 while (TRUE) {
268 if (int_vec_is_regular_word(v, len, q)) {
269 return TRUE;
270 }
271 if (!Gg.AG_element_next(q, v, 1, len)) {
272 return FALSE;
273 }
274 }
275#endif
276}
277
279{
280 //long int a;
282
283#if 0
284 a = Gg.AG_element_rank(q, v, 1, len);
285 //cout << "int_vec_next_regular_word current rank = " << a << endl;
286 for (a++; a < Q; a++) {
287 Gg.AG_element_unrank(q, v, 1, len, a);
288 //cout << "int_vec_next_regular_word testing ";
289 //int_vec_print(cout, v, len);
290 //cout << endl;
291 if (int_vec_is_regular_word(v, len, q)) {
292 return TRUE;
293 }
294 }
295 return FALSE;
296#else
297 while (TRUE) {
298 if (!Gg.AG_element_next(q, v, 1, len)) {
299 return FALSE;
300 }
301 if (int_vec_is_regular_word(v, len, q)) {
302 return TRUE;
303 }
304 }
305
306#endif
307}
308
309void combinatorics_domain::int_vec_splice(int *v, int *w, int len, int p)
310{
311 int q, i, j, a, h;
312
313 h = 0;
314 q = len / p;
315 for (i = 0; i < p; i++) {
316 for (j = 0; j < q; j++) {
317 a = v[i + j * p];
318 w[h++] = a;
319 }
320 }
321 if (h != len) {
322 cout << "combinatorics_domain::int_vec_splice h != len" << endl;
323 }
324}
325
326int combinatorics_domain::is_subset_of(int *A, int sz_A, int *B, int sz_B)
327{
328 int *B2;
329 int i, idx;
330 int ret = FALSE;
332
333 B2 = NEW_int(sz_B);
334 for (i = 0; i < sz_B; i++) {
335 B2[i] = B[i];
336 }
337 Sorting.int_vec_heapsort(B2, sz_B);
338 for (i = 0; i < sz_A; i++) {
339 if (!Sorting.int_vec_search(B2, sz_B, A[i], idx)) {
340 goto done;
341 }
342 }
343 ret = TRUE;
344done:
345 FREE_int(B2);
346 return ret;
347}
348
349int combinatorics_domain::set_find(int *elts, int size, int a)
350{
351 int idx;
353
354 if (!Sorting.int_vec_search(elts, size, a, idx)) {
355 cout << "set_find fatal: did not find" << endl;
356 cout << "a=" << a << endl;
357 Int_vec_print(cout, elts, size);
358 cout << endl;
359 exit(1);
360 }
361 return idx;
362}
363
365 int *subset, int subset_size,
366 int *complement, int &size_complement,
367 int universal_set_size)
368// subset must be in increasing order
369{
370 int i, j;
371
372 j = 0;
373 size_complement = 0;
374 for (i = 0; i < universal_set_size; i++) {
375 if (j < subset_size && subset[j] == i) {
376 j++;
377 continue;
378 }
379 complement[size_complement++] = i;
380 }
381}
382
384 long int *subset, int subset_size,
385 long int *complement, int &size_complement,
386 int universal_set_size)
387// subset must be in increasing order
388{
389 int i, j;
390
391 j = 0;
392 size_complement = 0;
393 for (i = 0; i < universal_set_size; i++) {
394 if (j < subset_size && subset[j] == i) {
395 j++;
396 continue;
397 }
398 complement[size_complement++] = i;
399 }
400}
401
403 int *subset, int subset_size,
404 int *complement, int &size_complement,
405 int universal_set_size)
406// subset does not need to be in increasing order
407{
408 int i, j;
409 int *subset2;
411
412 subset2 = NEW_int(subset_size);
413 Int_vec_copy(subset, subset2, subset_size);
414 Sorting.int_vec_heapsort(subset2, subset_size);
415
416 j = 0;
417 size_complement = 0;
418 for (i = 0; i < universal_set_size; i++) {
419 if (j < subset_size && subset2[j] == i) {
420 j++;
421 continue;
422 }
423 complement[size_complement++] = i;
424 }
425 FREE_int(subset2);
426}
427
429 int *elts, int &size,
430 int *elts_to_add, int nb_elts_to_add)
431{
432 int i;
433
434 for (i = 0; i < nb_elts_to_add; i++) {
435 set_add_element(elts, size, elts_to_add[i]);
436 }
437}
438
439void combinatorics_domain::set_add_element(int *elts, int &size, int a)
440{
441 int idx, i;
443
444 if (Sorting.int_vec_search(elts, size, a, idx)) {
445 return;
446 }
447 for (i = size; i > idx; i--) {
448 elts[i] = elts[i - 1];
449 }
450 elts[idx] = a;
451 size++;
452}
453
455 int *elts_to_delete, int nb_elts_to_delete)
456{
457 int i;
458
459 for (i = 0; i < nb_elts_to_delete; i++) {
460 set_delete_element(elts, size, elts_to_delete[i]);
461 }
462}
463
464
465void combinatorics_domain::set_delete_element(int *elts, int &size, int a)
466{
467 int idx, i;
469
470 if (!Sorting.int_vec_search(elts, size, a, idx)) {
471 return;
472 }
473 for (i = idx; i < size; i++) {
474 elts[i] = elts[i + 1];
475 }
476 size--;
477}
478
479
481 int a_len, long int *a, int b_len, long int *b)
482{
483 int i, l;
484
485 l = MINIMUM(a_len, b_len);
486 for (i = 0; i < l; i++) {
487 if (a[i] > b[i]) {
488 return 1;
489 }
490 if (a[i] < b[i]) {
491 return -1;
492 }
493 }
494 if (a_len > l) {
495 return 1;
496 }
497 if (b_len > l) {
498 return -1;
499 }
500 return 0;
501}
502
504{
505 long int r;
507
508 binomial(a, n, k, FALSE);
509 r = a.as_lint();
510 return r;
511}
512
514 int &m, int &n, int *&M,
515 int verbose_level)
516{
517 int f_v = (verbose_level >= 1);
518 int f_vv = (verbose_level >= 2);
519 int i, j;
520
521 m = int_n_choose_k(v, t);
522 n = int_n_choose_k(v, k);
523 M = NEW_int(m * n);
524 for (i = 0; i < m; i++) {
525 for (j = 0; j < n; j++) {
526 M[i * n + j] = f_is_subset_of(v, t, k, i, j);
527 }
528 }
529 if (f_v) {
530 cout << "make_t_k_incidence_matrix computed " << m << " x " << n
531 << " KM matrix" << endl;
532 }
533 if (f_vv) {
534 print_k_subsets_by_rank(cout, v, t);
535 print_k_subsets_by_rank(cout, v, k);
536 print_int_matrix(cout, M, m, n);
537 }
538}
539
540void combinatorics_domain::print_k_subsets_by_rank(ostream &ost, int v, int k)
541{
542 int *set;
543 int i, nb;
544
545 set = NEW_int(k);
546 nb = int_n_choose_k(v, k);
547 for (i = 0; i < nb; i++) {
548 unrank_k_subset(i, set, v, k);
549 cout << i << " : ";
551 cout << endl;
552 }
553 FREE_int(set);
554}
555
557 int rk_t_subset, int rk_k_subset)
558{
559 int *set1, *set2;
560 int i, j = 0, f_subset = TRUE;
561
562 set1 = NEW_int(t);
563 set2 = NEW_int(k);
564
565 unrank_k_subset(rk_t_subset, set1, v, t);
566 unrank_k_subset(rk_k_subset, set2, v, k);
567 for (i = 0; i < t; i++) {
568 while (j < k) {
569 if (set1[i] == set2[j]) {
570 break;
571 }
572 j++;
573 }
574 if (j == k) {
575 //cout << "did not find letter " << set1[i] << endl;
576 f_subset = FALSE;
577 break;
578 }
579 j++;
580 }
581
582 FREE_int(set1);
583 FREE_int(set2);
584 return f_subset;
585}
586
587int combinatorics_domain::rank_subset(int *set, int sz, int n)
588{
589 int r = 0;
590
591 rank_subset_recursion(set, sz, n, 0, r);
592 return r;
593}
594
596 int *set, int sz, int n, int a0, int &r)
597{
598 int a;
600
601 if (sz == 0) {
602 return;
603 }
604 r++;
605 for (a = a0; a < n; a++) {
606 if (set[0] == a) {
607 rank_subset_recursion(set + 1, sz - 1, n, a + 1, r);
608 return;
609 }
610 else {
611 r += NT.i_power_j(2, n - a - 1);
612 }
613 }
614}
615
616void combinatorics_domain::unrank_subset(int *set, int &sz, int n, int r)
617{
618 sz = 0;
619
620 unrank_subset_recursion(set, sz, n, 0, r);
621}
622
624 int *set, int &sz, int n, int a0, int &r)
625{
626 int a, b;
628
629 if (r == 0) {
630 return;
631 }
632 r--;
633 for (a = a0; a < n; a++) {
634 b = NT.i_power_j(2, n - a - 1);
635 if (r >= b) {
636 r -= b;
637 }
638 else {
639 set[sz++] = a;
640 unrank_subset_recursion(set, sz, n, a + 1, r);
641 return;
642 }
643 }
644}
645
646
647int combinatorics_domain::rank_k_subset(int *set, int n, int k)
648{
649 int r = 0, i, j;
651
652 if (k == 0) { // added Aug 25, 2018
653 return 0;
654 }
655 j = 0;
656 for (i = 0; i < n; i++) {
657 if (set[j] > i) {
658 binomial(a, n - i - 1, k - j - 1, FALSE);
659 r += a.as_int();
660 }
661 else {
662 j++;
663 }
664 if (j == k) {
665 break;
666 }
667 }
668 return r;
669}
670
671void combinatorics_domain::unrank_k_subset(int rk, int *set, int n, int k)
672{
673 int r1, i, j;
675
676 if (k == 0) { // added Aug 25, 2018
677 return;
678 }
679 j = 0;
680 for (i = 0; i < n; i++) {
681 binomial(a, n - i - 1, k - j - 1, FALSE);
682 r1 = a.as_int();
683 if (rk >= r1) {
684 rk -= r1;
685 continue;
686 }
687 set[j] = i;
688 j++;
689 if (j == k) {
690 break;
691 }
692 }
693}
694
696{
697 int i, j, l;
698
699 unrank_k_subset(rk, set, n, k);
700 j = 0;
701 l = 0;
702 for (i = 0; i < n; i++) {
703 if (j < k && set[j] == i) {
704 j++;
705 continue;
706 }
707 set[k + l] = i;
708 l++;
709 }
710
711}
712
713int combinatorics_domain::first_k_subset(int *set, int n, int k)
714{
715 int i;
716
717 if (k > n) {
718 return FALSE;
719 }
720 for (i = 0; i < k; i++) {
721 set[i] = i;
722 }
723 return TRUE;
724}
725
726int combinatorics_domain::next_k_subset(int *set, int n, int k)
727{
728 int i, ii, a;
729
730 for (i = 0; i < k; i++) {
731 a = set[k - 1 - i];
732 if (a < n - 1 - i) {
733 set[k - 1 - i] = a + 1;
734 for (ii = i - 1; ii >= 0; ii--) {
735 set[k - 1 - ii] = set[k - 1 - ii - 1] + 1;
736 }
737 return TRUE;
738 }
739 }
740 return FALSE;
741}
742
744 int *set, int n, int k, int backtrack_level)
745{
746 int i, ii, a, start;
747
748 start = k - 1 - backtrack_level;
749 for (i = start; i < k; i++) {
750 a = set[k - 1 - i];
751 if (a < n - 1 - i) {
752 set[k - 1 - i] = a + 1;
753 for (ii = i - 1; ii >= 0; ii--) {
754 set[k - 1 - ii] = set[k - 1 - ii - 1] + 1;
755 }
756 return TRUE;
757 }
758 }
759 return FALSE;
760}
761
763 int *set, int *k_subset_idx, int *permuted_set)
764{
765 int i, ii, j;
766
767 ii = 0;
768 j = -1;
769 for (i = 0; i < k; i++) {
770 permuted_set[i] = set[k_subset_idx[i]];
771 for (j++; j < k_subset_idx[i]; j++) {
772 permuted_set[k + ii] = set[j];
773 ii++;
774 }
775 }
776 for (j++; j < n; j++) {
777 permuted_set[k + ii] = set[j];
778 ii++;
779 }
780 if (ii != n - k) {
781 cout << "ii != n - k" << endl;
782 exit(1);
783 }
784}
785
787{
788 int a;
789
790 if (i == j) {
791 cout << "ordered_pair_rank i == j" << endl;
792 exit(1);
793 }
794 if (i < j) {
795 // without swap:
796 a = ij2k(i, j, n);
797 return 2 * a;
798 }
799 else {
800 // with swap
801 a = ij2k(j, i, n);
802 return 2 * a + 1;
803 }
804}
805
806void combinatorics_domain::ordered_pair_unrank(int rk, int &i, int &j, int n)
807{
808 int a;
809
810 if (rk % 2) {
811 int i1, j1;
812
813 // with swap
814 a = rk / 2;
815 k2ij(a, i1, j1, n);
816 i = j1;
817 j = i1;
818 }
819 else {
820 // without swap
821 a = rk / 2;
822 k2ij(a, i, j, n);
823 }
824}
825
827 int i, int j, int k, int l, int m, int n)
828{
829 int verbose_level = 0;
830 int f_v = (verbose_level >= 1);
831 int a, b, u, rk;
832 int six[5];
833 int sz;
835
836
837 if (f_v) {
838 cout << "unordered_triple_pair_rank " << i << j
839 << "," << k << l << "," << m << n << endl;
840 }
841
842 if (i > j) {
843 return unordered_triple_pair_rank(j, i, k, l, m, n);
844 }
845 if (k > l) {
846 return unordered_triple_pair_rank(i, j, l, k, m, n);
847 }
848 if (m > n) {
849 return unordered_triple_pair_rank(i, j, k, l, n, m);
850 }
851 if (k > m) {
852 return unordered_triple_pair_rank(i, j, m, n, k, l);
853 }
854 if (i > k) {
855 return unordered_triple_pair_rank(k, l, i, j, m, n);
856 }
857 if (k > m) {
858 return unordered_triple_pair_rank(i, j, m, n, k, l);
859 }
860 six[0] = m;
861 six[1] = n;
862 sz = 2;
863
864
865 Sorting.int_vec_search(six, sz, l, b);
866 for (u = sz; u > b; u--) {
867 six[u] = six[u - 1];
868 }
869 six[b] = l;
870 sz++;
871
872 if (f_v) {
873 cout << "unordered_triple_pair_rank : b = " << b << " : ";
874 Int_vec_print(cout, six, sz);
875 cout << endl;
876 }
877
878
879 if (k > six[0]) {
880 cout << "unordered_triple_pair_rank k > six[0]" << endl;
881 exit(1);
882 }
883 for (u = sz; u > 0; u--) {
884 six[u] = six[u - 1];
885 }
886 six[0] = k;
887 sz++;
888
889 if (f_v) {
890 cout << "unordered_triple_pair_rank : b = " << b << " : ";
891 Int_vec_print(cout, six, sz);
892 cout << endl;
893 }
894
895
896 Sorting.int_vec_search(six, sz, j, a);
897
898 if (f_v) {
899 cout << "unordered_triple_pair_rank : b = " << b
900 << " a = " << a << endl;
901 }
902
903
904 rk = a * 3 + b;
905 return rk;
906}
907
909{
910 if (rk == 0) {
911 v[0] = 0;
912 v[1] = 1;
913 v[2] = 2;
914 v[3] = 3;
915 }
916 else if (rk == 1) {
917 v[0] = 0;
918 v[1] = 2;
919 v[2] = 1;
920 v[3] = 3;
921 }
922 else if (rk == 2) {
923 v[0] = 0;
924 v[1] = 3;
925 v[2] = 1;
926 v[3] = 2;
927 }
928}
929
931{
932 if (v[0] > v[1]) {
933 int a = v[1];
934 v[1] = v[0];
935 v[0] = a;
936 }
937 if (v[2] > v[3]) {
938 int a = v[3];
939 v[3] = v[2];
940 v[2] = a;
941 }
942 if (v[2] < v[0]) {
943 int a, b;
944 a = v[0];
945 b = v[1];
946 v[0] = v[2];
947 v[1] = v[3];
948 v[2] = a;
949 v[3] = b;
950 }
951 if (v[0] != 0) {
952 cout << "set_partition_4_into_2_rank v[0] != 0";
953 }
954 if (v[1] == 1) {
955 return 0;
956 }
957 else if (v[1] == 2) {
958 return 1;
959 }
960 else if (v[1] == 3) {
961 return 2;
962 }
963 else {
964 cout << "set_partition_4_into_2_rank something is wrong" << endl;
965 exit(1);
966 }
967}
968
970 int &i, int &j, int &k, int &l, int &m, int &n)
971{
972 int a, b, u;
973 int six[5];
974 int sz;
975
976 a = rk / 3;
977 b = rk % 3;
978
979 //cout << "unordered_triple_pair_unrank rk=" << rk
980 //<< " a=" << a << " b=" << b << endl;
981 i = 0;
982 for (u = 0; u < 5; u++) {
983 six[u] = 1 + u;
984 }
985 sz = 5;
986 j = six[a];
987
988 //int_vec_print(cout, six, sz);
989 //cout << " j=" << j << endl;
990
991 for (u = a + 1; u < sz; u++) {
992 six[u - 1] = six[u];
993 }
994 sz--;
995 k = six[0];
996
997
998 //int_vec_print(cout, six, sz);
999 //cout << " k=" << k << endl;
1000
1001
1002 for (u = 1; u < sz; u++) {
1003 six[u - 1] = six[u];
1004 }
1005 sz--;
1006 l = six[b];
1007
1008
1009 //int_vec_print(cout, six, sz);
1010 //cout << " l=" << l << endl;
1011
1012
1013 for (u = b + 1; u < sz; u++) {
1014 six[u - 1] = six[u];
1015 }
1016 sz--;
1017 if (sz != 2) {
1018 cout << "unordered_triple_pair_unrank sz != 2" << endl;
1019 exit(1);
1020 }
1021 m = six[0];
1022 n = six[1];
1023 //int_vec_print(cout, six, sz);
1024 //cout << " m=" << m << " n=" << n << endl;
1025 //cout << "unordered_triple_pair_unrank rk=" << rk << " i=" << i
1026 //<< " j=" << j << " k=" << k << " l=" << l
1027 //<< " m=" << m << " n=" << n << endl;
1028}
1029
1030
1031
1032long int combinatorics_domain::ij2k_lint(long int i, long int j, long int n)
1033{
1034 if (i == j) {
1035 cout << "combinatorics_domain::ij2k_lint i == j" << endl;
1036 exit(1);
1037 }
1038 if (i > j) {
1039 return ij2k_lint(j, i, n);
1040 }
1041 else {
1042 return ((long int) (n - i) * (long int) i + (((long int) i * (long int) (i - 1)) >> 1)
1043 + (long int) j - (long int) i - (long int) 1);
1044 }
1045}
1046
1047void combinatorics_domain::k2ij_lint(long int k, long int & i, long int & j, long int n)
1048{
1049 long int ii, k_save = k;
1050
1051 for (ii = 0; ii < n; ii++) {
1052 if (k < n - ii - 1) {
1053 i = ii;
1054 j = k + ii + 1;
1055 return;
1056 }
1057 k -= (n - ii - 1);
1058 }
1059 cout << "combinatorics_domain::k2ij_lint k too large: k = " << k_save
1060 << " n = " << n << endl;
1061 exit(1);
1062}
1063
1064int combinatorics_domain::ij2k(int i, int j, int n)
1065{
1066 if (i == j) {
1067 cout << "ij2k() i == j" << endl;
1068 exit(1);
1069 }
1070 if (i > j) {
1071 return ij2k(j, i, n);
1072 }
1073 else {
1074 return ((n - i) * i + ((i * (i - 1)) >> 1) + j - i - 1);
1075 }
1076}
1077
1078void combinatorics_domain::k2ij(int k, int & i, int & j, int n)
1079{
1080 int ii, k_save = k;
1081
1082 for (ii = 0; ii < n; ii++) {
1083 if (k < n - ii - 1) {
1084 i = ii;
1085 j = k + ii + 1;
1086 return;
1087 }
1088 k -= (n - ii - 1);
1089 }
1090 cout << "k2ij: k too large: k = " << k_save
1091 << " n = " << n << endl;
1092 exit(1);
1093}
1094
1095int combinatorics_domain::ijk2h(int i, int j, int k, int n)
1096{
1097 int set[3];
1098 int h;
1099
1100 set[0] = i;
1101 set[1] = j;
1102 set[2] = k;
1103 h = rank_k_subset(set, n, 3);
1104 return h;
1105}
1106
1107void combinatorics_domain::h2ijk(int h, int &i, int &j, int &k, int n)
1108{
1109 int set[3];
1110
1111 unrank_k_subset(h, set, n, 3);
1112 i = set[0];
1113 j = set[1];
1114 k = set[2];
1115}
1116
1117
1118void combinatorics_domain::random_permutation(int *random_permutation, long int n)
1119{
1120 long int i, l, a;
1121 int *available_digits;
1123
1124 if (n == 0) {
1125 return;
1126 }
1127 if (n == 1) {
1128 random_permutation[0] = 0;
1129 return;
1130 }
1131 available_digits = NEW_int(n);
1132
1133 for (i = 0; i < n; i++) {
1134 available_digits[i] = i;
1135 }
1136 l = n;
1137 for (i = 0; i < n; i++) {
1138 if ((i % 1000) == 0) {
1139 cout << "random_permutation " << i << " / " << n << endl;
1140 }
1141 a = Os.random_integer(l);
1142 random_permutation[i] = available_digits[a];
1143 available_digits[a] = available_digits[l - 1];
1144#if 0
1145 for (j = a; j < l - 1; j++) {
1146 available_digits[j] = available_digits[j + 1];
1147 }
1148#endif
1149 l--;
1150 }
1151
1152 FREE_int(available_digits);
1153}
1154
1155void combinatorics_domain::perm_move(int *from, int *to, long int n)
1156{
1157 long int i;
1158
1159 for (i = 0; i < n; i++) {
1160 to[i] = from[i];
1161 }
1162}
1163
1165{
1166 long int i;
1167
1168 for (i = 0; i < n; i++) {
1169 a[i] = i;
1170 }
1171}
1172
1174{
1175 long int i;
1176
1177 for (i = 0; i < n; i++) {
1178 if (a[i] != i) {
1179 return FALSE;
1180 }
1181 }
1182 return TRUE;
1183}
1184
1186{
1187 long int i;
1188
1189 if (f >= n - 1) {
1190 cout << "perm_elementary_transposition f >= n - 1" << endl;
1191 exit(1);
1192 }
1193 for (i = 0; i < n; i++) {
1194 a[i] = i;
1195 }
1196 a[f] = f + 1;
1197 a[f + 1] = f;
1198}
1199
1200void combinatorics_domain::perm_mult(int *a, int *b, int *c, long int n)
1201{
1202 long int i, j, k;
1203
1204 for (i = 0; i < n; i++) {
1205 j = a[i];
1206 if (j < 0 || j >= n) {
1207 cout << "perm_mult a[" << i << "] = " << j
1208 << " out of range" << endl;
1209 exit(1);
1210 }
1211 k = b[j];
1212 if (k < 0 || k >= n) {
1213 cout << "perm_mult b[a[" << i << "] = " << j
1214 << "] = " << k << " out of range" << endl;
1215 exit(1);
1216 }
1217 c[i] = k;
1218 }
1219}
1220
1221void combinatorics_domain::perm_conjugate(int *a, int *b, int *c, long int n)
1222// c := a^b = b^-1 * a * b
1223{
1224 long int i, j, k;
1225
1226 for (i = 0; i < n; i++) {
1227 j = b[i];
1228 // now b^-1(j) = i
1229 k = a[i];
1230 k = b[k];
1231 c[j] = k;
1232 }
1233}
1234
1235void combinatorics_domain::perm_inverse(int *a, int *b, long int n)
1236// b := a^-1
1237{
1238 long int i, j;
1239
1240 for (i = 0; i < n; i++) {
1241 j = a[i];
1242 b[j] = i;
1243 }
1244}
1245
1246void combinatorics_domain::perm_raise(int *a, int *b, int e, long int n)
1247// b := a^e (e >= 0)
1248{
1249 long int i, j, k;
1250
1251 for (i = 0; i < n; i++) {
1252 k = i;
1253 for (j = 0; j < e; j++) {
1254 k = a[k];
1255 }
1256 b[i] = k;
1257 }
1258}
1259
1260void combinatorics_domain::perm_direct_product(long int n1, long int n2,
1261 int *perm1, int *perm2, int *perm3)
1262{
1263 long int i, j, a, b, c;
1264
1265 for (i = 0; i < n1; i++) {
1266 for (j = 0; j < n2; j++) {
1267 a = perm1[i];
1268 b = perm2[j];
1269 c = a * n2 + b;
1270 perm3[i * n2 + j] = c;
1271 }
1272 }
1273}
1274
1275void combinatorics_domain::perm_print_list(ostream &ost, int *a, int n)
1276{
1277 int i;
1278
1279 for (i = 0; i < n; i++) {
1280 ost << a[i] << " ";
1281 if (a[i] < 0 || a[i] >= n) {
1282 cout << "a[" << i << "] out of range" << endl;
1283 exit(1);
1284 }
1285 }
1286 cout << endl;
1287}
1288
1290 ostream &ost, int *a, int n, int offset)
1291{
1292 int i;
1293
1294 for (i = 0; i < n; i++) {
1295 ost << offset + a[i] << " ";
1296 if (a[i] < 0 || a[i] >= n) {
1297 cout << "a[" << i << "] out of range" << endl;
1298 exit(1);
1299 }
1300 }
1301 cout << endl;
1302}
1303
1305 ostream &ost, int *a,
1306 int m_plus_n, int m, int offset, int f_cycle_length)
1307{
1308 //cout << "perm_print_product_action" << endl;
1309 ost << "(";
1310 perm_print_offset(ost, a, m, offset, FALSE,
1311 f_cycle_length, FALSE, 0, FALSE, NULL, NULL);
1312 ost << "; ";
1313 perm_print_offset(ost, a + m, m_plus_n - m,
1314 offset + m, FALSE, f_cycle_length, FALSE, 0, FALSE, NULL, NULL);
1315 ost << ")";
1316 //cout << "perm_print_product_action done" << endl;
1317}
1318
1319void combinatorics_domain::perm_print(ostream &ost, int *a, int n)
1320{
1321 perm_print_offset(ost, a, n, 0, FALSE, FALSE, FALSE, 0, FALSE, NULL, NULL);
1322}
1323
1325 ostream &ost,
1326 int *a, int n,
1327 void (*point_label)(std::stringstream &sstr, long int pt, void *data),
1328 void *point_label_data)
1329{
1330 perm_print_offset(ost, a, n, 0, FALSE, FALSE, FALSE, 0, FALSE,
1331 point_label, point_label_data);
1332}
1333
1335 ostream &ost, int *a, int n)
1336{
1337 perm_print_offset(ost, a, n, 0, FALSE, TRUE, FALSE, 0, TRUE, NULL, NULL);
1338}
1339
1341 ostream &ost, int *a, int n)
1342{
1343 perm_print_offset(ost, a, n, 1, FALSE, FALSE, FALSE, 0, FALSE, NULL, NULL);
1344}
1345
1347 int *a, int n,
1348 int offset,
1349 int f_print_cycles_of_length_one,
1350 int f_cycle_length,
1351 int f_max_cycle_length,
1352 int max_cycle_length,
1353 int f_orbit_structure,
1354 void (*point_label)(std::stringstream &sstr, long int pt, void *data),
1355 void *point_label_data)
1356{
1357 int *have_seen;
1358 int i, l, l1, first, next, len;
1359 int f_nothing_printed_at_all = TRUE;
1360 int *orbit_length = NULL;
1361 int nb_orbits = 0;
1362
1363 //cout << "perm_print_offset n=" << n << " offset=" << offset << endl;
1364 if (f_orbit_structure) {
1365 orbit_length = NEW_int(n);
1366 }
1367 have_seen = NEW_int(n);
1368 for (l = 0; l < n; l++) {
1369 have_seen[l] = FALSE;
1370 }
1371 l = 0;
1372 while (l < n) {
1373 if (have_seen[l]) {
1374 l++;
1375 continue;
1376 }
1377 // work on a next cycle, starting at position l:
1378 first = l;
1379 //cout << "perm_print_offset cyle starting
1380 //"with " << first << endl;
1381 l1 = l;
1382 len = 1;
1383 while (TRUE) {
1384 if (l1 >= n) {
1385 cout << "perm_print_offset cyle starting with "
1386 << first << endl;
1387 cout << "l1 = " << l1 << " >= n" << endl;
1388 exit(1);
1389 }
1390 have_seen[l1] = TRUE;
1391 next = a[l1];
1392 if (next >= n) {
1393 cout << "perm_print_offset next = " << next
1394 << " >= n = " << n << endl;
1395 // print_list(ost);
1396 exit(1);
1397 }
1398 if (next == first) {
1399 break;
1400 }
1401 if (have_seen[next]) {
1402 cout << "perm_print_offset have_seen[next]" << endl;
1403 cout << "first=" << first << endl;
1404 cout << "len=" << len << endl;
1405 cout << "l1=" << l1 << endl;
1406 cout << "next=" << next << endl;
1407 for (i = 0; i < n; i++) {
1408 cout << i << " : " << a[i] << endl;
1409 }
1410 exit(1);
1411 }
1412 l1 = next;
1413 len++;
1414 }
1415 //cout << "perm_print_offset cyle starting with "
1416 //<< first << " has length " << len << endl;
1417 //cout << "nb_orbits=" << nb_orbits << endl;
1418 if (f_orbit_structure) {
1419 orbit_length[nb_orbits++] = len;
1420 }
1421 if (!f_print_cycles_of_length_one) {
1422 if (len == 1) {
1423 continue;
1424 }
1425 }
1426 if (f_max_cycle_length && len > max_cycle_length) {
1427 continue;
1428 }
1429 f_nothing_printed_at_all = FALSE;
1430 // print cycle, beginning with first:
1431 l1 = first;
1432 ost << "(";
1433 while (TRUE) {
1434 if (point_label) {
1435 stringstream sstr;
1436
1437 (*point_label)(sstr, l1, point_label_data);
1438 ost << sstr.str();
1439 }
1440 else {
1441 ost << l1 + offset;
1442 }
1443 next = a[l1];
1444 if (next == first) {
1445 break;
1446 }
1447 ost << ", ";
1448 l1 = next;
1449 }
1450 ost << ")"; // << endl;
1451 if (f_cycle_length) {
1452 if (len >= 10) {
1453 ost << "_{" << len << "}";
1454 }
1455 }
1456 //cout << "perm_print_offset done printing cycle" << endl;
1457 }
1458 if (f_nothing_printed_at_all) {
1459 ost << "id";
1460 }
1461 if (f_orbit_structure) {
1462
1464
1465 C.init(orbit_length, nb_orbits, FALSE, 0);
1466
1467 cout << "cycle type: ";
1468 //int_vec_print(cout, orbit_length, nb_orbits);
1469 //cout << " = ";
1470 C.print_naked(FALSE /* f_backwards*/);
1471
1472 FREE_int(orbit_length);
1473 }
1474 FREE_int(have_seen);
1475}
1476
1478 int *perm, long int degree, int *cycles, int &nb_cycles)
1479{
1480 int *have_seen;
1481 long int i, l, l1, first, next, len;
1482
1483 //cout << "perm_cycle_type degree=" << degree << endl;
1484 nb_cycles = 0;
1485 have_seen = NEW_int(degree);
1486 for (l = 0; l < degree; l++) {
1487 have_seen[l] = FALSE;
1488 }
1489 l = 0;
1490 while (l < degree) {
1491 if (have_seen[l]) {
1492 l++;
1493 continue;
1494 }
1495 // work on a next cycle, starting at position l:
1496 first = l;
1497 //cout << "perm_cycle_type cycle starting
1498 //"with " << first << endl;
1499 l1 = l;
1500 len = 1;
1501 while (TRUE) {
1502 if (l1 >= degree) {
1503 cout << "perm_cycle_type cyle starting with "
1504 << first << endl;
1505 cout << "l1 = " << l1 << " >= degree" << endl;
1506 exit(1);
1507 }
1508 have_seen[l1] = TRUE;
1509 next = perm[l1];
1510 if (next >= degree) {
1511 cout << "perm_cycle_type next = " << next
1512 << " >= degree = " << degree << endl;
1513 // print_list(ost);
1514 exit(1);
1515 }
1516 if (next == first) {
1517 break;
1518 }
1519 if (have_seen[next]) {
1520 cout << "perm_cycle_type have_seen[next]" << endl;
1521 cout << "first=" << first << endl;
1522 cout << "len=" << len << endl;
1523 cout << "l1=" << l1 << endl;
1524 cout << "next=" << next << endl;
1525 for (i = 0; i < degree; i++) {
1526 cout << i << " : " << perm[i] << endl;
1527 }
1528 exit(1);
1529 }
1530 l1 = next;
1531 len++;
1532 }
1533 //cout << "perm_print_offset cyle starting with "
1534 //<< first << " has length " << len << endl;
1535 //cout << "nb_orbits=" << nb_orbits << endl;
1536 cycles[nb_cycles++] = len;
1537 }
1538 FREE_int(have_seen);
1539}
1540
1542{
1543 int *have_seen;
1544 long int i, l, l1, first, next, len, order = 1;
1546
1547 have_seen = NEW_int(n);
1548 for (l = 0; l < n; l++) {
1549 have_seen[l] = FALSE;
1550 }
1551 l = 0;
1552 while (l < n) {
1553 if (have_seen[l]) {
1554 l++;
1555 continue;
1556 }
1557 // work on a next cycle, starting at position l:
1558 first = l;
1559 l1 = l;
1560 len = 1;
1561 while (TRUE) {
1562 have_seen[l1] = TRUE;
1563 next = a[l1];
1564 if (next > n) {
1565 cout << "perm_order: next = " << next
1566 << " > n = " << n << endl;
1567 // print_list(ost);
1568 exit(1);
1569 }
1570 if (next == first) {
1571 break;
1572 }
1573 if (have_seen[next]) {
1574 cout << "perm_order: have_seen[next]" << endl;
1575 for (i = 0; i < n; i++) {
1576 cout << i << " : " << a[i] << endl;
1577 }
1578 exit(1);
1579 }
1580 l1 = next;
1581 len++;
1582 }
1583 if (len == 1) {
1584 continue;
1585 }
1586 order = len * order / NT.gcd_lint(order, len);
1587 }
1588 FREE_int(have_seen);
1589 return order;
1590}
1591
1592int combinatorics_domain::perm_signum(int *perm, long int n)
1593{
1594 long int i, j, a, b, f;
1595 // f = number of inversions
1596
1597
1598 // compute the number of inversions:
1599 f = 0;
1600 for (i = 0; i < n; i++) {
1601 a = perm[i];
1602 for (j = i + 1; j < n; j++) {
1603 b = perm[j];
1604 if (b < a) {
1605 f++;
1606 }
1607 }
1608 }
1609 if (EVEN(f)) {
1610 return 1;
1611 }
1612 else {
1613 return -1;
1614 }
1615}
1616
1618{
1619 int *perm2;
1620 long int i;
1622
1623 perm2 = NEW_int(n);
1624 Int_vec_copy(perm, perm2, n);
1625 Sorting.int_vec_heapsort(perm2, n);
1626 for (i = 0; i < n; i++) {
1627 if (perm2[i] != i) {
1628 break;
1629 }
1630 }
1631 FREE_int(perm2);
1632 if (i == n) {
1633 return TRUE;
1634 }
1635 else {
1636 return FALSE;
1637 }
1638}
1639
1640int combinatorics_domain::is_permutation_lint(long int *perm, long int n)
1641{
1642 long int *perm2;
1643 long int i;
1645
1646 perm2 = NEW_lint(n);
1647 Lint_vec_copy(perm, perm2, n);
1648 Sorting.lint_vec_heapsort(perm2, n);
1649 for (i = 0; i < n; i++) {
1650 if (perm2[i] != i) {
1651 break;
1652 }
1653 }
1654 FREE_lint(perm2);
1655 if (i == n) {
1656 return TRUE;
1657 }
1658 else {
1659 return FALSE;
1660 }
1661}
1662
1664{
1665 int i;
1666
1667 for (i = 0; i < n; i++) {
1668 v[i] = 0;
1669 }
1670}
1671
1673{
1674 int i;
1675
1676 for (i = 0; i < n; i++) {
1677 if (v[i] < n - 1 - i) {
1678 v[i]++;
1679 for (i--; i >= 0; i--) {
1680 v[i] = 0;
1681 }
1682 return TRUE;
1683 }
1684 }
1685 return FALSE;
1686}
1687
1689 int n, int *code, int *perm)
1690{
1691 int *digits;
1692 int i, j, k;
1693
1694 digits = NEW_int(n);
1695 for (i = 0; i < n; i++) {
1696 digits[i] = i;
1697 }
1698
1699 for (i = 0; i < n; i++) {
1700
1701 // digits is an array of length n - i
1702
1703 k = code[i];
1704 perm[i] = digits[k];
1705 for (j = k; j < n - i - 1; j++) {
1706 digits[j] = digits[j + 1];
1707 }
1708 }
1709 FREE_int(digits);
1710}
1711
1713{
1714 int u1, v1;
1715
1716 while (u || v) {
1717 u1 = u % 2;
1718 v1 = v % 2;
1719 if (u1 && v1) {
1720 return FALSE;
1721 }
1722 u = u >> 1;
1723 v = v >> 1;
1724 }
1725 return TRUE;
1726}
1727
1729 int *A, int n, int kmax, int *memo, int verbose_level)
1730{
1731 int f_vv = (verbose_level >= 2);
1732 int k;
1733
1734 for (k = 1; k <= MINIMUM(kmax, n); k++) {
1735 if (!philip_hall_test(A, n, k, memo, verbose_level - 1)) {
1736 if (f_vv) {
1737 cout << "Hall test fails, k=" << k << endl;
1738 }
1739 return FALSE;
1740 }
1741 if (!philip_hall_test_dual(A, n, k, memo, verbose_level - 1)) {
1742 if (f_vv) {
1743 cout << "Hall test fails, k=" << k << ", dual" << endl;
1744 }
1745 return FALSE;
1746 }
1747 }
1748 return TRUE;
1749}
1750
1752 int *A, int n, int k, int *memo, int verbose_level)
1753// memo points to free memory of n int's
1754{
1755 int f_v = (verbose_level >= 1);
1756 int f_vv = (verbose_level >= 2);
1757 int i, j, l, c;
1758
1759 if (!first_k_subset(memo, n, k)) {
1760 return TRUE;
1761 }
1762 do {
1763 c = 0;
1764 for (j = 0; j < n; j++) {
1765 for (l = 0; l < k; l++) {
1766 i = memo[l];
1767 if (A[i * n + j]) {
1768 break;
1769 }
1770 }
1771 if (l < k) {
1772 c++;
1773 }
1774 if (c >= k) {
1775 break;
1776 }
1777 }
1778 if (c < k) {
1779 if (f_v) {
1780 cout << "Hall test fails for " << k << "-set ";
1782 cout << " c=" << c << " n=" << n << endl;
1783 }
1784 if (f_vv) {
1785 for (l = 0; l < k; l++) {
1786 i = memo[l];
1787 for (j = 0; j < n; j++) {
1788 if (A[i * n + j]) {
1789 cout << "*";
1790 }
1791 else {
1792 cout << ".";
1793 }
1794 }
1795 cout << endl;
1796 }
1797 }
1798 return FALSE;
1799 }
1800 } while (next_k_subset(memo, n, k));
1801 return TRUE;
1802}
1803
1805 int *A, int n, int k,
1806 int *memo, int verbose_level)
1807// memo points to free memory of n int's
1808{
1809 int f_v = (verbose_level >= 1);
1810 int f_vv = (verbose_level >= 2);
1811 int i, j, l, c;
1812
1813 if (!first_k_subset(memo, n, k)) {
1814 return TRUE;
1815 }
1816 do {
1817 c = 0;
1818 for (j = 0; j < n; j++) {
1819 for (l = 0; l < k; l++) {
1820 i = memo[l];
1821 if (A[j * n + i]) {
1822 break;
1823 }
1824 }
1825 if (l < k) {
1826 c++;
1827 }
1828 if (c >= k) {
1829 break;
1830 }
1831 }
1832 if (c < k) {
1833 if (f_v) {
1834 cout << "Hall test fails for " << k << "-set ";
1836 cout << " c=" << c << " n=" << n << endl;
1837 }
1838 if (f_vv) {
1839 for (l = 0; l < k; l++) {
1840 i = memo[l];
1841 for (j = 0; j < n; j++) {
1842 if (A[j * n + i]) {
1843 cout << "*";
1844 }
1845 else {
1846 cout << ".";
1847 }
1848 }
1849 cout << endl;
1850 }
1851 }
1852 return FALSE;
1853 }
1854 } while (next_k_subset(memo, n, k));
1855 return TRUE;
1856}
1857
1859 ostream &ost, int *A, int m, int n)
1860{
1861 int i, j;
1862
1863 for (i = 0; i < m; i++) {
1864 for (j = 0; j < n; j++) {
1865 if (A[i * n + j]) {
1866 ost << "*";
1867 }
1868 else {
1869 ost << ".";
1870 }
1871 }
1872 ost << endl;
1873 }
1874}
1875
1877 ostream &ost, int *A, int m, int n)
1878{
1879 int i, j;
1880
1881 for (i = 0; i < m; i++) {
1882 for (j = 0; j < n; j++) {
1883 ost << A[i * n + j] << " ";
1884 }
1885 ost << endl;
1886 }
1887}
1888
1890 field_theory::finite_field *F, int *roots)
1891{
1892 int i, j, k, j1, j2, j3, j4, n;
1893 int v[4];
1894 int L[4], P[4], sgn;
1895 int one, m_one, half, quarter, c, c2; /*tau, tau_inv,*/
1896 int a, b, m_a, m_b, m_half;
1897
1898 one = 1;
1899 m_one = F->negate(one);
1900 half = F->inverse(2);
1901 quarter = F->inverse(4);
1902 n = 0;
1903 for (c = 1; c < F->q; c++) {
1904 c2 = F->mult(c, c);
1905 if (c2 == 5) {
1906 break;
1907 }
1908 }
1909 if (c == F->q) {
1910 cout << "create_roots_H4: the field of order " << F->q
1911 << " does not contain a square root of 5" << endl;
1912 exit(1);
1913 }
1914 //tau = F->mult(F->add(1, c), half);
1915 //tau_inv = F->inverse(tau);
1916 a = F->mult(F->add(1, c), quarter);
1917 b = F->mult(F->add(m_one, c), quarter);
1918 m_a = F->negate(a);
1919 m_b = F->negate(b);
1920 m_half = F->negate(half);
1921 cout << "a=" << a << endl;
1922 cout << "b=" << b << endl;
1923 cout << "c=" << c << endl;
1924 //cout << "tau=" << tau << endl;
1925 //cout << "tau_inv=" << tau_inv << endl;
1926
1927 // create \{ \pm e_i \mid i=0,1,2,3 \}
1928 for (i = 0; i < 4; i++) {
1929 for (j = 0; j < 2; j++) {
1930 for (k = 0; k < 4; k++) {
1931 v[k] = 0;
1932 }
1933 if (j == 0) {
1934 v[i] = one;
1935 }
1936 else {
1937 v[i] = m_one;
1938 }
1939 for (k = 0; k < 4; k++) {
1940 roots[n * 4 + k] = v[k];
1941 }
1942 n++;
1943 } // next j
1944 } // next i
1945
1946 // creates the set of vectors
1947 // \{ 1/2 (\pm 1, \pm 1, \pm 1, \pm 1) \}
1948 for (j1 = 0; j1 < 2; j1++) {
1949 for (j2 = 0; j2 < 2; j2++) {
1950 for (j3 = 0; j3 < 2; j3++) {
1951 for (j4 = 0; j4 < 2; j4++) {
1952 // the zero vector:
1953 for (k = 0; k < 4; k++) {
1954 v[k] = 0;
1955 }
1956 if (j1 == 0)
1957 v[0] = one;
1958 else
1959 v[0] = m_one;
1960 if (j2 == 0)
1961 v[1] = one;
1962 else
1963 v[1] = m_one;
1964 if (j3 == 0)
1965 v[2] = one;
1966 else
1967 v[2] = m_one;
1968 if (j4 == 0)
1969 v[3] = one;
1970 else
1971 v[3] = m_one;
1972 for (k = 0; k < 4; k++) {
1973 roots[n * 4 + k] = F->mult(half, v[k]);
1974 }
1975 n++;
1976 } // next j4
1977 } // next j3
1978 } // next j2
1979 } // next j1
1980
1981 // creates the set of vectors
1982 // \{ \sigma ( (\pm a, \pm 1/2, \pm b, 0) ) \mid \sigma \in \Alt_4 \}
1983 for (j1 = 0; j1 < 2; j1++) {
1984 for (j2 = 0; j2 < 2; j2++) {
1985 for (j3 = 0; j3 < 2; j3++) {
1986 for (k = 0; k < 4; k++) {
1987 v[k] = 0;
1988 }
1989 if (j1 == 0) {
1990 v[0] = a;
1991 }
1992 else {
1993 v[0] = m_a;
1994 }
1995 if (j2 == 0) {
1996 v[1] = half;
1997 }
1998 else {
1999 v[1] = m_half;
2000 }
2001 if (j3 == 0) {
2002 v[2] = b;
2003 }
2004 else {
2005 v[2] = m_b;
2006 }
2007 first_lehmercode(4, L);
2008 while (TRUE) {
2010 sgn = perm_signum(P, 4);
2011 if (sgn == 1) {
2012 for (k = 0; k < 4; k++) {
2013 roots[n * 4 + k] = v[P[k]];
2014 }
2015 n++;
2016 }
2017 if (!next_lehmercode(4, L)) {
2018 break;
2019 }
2020 } // while
2021 } // next j3
2022 } // next j2
2023 } // next j1
2024 return n;
2025}
2026
2027
2029{
2030 long int a, b, c, a1, b1, c1, d, e, g;
2032
2033 if (n == k || k == 0) {
2034 return 1;
2035 }
2036 // now n >= 2
2037 c = generalized_binomial(n - 1, k - 1, q);
2038 a = NT.i_power_j_lint(q, n) - 1;
2039
2040 b = NT.i_power_j_lint(q, k) - 1;
2041
2042 g = NT.gcd_lint(a, b);
2043 a1 = a / g;
2044 b1 = b / g;
2045 a = a1;
2046 b = b1;
2047
2048 g = NT.gcd_lint(c, b);
2049 c1 = c / g;
2050 b1 = b / g;
2051 c = c1;
2052 b = b1;
2053
2054 if (b != 1) {
2055 cout << "error in generalized_binomial b != 1" << endl;
2056 exit(1);
2057 }
2058
2059 d = a * c;
2060 e = d / b;
2061 if (e * b != d) {
2062 cout << "error in generalized_binomial e * b != d" << endl;
2063 exit(1);
2064 }
2065 return e;
2066}
2067
2068void combinatorics_domain::print_tableau(int *Tableau, int l1, int l2,
2069 int *row_parts, int *col_parts)
2070{
2071 int i, j, a, b;
2072
2073 for (i = 0; i < l1; i++) {
2074 a = row_parts[i];
2075 for (j = 0; j < a; j++) {
2076 b = Tableau[i * l2 + j];
2077 cout << setw(3) << b << " ";
2078 }
2079 cout << endl;
2080 }
2081}
2082
2083int combinatorics_domain::ijk_rank(int i, int j, int k, int n)
2084{
2085 int set[3];
2086
2087 set[0] = i;
2088 set[1] = j;
2089 set[2] = k;
2090 return rank_k_subset(set, n, 3);
2091}
2092
2093void combinatorics_domain::ijk_unrank(int &i, int &j, int &k, int n, int rk)
2094{
2095 int set[3];
2096
2097 unrank_k_subset(rk, set, n, 3);
2098}
2099
2101{
2102 long int b, b2;
2103
2104 for (b = 1; ; b++) {
2105 b2 = binomial2(b);
2106 //cout << "b=" << b << " b2=" << b2 << " a2=" << a2 << endl;
2107 if (b2 > a2) {
2108 //cout << "return " << b - 1 << endl;
2109 break;
2110 }
2111 }
2112 return b - 1;
2113}
2114
2116{
2117 long int b, b3;
2118
2119 for (b = 1; ; b++) {
2120 b3 = binomial3(b);
2121 //cout << "b=" << b << " b3=" << b3 << " a3=" << a3 << endl;
2122 if (b3 > a3) {
2123 //cout << "return " << b - 1 << endl;
2124 break;
2125 }
2126 }
2127 return b - 1;
2128}
2129
2131{
2132 if (a == 0) {
2133 return 0;
2134 }
2135 if (EVEN(a)) {
2136 return (a >> 1) * (a - 1);
2137 }
2138 else {
2139 return a * (a >> 1);
2140 }
2141}
2142
2144{
2145 int r;
2146 if (a <= 2) {
2147 return 0;
2148 }
2149 r = a % 6;
2150 if (r == 0) {
2151 return (a / 6) * (a - 1) * (a - 2);
2152 }
2153 else if (r == 1) {
2154 return a * ((a - 1) / 6) * (a - 2);
2155 }
2156 else if (r == 2) {
2157 return a * (a - 1) * ((a - 2) / 6);
2158 }
2159 else if (r == 3) {
2160 return (a / 3) * ((a - 1) >> 1) * (a - 2);
2161 }
2162 else if (r == 4) {
2163 return (a >> 1) * ((a - 1) / 3) * (a - 2);
2164 }
2165 else if (r == 5) {
2166 return a * ((a - 1) >> 1) * ((a - 2) / 3);
2167 }
2168 cout << "error in binomial3" << endl;
2169 exit(1);
2170}
2171
2173{
2174 if (i) {
2175 return i - 1;
2176 }
2177 return 0;
2178}
2179
2180
2181void combinatorics_domain::make_partitions(int n, int *Part, int cnt)
2182{
2183 int *part;
2184 int cnt1;
2185
2186 cnt1 = 0;
2187
2188
2189 part = NEW_int(n + 1);
2190
2191 Int_vec_zero(part, n + 1);
2192 part[n] = 1;
2193 Int_vec_copy(part + 1, Part + cnt1 * n, n);
2194
2195 cnt1 = 1;
2196 while (TRUE) {
2197
2198 if (!next_partition(n, part)) {
2199 break;
2200 }
2201 Int_vec_copy(part + 1, Part + cnt1 * n, n);
2202 cnt1++;
2203 }
2204 if (cnt1 != cnt) {
2205 cout << "make_partitions cnt1 != cnt" << endl;
2206 exit(1);
2207 }
2208}
2209
2211{
2212 int cnt;
2213 int *part;
2214
2215 cnt = 0;
2216
2217
2218 part = NEW_int(n + 1);
2219
2220 Int_vec_zero(part, n + 1);
2221 part[n] = 1;
2222
2223
2224 cnt = 1;
2225
2226 while (TRUE) {
2227
2228 if (!next_partition(n, part)) {
2229 break;
2230 }
2231 cnt++;
2232 }
2233
2234 return cnt;
2235}
2236
2238{
2239 int s, i, j, q, r;
2240
2241 s = part[1];
2242 for (i = 2; i <= n; i++) {
2243 if (part[i]) {
2244 s += i;
2245 part[i]--;
2246 break;
2247 }
2248 }
2249 if (i == n + 1) {
2250 return FALSE;
2251 }
2252 for (j = i - 1; j >= 1; j--) {
2253 q = s / j;
2254 r = s - q * j;
2255 part[j] = q;
2256 s = r;
2257 }
2258 return TRUE;
2259}
2260
2261#define TABLE_BINOMIALS_MAX 1000
2262
2263static ring_theory::longinteger_object *tab_binomials = NULL;
2264static int tab_binomials_size = 0;
2265
2266
2268{
2270
2271 binomial(a, n, k, 0 /* verbose_level */);
2272 return a.as_lint();
2273}
2274
2275
2277{
2278 int f_v = (verbose_level >= 1);
2281 int r;
2282
2283 if (f_v) {
2284 cout << "combinatorics_domain::binomial "
2285 "n=" << n << " k=" << k << endl;
2286 }
2287 if (k < 0 || k > n) {
2288 a.create(0, __FILE__, __LINE__);
2289 return;
2290 }
2291 if (k == n) {
2292 a.create(1, __FILE__, __LINE__);
2293 return;
2294 }
2295 if (k == 0) {
2296 a.create(1, __FILE__, __LINE__);
2297 return;
2298 }
2299 if (n < TABLE_BINOMIALS_MAX) {
2300 if (f_v) {
2301 cout << "combinatorics_domain::binomial using table" << endl;
2302 }
2303 binomial_with_table(a, n, k);
2304 return;
2305 }
2306 else {
2307 binomial(b, n, k - 1, verbose_level);
2308 }
2309 c.create(n - k + 1, __FILE__, __LINE__);
2310 D.mult(b, c, d);
2311 D.integral_division_by_int(d, k, a, r);
2312 if (r != 0) {
2313 cout << "combinatorics_domain::binomial k != 0" << endl;
2314 exit(1);
2315 }
2316 if (f_v) {
2317 cout << "combinatorics_domain::binomial "
2318 "n=" << n << " k=" << k << " done" << endl;
2319 }
2320}
2321
2323{
2324 int i, j;
2326
2327 if (k < 0 || k > n) {
2328 a.create(0, __FILE__, __LINE__);
2329 return;
2330 }
2331 if (k == n) {
2332 a.create(1, __FILE__, __LINE__);
2333 return;
2334 }
2335 if (k == 0) {
2336 a.create(1, __FILE__, __LINE__);
2337 return;
2338 }
2339
2340 // reallocate table if necessary:
2341 if (n >= tab_binomials_size) {
2342 //cout << "binomial_with_table
2343 // reallocating table to size " << n + 1 << endl;
2344 ring_theory::longinteger_object *tab_binomials2 =
2345 NEW_OBJECTS(ring_theory::longinteger_object, (n + 1) * (n + 1));
2346 for (i = 0; i < tab_binomials_size; i++) {
2347 for (j = 0; j <= i; j++) {
2348 tab_binomials[i * tab_binomials_size +
2349 j].swap_with(tab_binomials2[i * (n + 1) + j]);
2350 }
2351 }
2352 for ( ; i <= n; i++) {
2353 for (j = 0; j <= i; j++) {
2354 tab_binomials2[i * (n + 1) + j].create(0, __FILE__, __LINE__);
2355 }
2356 }
2357 if (tab_binomials) {
2358 FREE_OBJECTS(tab_binomials);
2359 }
2360 tab_binomials = tab_binomials2;
2361 tab_binomials_size = n + 1;
2362#if 0
2363 for (i = 0; i < tab_binomials_size; i++) {
2364 for (j = 0; j <= i; j++) {
2365 tab_binomials2[i * (n + 1) + j].print(cout);
2366 cout << " ";
2367 }
2368 cout << endl;
2369 }
2370 cout << endl;
2371#endif
2372 }
2373 if (tab_binomials[n * tab_binomials_size + k].is_zero()) {
2375 int r;
2376
2377 binomial_with_table(b, n, k - 1);
2378 //cout << "recursion, binom " << n << ", " << k - 1 << " = ";
2379 //b.print(cout);
2380 //cout << endl;
2381
2382 c.create(n - k + 1, __FILE__, __LINE__);
2383 D.mult(b, c, d);
2384 D.integral_division_by_int(d, k, a, r);
2385 if (r != 0) {
2386 cout << "combinatorics_domain::binomial_with_table k != 0" << endl;
2387 exit(1);
2388 }
2389 a.assign_to(tab_binomials[n * tab_binomials_size + k]);
2390 //cout << "new table entry n=" << n << " k=" << k << " : ";
2391 //a.print(cout);
2392 //cout << " ";
2393 //tab_binomials[n * tab_binomials_size + k].print(cout);
2394 //cout << endl;
2395 }
2396 else {
2397 tab_binomials[n * tab_binomials_size + k].assign_to(a);
2398 }
2399}
2400
2402 ring_theory::longinteger_object &a, int n, int *part)
2403{
2406 int i, ai, j;
2407
2408 D.factorial(b, n);
2409 for (i = 1; i <= n; i++) {
2410 ai = part[i - 1];
2411 c.create(1, __FILE__, __LINE__);
2412 for (j = 0; j < ai; j++) {
2413 D.mult_integer_in_place(c, i);
2414 }
2415 for (j = 1; j <= ai; j++) {
2416 D.mult_integer_in_place(c, j);
2417 }
2418 D.integral_division_exact(b, c, d);
2419 d.assign_to(b);
2420 }
2421 b.assign_to(a);
2422}
2423
2424
2425#define TABLE_Q_BINOMIALS_MAX 200
2426
2427
2428static ring_theory::longinteger_object *tab_q_binomials = NULL;
2429static int tab_q_binomials_size = 0;
2430static int tab_q_binomials_q = 0;
2431
2432
2434 int n, int k, int q, int verbose_level)
2435{
2436 int i, j;
2437 //longinteger_domain D;
2438
2439 //cout << "q_binomial_with_table n=" << n
2440 // << " k=" << k << " q=" << q << endl;
2441 if (k < 0 || k > n) {
2442 a.create(0, __FILE__, __LINE__);
2443 return;
2444 }
2445 if (k == n) {
2446 a.create(1, __FILE__, __LINE__);
2447 return;
2448 }
2449 if (k == 0) {
2450 a.create(1, __FILE__, __LINE__);
2451 return;
2452 }
2453
2454 // reallocate table if necessary:
2455 if (n >= tab_q_binomials_size) {
2456 if (tab_q_binomials_size > 0 && q != tab_q_binomials_q) {
2457
2458
2459 q_binomial_no_table(a, n, k, q, verbose_level);
2460 return;
2461#if 0
2462 cout << "tab_q_binomials_size > 0 && q != tab_q_binomials_q" << endl;
2463 cout << "q=" << q << endl;
2464 cout << "tab_q_binomials_q=" << tab_q_binomials_q << endl;
2465 exit(1);
2466#endif
2467 }
2468 else {
2469 tab_q_binomials_q = q;
2470 }
2471 //cout << "binomial_with_table
2472 // reallocating table to size " << n + 1 << endl;
2473 ring_theory::longinteger_object *tab_q_binomials2 =
2474 NEW_OBJECTS(ring_theory::longinteger_object, (n + 1) * (n + 1));
2475 for (i = 0; i < tab_q_binomials_size; i++) {
2476 for (j = 0; j <= i; j++) {
2477 tab_q_binomials[i * tab_q_binomials_size +
2478 j].swap_with(tab_q_binomials2[i * (n + 1) + j]);
2479 }
2480 }
2481 for ( ; i <= n; i++) {
2482 for (j = 0; j <= i; j++) {
2483 tab_q_binomials2[i * (n + 1) + j].create(0, __FILE__, __LINE__);
2484 }
2485 }
2486 if (tab_q_binomials) {
2487 FREE_OBJECTS(tab_q_binomials);
2488 }
2489 tab_q_binomials = tab_q_binomials2;
2490 tab_q_binomials_size = n + 1;
2491#if 0
2492 for (i = 0; i < tab_q_binomials_size; i++) {
2493 for (j = 0; j <= i; j++) {
2494 tab_q_binomials2[i * (n + 1) + j].print(cout);
2495 cout << " ";
2496 }
2497 cout << endl;
2498 }
2499 cout << endl;
2500#endif
2501 }
2502 if (tab_q_binomials[n * tab_q_binomials_size + k].is_zero()) {
2503
2504 q_binomial_no_table(a, n, k, q, verbose_level);
2505 a.assign_to(tab_q_binomials[n * tab_q_binomials_size + k]);
2506 //cout << "new table entry n=" << n << " k=" << k << " : ";
2507 //a.print(cout);
2508 //cout << " ";
2509 //tab_q_binomials[n * tab_q_binomials_size + k].print(cout);
2510 //cout << endl;
2511 }
2512 else {
2513 tab_q_binomials[n * tab_q_binomials_size + k].assign_to(a);
2514 }
2515}
2516
2517
2520 int n, int k, int q, int verbose_level)
2521{
2522 int f_v = (verbose_level >= 1);
2523 ring_theory::longinteger_object b, c, top, bottom, r;
2524
2525 if (f_v) {
2526 cout << "combinatorics_domain::q_binomial "
2527 "n=" << n << " k=" << k << " q=" << q << endl;
2528 }
2529 if (k < 0 || k > n) {
2530 a.create(0, __FILE__, __LINE__);
2531 return;
2532 }
2533 if (k == n) {
2534 a.create(1, __FILE__, __LINE__);
2535 return;
2536 }
2537 if (k == 0) {
2538 a.create(1, __FILE__, __LINE__);
2539 return;
2540 }
2541 //cout << "longinteger_domain::q_binomial
2542 //n=" << n << " k=" << k << " q=" << q << endl;
2543 if (n < TABLE_Q_BINOMIALS_MAX) {
2544 q_binomial_with_table(a, n, k, q, verbose_level);
2545 }
2546 else {
2547 q_binomial_no_table(b, n, k, q, verbose_level);
2548 }
2549 if (f_v) {
2550 cout << "combinatorics_domain::q_binomial "
2551 "n=" << n << " k=" << k << " q=" << q
2552 << " yields " << a << endl;
2553 }
2554}
2555
2558 int n, int k, int q, int verbose_level)
2559{
2560 int f_v = (verbose_level >= 1);
2561 ring_theory::longinteger_object b, c, top, bottom, r;
2563
2564 if (f_v) {
2565 cout << "combinatorics_domain::q_binomial_no_table "
2566 "n=" << n << " k=" << k << " q=" << q << endl;
2567 }
2568 if (k < 0 || k > n) {
2569 a.create(0, __FILE__, __LINE__);
2570 return;
2571 }
2572 if (k == n) {
2573 a.create(1, __FILE__, __LINE__);
2574 return;
2575 }
2576 if (k == 0) {
2577 a.create(1, __FILE__, __LINE__);
2578 return;
2579 }
2580 q_binomial_no_table(b, n - 1, k - 1, q, verbose_level);
2581 D.create_qnm1(c, q, n);
2582 D.mult(b, c, top);
2583 D.create_qnm1(bottom, q, k);
2584 D.integral_division(top, bottom, a, r, verbose_level - 1);
2585 if (!r.is_zero()) {
2586 cout << "combinatorics_domain::q_binomial_no_table "
2587 "remainder is not zero" << endl;
2588 cout << "q=" << q << endl;
2589 cout << "n-1=" << n-1 << endl;
2590 cout << "k-1=" << k-1 << endl;
2591 cout << "top=" << top << endl;
2592 cout << "bottom=" << bottom << endl;
2593 exit(1);
2594 }
2595 if (f_v) {
2596 cout << "combinatorics_domain::q_binomial_no_table "
2597 "n=" << n << " k=" << k << " q=" << q
2598 << " yields " << a << endl;
2599 }
2600}
2601
2602
2603static ring_theory::longinteger_object *tab_krawtchouk = NULL;
2604static int *tab_krawtchouk_entry_computed = NULL;
2605static int tab_krawtchouk_size = 0;
2606static int tab_krawtchouk_n = 0;
2607static int tab_krawtchouk_q = 0;
2608
2610 int n, int q, int k, int x)
2611{
2612 int i, j, kx;
2614
2615 if (tab_krawtchouk_size) {
2616 if (n != tab_krawtchouk_n || q != tab_krawtchouk_q) {
2617 delete [] tab_krawtchouk;
2618 FREE_int(tab_krawtchouk_entry_computed);
2619 tab_krawtchouk_size = 0;
2620 tab_krawtchouk_n = 0;
2621 tab_krawtchouk_q = 0;
2622 }
2623 }
2624 kx = MAXIMUM(k, x);
2625 // reallocate table if necessary:
2626 if (kx >= tab_krawtchouk_size) {
2627 kx++;
2628 //cout << "krawtchouk_with_table
2629 //reallocating table to size " << kx << endl;
2630 ring_theory::longinteger_object *tab_krawtchouk2 =
2632 int *tab_krawtchouk_entry_computed2 = NEW_int(kx * kx);
2633 for (i = 0; i < kx; i++) {
2634 for (j = 0; j < kx; j++) {
2635 tab_krawtchouk_entry_computed2[i * kx + j] = FALSE;
2636 tab_krawtchouk2[i * kx + j].create(0, __FILE__, __LINE__);
2637 }
2638 }
2639 for (i = 0; i < tab_krawtchouk_size; i++) {
2640 for (j = 0; j < tab_krawtchouk_size; j++) {
2641 tab_krawtchouk[i * tab_krawtchouk_size + j
2642 ].swap_with(tab_krawtchouk2[i * kx + j]);
2643 tab_krawtchouk_entry_computed2[i * kx + j] =
2644 tab_krawtchouk_entry_computed[
2645 i * tab_krawtchouk_size + j];
2646 }
2647 }
2648 if (tab_krawtchouk) {
2649 FREE_OBJECTS(tab_krawtchouk);
2650 }
2651 if (tab_krawtchouk_entry_computed) {
2652 FREE_int(tab_krawtchouk_entry_computed);
2653 }
2654 tab_krawtchouk = tab_krawtchouk2;
2655 tab_krawtchouk_entry_computed = tab_krawtchouk_entry_computed2;
2656 tab_krawtchouk_size = kx;
2657 tab_krawtchouk_n = n;
2658 tab_krawtchouk_q = q;
2659#if 0
2660 for (i = 0; i < tab_krawtchouk_size; i++) {
2661 for (j = 0; j < tab_krawtchouk_size; j++) {
2662 tab_krawtchouk[i * tab_krawtchouk_size + j].print(cout);
2663 cout << " ";
2664 }
2665 cout << endl;
2666 }
2667 cout << endl;
2668#endif
2669 }
2670 if (!tab_krawtchouk_entry_computed[k * tab_krawtchouk_size + x]) {
2671 ring_theory::longinteger_object n_choose_k, b, c, d, e, f;
2672
2673 if (x < 0) {
2674 cout << "combinatorics_domain::krawtchouk_with_table x < 0" << endl;
2675 exit(1);
2676 }
2677 if (k < 0) {
2678 cout << "combinatorics_domain::krawtchouk_with_table k < 0" << endl;
2679 exit(1);
2680 }
2681 if (x == 0) {
2682 binomial(n_choose_k, n, k, FALSE);
2683 if (q != 1) {
2684 b.create(q - 1, __FILE__, __LINE__);
2685 D.power_int(b, k);
2686 D.mult(n_choose_k, b, a);
2687 }
2688 else {
2689 n_choose_k.assign_to(a);
2690 }
2691 }
2692 else if (k == 0) {
2693 a.create(1, __FILE__, __LINE__);
2694 }
2695 else {
2696 krawtchouk_with_table(b, n, q, k, x - 1);
2697 //cout << "K_" << k << "(" << x - 1 << ")=" << b << endl;
2698 c.create(-q + 1, __FILE__, __LINE__);
2699 krawtchouk_with_table(d, n, q, k - 1, x);
2700 //cout << "K_" << k - 1<< "(" << x << ")=" << d << endl;
2701 D.mult(c, d, e);
2702 //cout << " e=";
2703 //e.print(cout);
2704 D.add(b, e, c);
2705 //cout << " c=";
2706 //c.print(cout);
2707 d.create(-1, __FILE__, __LINE__);
2708 krawtchouk_with_table(e, n, q, k - 1, x - 1);
2709 //cout << "K_" << k - 1<< "(" << x - 1 << ")=" << e << endl;
2710 D.mult(d, e, f);
2711 //cout << " f=";
2712 //f.print(cout);
2713 //cout << " c=";
2714 //c.print(cout);
2715 D.add(c, f, a);
2716 //cout << " a=";
2717 //a.print(cout);
2718 //cout << endl;
2719 }
2720
2721 a.assign_to(tab_krawtchouk[k * tab_krawtchouk_size + x]);
2722 tab_krawtchouk_entry_computed[
2723 k * tab_krawtchouk_size + x] = TRUE;
2724 //cout << "new table entry k=" << k << " x=" << x << " : " << a << endl;
2725 }
2726 else {
2727 tab_krawtchouk[k * tab_krawtchouk_size + x].assign_to(a);
2728 }
2729}
2730
2732 int n, int q, int k, int x)
2733{
2734 //cout << "combinatorics_domain::krawtchouk n=" << n << " q=" << q << " k=" << k << " x=" << x << endl;
2735 krawtchouk_with_table(a, n, q, k, x);
2736}
2737
2738
2740{
2741 int f_v = (verbose_level >= 1);
2742
2743 if (f_v) {
2744 cout << "combinatorics_domain::do_tdo_refinement" << endl;
2745 }
2746
2747 tdo_refinement *R;
2748
2750
2751 R->init(Descr, verbose_level);
2752 R->main_loop(verbose_level);
2753
2754 FREE_OBJECT(R);
2755
2756 if (f_v) {
2757 cout << "combinatorics_domain::do_tdo_refinement done" << endl;
2758 }
2759}
2760
2761void combinatorics_domain::do_tdo_print(std::string &fname, int verbose_level)
2762{
2763 int f_v = (verbose_level >= 1);
2764 int f_vv = (verbose_level >= 2);
2765 int cnt;
2766 //char str[1000];
2767 //char ext[1000];
2768 //char fname_out[1000];
2769 int f_widor = FALSE;
2770 int f_doit = FALSE;
2771
2772 if (f_v) {
2773 cout << "combinatorics_domain::do_tdo_print" << endl;
2774 }
2775
2776 cout << "opening file " << fname << " for reading" << endl;
2777 ifstream f(fname);
2778 //ofstream *g = NULL;
2779
2780 //ofstream *texfile;
2781
2782
2783#if 0
2784 strcpy(str, fname);
2785 get_extension_if_present(str, ext);
2786 chop_off_extension_if_present(str, ext);
2787#endif
2788
2789#if 0
2790 sprintf(fname_out, "%sw.tdo", str);
2791 if (f_w) {
2792 g = new ofstream(fname_out);
2793 }
2794 if (f_texfile) {
2795 texfile = new ofstream(texfile_name);
2796 }
2797#endif
2798
2799
2800 geo_parameter GP;
2802
2803
2804 //Vector vm, VM, VM_mult;
2805 //discreta_base mu;
2806
2807#if 0
2808 if (f_intersection) {
2809 VM.m_l(0);
2810 VM_mult.m_l(0);
2811 }
2812#endif
2813
2814 for (cnt = 0; ; cnt++) {
2815 if (f.eof()) {
2816 cout << "eof reached" << endl;
2817 break;
2818 }
2819 if (f_widor) {
2820 if (!GP.input(f)) {
2821 //cout << "GP.input returns FALSE" << endl;
2822 break;
2823 }
2824 }
2825 else {
2826 if (!GP.input_mode_stack(f, verbose_level - 1)) {
2827 //cout << "GP.input_mode_stack returns FALSE" << endl;
2828 break;
2829 }
2830 }
2831 //if (f_v) {
2832 //cout << "read decomposition " << cnt << endl;
2833 //}
2834
2835 f_doit = TRUE;
2836#if 0
2837 if (f_range) {
2838 if (cnt < range_first || cnt >= range_first + range_len)
2839 f_doit = FALSE;
2840 }
2841 if (f_select) {
2842 if (strcmp(GP.label, select_label))
2843 continue;
2844 }
2845 if (f_nt) {
2846 if (GP.row_level == GP.col_level)
2847 continue;
2848 }
2849#endif
2850
2851 if (!f_doit) {
2852 continue;
2853 }
2854 //cout << "before convert_single_to_stack" << endl;
2855 //GP.convert_single_to_stack();
2856 //cout << "after convert_single_to_stack" << endl;
2857 //sprintf(label, "%s.%d", str, i);
2858 //GP.write(g, label);
2859 if (f_vv) {
2860 cout << "before init_tdo_scheme" << endl;
2861 }
2862 GP.init_tdo_scheme(G, verbose_level - 1);
2863 if (f_vv) {
2864 cout << "after init_tdo_scheme" << endl;
2865 }
2866 GP.print_schemes(G);
2867
2868#if 0
2869 if (f_C) {
2870 GP.print_C_source();
2871 }
2872#endif
2873 if (TRUE /* f_tex */) {
2874 GP.print_scheme_tex(cout, G, ROW_SCHEME);
2875 GP.print_scheme_tex(cout, G, COL_SCHEME);
2876 }
2877#if 0
2878 if (f_texfile) {
2879 if (f_ROW) {
2880 GP.print_scheme_tex(*texfile, G, ROW_SCHEME);
2881 }
2882 if (f_COL) {
2883 GP.print_scheme_tex(*texfile, G, COL_SCHEME);
2884 }
2885 }
2886 if (f_Tex) {
2887 char fname[1000];
2888
2889 sprintf(fname, "%s.tex", GP.label);
2890 ofstream f(fname);
2891
2892 GP.print_scheme_tex(f, G, ROW);
2893 GP.print_scheme_tex(f, G, COL);
2894 }
2895 if (f_intersection) {
2896 Vector V, M;
2897 intersection_of_columns(GP, G,
2898 intersection_j1, intersection_j2, V, M, verbose_level - 1);
2899 vm.m_l(2);
2900 vm.s_i(0).swap(V);
2901 vm.s_i(1).swap(M);
2902 cout << "vm:" << vm << endl;
2903 int idx;
2904 mu.m_i_i(1);
2905 if (VM.search(vm, &idx)) {
2906 VM_mult.m_ii(idx, VM_mult.s_ii(idx) + 1);
2907 }
2908 else {
2909 cout << "inserting at position " << idx << endl;
2910 VM.insert_element(idx, vm);
2911 VM_mult.insert_element(idx, mu);
2912 }
2913 }
2914 if (f_w) {
2915 GP.write_mode_stack(*g, GP.label);
2916 nb_written++;
2917 }
2918#endif
2919 }
2920
2921#if 0
2922 if (f_w) {
2923 *g << "-1 " << nb_written << endl;
2924 delete g;
2925
2926 }
2927
2928 if (f_texfile) {
2929 delete texfile;
2930 }
2931
2932 if (f_intersection) {
2933 int cl, c, l, j, L;
2934 cout << "the intersection types are:" << endl;
2935 for (i = 0; i < VM.s_l(); i++) {
2936 //cout << setw(5) << VM_mult.s_ii(i) << " x " << VM.s_i(i) << endl;
2937 cout << "intersection type " << i + 1 << ":" << endl;
2938 Vector &V = VM.s_i(i).as_vector().s_i(0).as_vector();
2939 Vector &M = VM.s_i(i).as_vector().s_i(1).as_vector();
2940 //cout << "V=" << V << endl;
2941 //cout << "M=" << M << endl;
2942 cl = V.s_l();
2943 for (c = 0; c < cl; c++) {
2944 Vector &Vc = V.s_i(c).as_vector();
2945 Vector &Mc = M.s_i(c).as_vector();
2946 //cout << c << " : " << Vc << "," << Mc << endl;
2947 l = Vc.s_l();
2948 for (j = 0; j < l; j++) {
2949 Vector &the_type = Vc.s_i(j).as_vector();
2950 int mult = Mc.s_ii(j);
2951 cout << setw(5) << mult << " x " << the_type << endl;
2952 }
2953 cout << "--------------------------" << endl;
2954 }
2955 cout << "appears " << setw(5) << VM_mult.s_ii(i) << " times" << endl;
2956
2957 classify *C;
2958 classify *C_pencil;
2959 int f_second = FALSE;
2960 int *pencil_data;
2961 int pencil_data_size = 0;
2962 int pos, b, hh;
2963
2964 C = new classify[cl];
2965 C_pencil = new classify;
2966
2967 for (c = 0; c < cl; c++) {
2968 Vector &Vc = V.s_i(c).as_vector();
2969 Vector &Mc = M.s_i(c).as_vector();
2970 //cout << c << " : " << Vc << "," << Mc << endl;
2971 l = Vc.s_l();
2972 L = 0;
2973 for (j = 0; j < l; j++) {
2974 Vector &the_type = Vc.s_i(j).as_vector();
2975 int mult = Mc.s_ii(j);
2976 if (the_type.s_ii(1) == 1 && the_type.s_ii(0)) {
2977 pencil_data_size += mult;
2978 }
2979 }
2980 }
2981 //cout << "pencil_data_size=" << pencil_data_size << endl;
2982 pencil_data = new int[pencil_data_size];
2983 pos = 0;
2984
2985 for (c = 0; c < cl; c++) {
2986 Vector &Vc = V.s_i(c).as_vector();
2987 Vector &Mc = M.s_i(c).as_vector();
2988 //cout << c << " : " << Vc << "," << Mc << endl;
2989 l = Vc.s_l();
2990 L = 0;
2991 for (j = 0; j < l; j++) {
2992 Vector &the_type = Vc.s_i(j).as_vector();
2993 int mult = Mc.s_ii(j);
2994 if (the_type.s_ii(1) == 1 && the_type.s_ii(0)) {
2995 b = the_type.s_ii(0);
2996 for (hh = 0; hh < mult; hh++) {
2997 pencil_data[pos++] = b;
2998 }
2999 }
3000 }
3001 }
3002 //cout << "pencil_data: ";
3003 //int_vec_print(cout, pencil_data, pencil_data_size);
3004 //cout << endl;
3005 C_pencil->init(pencil_data, pencil_data_size, FALSE /*f_second */, verbose_level - 2);
3006 delete [] pencil_data;
3007
3008 for (c = 0; c < cl; c++) {
3009 Vector &Vc = V.s_i(c).as_vector();
3010 Vector &Mc = M.s_i(c).as_vector();
3011 //cout << c << " : " << Vc << "," << Mc << endl;
3012 l = Vc.s_l();
3013 L = 0;
3014 for (j = 0; j < l; j++) {
3015 Vector &the_type = Vc.s_i(j).as_vector();
3016 if (the_type.s_ii(1))
3017 continue;
3018 int mult = Mc.s_ii(j);
3019 L += mult;
3020 }
3021 int *data;
3022 int k, h, a;
3023
3024 data = new int[L];
3025 k = 0;
3026 for (j = 0; j < l; j++) {
3027 Vector &the_type = Vc.s_i(j).as_vector();
3028 int mult = Mc.s_ii(j);
3029 if (the_type.s_ii(1))
3030 continue;
3031 a = the_type.s_ii(0);
3032 for (h = 0; h < mult; h++) {
3033 data[k++] = a;
3034 }
3035 }
3036 //cout << "data: ";
3037 //int_vec_print(cout, data, L);
3038 //cout << endl;
3039 C[c].init(data, L, f_second, verbose_level - 2);
3040 delete [] data;
3041 }
3042
3043 cout << "Intersection type " << i + 1 << ": pencil type: (";
3044 C_pencil->print_naked(FALSE /*f_backwards*/);
3045 cout << ") ";
3046 cout << "intersection type: (";
3047 for (c = 0; c < cl; c++) {
3048 C[c].print_naked(FALSE /*f_backwards*/);
3049 if (c < cl - 1)
3050 cout << " | ";
3051 }
3052 cout << ") appears " << VM_mult.s_ii(i) << " times" << endl;
3053 //C_pencil->print();
3054 delete [] C;
3055 delete C_pencil;
3056 }
3057 }
3058#endif
3059
3060 if (f_v) {
3061 cout << "combinatorics_domain::do_tdo_print done" << endl;
3062 }
3063}
3064
3065void combinatorics_domain::make_elementary_symmetric_functions(int n, int k_max, int verbose_level)
3066{
3067 int f_v = (verbose_level >= 1);
3068
3069 if (f_v) {
3070 cout << "combinatorics_domain::make_elementary_symmetric_function" << endl;
3071 }
3072 int *set;
3074 int k, j;
3075 int f_first;
3076
3077
3078 set = NEW_int(k_max);
3079 for (k = 1; k <= k_max; k++) {
3080 cout << "k=" << k << " : " << endl;
3081 Combi.first_k_subset(set, n, k);
3082 f_first = TRUE;
3083 while (TRUE) {
3084 if (f_first) {
3085 f_first = FALSE;
3086 }
3087 else {
3088 cout << " + ";
3089 }
3090 for (j = 0; j < k; j++) {
3091 cout << "x" << set[j];
3092 if (j < k - 1) {
3093 cout << "*";
3094 }
3095 }
3096 if (!Combi.next_k_subset(set, n, k)) {
3097 break;
3098 }
3099 }
3100 cout << endl;
3101 }
3102
3103 FREE_int(set);
3104 if (f_v) {
3105 cout << "combinatorics_domain::make_elementary_symmetric_functions done" << endl;
3106 }
3107
3108}
3109
3110void combinatorics_domain::Dedekind_numbers(int n_min, int n_max, int q_min, int q_max, int verbose_level)
3111{
3112 int f_v = (verbose_level >= 1);
3113
3114 if (f_v) {
3115 cout << "combinatorics_domain::Dedekind_numbers" << endl;
3116 }
3117 {
3118 char str[1000];
3119 string fname;
3120
3121 snprintf(str, 1000, "Dedekind_%d_%d_%d_%d.csv", n_min, n_max, q_min, q_max);
3122 fname.assign(str);
3123
3124
3125 {
3126 ofstream ost(fname);
3127
3128 if (f_v) {
3129 cout << "combinatorics_domain::Dedekind_numbers writing csv file" << endl;
3130 }
3131 //report(ost, verbose_level);
3132
3133 int n, q;
3136
3137 ost << "ROW";
3138 for (q = q_min; q <= q_max; q++) {
3139 ost << "," << q;
3140 }
3141 ost << endl;
3142 for (n = n_min; n <= n_max; n++) {
3143 ost << n;
3144 for (q = q_min; q <= q_max; q++) {
3146
3147 cout << "computing n=" << n << " q=" << q << endl;
3148 D.Dedekind_number(Dnq, n, q, verbose_level);
3149 ost << "," << Dnq;
3150 }
3151 ost << endl;
3152 }
3153 ost << "END" << endl;
3154
3155 if (f_v) {
3156 cout << "combinatorics_domain::Dedekind_numbers writing csv file" << endl;
3157 }
3158
3159
3160 }
3162
3163 cout << "combinatorics_domain::Dedekind_numbers written file " << fname << " of size "
3164 << Fio.file_size(fname) << endl;
3165 }
3166
3167
3168
3169
3170 if (f_v) {
3171 cout << "combinatorics_domain::Dedekind_numbers done" << endl;
3172 }
3173}
3174
3175
3176
3177void combinatorics_domain::convert_stack_to_tdo(std::string &stack_fname, int verbose_level)
3178{
3179 int f_v = (verbose_level >= 1);
3180 int f_vv = (verbose_level >= 2);
3181 int i;
3182 string fname;
3183 string fname_out;
3184 string label;
3186
3187 if (f_v) {
3188 cout << "combinatorics_domain::convert_stack_to_tdo" << endl;
3189 }
3190 fname.assign(stack_fname);
3191 ST.chop_off_extension(fname);
3192 fname_out.assign(fname);
3193 fname_out.append(".tdo");
3194
3195 if (f_v) {
3196 cout << "reading stack file " << stack_fname << endl;
3197 }
3198 {
3199 geo_parameter GP;
3201 ifstream f(stack_fname);
3202 ofstream g(fname_out);
3203 for (i = 0; ; i++) {
3204 if (f.eof()) {
3205 if (f_v) {
3206 cout << "end of file reached" << endl;
3207 }
3208 break;
3209 }
3210 if (!GP.input(f)) {
3211 if (f_v) {
3212 cout << "GP.input returns false" << endl;
3213 }
3214 break;
3215 }
3216 if (f_v) {
3217 cout << "read decomposition " << i
3218 << " v=" << GP.v << " b=" << GP.b << endl;
3219 }
3220 GP.convert_single_to_stack(verbose_level - 1);
3221 if (f_v) {
3222 cout << "after convert_single_to_stack" << endl;
3223 }
3224 if (strlen(GP.label.c_str())) {
3225 GP.write(g, GP.label);
3226 }
3227 else {
3228 char str[1000];
3229 string s;
3230
3231 sprintf(str, "%d", i);
3232 s.assign(str);
3233 GP.write(g, s);
3234 }
3235
3236 if (f_v) {
3237 cout << "after write" << endl;
3238 }
3239 GP.init_tdo_scheme(G, verbose_level - 1);
3240 if (f_v) {
3241 cout << "after init_tdo_scheme" << endl;
3242 }
3243 if (f_vv) {
3244 GP.print_schemes(G);
3245 }
3246 }
3247 g << "-1 " << i << endl;
3248 }
3249 if (f_v) {
3251 cout << "written file " << fname_out << " of size " << Fio.file_size(fname_out) << endl;
3252 cout << "combinatorics_domain::convert_stack_to_tdo done" << endl;
3253 }
3254}
3255
3256void combinatorics_domain::do_parameters_maximal_arc(int q, int r, int verbose_level)
3257{
3258 int f_v = (verbose_level >= 1);
3259 int m = 2, n = 2;
3260 int v[2], b[2], aij[4];
3261 int Q;
3262 char fname[1000];
3264
3265 if (f_v) {
3266 cout << "combinatorics_domain::do_parameters_maximal_arc q=" << q << " r=" << r << endl;
3267 }
3268
3269 Q = q * q;
3270 v[0] = q * (r - 1) + r;
3271 v[1] = Q + q * (2 - r) - r + 1;
3272 b[0] = Q - Q / r + q * 2 - q / r + 1;
3273 b[1] = Q / r + q / r - q;
3274 aij[0] = q + 1;
3275 aij[1] = 0;
3276 aij[2] = q - q / r + 1;
3277 aij[3] = q / r;
3278 snprintf(fname, 1000, "max_arc_q%d_r%d.stack", q, r);
3279
3280 Fio.write_decomposition_stack(fname, m, n, v, b, aij, verbose_level - 1);
3281}
3282
3283void combinatorics_domain::do_parameters_arc(int q, int s, int r, int verbose_level)
3284{
3285 int f_v = (verbose_level >= 1);
3286 int m = 2, n = 1;
3287 int v[2], b[1], aij[2];
3288 char fname[1000];
3290
3291 if (f_v) {
3292 cout << "combinatorics_domain::do_parameters_maximal_arc q=" << q << " s=" << s << " r=" << r << endl;
3293 }
3294
3295 v[0] = s;
3296 v[1] = q * q + q + 1 - s;
3297 b[0] = q * q + q + 1;
3298 aij[0] = q + 1;
3299 aij[1] = q + 1;
3300 snprintf(fname, 1000, "arc_q%d_s%d_r%d.stack", q, s, r);
3301
3302 Fio.write_decomposition_stack(fname, m, n, v, b, aij, verbose_level - 1);
3303}
3304
3306 int f_grouping, double x_stretch, int verbose_level)
3307// creates a layered graph file from a text file
3308// which was created by DISCRETA/sgls2.cpp
3309{
3310 int f_v = (verbose_level >= 1);
3312
3313 if (f_v) {
3314 cout << "interface_combinatorics::do_read_poset_file" << endl;
3315 }
3316
3318
3320 LG->init_poset_from_file(fname, f_grouping, x_stretch, verbose_level - 1);
3321
3322
3323 string fname_out;
3325
3326 fname_out.assign(fname);
3327
3328 ST.replace_extension_with(fname_out, ".layered_graph");
3329
3330
3331 LG->write_file(fname_out, 0 /*verbose_level*/);
3332
3333 cout << "Written file " << fname_out << " of size "
3334 << Fio.file_size(fname_out) << endl;
3335
3336 FREE_OBJECT(LG);
3337
3338 if (f_v) {
3339 cout << "combinatorics_domain::do_read_poset_file done" << endl;
3340 }
3341}
3342
3343
3344void combinatorics_domain::do_make_tree_of_all_k_subsets(int n, int k, int verbose_level)
3345{
3346 int f_v = (verbose_level >= 1);
3347
3348 if (f_v) {
3349 cout << "combinatorics_domain::do_make_tree_of_all_k_subsets" << endl;
3350 }
3351
3353 int *set;
3354 int N;
3355 int h, i;
3356 char fname[1000];
3357
3358
3359 snprintf(fname, 1000, "all_k_subsets_%d_%d.tree", n, k);
3360 set = NEW_int(k);
3361 N = Combi.int_n_choose_k(n, k);
3362
3363
3364 {
3365 ofstream fp(fname);
3366
3367 for (h = 0; h < N; h++) {
3368 Combi.unrank_k_subset(h, set, n, k);
3369 fp << k;
3370 for (i = 0; i < k; i++) {
3371 fp << " " << set[i];
3372 }
3373 fp << endl;
3374 }
3375 fp << "-1" << endl;
3376 }
3377 FREE_int(set);
3378
3379 if (f_v) {
3380 cout << "combinatorics_domain::do_make_tree_of_all_k_subsets done" << endl;
3381 }
3382}
3383
3385 std::string &fname_csv, int verbose_level)
3386{
3387 int f_v = (verbose_level >= 1);
3388
3389 if (f_v) {
3390 cout << "combinatorics_domain::create_random_permutation" << endl;
3391 }
3392
3393 {
3395
3396
3397 int *P;
3398
3399 P = NEW_int(deg);
3400 random_permutation(P, deg);
3401
3402 Fio.int_vec_write_csv(P, deg, fname_csv, "perm");
3403
3404 FREE_int(P);
3405 }
3406
3407 if (f_v) {
3408 cout << "combinatorics_domain::create_random_permutation done" << endl;
3409 }
3410}
3411
3412void combinatorics_domain::compute_incidence_matrix(int v, int b, int k, long int *Blocks_coded,
3413 int *&M, int verbose_level)
3414{
3415 int f_v = (verbose_level >= 1);
3416
3417 if (f_v) {
3418 cout << "combinatorics_domain::compute_incidence_matrix" << endl;
3419 }
3420 //int N = k * b;
3421 int i, j, h;
3422 int *B;
3423
3424 M = NEW_int(v * b);
3425 B = NEW_int(v);
3426 Int_vec_zero(M, v * b);
3427 for (j = 0; j < b; j++) {
3428 unrank_k_subset(Blocks_coded[j], B, v, k);
3429 for (h = 0; h < k; h++) {
3430 i = B[h];
3431 M[i * b + j] = 1;
3432 }
3433 }
3434 FREE_int(B);
3435
3436 if (f_v) {
3437 cout << "combinatorics_domain::compute_incidence_matrix done" << endl;
3438 }
3439}
3440
3441void combinatorics_domain::compute_blocks(int v, int b, int k, long int *Blocks_coded,
3442 int *&Blocks, int verbose_level)
3443{
3444 int f_v = (verbose_level >= 1);
3445
3446 if (f_v) {
3447 cout << "combinatorics_domain::compute_blocks" << endl;
3448 }
3449 int j;
3450
3451 Blocks = NEW_int(b * k);
3452 Int_vec_zero(Blocks, b * k);
3453 for (j = 0; j < b; j++) {
3454 unrank_k_subset(Blocks_coded[j], Blocks + j * k, v, k);
3455 }
3456
3457 if (f_v) {
3458 cout << "combinatorics_domain::compute_blocks done" << endl;
3459 }
3460}
3461
3463 int v, int k, int b, long int *Blocks_coded,
3464 int &b_reduced,
3465 int verbose_level)
3466{
3467 int f_v = (verbose_level >= 1);
3468
3469 if (f_v) {
3470 cout << "combinatorics_domain::refine_the_partition" << endl;
3471 }
3472
3473
3474 //int N = k * b;
3475 int *M;
3476 //int i, j;
3477 int *R;
3478
3479 R = NEW_int(v);
3480
3481 compute_incidence_matrix(v, b, k, Blocks_coded,
3482 M, verbose_level);
3483
3484 {
3487
3488
3490
3491 Inc->init_by_matrix(v, b, M, 0 /* verbose_level */);
3492
3494
3495 Stack->allocate_with_two_classes(v + b, v, b, 0 /* verbose_level */);
3496
3497
3498
3499 while (TRUE) {
3500
3501 int ht0, ht1;
3502
3503 ht0 = Stack->ht;
3504
3505 if (f_v) {
3506 cout << "combinatorics_domain::refine_the_partition before refine_column_partition_safe" << endl;
3507 }
3508 Inc->refine_column_partition_safe(*Stack, verbose_level - 2);
3509 if (f_v) {
3510 cout << "combinatorics_domain::refine_the_partition after refine_column_partition_safe" << endl;
3511 }
3512 if (f_v) {
3513 cout << "combinatorics_domain::refine_the_partition before refine_row_partition_safe" << endl;
3514 }
3515 Inc->refine_row_partition_safe(*Stack, verbose_level - 2);
3516 if (f_v) {
3517 cout << "combinatorics_domain::refine_the_partition after refine_row_partition_safe" << endl;
3518 }
3519 ht1 = Stack->ht;
3520 if (ht1 == ht0) {
3521 break;
3522 }
3523 }
3524
3525 int f_labeled = TRUE;
3526
3527 Inc->print_partitioned(cout, *Stack, f_labeled);
3529 Stack->print_classes(cout);
3530
3531
3532 int f_print_subscripts = FALSE;
3533 if (f_v) {
3534 cout << "Decomposition:\\\\" << endl;
3535 cout << "Row scheme:\\\\" << endl;
3537 cout, TRUE /* f_enter_math */,
3538 f_print_subscripts, *Stack);
3539 cout << "Column scheme:\\\\" << endl;
3541 cout, TRUE /* f_enter_math */,
3542 f_print_subscripts, *Stack);
3543 }
3544
3545 data_structures::set_of_sets *Row_classes;
3546 data_structures::set_of_sets *Col_classes;
3547
3548 Stack->get_row_classes(Row_classes, verbose_level);
3549 if (f_v) {
3550 cout << "Row classes:\\\\" << endl;
3551 Row_classes->print_table_tex(cout);
3552 }
3553
3554
3555 Stack->get_column_classes(Col_classes, verbose_level);
3556 if (f_v) {
3557 cout << "Col classes:\\\\" << endl;
3558 Col_classes->print_table_tex(cout);
3559 }
3560
3561 if (Row_classes->nb_sets > 1) {
3562 if (f_v) {
3563 cout << "combinatorics_domain::refine_the_partition The row partition splits" << endl;
3564 }
3565 }
3566
3567 if (Col_classes->nb_sets > 1) {
3568 if (f_v) {
3569 cout << "combinatorics_domain::refine_the_partition The col partition splits" << endl;
3570 }
3571
3572 int idx;
3573 int j, a;
3574
3575 idx = Col_classes->find_smallest_class();
3576
3577 b_reduced = Col_classes->Set_size[idx];
3578
3579 for (j = 0; j < b_reduced; j++) {
3580 a = Col_classes->Sets[idx][j];
3581 Blocks_coded[j] = Blocks_coded[a];
3582 }
3583 if (f_v) {
3584 cout << "combinatorics_domain::refine_the_partition reducing from " << b << " down to " << b_reduced << endl;
3585 }
3586 }
3587 else {
3588 if (f_v) {
3589 cout << "combinatorics_domain::refine_the_partition The col partition does not split" << endl;
3590 }
3591 b_reduced = b;
3592 }
3593
3594
3595 FREE_OBJECT(Inc);
3596 FREE_OBJECT(Stack);
3597 FREE_OBJECT(Row_classes);
3598 FREE_OBJECT(Col_classes);
3599 }
3600
3601 FREE_int(R);
3602 FREE_int(M);
3603
3604 if (f_v) {
3605 cout << "combinatorics_domain::refine_the_partition done" << endl;
3606 }
3607
3608}
3609
3610
3612 int *&M, int &nb_rows, int &nb_cols,
3613 int verbose_level)
3614{
3615 int f_v = (verbose_level >= 1);
3616 int i, j, u;
3617
3618 if (f_v) {
3619 cout << "combinatorics_domain::create_incidence_matrix_of_graph" << endl;
3620 }
3621 nb_rows = n;
3622 nb_cols = 0;
3623 for (i = 0; i < n; i++) {
3624 for (j = i + 1; j < n; j++) {
3625 if (Adj[i * n + j]) {
3626 nb_cols++;
3627 }
3628 }
3629 }
3630 M = NEW_int(n * nb_cols);
3631 Int_vec_zero(M, n * nb_cols);
3632 u = 0;
3633 for (i = 0; i < n; i++) {
3634 for (j = i + 1; j < n; j++) {
3635 if (Adj[i * n + j]) {
3636 M[i * nb_cols + u] = 1;
3637 M[j * nb_cols + u] = 1;
3638 u++;
3639 }
3640 }
3641 }
3642 if (f_v) {
3643 cout << "combinatorics_domain::create_incidence_matrix_of_graph done" << endl;
3644 }
3645}
3646
3647
3648
3650{
3651 int verbose_level = 0;
3652 int f_v = (verbose_level >= 1);
3653
3654 if (f_v) {
3655 cout << "combinatorics_domain::free_global_data" << endl;
3656 }
3657 if (tab_binomials) {
3658 if (f_v) {
3659 cout << "combinatorics_domain::free_global_data before "
3660 "FREE_OBJECTS(tab_binomials)" << endl;
3661 }
3662 FREE_OBJECTS(tab_binomials);
3663 if (f_v) {
3664 cout << "combinatorics_domain::free_global_data after "
3665 "FREE_OBJECTS(tab_binomials)" << endl;
3666 }
3667 tab_binomials = NULL;
3668 tab_binomials_size = 0;
3669 }
3670 if (tab_q_binomials) {
3671 if (f_v) {
3672 cout << "combinatorics_domain::free_global_data before "
3673 "FREE_OBJECTS(tab_q_binomials)" << endl;
3674 }
3675 FREE_OBJECTS(tab_q_binomials);
3676 if (f_v) {
3677 cout << "combinatorics_domain::free_global_data after "
3678 "FREE_OBJECTS(tab_q_binomials)" << endl;
3679 }
3680 tab_q_binomials = NULL;
3681 tab_q_binomials_size = 0;
3682 }
3683 if (f_v) {
3684 cout << "combinatorics_domain::free_global_data done" << endl;
3685 }
3686}
3687
3689{
3690 if (tab_q_binomials) {
3691 FREE_OBJECTS(tab_q_binomials);
3692 tab_q_binomials = NULL;
3693 }
3694}
3695
3696
3697
3698}}}
3699
3700
3701
3702
void size_of_conjugacy_class_in_sym_n(ring_theory::longinteger_object &a, int n, int *part)
int philip_hall_test(int *A, int n, int k, int *memo, int verbose_level)
void subset_permute_up_front(int n, int k, int *set, int *k_subset_idx, int *permuted_set)
void q_binomial_with_table(ring_theory::longinteger_object &a, int n, int k, int q, int verbose_level)
void create_incidence_matrix_of_graph(int *Adj, int n, int *&M, int &nb_rows, int &nb_cols, int verbose_level)
void binomial(ring_theory::longinteger_object &a, int n, int k, int verbose_level)
void perm_print_with_print_point_function(std::ostream &ost, int *a, int n, void(*point_label)(std::stringstream &sstr, long int pt, void *data), void *point_label_data)
int unordered_triple_pair_rank(int i, int j, int k, int l, int m, int n)
int compare_lexicographically(int a_len, long int *a, int b_len, long int *b)
void perm_print_offset(std::ostream &ost, int *a, int n, int offset, int f_print_cycles_of_length_one, int f_cycle_length, int f_max_cycle_length, int max_cycle_length, int f_orbit_structure, void(*point_label)(std::stringstream &sstr, long int pt, void *data), void *point_label_data)
void binomial_with_table(ring_theory::longinteger_object &a, int n, int k)
void unrank_subset_recursion(int *set, int &sz, int n, int a0, int &r)
void set_complement_lint(long int *subset, int subset_size, long int *complement, int &size_complement, int universal_set_size)
void make_elementary_symmetric_functions(int n, int k_max, int verbose_level)
void q_binomial_no_table(ring_theory::longinteger_object &a, int n, int k, int q, int verbose_level)
int create_roots_H4(field_theory::finite_field *F, int *roots)
int f_is_subset_of(int v, int t, int k, int rk_t_subset, int rk_k_subset)
void set_complement_safe(int *subset, int subset_size, int *complement, int &size_complement, int universal_set_size)
int next_k_subset_at_level(int *set, int n, int k, int backtrack_level)
void print_tableau(int *Tableau, int l1, int l2, int *row_parts, int *col_parts)
void do_tdo_refinement(tdo_refinement_description *Descr, int verbose_level)
void do_read_poset_file(std::string &fname, int f_grouping, double x_stretch, int verbose_level)
void perm_print_product_action(std::ostream &ost, int *a, int m_plus_n, int m, int offset, int f_cycle_length)
void print_01_matrix_with_stars(std::ostream &ost, int *A, int m, int n)
void unordered_triple_pair_unrank(int rk, int &i, int &j, int &k, int &l, int &m, int &n)
void krawtchouk_with_table(ring_theory::longinteger_object &a, int n, int q, int k, int x)
void perm_cycle_type(int *perm, long int degree, int *cycles, int &nb_cycles)
int philip_hall_test_dual(int *A, int n, int k, int *memo, int verbose_level)
void perm_print_list_offset(std::ostream &ost, int *a, int n, int offset)
void convert_stack_to_tdo(std::string &stack_fname, int verbose_level)
void Dedekind_numbers(int n_min, int n_max, int q_min, int q_max, int verbose_level)
void set_delete_elements(int *elts, int &size, int *elts_to_delete, int nb_elts_to_delete)
void create_random_permutation(int deg, std::string &fname_csv, int verbose_level)
void perm_direct_product(long int n1, long int n2, int *perm1, int *perm2, int *perm3)
void partition_dual(int *part, int *dual_part, int n, int verbose_level)
void krawtchouk(ring_theory::longinteger_object &a, int n, int q, int k, int x)
void compute_blocks(int v, int b, int k, long int *Blocks_coded, int *&Blocks, int verbose_level)
void set_complement(int *subset, int subset_size, int *complement, int &size_complement, int universal_set_size)
int hall_test(int *A, int n, int kmax, int *memo, int verbose_level)
void make_t_k_incidence_matrix(int v, int t, int k, int &m, int &n, int *&M, int verbose_level)
void set_add_elements(int *elts, int &size, int *elts_to_add, int nb_elts_to_add)
void make_all_partitions_of_n(int n, int *&Table, int &nb, int verbose_level)
void refine_the_partition(int v, int k, int b, long int *Blocks_coded, int &b_reduced, int verbose_level)
void rank_subset_recursion(int *set, int sz, int n, int a0, int &r)
void q_binomial(ring_theory::longinteger_object &a, int n, int k, int q, int verbose_level)
void print_int_matrix(std::ostream &ost, int *A, int m, int n)
void k2ij_lint(long int k, long int &i, long int &j, long int n)
void compute_incidence_matrix(int v, int b, int k, long int *Blocks_coded, int *&M, int verbose_level)
decomposition stack of a linear space or incidence geometry
void write(std::ofstream &aStream, std::string &label)
void write_mode_stack(std::ofstream &aStream, std::string &label)
int input_mode_stack(std::ifstream &aStream, int verbose_level)
void print_scheme_tex(std::ostream &ost, tdo_scheme_synthetic &G, int h)
void init_tdo_scheme(tdo_scheme_synthetic &G, int verbose_level)
refinement of the parameters of a linear space
void init(tdo_refinement_description *Descr, int verbose_level)
canonical tactical decomposition of an incidence structure
void set_print(std::ostream &ost, int *v, int len)
Definition: int_vec.cpp:1043
data structure for set partitions following Jeffrey Leon
void get_column_classes(set_of_sets *&Sos, int verbose_level)
void allocate_with_two_classes(int n, int v, int b, int verbose_level)
void get_row_classes(set_of_sets *&Sos, int verbose_level)
a collection of functions related to sorted vectors
int int_vec_search(int *v, int len, int a, int &idx)
Definition: sorting.cpp:1094
functions related to strings and character arrays
void replace_extension_with(char *p, const char *new_ext)
a statistical analysis of data consisting of single integers
void init(int *data, int data_length, int f_second, int verbose_level)
Definition: tally.cpp:72
various functions related to geometries
Definition: geometry.h:721
void AG_element_unrank(int q, int *v, int stride, int len, long int a)
int AG_element_next(int q, int *v, int stride, int len)
long int AG_element_rank(int q, int *v, int stride, int len)
interface for various incidence geometries
Definition: geometry.h:1099
void get_and_print_row_tactical_decomposition_scheme_tex(std::ostream &ost, int f_enter_math, int f_print_subscripts, data_structures::partitionstack &PStack)
int refine_row_partition_safe(data_structures::partitionstack &PStack, int verbose_level)
void get_and_print_decomposition_schemes(data_structures::partitionstack &PStack)
int refine_column_partition_safe(data_structures::partitionstack &PStack, int verbose_level)
void get_and_print_column_tactical_decomposition_scheme_tex(std::ostream &ost, int f_enter_math, int f_print_subscripts, data_structures::partitionstack &PStack)
void print_partitioned(std::ostream &ost, data_structures::partitionstack &P, int f_labeled)
void init_by_matrix(int m, int n, int *M, int verbose_level)
a data structure to store layered graphs or Hasse diagrams
Definition: graph_theory.h:654
void init_poset_from_file(std::string &fname, int f_grouping, double x_stretch, int verbose_level)
void write_file(std::string &fname, int verbose_level)
void int_vec_write_csv(int *v, int len, std::string &fname, const char *label)
Definition: file_io.cpp:1175
void write_decomposition_stack(char *fname, int m, int n, int *v, int *b, int *aij, int verbose_level)
Definition: file_io.cpp:3378
domain to compute with objects of type longinteger
Definition: ring_theory.h:240
void integral_division_exact(longinteger_object &a, longinteger_object &b, longinteger_object &a_over_b)
void add(longinteger_object &a, longinteger_object &b, longinteger_object &c)
void integral_division_by_int(longinteger_object &a, int b, longinteger_object &q, int &r)
void mult(longinteger_object &a, longinteger_object &b, longinteger_object &c)
void integral_division(longinteger_object &a, longinteger_object &b, longinteger_object &q, longinteger_object &r, int verbose_level)
void Dedekind_number(longinteger_object &Dnq, int n, int q, int verbose_level)
a class to represent arbitrary precision integers
Definition: ring_theory.h:366
void create(long int i, const char *file, int line)
#define COL_SCHEME
#define ROW_SCHEME
#define TABLE_Q_BINOMIALS_MAX
#define TABLE_BINOMIALS_MAX
#define Lint_vec_copy(A, B, C)
Definition: foundations.h:694
#define FREE_OBJECTS(p)
Definition: foundations.h:652
#define MINIMUM(x, y)
Definition: foundations.h:216
#define FREE_int(p)
Definition: foundations.h:640
#define Int_vec_zero(A, B)
Definition: foundations.h:713
#define NEW_OBJECT(type)
Definition: foundations.h:638
#define FREE_OBJECT(p)
Definition: foundations.h:651
#define NEW_int(n)
Definition: foundations.h:625
#define NEW_OBJECTS(type, n)
Definition: foundations.h:639
#define TRUE
Definition: foundations.h:231
#define FALSE
Definition: foundations.h:234
#define EVEN(x)
Definition: foundations.h:221
#define Int_vec_copy(A, B, C)
Definition: foundations.h:693
#define FREE_lint(p)
Definition: foundations.h:642
#define NEW_lint(n)
Definition: foundations.h:628
#define Int_vec_print(A, B, C)
Definition: foundations.h:685
#define MAXIMUM(x, y)
Definition: foundations.h:217
orbiter_kernel_system::orbiter_session * Orbiter
global Orbiter session
the orbiter library for the classification of combinatorial objects