Orbiter 2022
Combinatorial Objects
partitionstack.cpp
Go to the documentation of this file.
1// partitionstack.cpp
2//
3// Anton Betten
4//
5// started in D2/partition_stack.cpp: November 22, 2000
6// included into GALOIS: July 3, 2007
7// added TDO for orthogonal: July 10, 2007
8
9
10
11
12#include "foundations.h"
13
14using namespace std;
15
16
17namespace orbiter {
18namespace layer1_foundations {
19namespace data_structures {
20
21
22
23// #############################################################################
24// now comes partitionstack
25// #############################################################################
26
27#if 0
28ostream& operator<<(ostream& ost, partitionstack& p)
29{
30 // cout << "partitionstack::operator<< starting" << endl;
31 p.print(ost);
32 // cout << "partitionstack::operator<< finished" << endl";
33 return ost;
34};
35#endif
36
37
39{
40 n = 0;
41 ht = 0;
42 ht0 = 0;
43
44 pointList = NULL;
45 invPointList = NULL;
46 cellNumber = NULL;
47
48 startCell = NULL;
49 cellSize = NULL;
50 parent = NULL;
51
52 nb_subsets = 0;
53 subset = NULL;
54 subset_first = NULL;
55 subset_length = NULL;
56 subsets = NULL;
57
58 subset = NULL;
59 subset_size = 0;
60}
61
63{
64 free();
65}
66
68{
69 if (pointList) {
71 }
72 if (invPointList) {
74 }
75 if (cellNumber) {
77 }
78
79 if (startCell) {
81 }
82 if (cellSize) {
84 }
85 if (parent) {
87 }
88
89 if (subset) {
91 }
92 if (subset_first) {
94 }
95 if (subset_length) {
97 }
98 if (subsets) {
100 }
101
102}
103
104
105void partitionstack::allocate(int n, int verbose_level)
106{
107 int f_v = (verbose_level >= 1);
108 int i;
109
110 if (f_v) {
111 cout << "partitionstack::allocate n=" << n << endl;
112 }
113
115 ht = 1;
116
117 //cout << "partitionstack::partitionstack() 1" << endl;
120
121 //cout << "partitionstack::partitionstack() 4" << endl;
123
124 if (f_v) {
125 cout << "partitionstack::allocate startCell" << endl;
126 }
127 startCell = NEW_int(n + 1);
128 cellSize = NEW_int(n + 1);
129 parent = NEW_int(n + 1);
130
131 // used if SPLIT_MULTIPLY is not defined:
132 subset = NEW_int(n + 1);
133
134 if (f_v) {
135 cout << "partitionstack::allocate subset_first" << endl;
136 }
137 //cout << "partitionstack::partitionstack() 7" << endl;
138 // used if SPLIT_MULTIPLY is defined:
139 nb_subsets = 0;
140 subset_first = NEW_int(n + 1);
141 subset_length = NEW_int(n + 1);
142 subsets = NEW_int(n + 1);
143
144 //cout << "partitionstack::partitionstack() 8" << endl;
145 for (i = 0; i < n; i++) {
146 pointList[i] = i;
147 invPointList[i] = i;
148 cellNumber[i] = 0;
149 }
150 startCell[0] = 0;
151 cellSize[0] = n;
152 parent[0] = 0;
153
154 if (f_v) {
155 cout << "partitionstack::allocate done" << endl;
156 }
157}
158
159void partitionstack::allocate_with_two_classes(int n, int v, int b, int verbose_level)
160{
161 int f_v = (verbose_level >= 1);
162
163 if (f_v) {
164 cout << "partitionstack::allocate_with_two_classes n=" << n << " v=" << v << " b=" << b << endl;
165 }
166
167 allocate(v + b, 0 /* verbose_level */);
168 subset_continguous(v, b);
169 split_cell(0 /* verbose_level */);
170 sort_cells();
171
172 if (f_v) {
173 cout << "partitionstack::allocate_with_two_classes done" << endl;
174 }
175}
176
178{
179 if (cell < h) {
180 return cell;
181 }
182 else {
183 return parent_at_height(h, parent[cell]);
184 }
185}
186
188{
189 if (ht > n) {
190 cout << "partitionstack::is_discrete ht > n" << endl;
191 exit(1);
192 }
193 if (ht == n) {
194 return TRUE;
195 }
196 else {
197 return FALSE;
198 }
199}
200
202{
203 int min_size = 0, cell, i;
204
205 cell = -1;
206 for (i = 0; i < ht; i++) {
207 if (cellSize[i] == 1) {
208 continue;
209 }
210 if (cell == -1 || cellSize[i] < min_size) {
211 cell = i;
212 min_size = cellSize[i];
213 }
214 }
215 if (cell == -1) {
216 cout << "partitionstack::smallest_non_discrete_cell "
217 "partition is discrete" << endl;
218 }
219 return cell;
220}
221
223{
224 int max_size = 0, cell, i;
225
226 cell = -1;
227 for (i = 0; i < ht; i++) {
228 if (cellSize[i] == 1) {
229 continue;
230 }
231 if (cell == -1 || cellSize[i] > max_size) {
232 cell = i;
233 max_size = cellSize[i];
234 }
235 }
236 if (cell == -1) {
237 cout << "partitionstack::biggest_non_discrete_cell "
238 "partition is discrete" << endl;
239 }
240 return cell;
241}
242
244{
245 int min_size = 0, cell, i;
246 int first_column_element = startCell[1];
247
248 cell = -1;
249 for (i = 0; i < ht; i++) {
250 if (cellSize[i] == 1) {
251 continue;
252 }
253 if (startCell[i] >= first_column_element) {
254 continue;
255 }
256 if (cell == -1 || cellSize[i] < min_size) {
257 cell = i;
258 min_size = cellSize[i];
259 }
260 }
261 if (cell == -1) {
263 }
264 return cell;
265}
266
268{
269 int max_size = 0, cell, i;
270 int first_column_element = startCell[1];
271
272 cell = -1;
273 for (i = 0; i < ht; i++) {
274 if (cellSize[i] == 1) {
275 continue;
276 }
277 if (startCell[i] >= first_column_element) {
278 continue;
279 }
280 if (cell == -1 || cellSize[i] > max_size) {
281 cell = i;
282 max_size = cellSize[i];
283 }
284 }
285 if (cell == -1) {
287 }
288 return cell;
289}
290
292{
293 int i, c, l, n;
294
295 n = 0;
296 i = from;
297 while (i < from + len) {
298 c = cellNumber[i];
299 l = cellSize[c];
300 n++;
301 i += l;
302 }
303 return n;
304}
305
306int partitionstack::is_subset_of_cell(int *set, int size, int &cell_idx)
307{
308 int i, a, idx, c;
309
310 for (i = 0; i < size; i++) {
311 a = set[i];
312 idx = invPointList[a];
313 c = cellNumber[idx];
314 if (i == 0) {
315 cell_idx = c;
316 }
317 else {
318 if (cell_idx != c) {
319 return FALSE;
320 }
321 }
322 }
323 return TRUE;
324}
325
327{
328 int i;
329
330 for (i = 0; i < ht; i++) {
331 sort_cell(i);
332 }
333 check();
334}
335
337{
338 int i, first, len, a;
339 sorting Sorting;
340
341 first = startCell[cell];
342 len = cellSize[cell];
343
344#if 0
345 cout << "before sort, cell " << cell << " : " << endl;
346 for (i = 0; i < len; i++) {
347 cout << pointList[first + i] << " ";
348 }
349 cout << endl;
350#endif
351 Sorting.int_vec_quicksort_increasingly(pointList + first, len);
352#if 0
353 cout << "after sort, cell " << cell << " : " << endl;
354 for (i = 0; i < len; i++) {
355 cout << pointList[first + i] << " ";
356 }
357 cout << endl;
358#endif
359
360#if 0
361 for (i = 0; i < len; i++) {
362 for (j = i + 1; j < len; j++) {
363 a = pointList[first + i];
364 b = pointList[first + j];
365 if (a < b)
366 continue;
367 pointList[first + i] = b;
368 pointList[first + j] = a;
369 }
370 }
371#endif
372 for (i = 0; i < len; i++) {
373 a = pointList[first + i];
374 invPointList[a] = first + i;
375 }
376}
377
379{
380 int i, j, first, len, half_len, a, b;
381
382 first = startCell[cell];
383 len = cellSize[cell];
384 half_len = len >> 1;
385 for (i = 0; i < half_len; i++) {
386 j = len - 1 - i;
387 a = pointList[first + i];
388 b = pointList[first + j];
389 pointList[first + i] = b;
390 pointList[first + j] = a;
391 }
392 for (i = 0; i < len; i++) {
393 a = pointList[first + i];
394 invPointList[a] = first + i;
395 }
396}
397
399{
400 int i, a;
401
402 for (i = 0; i < n; i++) {
403 a = pointList[i];
404 if (invPointList[a] != i) {
405 cout << "partitionstack::check "
406 "invPointList corrupt" << endl;
407 cout << "i=" << i << " pointList[i]=a=" << a
408 << " invPointList[a]=" << invPointList[a] << endl;
409 print_raw();
410 print(cout);
411 exit(1);
412 }
413 }
414}
415
417{
418 int i, first, len;
419
420 cout << "ht = " << ht << endl;
421 cout << "i : first : len " << endl;
422 for (i = 0; i < ht; i++) {
423 first = startCell[i];
424 len = cellSize[i];
425 cout << setw(5) << i << " : " << setw(5) << first
426 << " : " << setw(5) << len << endl;
427 }
428 cout << "i : pointList : invPointList : cellNumber" << endl;
429 for (i = 0; i < n; i++) {
430 cout << setw(5) << i << " : " << setw(5) << pointList[i]
431 << " : " << setw(5) << invPointList[i] << " : "
432 << setw(5) << cellNumber[i] << endl;
433 }
434}
435
436void partitionstack::print_class(ostream& ost, int idx)
437{
438 int first, len, j;
439 int *S;
440 sorting Sorting;
441
442 S = NEW_int(n);
443 first = startCell[idx];
444 len = cellSize[idx];
445 ost << "C_{" << idx << "} of size " << len
446 << " descendant of " << parent[idx] << " is ";
447 for (j = 0; j < len; j++) {
448 S[j] = pointList[first + j];
449 }
450 Sorting.int_vec_heapsort(S, len);
452 ost << "_{" << len << "}" << endl;
453 FREE_int(S);
454}
455
457{
458 int i;
459
460 for (i = 0; i < ht; i++) {
461 ost << "$";
462 print_class_tex(ost, i);
463 ost << "$\\\\" << endl;
464 }
465}
466
467void partitionstack::print_class_tex(ostream& ost, int idx)
468{
469 int first_column_element = startCell[1];
470 int first, len, j;
471 int *S;
472 sorting Sorting;
473
474 S = NEW_int(n);
475 first = startCell[idx];
476 len = cellSize[idx];
477 ost << "C_{" << idx << "} = ";
478 for (j = 0; j < len; j++) {
479 S[j] = pointList[first + j];
480 }
481 if (is_col_class(idx)) {
482 for (j = 0; j < len; j++) {
483 S[j] -= first_column_element;
484 }
485 }
486 Sorting.int_vec_heapsort(S, len);
487 ost << "\\{ ";
488 for (j = 0; j < len; j++) {
489 ost << S[j];
490 if (j < len - 1)
491 ost << ", ";
492 }
493 ost << " \\}";
494 ost << "_{" << len << "}" << endl;
495 FREE_int(S);
496}
497
499{
500 int first_column_element = startCell[1];
501 int first, len, j;
502 int *S;
503 sorting Sorting;
504
505 S = NEW_int(n);
506 first = startCell[idx];
507 len = cellSize[idx];
508 ost << "C_{" << idx << "} of size " << len
509 << " descendant of C_{" << parent[idx] << "} is ";
510 for (j = 0; j < len; j++) {
511 S[j] = pointList[first + j];
512 }
513 if (is_col_class(idx)) {
514 for (j = 0; j < len; j++) {
515 S[j] -= first_column_element;
516 }
517 }
518 Sorting.int_vec_heapsort(S, len);
519 //int_set_print(ost, S, len);
520 if (is_col_class(idx)) {
521 ost << "lines {";
522 }
523 else {
524 ost << "points {";
525 }
526 for (j = 0; j < len; j++) {
527 ost << S[j];
528 if (j < len - 1) {
529 ost << ", ";
530 }
531 }
532 ost << " }";
533 ost << "_{" << len << "}" << endl;
534 FREE_int(S);
535}
536
538{
539 int i;
540
541 for (i = 0; i < ht; i++) {
542 print_class(ost, i);
543 }
544}
545
547{
548 int i;
549
550 for (i = 0; i < ht; i++) {
552 }
553}
554
555ostream& partitionstack::print(ostream& ost)
556{
557 int i, j, first, len, a, /*pt,*/ prev_pt, j0;
558 int f_erroneous2 = FALSE;
559
560 //check();
561 //ost << "partitionstack of height " << ht << " : ";
562 ost << "( ";
563 for (i = 0; i < ht; i++) {
564 first = startCell[i];
565 len = cellSize[i];
566 //ost << "C_{" << i << "} of size " << len
567 //<< " descendant of " << parent[i] << " is ";
568 //ost << "{ ";
569 j0 = 0;
570 for (j = 1; j <= len; j++) {
571 prev_pt = pointList[first + j - 1];
572 if (j == len || pointList[first + j] != prev_pt + 1) {
573 //pt = pointList[first + j];
574 if (j0 == j - 1) {
575 cout << prev_pt;
576 if (j < len) {
577 cout << ", ";
578 }
579 }
580 else {
581 cout << pointList[first + j0] << "-" << prev_pt;
582 if (j < len) {
583 cout << ", ";
584 }
585 }
586 j0 = j;
587 }
588 if (j < len) {
589 a = pointList[first + j];
590 if (invPointList[a] != first + j) {
591 f_erroneous2 = TRUE;
592 }
593 }
594 }
595 //ost << " }_{" << len << "}";
596 if (i < ht - 1) {
597 ost << "| ";
598 }
599 }
600 ost << " ) height " << ht << " class sizes: (";
601 for (i = 0; i < ht; i++) {
602 len = cellSize[i];
603 ost << len;
604 if (i < ht - 1) {
605 ost << ",";
606 }
607 }
608 ost << ") parent: ";
609 for (i = 0; i < ht; i++) {
610 ost << parent[i] << " ";
611 }
612 ost << endl;
613 if (f_erroneous2) {
614 cout << "erroneous partition stack: invPointList corrupt" << endl;
615 exit(1);
616 }
617 return ost;
618}
619
621{
622 int j, first, len;
623
624 first = startCell[i];
625 len = cellSize[i];
626 cout << "{ ";
627 for (j = 0; j < len; j++) {
628 cout << pointList[first + j];
629 if (j < len - 1) {
630 cout << ", ";
631 }
632 }
633 cout << " }";
634}
635
636void partitionstack::print_cell_latex(ostream &ost, int i)
637{
638 int j, first, len;
639
640 first = startCell[i];
641 len = cellSize[i];
642 ost << "\\{ ";
643 for (j = 0; j < len; j++) {
644 ost << pointList[first + j];
645 if (j < len - 1) {
646 ost << ", ";
647 }
648 }
649 ost << " \\}";
650}
651
653 int *&cell, int &cell_sz, int verbose_level)
654{
655 int f_v = (verbose_level >= 1);
656 int j, first;
658
659 if (f_v) {
660 cout << "partitionstack::get_cell i=" << i << endl;
661 }
662 first = startCell[i];
663 cell_sz = cellSize[i];
664 cell = NEW_int(cell_sz);
665 for (j = 0; j < cell_sz; j++) {
666 cell[j] = pointList[first + j];
667 }
668 sorting Sorting;
669
670 Sorting.int_vec_heapsort(cell, cell_sz);
671
672 if (f_v) {
673 cout << "partitionstack::get_cell i=" << i << " done" << endl;
674 }
675}
676
678 long int *&cell, int &cell_sz, int verbose_level)
679{
680 int f_v = (verbose_level >= 1);
681 int j, first;
683
684 if (f_v) {
685 cout << "partitionstack::get_cell_lint i=" << i << endl;
686 }
687 first = startCell[i];
688 cell_sz = cellSize[i];
689 cell = NEW_lint(cell_sz);
690 for (j = 0; j < cell_sz; j++) {
691 cell[j] = pointList[first + j];
692 }
693
694 sorting Sorting;
695
696 Sorting.lint_vec_heapsort(cell, cell_sz);
697
698 if (f_v) {
699 cout << "partitionstack::get_cell_lint i=" << i << " done" << endl;
700 }
701}
702
703void partitionstack::get_row_classes(set_of_sets *&Sos, int verbose_level)
704{
705 int f_v = (verbose_level >= 1);
707
708 if (f_v) {
709 cout << "partitionstack::get_row_classes" << endl;
710 }
711
712 int *row_classes;
713 int nb_row_classes;
714 int *col_classes;
715 int nb_col_classes;
716 int i;
717
718 row_classes = NEW_int(ht);
719 col_classes = NEW_int(ht);
720
722 row_classes,
723 nb_row_classes,
724 col_classes,
725 nb_col_classes,
726 0 /* verbose_level*/);
727
728 Sos = NEW_OBJECT(set_of_sets);
729
730 int first_column_element = startCell[1];
731
732 Sos->init_simple(first_column_element /* underlying_set_size */,
733 nb_row_classes, 0 /* verbose_level*/);
734
735 for (i = 0; i < nb_row_classes; i++) {
736
737 long int *cell;
738 int cell_sz;
739
740 get_cell_lint(row_classes[i],
741 cell, cell_sz,
742 0 /* verbose_level*/);
743 Sos->Sets[i] = cell;
744 Sos->Set_size[i] = cell_sz;
745 }
746
747 FREE_int(row_classes);
748 FREE_int(col_classes);
749
750 if (f_v) {
751 cout << "partitionstack::get_row_classes" << endl;
752 }
753}
754
755
757{
758 int f_v = (verbose_level >= 1);
760
761 if (f_v) {
762 cout << "partitionstack::get_column_classes" << endl;
763 }
764
765 int *row_classes;
766 int nb_row_classes;
767 int *col_classes;
768 int nb_col_classes;
769 int i, j;
770
771 row_classes = NEW_int(ht);
772 col_classes = NEW_int(ht);
773
775 row_classes,
776 nb_row_classes,
777 col_classes,
778 nb_col_classes,
779 0 /* verbose_level*/);
780
781 Sos = NEW_OBJECT(set_of_sets);
782
783 int first_column_element = startCell[1];
784
785 Sos->init_simple(n - first_column_element /* underlying_set_size */,
786 nb_col_classes, 0 /* verbose_level*/);
787
788 for (i = 0; i < nb_col_classes; i++) {
789
790 long int *cell;
791 int cell_sz;
792
793 get_cell_lint(col_classes[i],
794 cell, cell_sz,
795 0 /* verbose_level*/);
796 for (j = 0; j < cell_sz; j++) {
797 cell[j] -= first_column_element;
798 }
799 Sos->Sets[i] = cell;
800 Sos->Set_size[i] = cell_sz;
801 }
802
803 FREE_int(row_classes);
804 FREE_int(col_classes);
805
806 if (f_v) {
807 cout << "partitionstack::get_column_classes" << endl;
808 }
809}
810
811
812
814 std::string &fname, int verbose_level)
815{
816 int f_v = (verbose_level >= 1);
817 int j, first, len;
818 long int *set;
820
821 if (f_v) {
822 cout << "partitionstack::write_cell_to_file "
823 "writing cell " << i << " to file " << fname << endl;
824 }
825 first = startCell[i];
826 len = cellSize[i];
827 set = NEW_lint(len);
828 for (j = 0; j < len; j++) {
829 set[j] = pointList[first + j];
830 }
831 Fio.write_set_to_file(fname, set, len, verbose_level - 1);
832 FREE_lint(set);
833}
834
836 std::string &fname, int verbose_level)
837{
838 int f_v = (verbose_level >= 1);
839 int j, first, len, m = 0;
840 long int *set;
842
843 if (f_v) {
844 cout << "partitionstack::write_cell_to_file_points_or_lines "
845 "writing cell " << i << " to file " << fname << endl;
846 }
847 if (is_col_class(i)) {
848 m = startCell[1];
849 }
850 first = startCell[i];
851 len = cellSize[i];
852 set = NEW_lint(len);
853 for (j = 0; j < len; j++) {
854 set[j] = pointList[first + j] - m;
855 }
856 Fio.write_set_to_file(fname, set, len, verbose_level - 1);
857 FREE_lint(set);
858}
859
861{
862#ifdef SPLIT_MULTIPLY
863 int i;
864
865 for (i = 0; i < nb_subsets; i++) {
866 int_set_print(subsets + subset_first[i],
867 subset_length[i]);
868 if (i < nb_subsets - 1)
869 cout << ", ";
870 }
871#else
873#endif
874}
875
877 int size, long int *set, int verbose_level)
878{
879 int f_v = (verbose_level >= 1);
880 int *set2;
881
882 if (f_v) {
883 cout << "partitionstack::refine_arbitrary_set_lint" << endl;
884 }
885 set2 = NEW_int(size);
886 Lint_vec_copy_to_int(set, set2, size);
887 refine_arbitrary_set(size, set2, verbose_level);
888 if (f_v) {
889 cout << "partitionstack::refine_arbitrary_set_lint done" << endl;
890 }
891}
892
893
895 int size, int *set, int verbose_level)
896{
897 int f_v = (verbose_level >= 1);
898 int f_vv = (verbose_level >= 2);
899 int *set2;
900 int i, sz, sz2, a, c, d;
901
902 if (f_v) {
903 cout << "partitionstack::refine_arbitrary_set" << endl;
904 if (f_vv) {
905 cout << "set: ";
906 Int_vec_print(cout, set, size);
907 cout << endl;
908 }
909 }
910 set2 = NEW_int(size);
911 for (i = 0; i < size; i++) {
912 set2[i] = set[i];
913 }
914 sz = size;
915 while (sz) {
916 a = set2[0];
917 c = cellNumber[invPointList[a]];
918 subset[0] = a;
919 subset_size = 1;
920 sz2 = 0;
921 for (i = 1; i < sz; i++) {
922 a = set2[i];
923 d = cellNumber[invPointList[a]];
924 if (c == d) {
925 subset[subset_size++] = a;
926 }
927 else {
928 set2[sz2++] = a;
929 }
930 }
931 if (subset_size < cellSize[c]) {
933 }
934 sz = sz2;
935 }
936
937 FREE_int(set2);
938 if (f_v) {
939 cout << "partitionstack::refine_arbitrary_set finished" << endl;
940 }
941}
942
943
944void partitionstack::split_cell(int verbose_level)
945{
946#ifdef SPLIT_MULTIPLY
947 int i;
948
949 for (i = 0; i < nb_subsets; i++) {
951 subset_length[i], verbose_level);
952 }
953#else
954 split_cell(subset, subset_size, verbose_level);
955#endif
956}
957
959 int set_size, int f_front, int verbose_level)
960{
961 int f_v = (verbose_level >= 1);
962 int f_vv = (verbose_level >= 2);
963 int *f_done;
964 int *cell_nb;
965 int *set2;
966 int set2_sz;
967 int nb_done;
968 int i, a, pos_a, c;
969
970 if (f_v) {
971 cout << "split_multiple_cells() for subset { ";
972 for (i = 0; i < set_size; i++) {
973 cout << set[i] << " ";
974 }
975 cout << "}" << endl;
976 }
977 f_done = NEW_int(set_size);
978 cell_nb = NEW_int(set_size);
979 set2 = NEW_int(set_size);
980
981 for (i = 0; i < set_size; i++) {
982 f_done[i] = FALSE;
983 }
984 for (i = 0; i < set_size; i++) {
985 a = set[i];
986 pos_a = invPointList[a];
987 c = cellNumber[pos_a];
988 cell_nb[i] = c;
989 }
990 if (f_v) {
991 cout << "cell_nb : ";
992 Int_vec_print(cout, cell_nb, set_size);
993 cout << endl;
994 }
995 nb_done = 0;
996 while (nb_done < set_size) {
997 for (i = 0; i < set_size; i++) {
998 if (!f_done[i]) {
999 break;
1000 }
1001 }
1002 // now we split the set containing set[i]
1003 c = cell_nb[i];
1004 set2_sz = 0;
1005 for (; i < set_size; i++) {
1006 if (!f_done[i] && cell_nb[i] == c) {
1007 set2[set2_sz++] = set[i];
1008 nb_done++;
1009 f_done[i] = TRUE;
1010 }
1011 }
1012 if (f_vv) {
1013 cout << "splitting set of size " << set2_sz << " which is ";
1014 Int_vec_print(cout, set2, set2_sz);
1015 cout << " from class " << c << endl;
1016 }
1017 split_cell_front_or_back(set2, set2_sz, f_front, verbose_level - 2);
1018 if (f_vv) {
1019 cout << "after split:" << endl;
1021 }
1022 }
1023 FREE_int(f_done);
1024 FREE_int(cell_nb);
1025 FREE_int(set2);
1026}
1027
1029 int *set, int set_size, int f_front, int verbose_level)
1030{
1031 int f_v = (verbose_level >= 1);
1032 int first_column_element = startCell[1];
1033 int *set2, i;
1034
1035 if (f_v) {
1036 cout << "partitionstack::split_line_cell_front_or_back" << endl;
1037 }
1038 set2 = NEW_int(set_size);
1039 for (i = 0; i < set_size; i++) {
1040 set2[i] = set[i] + first_column_element;
1041 }
1042 split_cell_front_or_back(set2, set_size, f_front, verbose_level);
1043 FREE_int(set2);
1044}
1045
1047 int *set, int set_size, int f_front, int verbose_level)
1048{
1049 int f_v = (verbose_level >= 1);
1050 int f_vv = (verbose_level >= 2);
1051 int a, b, c, f, l, j, pos_a, new_pos, i;
1052
1053 if (f_v) {
1054 cout << "split_cell_front_or_back for subset { ";
1055 for (i = 0; i < set_size; i++) {
1056 cout << set[i] << " ";
1057 }
1058 cout << "}" << endl;
1059 }
1060 check();
1061 if (set_size <= 0) {
1062 cout << "partitionstack::split_cell_front_or_back "
1063 "set_size <= 0" << endl;
1064 exit(1);
1065 }
1066 a = set[0];
1067 pos_a = invPointList[a];
1068 c = cellNumber[pos_a];
1069 f = startCell[c];
1070 l = cellSize[c];
1071 if (f_vv) {
1072 cout << "split_cell_front_or_back c=" << c << " f=" << f
1073 << " l=" << l << endl;
1074 }
1075 if (set_size == l) {
1076 // nothing to do
1077 return;
1078 }
1079 else if (set_size > l) {
1080 cout << "split_cell_front_or_back "
1081 "subset_size > cellSize" << endl;
1082 cout << "split_cell_front_or_back for subset { ";
1083 for (i = 0; i < set_size; i++) {
1084 cout << set[i] << " ";
1085 }
1086 cout << "}" << endl;
1087 print(cout);
1088 cout << endl;
1089 exit(1);
1090 }
1091 for (j = 0; j < set_size; j++) {
1092 a = set[set_size - 1 - j];
1093 pos_a = invPointList[a];
1094 if (f_front) {
1095 new_pos = f + j;
1096 }
1097 else {
1098 new_pos = f + l - 1 - j;
1099 }
1100 if (FALSE /*f_vv*/) {
1101 cout << "split_cell_front_or_back: a=" << a
1102 << " pos_a=" << pos_a << " new_pos="
1103 << new_pos << endl;
1104 }
1105 if (pos_a != new_pos) {
1106 b = pointList[new_pos];
1107 pointList[new_pos] = a;
1108 invPointList[a] = new_pos;
1109 pointList[pos_a] = b;
1110 invPointList[b] = pos_a;
1111 }
1112 if (f_front) {
1113 //cellNumber[pos_a] = ht;
1114 }
1115 else {
1116 cellNumber[new_pos] = ht;
1117 }
1118 }
1119
1120 if (f_front) {
1121 cellSize[c] = set_size;
1122 startCell[ht] = f + set_size;
1123 cellSize[ht] = l - set_size;
1124 for (j = 0; j < l - set_size; j++) {
1125 cellNumber[f + set_size + j] = ht;
1126 }
1127 }
1128 else {
1129 cellSize[c] = l - set_size;
1130 // cout << "cellSize[c]=" << cellSize[c] << endl;
1131
1132 parent[ht] = c;
1133 startCell[ht] = f + l - set_size;
1134 cellSize[ht] = set_size;
1135 }
1136 parent[ht] = c;
1137 ht++;
1138 if (f_v) {
1139 cout << "split_cell_front_or_back() done" << endl;
1140 }
1141}
1142
1144 int *set, int set_size, int verbose_level)
1145{
1146 int f_v = (verbose_level >= 1);
1147
1148 if (f_v) {
1149 cout << "partitionstack::split_cell" << endl;
1150 }
1151 split_cell_front_or_back(set, set_size, FALSE, verbose_level);
1152}
1153
1155{
1156 int i, f1, f2, l1, l2, p;
1157
1158 ht--;
1159 f2 = startCell[ht];
1160 l2 = cellSize[ht];
1161 p = parent[ht];
1162 f1 = startCell[p];
1163 l1 = cellSize[p];
1164 if (f1 + l1 != f2) {
1165 cout << "partitionstack::join_cell f1 + l1 != f2" << endl;
1166 cout << "cell = " << p << endl;
1167 print(cout);
1168 cout << endl;
1169 exit(1);
1170 }
1171 for (i = 0; i < l2; i++) {
1172 cellNumber[f2 + i] = p;
1173 }
1174 cellSize[p] += l2;
1175}
1176
1178{
1179 while (ht > ht0) {
1180 join_cell();
1181 }
1182}
1183
1185{
1186#ifdef SPLIT_MULTIPLY
1187 nb_subsets = 1;
1188 subset_first[0] = 0;
1189 subset_first[1] = 1;
1190 subset_length[0] = 1;
1191 subsets[0] = pt;
1192#else
1193 subset_size = 1;
1194 subset[0] = pt;
1195#endif
1196}
1197
1199{
1200#ifdef SPLIT_MULTIPLY
1201 int i;
1202 nb_subsets = 1;
1203 subset_first[0] = 0;
1204 subset_first[1] = len;
1205 subset_length[0] = len;
1206 for (i = 0; i < len; i++)
1207 subsets[i] = from + i;
1208#else
1209 for (subset_size = 0; subset_size < len; subset_size++) {
1210 subset[subset_size] = from + subset_size;
1211 }
1212#endif
1213}
1214
1216{
1217 int first_column_element = startCell[1];
1218
1219 if (c >= ht) {
1220 cout << "partitionstack::is_row_class c >= ht, fatal" << endl;
1221 exit(1);
1222 }
1223 if (pointList[startCell[c]] >= first_column_element) {
1224 return FALSE;
1225 }
1226 else {
1227 return TRUE;
1228 }
1229}
1230
1232{
1233 if (c >= ht) {
1234 cout << "partitionstack::is_col_class c >= ht, fatal" << endl;
1235 exit(1);
1236 }
1237 if (is_row_class(c)) {
1238 return FALSE;
1239 }
1240 else {
1241 return TRUE;
1242 }
1243}
1244
1246 int *&row_classes, int *&row_class_inv, int &nb_row_classes,
1247 int *&col_classes, int *&col_class_inv, int &nb_col_classes,
1248 int verbose_level)
1249{
1250 int i, c;
1251
1252 row_classes = NEW_int(ht);
1253 col_classes = NEW_int(ht);
1254 row_class_inv = NEW_int(ht);
1255 col_class_inv = NEW_int(ht);
1256 get_row_and_col_classes(row_classes, nb_row_classes,
1257 col_classes, nb_col_classes, verbose_level - 1);
1258 for (i = 0; i < ht; i++) {
1259 row_class_inv[i] = col_class_inv[i] = -1;
1260 }
1261 for (i = 0; i < nb_row_classes; i++) {
1262 c = row_classes[i];
1263 row_class_inv[c] = i;
1264 }
1265 for (i = 0; i < nb_col_classes; i++) {
1266 c = col_classes[i];
1267 col_class_inv[c] = i;
1268 }
1269}
1270
1272 int *row_classes, int nb_row_classes,
1273 int *col_classes, int nb_col_classes,
1274 int *row_perm, int *row_perm_inv,
1275 int *col_perm, int *col_perm_inv)
1276{
1277 int i, j, c, a, f, l, pos;
1278 int first_column_element = startCell[1];
1279
1280 pos = 0;
1281 for (i = 0; i < nb_row_classes; i++) {
1282 c = row_classes[i];
1283 f = startCell[c];
1284 l = cellSize[c];
1285 for (j = 0; j < l; j++) {
1286 a = pointList[f + j];
1287 row_perm_inv[pos] = a;
1288 row_perm[a] = pos;
1289 pos++;
1290 }
1291 }
1292 pos = 0;
1293 for (i = 0; i < nb_col_classes; i++) {
1294 c = col_classes[i];
1295 f = startCell[c];
1296 l = cellSize[c];
1297 for (j = 0; j < l; j++) {
1298 a = pointList[f + j] - first_column_element;
1299 col_perm_inv[pos] = a;
1300 col_perm[a] = pos;
1301 pos++;
1302 }
1303 }
1304}
1305
1307 int *row_classes, int &nb_row_classes,
1308 int *col_classes, int &nb_col_classes, int verbose_level)
1309{
1310 int i, c, l;
1311 int f_v = (verbose_level >= 1);
1312 int f_vv = (verbose_level >= 2);
1313
1314 if (f_v) {
1315 cout << "partitionstack::get_row_and_col_classes n = " << n << endl;
1316 }
1317 nb_row_classes = 0;
1318 nb_col_classes = 0;
1319#if 0
1320 for (c = 0; c < ht; c++) {
1321 if (is_row_class(c)) {
1322 row_classes[nb_row_classes++] = c;
1323 }
1324 else {
1325 col_classes[nb_col_classes++] = c;
1326 }
1327 }
1328#endif
1329 i = 0;
1330 while (i < n) {
1331 c = cellNumber[i];
1332 if (f_vv) {
1333 cout << i << " : " << c << endl;
1334 }
1335 if (is_row_class(c)) {
1336 row_classes[nb_row_classes++] = c;
1337 }
1338 else {
1339 col_classes[nb_col_classes++] = c;
1340 }
1341 l = cellSize[c];
1342 i += l;
1343 }
1344}
1345
1347 int *V, int nb_V, int *B, int nb_B, int verbose_level)
1348{
1349 int f_v = (verbose_level >= 1);
1350 int i, l;
1351
1352 if (f_v) {
1353 cout << "partitionstack::initial_matrix_decomposition "
1354 "before: " << endl;
1355 print(cout);
1356 cout << endl;
1357 }
1358
1359 // split rows and columns
1360 subset_continguous(nbrows, nbcols);
1362
1363 l = V[0];
1364 for (i = 1; i < nb_V; i++) {
1365 subset_continguous(l, nbrows - l);
1367 l += V[i];
1368 }
1369
1370 l = B[0];
1371 for (i = 1; i < nb_B; i++) {
1372 subset_continguous(nbrows + l, nbcols - l);
1374 l += B[i];
1375 }
1376
1377 if (f_v) {
1378 cout << "partitionstack::initial_matrix_decomposition "
1379 "after" << endl;
1380 print(cout);
1381 cout << endl;
1382 }
1383}
1384
1386 int ancestor_cell, int verbose_level)
1387{
1388 int f_v = (verbose_level >= 1);
1389 int c;
1390
1391 if (f_v) {
1392 cout << "is_descendant_of: cell=" << cell << endl;
1393 }
1394 c = cell;
1395 if (cell == ancestor_cell) {
1396 if (f_v) {
1397 cout << "is_descendant_of: "
1398 "cell == ancestor_cell, so yes" << endl;
1399 }
1400 return TRUE;
1401 }
1402 while (parent[c] != c) {
1403 c = parent[c];
1404 if (f_v) {
1405 cout << "is_descendant_of: c=" << c << endl;
1406 }
1407 if (c == ancestor_cell) {
1408 if (f_v) {
1409 cout << "is_descendant_of: "
1410 "c == ancestor_cell, so yes" << endl;
1411 }
1412 return TRUE;
1413 }
1414 }
1415 if (f_v) {
1416 cout << "is_descendant_of: parent[c] == c, so no" << endl;
1417 }
1418 return FALSE;
1419}
1420
1422 int ancestor_cell, int level, int verbose_level)
1423{
1424 int f_v = (verbose_level >= 1);
1425 int c;
1426
1427 if (f_v) {
1428 cout << "is_descendant_of_at_level: cell=" << cell
1429 << " ancestor_cell = " << ancestor_cell
1430 << " level = " << level << endl;
1431 }
1432 if (cell == ancestor_cell) {
1433 if (f_v) {
1434 cout << "is_descendant_of_at_level: "
1435 "cell == ancestor_cell, so yes" << endl;
1436 }
1437 return TRUE;
1438 }
1439 c = cell;
1440 if (c < level) {
1441 if (f_v) {
1442 cout << "is_descendant_of_at_level: "
1443 "c < level, so no" << endl;
1444 }
1445 return FALSE;
1446 }
1447 while (parent[c] != c) {
1448 c = parent[c];
1449 if (f_v) {
1450 cout << "is_descendant_of_at_level: c=" << c << endl;
1451 }
1452 if (c == ancestor_cell) {
1453 if (f_v) {
1454 cout << "is_descendant_of_at_level: "
1455 "c == ancestor_cell, so yes" << endl;
1456 }
1457 return TRUE;
1458 }
1459 if (c < level) {
1460 if (f_v) {
1461 cout << "is_descendant_of_at_level: "
1462 "c < level, so no" << endl;
1463 }
1464 return FALSE;
1465 }
1466 }
1467 if (f_v) {
1468 cout << "is_descendant_of_at_level: "
1469 "parent[c] == c, so no" << endl;
1470 }
1471 return FALSE;
1472}
1473
1474int partitionstack::cellSizeAtLevel(int cell, int level)
1475{
1476 int i, s, S = 0;
1477
1478 for (i = level; i < ht; i++) {
1479 if (is_descendant_of_at_level(i, cell, level, FALSE)) {
1480 //cout << "cell " << i << " of size "
1481 //<< cellSize[i] << " is a descendant of cell " << cell << endl;
1482 s = cellSize[i];
1483 S += s;
1484 }
1485 }
1486 if (cell < level) {
1487 S += cellSize[cell];
1488 }
1489 return S;
1490}
1491
1492
1494 int *row_classes, int nb_row_classes,
1495 int *col_classes, int nb_col_classes)
1496{
1497 int i, j, c, f, l, a;
1498 int first_column_element = startCell[1];
1499
1500 for (i = 0; i < nb_row_classes; i++) {
1501 c = row_classes[i];
1502 f = startCell[c];
1503 l = cellSize[c];
1504 ost << "${\\cal V}_" << i << " = \\{";
1505 for (j = 0; j < l; j++) {
1506 a = pointList[f + j];
1507 ost << a;
1508 if (j < l - 1) {
1509 ost << ", ";
1510 }
1511 if ((j + 1) % 25 == 0) {
1512 ost << "\\\\" << endl;
1513 }
1514 }
1515 ost << "\\}$ of size " << l << "\\\\" << endl;
1516 }
1517 for (i = 0; i < nb_col_classes; i++) {
1518 c = col_classes[i];
1519 f = startCell[c];
1520 l = cellSize[c];
1521 ost << "${\\cal B}_" << i << " = \\{";
1522 for (j = 0; j < l; j++) {
1523 a = pointList[f + j] - first_column_element;
1524 ost << a;
1525 if (j < l - 1) {
1526 ost << ", ";
1527 }
1528 if ((j + 1) % 25 == 0) {
1529 ost << "\\\\" << endl;
1530 }
1531 }
1532 ost << "\\}$ of size " << l << "\\\\" << endl;
1533 }
1534}
1535
1537 int *row_classes, int nb_row_classes,
1538 int *col_classes, int nb_col_classes,
1539 int *scheme, int marker1, int marker2)
1540{
1541 int c, i, j;
1542
1543 if (marker1 >= 0) ost << " ";
1544 if (marker2 >= 0) ost << " ";
1545
1546 ost << " | ";
1547 for (j = 0; j < nb_col_classes; j++) {
1548 c = col_classes[j];
1549 ost << setw(6) << cellSize[c] << "_{" << setw(3) << c << "}";
1550 }
1551 ost << endl;
1552
1553 if (marker1 >= 0) ost << "--";
1554 if (marker2 >= 0) ost << "--";
1555 ost << "---------------";
1556 for (i = 0; i < nb_col_classes; i++) {
1557 ost << "------------";
1558 }
1559 ost << endl;
1560 for (i = 0; i < nb_row_classes; i++) {
1561 c = row_classes[i];
1562 ost << setw(6) << cellSize[c] << "_{" << setw(3) << c << "}";
1563 if (marker1 >= 0) {
1564 if (is_descendant_of(c, marker1, 0)) {
1565 ost << " *";
1566 }
1567 else {
1568 ost << " ";
1569 }
1570 }
1571 if (marker2 >= 0) {
1572 if (is_descendant_of(c, marker2, 0)) {
1573 ost << " *";
1574 }
1575 else {
1576 ost << " ";
1577 }
1578 }
1579 ost << " | ";
1580 //f = P.startCell[c];
1581 for (j = 0; j < nb_col_classes; j++) {
1582 ost << setw(12) << scheme[i * nb_col_classes + j];
1583 }
1584 ost << endl;
1585 }
1586 ost << endl;
1587 ost << endl;
1588}
1589
1591 int *row_classes, int nb_row_classes,
1592 int *col_classes, int nb_col_classes,
1593 int *scheme)
1594{
1595 int c, i, j;
1596
1597 ost << "\\begin{align*}" << endl;
1598 ost << "\\begin{array}{r|*{" << nb_col_classes << "}{r}}" << endl;
1599 ost << " ";
1600 for (j = 0; j < nb_col_classes; j++) {
1601 ost << " & ";
1602 c = col_classes[j];
1603 ost << setw(6) << cellSize[c] << "_{" << setw(3) << c << "}";
1604 }
1605 ost << "\\\\" << endl;
1606 ost << "\\hline" << endl;
1607 for (i = 0; i < nb_row_classes; i++) {
1608 c = row_classes[i];
1609 ost << setw(6) << cellSize[c] << "_{" << setw(3) << c << "}";
1610 //f = P.startCell[c];
1611 for (j = 0; j < nb_col_classes; j++) {
1612 ost << " & " << setw(12) << scheme[i * nb_col_classes + j];
1613 }
1614 ost << "\\\\" << endl;
1615 }
1616 ost << "\\end{array}" << endl;
1617 ost << "\\end{align*}" << endl;
1618}
1619
1621 int *row_classes, int nb_row_classes,
1622 int *col_classes, int nb_col_classes,
1623 int *row_scheme, int *col_scheme, int f_print_subscripts)
1624{
1626 row_classes, nb_row_classes,
1627 col_classes, nb_col_classes,
1628 row_scheme, col_scheme, f_print_subscripts);
1629}
1630
1632 ostream &ost, int f_enter_math_mode,
1633 int *row_classes, int nb_row_classes,
1634 int *col_classes, int nb_col_classes,
1635 int *row_scheme, int *col_scheme, int f_print_subscripts)
1636{
1637 int c, i, j;
1638
1639 if (f_enter_math_mode) {
1640 ost << "\\begin{align*}" << endl;
1641 }
1642 ost << "\\begin{array}{r|*{" << nb_col_classes << "}{r}}" << endl;
1643 ost << " ";
1644 for (j = 0; j < nb_col_classes; j++) {
1645 ost << " & ";
1646 c = col_classes[j];
1647 ost << setw(6) << cellSize[c];
1648 if (f_print_subscripts) {
1649 ost << "_{" << setw(3) << c << "}";
1650 }
1651 }
1652 ost << "\\\\" << endl;
1653 ost << "\\hline" << endl;
1654 for (i = 0; i < nb_row_classes; i++) {
1655 c = row_classes[i];
1656 ost << setw(6) << cellSize[c];
1657 if (f_print_subscripts) {
1658 ost << "_{" << setw(3) << c << "}";
1659 }
1660 //f = P.startCell[c];
1661 for (j = 0; j < nb_col_classes; j++) {
1662 ost << " & " << setw(12) << row_scheme[i * nb_col_classes + j]
1663 << "\\backslash " << col_scheme[i * nb_col_classes + j];
1664 }
1665 ost << "\\\\" << endl;
1666 }
1667 ost << "\\end{array}" << endl;
1668 if (f_enter_math_mode) {
1669 ost << "\\end{align*}" << endl;
1670 }
1671}
1672
1674 std::ostream &ost, int f_enter_math_mode,
1675 int *row_classes, int nb_row_classes,
1676 int *col_classes, int nb_col_classes,
1677 int *row_scheme, int f_print_subscripts)
1678{
1679 int c, i, j;
1680
1681 ost << "%{\\renewcommand{\\arraycolsep}{1pt}" << endl;
1682 if (f_enter_math_mode) {
1683 ost << "\\begin{align*}" << endl;
1684 }
1685 ost << "\\begin{array}{r|*{" << nb_col_classes << "}{r}}" << endl;
1686 ost << "\\rightarrow ";
1687 for (j = 0; j < nb_col_classes; j++) {
1688 ost << " & ";
1689 c = col_classes[j];
1690 ost << setw(6) << cellSize[c];
1691 if (f_print_subscripts) {
1692 ost << "_{" << setw(3) << c << "}";
1693 }
1694 }
1695 ost << "\\\\" << endl;
1696 ost << "\\hline" << endl;
1697 for (i = 0; i < nb_row_classes; i++) {
1698 c = row_classes[i];
1699 ost << setw(6) << cellSize[c];
1700 if (f_print_subscripts) {
1701 ost << "_{" << setw(3) << c << "}";
1702 }
1703 //f = P.startCell[c];
1704 for (j = 0; j < nb_col_classes; j++) {
1705 ost << " & " << setw(12) << row_scheme[i * nb_col_classes + j];
1706 }
1707 ost << "\\\\" << endl;
1708 }
1709 ost << "\\end{array}" << endl;
1710 if (f_enter_math_mode) {
1711 ost << "\\end{align*}" << endl;
1712 }
1713 ost << "%}" << endl;
1714}
1715
1717 ostream &ost, int f_enter_math_mode,
1718 int *row_classes, int nb_row_classes,
1719 int *col_classes, int nb_col_classes,
1720 int *col_scheme, int f_print_subscripts)
1721{
1722 int c, i, j;
1723
1724 ost << "%{\\renewcommand{\\arraycolsep}{1pt}" << endl;
1725 if (f_enter_math_mode) {
1726 ost << "\\begin{align*}" << endl;
1727 }
1728 ost << "\\begin{array}{r|*{" << nb_col_classes << "}{r}}" << endl;
1729 ost << "\\downarrow ";
1730 for (j = 0; j < nb_col_classes; j++) {
1731 ost << " & ";
1732 c = col_classes[j];
1733 ost << setw(6) << cellSize[c];
1734 if (f_print_subscripts) {
1735 ost << "_{" << setw(3) << c << "}";
1736 }
1737 }
1738 ost << "\\\\" << endl;
1739 ost << "\\hline" << endl;
1740 for (i = 0; i < nb_row_classes; i++) {
1741 c = row_classes[i];
1742 ost << setw(6) << cellSize[c];
1743 if (f_print_subscripts) {
1744 ost << "_{" << setw(3) << c << "}";
1745 }
1746 //f = P.startCell[c];
1747 for (j = 0; j < nb_col_classes; j++) {
1748 ost << " & " << setw(12) << col_scheme[i * nb_col_classes + j];
1749 }
1750 ost << "\\\\" << endl;
1751 }
1752 ost << "\\end{array}" << endl;
1753 if (f_enter_math_mode) {
1754 ost << "\\end{align*}" << endl;
1755 }
1756 ost << "%}" << endl;
1757}
1758
1760 ostream &ost, int f_enter_math_mode,
1761 int *row_classes, int nb_row_classes,
1762 int *col_classes, int nb_col_classes,
1763 int f_print_subscripts)
1764{
1765 int c, i, j;
1766
1767 if (f_enter_math_mode) {
1768 ost << "\\begin{align*}" << endl;
1769 }
1770 ost << "\\begin{array}{r|*{" << nb_col_classes << "}{r}}" << endl;
1771 ost << " ";
1772 for (j = 0; j < nb_col_classes; j++) {
1773 ost << " & ";
1774 c = col_classes[j];
1775 ost << setw(6) << cellSize[c];
1776 if (f_print_subscripts) {
1777 ost << "_{" << setw(3) << c << "}";
1778 }
1779 }
1780 ost << "\\\\" << endl;
1781 ost << "\\hline" << endl;
1782 for (i = 0; i < nb_row_classes; i++) {
1783 c = row_classes[i];
1784 ost << setw(6) << cellSize[c];
1785 if (f_print_subscripts) {
1786 ost << "_{" << setw(3) << c << "}";
1787 }
1788 //f = P.startCell[c];
1789 for (j = 0; j < nb_col_classes; j++) {
1790 ost << " & ";
1791 }
1792 ost << "\\\\" << endl;
1793 }
1794 ost << "\\end{array}" << endl;
1795 if (f_enter_math_mode) {
1796 ost << "\\end{align*}" << endl;
1797 }
1798}
1799
1801 int ht0, int *data, int depth, int hash0)
1802{
1803 int cell, i, j, first, len, ancestor;
1804 int h;
1805 algorithms Algo;
1806
1807 if (ht0 == ht) {
1808 h = Algo.hashing(hash0, 1);
1809 }
1810 else {
1811 h = Algo.hashing(hash0, 0);
1812 }
1813
1814 for (cell = 0; cell < ht0; cell++) {
1815 if (is_row_class(cell)) {
1816 continue;
1817 }
1818 first = startCell[cell];
1819 len = cellSize[cell];
1820
1821 h = Algo.hashing(h, len);
1822
1823 j = pointList[first];
1824 for (i = 0; i < depth; i++) {
1825 h = Algo.hashing(h, data[j * depth + i]);
1826 }
1827 }
1828 for (cell = ht0; cell < ht; cell++) {
1829 ancestor = parent_at_height(ht0, cell);
1830 h = Algo.hashing(h, ancestor);
1831
1832 first = startCell[cell];
1833 len = cellSize[cell];
1834
1835 h = Algo.hashing(h, len);
1836
1837 j = pointList[first];
1838 for (i = 0; i < depth; i++) {
1839 h = Algo.hashing(h, data[j * depth + i]);
1840 }
1841 }
1842 return h;
1843}
1844
1846 int *data, int depth, int hash0)
1847{
1848 int cell, i, j, first, len, ancestor;
1849 int h;
1850 algorithms Algo;
1851
1852 if (ht0 == ht) {
1853 h = Algo.hashing(hash0, 1);
1854 }
1855 else {
1856 h = Algo.hashing(hash0, 0);
1857 }
1858 for (cell = 0; cell < ht0; cell++) {
1859 if (is_col_class(cell)) {
1860 continue;
1861 }
1862 first = startCell[cell];
1863 len = cellSize[cell];
1864
1865 h = Algo.hashing(h, len);
1866
1867 j = pointList[first];
1868 for (i = 0; i < depth; i++) {
1869 h = Algo.hashing(h, data[j * depth + i]);
1870 }
1871 }
1872 for (cell = ht0; cell < ht; cell++) {
1873 ancestor = parent_at_height(ht0, cell);
1874 h = Algo.hashing(h, ancestor);
1875
1876 first = startCell[cell];
1877 len = cellSize[cell];
1878
1879 h = Algo.hashing(h, len);
1880
1881 j = pointList[first];
1882 for (i = 0; i < depth; i++) {
1883 h = Algo.hashing(h, data[j * depth + i]);
1884 }
1885 }
1886 return h;
1887}
1888
1890 int ht0, int *data, int depth)
1891{
1892 int cell, j, first, ancestor;
1893
1894 cout << "the old col parts:" << endl;
1895 for (cell = 0; cell < ht0; cell++) {
1896 if (is_row_class(cell)) {
1897 continue;
1898 }
1899 first = startCell[cell];
1900 j = pointList[first];
1901 cout << "cell " << cell << " of size " << cellSize[cell] << " : ";
1902 Int_vec_print(cout, data + j * depth, depth);
1903 cout << " : ";
1904 Int_vec_print(cout, pointList + first, cellSize[cell]);
1905 cout << endl;
1906 }
1907 if (ht0 == ht) {
1908 cout << "no splitting" << endl;
1909 }
1910 else {
1911 cout << "the " << ht - ht0
1912 << " n e w col parts that were split off are:" << endl;
1913 for (cell = ht0; cell < ht; cell++) {
1914 ancestor = parent_at_height(ht0, cell);
1915 first = startCell[cell];
1916 j = pointList[first];
1917 cout << "cell " << cell << " of size " << cellSize[cell]
1918 << " ancestor cell is " << ancestor << " : ";
1919 Int_vec_print(cout, data + j * depth, depth);
1920 cout << " : ";
1921 Int_vec_print(cout, pointList + first, cellSize[cell]);
1922 cout << endl;
1923 }
1924 }
1925}
1926
1928 int ht0, int *data, int depth)
1929{
1930 int cell, j, first, ancestor;
1931
1932 cout << "the old row parts:" << endl;
1933 for (cell = 0; cell < ht0; cell++) {
1934 if (is_col_class(cell)) {
1935 continue;
1936 }
1937 first = startCell[cell];
1938 j = pointList[first];
1939 cout << "cell " << cell << " of size " << cellSize[cell] << " : ";
1940 Int_vec_print(cout, data + j * depth, depth);
1941 cout << " : ";
1942 Int_vec_print(cout, pointList + first, cellSize[cell]);
1943 cout << endl;
1944 }
1945 if (ht0 == ht) {
1946 cout << "no splitting" << endl;
1947 }
1948 else {
1949 cout << "the " << ht - ht0 << " n e w row parts "
1950 "that were split off are:" << endl;
1951 for (cell = ht0; cell < ht; cell++) {
1952 ancestor = parent_at_height(ht0, cell);
1953 first = startCell[cell];
1954 j = pointList[first];
1955 cout << "cell " << cell << " of size " << cellSize[cell]
1956 << " ancestor cell is " << ancestor << " : ";
1957 Int_vec_print(cout, data + j * depth, depth);
1958 cout << " : ";
1959 Int_vec_print(cout, pointList + first, cellSize[cell]);
1960 cout << endl;
1961 }
1962 }
1963}
1964
1965
1966void partitionstack::radix_sort(int left, int right, int *C,
1967 int length, int radix, int verbose_level)
1968{
1969 int ma, mi, i, lo, mask;
1970 int f_v = (verbose_level >= 1);
1971
1972 if (f_v) {
1973 cout << "radix sort radix = " << radix
1974 << ", left = " << left << ", right = " << right << endl;
1975 }
1976 if (radix == length) {
1977 return;
1978 }
1979 if (left == right) {
1980 return;
1981 }
1982 ma = mi = C[pointList[left] * length + radix];
1983 for (i = left + 1; i <= right; i++) {
1984 ma = MAXIMUM(ma, C[pointList[i] * length + radix]);
1985 mi = MINIMUM(mi, C[pointList[i] * length + radix]);
1986 }
1987 if (f_v) {
1988 cout << "radix sort radix=" << radix
1989 << ", minimum is " << mi
1990 << " maximum is " << ma << endl;
1991 }
1992 if (mi == ma) {
1993 radix_sort(left, right, C, length, radix + 1, verbose_level);
1994 return;
1995 }
1996 lo = my_log2(ma);
1997 if (f_v) {
1998 cout << "log2 = " << lo << endl;
1999 }
2000 mask = (1 << (lo - 1));
2001 if (f_v) {
2002 cout << "mask = " << mask << endl;
2003 }
2004 radix_sort_bits(left, right, C, length, radix, mask, verbose_level);
2005}
2006
2007void partitionstack::radix_sort_bits(int left, int right,
2008 int *C, int length, int radix, int mask, int verbose_level)
2009{
2010 int l, r, i, len;
2011 int f_v = (verbose_level >= 1);
2012
2013 if (f_v) {
2014 cout << "partitionstack::radix_sort_bits() mask = " << mask
2015 << " left=" << left << " right=" << right << endl;
2016 }
2017 if (left >= right) {
2018 return;
2019 }
2020 if (mask == 0) {
2021 radix_sort(left, right, C, length, radix + 1, verbose_level);
2022 return;
2023 }
2024 l = left;
2025 r = right;
2026 while (l < r) {
2027 while (l <= right) {
2028 if (!(C[pointList[l] * length + radix] & mask)) {
2029 break;
2030 }
2031 l++;
2032 }
2033 while (r >= left) {
2034 if ((C[pointList[r] * length + radix] & mask)) {
2035 break;
2036 }
2037 r--;
2038 }
2039 // now: everything in [left .. l -1] has the bit = 1
2040 // everything in [r+1,...,right] has the bit = 0
2041 if (l < r) {
2043 }
2044 if (f_v) {
2045 cout << "l = " << l << " r = " << r << endl;
2046 }
2047 }
2048
2049 // now l = r+1
2050 // if r = left - 1 then all elements had that bit equal to 0
2051 // if l = right + 1 then all elements had that bit equal to 1
2052 mask >>= 1;
2053 if (r == left - 1) {
2054 if (f_v) {
2055 cout << "radix_sort_bits no splitting, all bits 0" << endl;
2056 }
2057 radix_sort_bits(left, right, C,
2058 length, radix, mask, verbose_level);
2059 }
2060 else if (l == right + 1) {
2061 if (f_v) {
2062 cout << "radix_sort_bits no splitting, all bits 1" << endl;
2063 }
2064 radix_sort_bits(left, right, C,
2065 length, radix, mask, verbose_level);
2066 }
2067 else {
2068 if (f_v) {
2069 cout << "radix_sort_bits splitting "
2070 "l=" << l << " r=" << r << endl;
2071 }
2072 // we are splitting off the points in the interval [l..right]
2073 len = right - l + 1;
2074 for (i = 0; i < len; i++) {
2075 subset[i] = pointList[l + i];
2076 }
2077 //cout << "radix_sort split partition, len = " << len << endl;
2078 subset_size = len;
2080
2081 radix_sort_bits(left, r, C, length, radix, mask, verbose_level);
2082 radix_sort_bits(l, right, C, length, radix, mask, verbose_level);
2083 }
2084}
2085
2086void partitionstack::swap_ij(int *perm, int *perm_inv, int i, int j)
2087{
2088 int tmp;
2089
2090 tmp = perm[j];
2091 perm[j] = perm[i];
2092 perm[i] = tmp;
2093 perm_inv[perm[i]] = i;
2094 perm_inv[perm[j]] = j;
2095}
2096
2098{
2099 int i = 0;
2100
2101 while (m) {
2102 i++;
2103 m >>= 1;
2104 }
2105 return i;
2106}
2107
2109 int *orbit_first, int *orbit_len, int *orbit,
2110 int offset,
2111 int verbose_level)
2112{
2113 int f_v = (verbose_level >= 1);
2114 int f_vv = (verbose_level >= 2);
2115 int i, j, f, l, cell_idx, cell_size;
2116 int *Set;
2117
2118 if (f_v) {
2119 cout << "partitionstack::split_by_orbit_partition" << endl;
2120 }
2121 Set = NEW_int(n);
2122
2123 for (i = 0; i < nb_orbits; i++) {
2124 f = orbit_first[i];
2125 l = orbit_len[i];
2126 if (f_vv) {
2127 cout << "partitionstack::split_by_orbit_partition "
2128 "orbit " << i << " first=" << f
2129 << " length=" << l << endl;
2130 }
2131 for (j = 0; j < l; j++) {
2132 Set[j] = orbit[f + j] + offset;
2133 }
2134 if (f_vv) {
2135 cout << "orbit: ";
2136 Int_vec_print(cout, Set, l);
2137 cout << endl;
2138 }
2139 cell_idx = 0;
2140 if (!is_subset_of_cell(Set, l, cell_idx)) {
2141 cout << "partitionstack::split_by_orbit_partition "
2142 "the subset is not subset of a cell of the "
2143 "partition, error" << endl;
2144 exit(1);
2145 }
2146 cell_size = cellSize[cell_idx];
2147 if (l < cell_size) {
2148 // we need to split the cell:
2149 if (f_v) {
2150 cout << "orbit " << i << " of length=" << l
2151 << " is split off from cell " << cell_idx
2152 << " to form a n e w cell C_{" << ht << "}, so "
2153 << cell_size << " = " << cell_size - l
2154 << " + " << l << endl;
2155 }
2156 split_cell(Set, l, 0 /*verbose_level*/);
2157 }
2158 }
2159 FREE_int(Set);
2160 if (f_v) {
2161 cout << "partitionstack::split_by_orbit_partition done" << endl;
2162 }
2163}
2164
2165
2166}}}
2167
2168
void set_print(std::ostream &ost, int *v, int len)
Definition: int_vec.cpp:1043
void get_row_and_col_classes(int *row_classes, int &nb_row_classes, int *col_classes, int &nb_col_classes, int verbose_level)
void print_column_refinement_info(int ht0, int *data, int depth)
void get_column_classes(set_of_sets *&Sos, int verbose_level)
void print_decomposition_tex(std::ostream &ost, int *row_classes, int nb_row_classes, int *col_classes, int nb_col_classes)
void allocate_and_get_decomposition(int *&row_classes, int *&row_class_inv, int &nb_row_classes, int *&col_classes, int *&col_class_inv, int &nb_col_classes, int verbose_level)
void split_multiple_cells(int *set, int set_size, int f_front, int verbose_level)
void print_tactical_decomposition_scheme_tex_internal(std::ostream &ost, int f_enter_math_mode, int *row_classes, int nb_row_classes, int *col_classes, int nb_col_classes, int *row_scheme, int *col_scheme, int f_print_subscripts)
void get_cell(int i, int *&cell, int &cell_sz, int verbose_level)
void get_row_and_col_permutation(int *row_classes, int nb_row_classes, int *col_classes, int nb_col_classes, int *row_perm, int *row_perm_inv, int *col_perm, int *col_perm_inv)
int is_descendant_of(int cell, int ancestor_cell, int verbose_level)
void split_cell_front_or_back(int *set, int set_size, int f_front, int verbose_level)
void split_line_cell_front_or_back(int *set, int set_size, int f_front, int verbose_level)
void print_row_tactical_decomposition_scheme_tex(std::ostream &ost, int f_enter_math_mode, int *row_classes, int nb_row_classes, int *col_classes, int nb_col_classes, int *row_scheme, int f_print_subscripts)
void print_tactical_decomposition_scheme_tex(std::ostream &ost, int *row_classes, int nb_row_classes, int *col_classes, int nb_col_classes, int *row_scheme, int *col_scheme, int f_print_subscripts)
void get_cell_lint(int i, long int *&cell, int &cell_sz, int verbose_level)
void print_non_tactical_decomposition_scheme_tex(std::ostream &ost, int f_enter_math_mode, int *row_classes, int nb_row_classes, int *col_classes, int nb_col_classes, int f_print_subscripts)
void radix_sort(int left, int right, int *C, int length, int radix, int verbose_level)
int is_subset_of_cell(int *set, int size, int &cell_idx)
void split_by_orbit_partition(int nb_orbits, int *orbit_first, int *orbit_len, int *orbit, int offset, int verbose_level)
void radix_sort_bits(int left, int right, int *C, int length, int radix, int mask, int verbose_level)
void print_column_tactical_decomposition_scheme_tex(std::ostream &ost, int f_enter_math_mode, int *row_classes, int nb_row_classes, int *col_classes, int nb_col_classes, int *col_scheme, int f_print_subscripts)
int hash_column_refinement_info(int ht0, int *data, int depth, int hash0)
void write_cell_to_file(int i, std::string &fname, int verbose_level)
void swap_ij(int *perm, int *perm_inv, int i, int j)
int hash_row_refinement_info(int ht0, int *data, int depth, int hash0)
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)
void initial_matrix_decomposition(int nbrows, int nbcols, int *V, int nb_V, int *B, int nb_B, int verbose_level)
int is_descendant_of_at_level(int cell, int ancestor_cell, int level, int verbose_level)
void refine_arbitrary_set_lint(int size, long int *set, int verbose_level)
void write_cell_to_file_points_or_lines(int i, std::string &fname, int verbose_level)
void print_decomposition_scheme_tex(std::ostream &ost, int *row_classes, int nb_row_classes, int *col_classes, int nb_col_classes, int *scheme)
void refine_arbitrary_set(int size, int *set, int verbose_level)
void print_decomposition_scheme(std::ostream &ost, int *row_classes, int nb_row_classes, int *col_classes, int nb_col_classes, int *scheme, int marker1, int marker2)
void init_simple(int underlying_set_size, int nb_sets, int verbose_level)
Definition: set_of_sets.cpp:67
a collection of functions related to sorted vectors
void write_set_to_file(std::string &fname, long int *the_set, int set_size, int verbose_level)
Definition: file_io.cpp:2434
#define MINIMUM(x, y)
Definition: foundations.h:216
#define FREE_int(p)
Definition: foundations.h:640
#define NEW_OBJECT(type)
Definition: foundations.h:638
#define NEW_int(n)
Definition: foundations.h:625
#define TRUE
Definition: foundations.h:231
#define FALSE
Definition: foundations.h:234
#define Lint_vec_copy_to_int(A, B, C)
Definition: foundations.h:723
#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
std::ostream & operator<<(std::ostream &ost, class discreta_base &p)
the orbiter library for the classification of combinatorial objects