Orbiter 2022
Combinatorial Objects
gl_classes.cpp
Go to the documentation of this file.
1// gl_classes.cpp
2//
3// Anton Betten
4//
5// Oct 23, 2013
6
7
8
9
10#include "foundations.h"
11
12
13using namespace std;
14
15
16namespace orbiter {
17namespace layer1_foundations {
18namespace algebra {
19
20
22{
23 k = q = 0;
24 F = NULL;
26 Nb_part = NULL;
27 Partitions = NULL;
28 v = NULL;
29 w = NULL;
30 //null();
31}
32
34{
35 freeself();
36}
37
39{
40}
41
43{
44 int i;
45
48 }
49 if (Nb_part) {
51 }
52 if (Partitions) {
53 for (i = 1; i <= k; i++) {
55 }
57 }
58 if (v) {
59 FREE_int(v);
60 }
61 if (w) {
62 FREE_int(w);
63 }
64 null();
65}
66
67void gl_classes::init(int k, field_theory::finite_field *F, int verbose_level)
68{
69 int f_v = (verbose_level >= 1);
70 int d;
72
73 if (f_v) {
74 cout << "gl_classes::init" << endl;
75 }
78 q = F->q;
79 if (f_v) {
80 cout << "gl_classes::init k = " << k << " q = " << q << endl;
81 }
82
84
85 if (f_v) {
86 cout << "gl_classes before Table_of_polynomials->init" << endl;
87 }
88 Table_of_polynomials->init(k, F, verbose_level - 2);
89 if (f_v) {
90 cout << "gl_classes after Table_of_polynomials->init" << endl;
91 }
92
93
94 if (f_v) {
95 cout << "gl_classes::init making partitions" << endl;
96 }
97 Partitions = NEW_pint(k + 1);
98 Nb_part = NEW_int(k + 1);
99 for (d = 1; d <= k; d++) {
100
102 Partitions[d],
103 Nb_part[d],
104 verbose_level);
105
106 }
107 if (f_v) {
108 cout << "gl_classes k = " << k
109 << " q = " << q << " Nb_part = ";
110 Int_vec_print(cout, Nb_part + 1, k);
111 cout << endl;
112 }
113
114 v = NEW_int(k);
115 w = NEW_int(k);
116
117 if (f_v) {
118 cout << "gl_classes::init k = " << k
119 << " q = " << q << " done" << endl;
120 }
121}
122
124 int *Select_partition, int verbose_level)
125{
126 int f_v = (verbose_level >= 1);
127
128 if (f_v) {
129 cout << "gl_classes::select_partition_first" << endl;
130 }
131 Int_vec_zero(Select_partition, Table_of_polynomials->nb_irred);
132 return TRUE;
133}
134
136 int *Select_partition, int verbose_level)
137{
138 int f_v = (verbose_level >= 1);
139 int i, m;
140
141 if (f_v) {
142 cout << "gl_classes::select_partition_next" << endl;
143 }
144 for (i = Table_of_polynomials->nb_irred - 1; i >= 0; i--) {
145 m = Select[i];
146 if (m > 1) {
147 if (Select_partition[i] < Nb_part[m] - 1) {
148 Select_partition[i]++;
149 return TRUE;
150 }
151 Select_partition[i] = 0;
152 }
153 }
154 return FALSE;
155}
156
157int gl_classes::first(int *Select,
158 int *Select_partition, int verbose_level)
159{
160 int f_v = (verbose_level >= 1);
161
162 if (f_v) {
163 cout << "gl_classes::first" << endl;
164 }
166 Select, verbose_level)) {
167 return FALSE;
168 }
169 while (TRUE) {
170 if (select_partition_first(Select,
171 Select_partition, verbose_level)) {
172 return TRUE;
173 }
175 Select, verbose_level)) {
176 return FALSE;
177 }
178 }
179}
180
181int gl_classes::next(int *Select,
182 int *Select_partition, int verbose_level)
183{
184 int f_v = (verbose_level >= 1);
185
186 if (f_v) {
187 cout << "gl_classes::next" << endl;
188 }
189 if (select_partition_next(Select, Select_partition, verbose_level)) {
190 return TRUE;
191 }
192 while (TRUE) {
194 Select, verbose_level)) {
195 return FALSE;
196 }
197 if (select_partition_first(Select,
198 Select_partition, verbose_level)) {
199 return TRUE;
200 }
201 }
202}
203
204
206 gl_class_rep *R, int verbose_level)
207{
208 int f_v = (verbose_level >= 1);
209 int *Select, *Select_Partition;
210 int i, a, m, p;
211
212 if (f_v) {
213 cout << "gl_classes::make_matrix_from_class_rep" << endl;
214 }
216 Select_Partition = NEW_int(Table_of_polynomials->nb_irred);
218 Int_vec_zero(Select_Partition, Table_of_polynomials->nb_irred);
219
220 for (i = 0; i < R->type_coding->m; i++) {
221 a = R->type_coding->s_ij(i, 0);
222 m = R->type_coding->s_ij(i, 1);
223 p = R->type_coding->s_ij(i, 2);
224 Select[a] = m;
225 Select_Partition[a] = p;
226 }
227 if (f_v) {
228 cout << "gl_classes::make_matrix_from_class_rep before make_matrix_in_rational_normal_form" << endl;
229 }
231 Mtx, Select, Select_Partition,
232 verbose_level - 1);
233 if (f_v) {
234 cout << "gl_classes::make_matrix_from_class_rep after make_matrix_in_rational_normal_form" << endl;
235 }
236 FREE_int(Select);
237 FREE_int(Select_Partition);
238 if (f_v) {
239 cout << "gl_classes::make_matrix_from_class_rep done" << endl;
240 }
241}
242
243
245 int *Mtx,
246 int *Select, int *Select_Partition,
247 int verbose_level)
248{
249 int f_v = (verbose_level >= 1);
250 int a, m, p, d, tt;
251 int aa, coef, m_one, i, j, i0;
252 int *pol;
253 int *part;
254
255 if (f_v) {
256 cout << "gl_classes::make_matrix_in_rational_normal_form" << endl;
257 cout << "Select=";
259 cout << endl;
260 cout << "Select_Partition=";
261 Int_vec_print(cout, Select_Partition, Table_of_polynomials->nb_irred);
262 cout << endl;
263 cout << "Degree=";
266 cout << endl;
267 }
268
269 Int_vec_zero(Mtx, k * k);
270 m_one = F->negate(1);
271
272 // take care of the irreducible polynomial blocks first:
273 i0 = 0;
274 for (a = Table_of_polynomials->nb_irred - 1; a >= 0; a--) {
275 m = Select[a];
276 p = Select_Partition[a];
278 if (m) {
280 pol = Table_of_polynomials->Tables[d] + tt * (d + 1);
281 for (aa = 0; aa < m; aa++) {
282 // fill in m companion matrices of type pol of size d x d:
283
284 // right hand side column:
285 for (i = 0; i < d; i++) {
286 coef = F->mult(m_one, pol[i]);
287 Mtx[(i0 + i) * k + i0 + d - 1] = coef;
288 }
289 // lower diagonal:
290 for (j = 0; j < d - 1; j++) {
291 Mtx[(i0 + j + 1) * k + i0 + j] = 1;
292 }
293 i0 += d;
294 }
295 }
296 }
297 if (i0 != k) {
298 cout << "gl_classes::make_matrix_in_rational_normal_form "
299 "i0 != k (first time)" << endl;
300 exit(1);
301 }
302
303 // now take care of the partition:
304 i0 = 0;
305 for (a = Table_of_polynomials->nb_irred - 1; a >= 0; a--) {
306 m = Select[a];
307 p = Select_Partition[a];
309 if (m) {
311 pol = Table_of_polynomials->Tables[d] + tt * (d + 1);
312 if (m > 1) {
313 int ii, jj, b;
314
315 part = Partitions[m] + p * m;
316 for (ii = m; ii >= 1; ii--) {
317 jj = part[ii - 1];
318 for (b = 0; b < jj; b++) {
319 // we have a block of ii times the same
320 // polynomial, join them by ones:
321 for (i = 0; i < ii; i++) {
322 if (i < ii - 1) {
323 Mtx[(i0 + d) * k + i0 + d - 1] = 1;
324 }
325 i0 += d;
326 }
327 }
328 }
329 }
330 else { // m == 1
331 i0 += d;
332 }
333 }
334 }
335 if (i0 != k) {
336 cout << "gl_classes::make_matrix_in_rational_normal_form "
337 "i0 != k (second time)" << endl;
338 exit(1);
339 }
340
341 if (f_v) {
342 cout << "gl_classes::make_matrix_in_rational_normal_form done" << endl;
343 }
344}
345
347 int *poly_degree, int *poly_mult, int *partition_idx,
349 int verbose_level)
350// Computes the centralizer order of a matrix in GL(k,q)
351// according to Kung's formula~\cite{Kung81}.
352{
353 int f_v = (verbose_level >= 1);
356 int a, m, d, p, i, j, b, mue_i, aa, bb, cc;
357 int *part;
360
361 if (f_v) {
362 cout << "gl_classes::centralizer_order_Kung_basic" << endl;
363 }
364 co.create(1, __FILE__, __LINE__);
365
366 for (a = 0; a < nb_irreds; a++) {
367
368 // loop over all polynomials:
369
370 d = poly_degree[a];
371 m = poly_mult[a];
372 p = partition_idx[a];
373 if (f_v) {
374 cout << "gl_classes::centralizer_order_Kung_basic "
375 "a=" << a << " d=" << d
376 << " m=" << m << " p=" << p << endl;
377 }
378
379 // does the polynomial appear?
380 if (m) {
381
382 // yes!
383
384 part = Partitions[m] + p * m;
385
386 // here comes Kung's formula:
387 co1.create(1, __FILE__, __LINE__);
388 for (i = 1; i <= m; i++) {
389 b = part[i - 1];
390 if (b == 0) {
391 continue;
392 }
393 for (j = 1; j <= b; j++) {
394 mue_i = Combi.Kung_mue_i(part, i, m);
395
396 aa = NT.i_power_j(q, d * mue_i);
397 bb = NT.i_power_j(q, d * (mue_i - j));
398 cc = aa - bb;
399 e.create(cc, __FILE__, __LINE__);
400 D.mult(e, co1, f);
401 f.assign_to(co1);
402 }
403 }
404 D.mult(co, co1, f);
405 f.assign_to(co);
406
407 } // if m
408 }
409 if (f_v) {
410 cout << "gl_classes::centralizer_order_Kung_basic done" << endl;
411 }
412}
413
415 int *Select_polynomial,
416 int *Select_partition, ring_theory::longinteger_object &co,
417 int verbose_level)
418// Computes the centralizer order of a matrix in GL(k,q)
419// according to Kung's formula~\cite{Kung81}.
420{
423 int a, m, d, p, i, j, b, mue_i, aa, bb, cc;
424 int *part;
427
428 co.create(1, __FILE__, __LINE__);
429 for (a = Table_of_polynomials->nb_irred - 1; a >= 0; a--) {
430
431 // loop over all polynomials:
432
433 m = Select_polynomial[a];
435 p = Select_partition[a];
436
437
438 // does the polynomial appear?
439 if (m) {
440
441 // yes:
442
443 part = Partitions[m] + p * m;
444
445 // here comes Kung's formula:
446 co1.create(1, __FILE__, __LINE__);
447 for (i = 1; i <= m; i++) {
448 b = part[i - 1];
449 if (b == 0) {
450 continue;
451 }
452 for (j = 1; j <= b; j++) {
453 mue_i = Combi.Kung_mue_i(part, i, m);
454 aa = NT.i_power_j(q, d * mue_i);
455 bb = NT.i_power_j(q, d * (mue_i - j));
456 cc = aa - bb;
457 e.create(cc, __FILE__, __LINE__);
458 D.mult(e, co1, f);
459 f.assign_to(co1);
460 }
461 }
462 D.mult(co, co1, f);
463 f.assign_to(co);
464
465 } // if m
466 }
467}
468
469
470
471void gl_classes::make_classes(gl_class_rep *&R, int &nb_classes,
472 int f_no_eigenvalue_one, int verbose_level)
473{
474 int f_v = (verbose_level >= 1);
475 int f_vv = (verbose_level >= 2);
476 int f_vvv = (verbose_level >= 3);
477 int cnt;
478 int *Mtx;
479 long int a, b;
480 ring_theory::longinteger_object go, co, f, g, cl, r, sum;
484
485 if (f_v) {
486 cout << "gl_classes::make_classes "
487 "k = " << k << " q = " << q << endl;
488 }
489 int *Select_polynomial;
490 int *Select_partition;
491 int i, m, p;
492
493 if (f_v) {
494 cout << "gl_classes::make_classes "
495 "nb_irred = " << Table_of_polynomials->nb_irred << endl;
496 }
497 Mtx = NEW_int(k * k);
498 Select_polynomial = NEW_int(Table_of_polynomials->nb_irred);
499 Select_partition = NEW_int(Table_of_polynomials->nb_irred);
500
501
502
503 go.create(1, __FILE__, __LINE__);
504 a = NT.i_power_j(q, k);
505 for (i = 0; i < k; i++) {
506 b = a - NT.i_power_j_lint(q, i);
507 f.create(b, __FILE__, __LINE__);
508 D.mult(go, f, g);
509 g.assign_to(go);
510 }
511 if (f_vv) {
512 cout << "gl_classes::make_classes "
513 "The order of GL(k,q) is "
514 << go << endl;
515 }
516
517 sum.create(0, __FILE__, __LINE__);
518
519
520
521
522 cnt = 0;
523 first(Select_polynomial, Select_partition, verbose_level - 2);
524 while (TRUE) {
525
526
527 if (f_no_eigenvalue_one) {
528 if (Select_polynomial[0]) {
529 goto loop1;
530 }
531 }
532
533 if (f_vv) {
534 cout << "gl_classes::make_classes The class " << cnt << " is:" << endl;
535 Int_vec_print(cout, Select_polynomial,
537 cout << " : ";
538
539 int f_first = TRUE;
540 for (i = 0; i < Table_of_polynomials->nb_irred; i++) {
541 m = Select_polynomial[i];
542 //d = Degree[i];
543 p = Select_partition[i];
544 if (m) {
545 if (f_vvv) {
546 cout << "gl_classes::make_classes i=" << i << " m=" << m << " p=" << p << endl;
547 }
548 if (!f_first) {
549 cout << ", ";
550 }
551 Combi.partition_print(cout, Partitions[m] + p * m, m);
552 }
553 f_first = FALSE;
554 }
555 cout << endl;
556 }
557
559 Mtx, Select_polynomial, Select_partition,
560 verbose_level - 2);
561
562 if (f_vv) {
563 cout << "gl_classes::make_classes Representative:" << endl;
565 }
566
567
568 centralizer_order_Kung(Select_polynomial, Select_partition, co,
569 verbose_level - 2);
570 if (f_vv) {
571 cout << "gl_classes::make_classes Centralizer order = " << co << endl;
572 }
573
574 D.integral_division(go, co, cl, r, 0 /* verbose_level */);
575
576 if (f_vv) {
577 cout << "gl_classes::make_classes Class length = " << cl << endl;
578 }
579
580 D.add(sum, cl, g);
581 g.assign_to(sum);
582 if (f_vv) {
583 cout << "gl_classes::make_classes Total = " << sum << endl;
584 }
585
586
587
588 cnt++;
589loop1:
590
591 if (!next(Select_polynomial, Select_partition, verbose_level - 2)) {
592 break;
593 }
594
595 }
596
597 cout << endl;
598
599 nb_classes = cnt;
600
601 if (f_vv) {
602 cout << "gl_classes::make_classes Total = " << sum << " in " << nb_classes
603 << " conjugacy classes" << endl;
604 }
605
606 R = NEW_OBJECTS(gl_class_rep, nb_classes);
607
608 sum.create(0, __FILE__, __LINE__);
609
610
611 cnt = 0;
612 first(Select_polynomial, Select_partition, verbose_level - 2);
613 while (TRUE) {
614
615 if (f_no_eigenvalue_one) {
616 if (Select_polynomial[0]) {
617 goto loop2;
618 }
619 }
620
621 if (f_vv) {
622 cout << "gl_classes::make_classes The class " << cnt << " is:" << endl;
623 Int_vec_print(cout, Select_polynomial,
625 cout << " : ";
626 int f_first = TRUE;
627 for (i = 0; i < Table_of_polynomials->nb_irred; i++) {
628 m = Select_polynomial[i];
629 //d = Degree[i];
630 p = Select_partition[i];
631 if (m) {
632 if (f_vvv) {
633 cout << "i=" << i << " m=" << m << " p=" << p << endl;
634 }
635 if (!f_first) {
636 cout << ", ";
637 }
638 Combi.partition_print(cout, Partitions[m] + p * m, m);
639 f_first = FALSE;
640 }
641 }
642 cout << endl;
643 }
644
645
647 Select_polynomial, Select_partition, verbose_level);
648
650 Mtx,
651 Select_polynomial, Select_partition,
652 verbose_level - 2);
653
654 if (f_vv) {
655 cout << "gl_classes::make_classes Representative:" << endl;
657 }
658
659
660 centralizer_order_Kung(Select_polynomial, Select_partition, co,
661 verbose_level - 2);
662
663 if (f_vv) {
664 cout << "gl_classes::make_classes Centralizer order = " << co << endl;
665 }
666
667 D.integral_division(go, co, cl, r, 0 /* verbose_level */);
668
669 if (f_vv) {
670 cout << "gl_classes::make_classes Class length = " << cl << endl;
671 }
672 D.add(sum, cl, g);
673 g.assign_to(sum);
674 if (f_vv) {
675 cout << "gl_classes::make_classes Total = " << sum << endl;
676 }
677
678
681 co.assign_to(*R[cnt].centralizer_order);
682 cl.assign_to(*R[cnt].class_length);
683
684 cnt++;
685loop2:
686
687 if (!next(Select_polynomial, Select_partition, verbose_level - 2)) {
688 break;
689 }
690
691 }
692
693
694 FREE_int(Mtx);
695 FREE_int(Select_polynomial);
696 FREE_int(Select_partition);
697
698 if (f_v) {
699 cout << "gl_classes::make_classes k = " << k << " q = " << q
700 << " done" << endl;
701 }
702}
703
705 gl_class_rep *R, int *Basis, int verbose_level)
706{
707 int f_v = (verbose_level >= 1);
708 int *M2;
709 int *M3;
710 //int *Basis;
711 int *Basis_inv;
712 int *Mult;
713 int *Select_partition;
714
715
716 if (f_v) {
717 cout << "gl_classes::identify_matrix "
718 "k = " << k << " q = " << q << endl;
719 }
720 if (f_v) {
721 cout << "gl_classes::identify_matrix "
722 "input matrix=" << endl;
724 }
725
726 M2 = NEW_int(k * k);
727 M3 = NEW_int(k * k);
728 //Basis = NEW_int(k * k);
729 Basis_inv = NEW_int(k * k);
731 Select_partition = NEW_int(Table_of_polynomials->nb_irred);
732
733 {
736
737
738
739 U.create_object_by_rank(char_poly, 0, __FILE__, __LINE__, verbose_level);
740
741 U.characteristic_polynomial(Mtx, k, char_poly, verbose_level - 2);
742
743 if (f_v) {
744 cout << "gl_classes::identify_matrix "
745 "The characteristic polynomial is ";
746 U.print_object(char_poly, cout);
747 cout << endl;
748 }
749
751 char_poly,
752 Mtx, M2, k,
753 verbose_level);
754
755 if (f_v) {
756 cout << "gl_classes::identify_matrix "
757 "After substitution, the matrix is " << endl;
759 }
760
761
762 if (f_v) {
763 cout << "gl_classes::identify_matrix before factorize_polynomial" << endl;
764 }
765
767 char_poly, Mult, verbose_level);
768
769 if (f_v) {
770 cout << "gl_classes::identify_matrix after factorize_polynomial" << endl;
771 }
772
773 if (f_v) {
774 cout << "gl_classes::identify_matrix factorization: ";
776 cout << endl;
777 }
778
779 if (f_v) {
780 cout << "gl_classes::identify_matrix before identify2" << endl;
781 }
782
783 identify2(Mtx, char_poly, Mult,
784 Select_partition, Basis,
785 verbose_level);
786
787 if (f_v) {
788 cout << "gl_classes::identify_matrix after identify2" << endl;
789 }
790
791 if (f_v) {
792 cout << "gl_classes::identify_matrix before R->init" << endl;
793 }
795 Mult, Select_partition, verbose_level);
796 if (f_v) {
797 cout << "gl_classes::identify_matrix after R->init" << endl;
798 }
799
800
801
802 F->Linear_algebra->matrix_inverse(Basis, Basis_inv, k, 0 /* verbose_level */);
803
804 F->Linear_algebra->mult_matrix_matrix(Basis_inv, Mtx, M2, k, k, k, 0 /* verbose_level */);
805
806 F->Linear_algebra->mult_matrix_matrix(M2, Basis, M3, k, k, k, 0 /* verbose_level */);
807
808 if (f_v) {
809 cout << "gl_classes::identify_matrix B^-1 * A * B = " << endl;
811 cout << endl;
812 }
813
814
815 U.delete_object(char_poly);
816
817 }
818
819 FREE_int(M2);
820 FREE_int(M3);
821 //FREE_int(Basis);
822 FREE_int(Basis_inv);
823 FREE_int(Mult);
824 FREE_int(Select_partition);
825
826 if (f_v) {
827 cout << "gl_classes::identify_matrix "
828 "k = " << k << " q = " << q << " done" << endl;
829 }
830}
831
833 int *Mult, int *Select_partition, int *Basis,
834 int verbose_level)
835{
836 int f_v = (verbose_level >= 1);
837 int f_vv = (verbose_level >= 2);
838 int i, h, nb_irreds;
839 int *Irreds;
840
841 if (f_v) {
842 cout << "gl_classes::identify2 k = " << k << " q = " << q << endl;
843 }
844
847
848 // nb_irreds is the number of distinct irreducible factors
849 // of the characteristic polynomial (not counting multiplicities)
850
851 Irreds = NEW_int(nb_irreds);
852
853
854 i = 0;
855 for (h = Table_of_polynomials->nb_irred - 1; h >= 0; h--) {
856
857 if (Mult[h] == 0) {
858 continue;
859 }
860 Irreds[i++] = h;
861
862 } // next h
863
864
865 if (i != nb_irreds) {
866 cout << "gl_classes::identify2 i != nb_irreds" << endl;
867 exit(1);
868 }
869
870
871
872 if (f_v) {
873 cout << "gl_classes::identify2 "
874 "k = " << k << " q = " << q << " Irreds: ";
875 Int_vec_print(cout, Irreds, nb_irreds);
876 cout << endl;
877 }
878
879
880
881
882 matrix_block_data *Data;
883
884 Data = NEW_OBJECTS(matrix_block_data, nb_irreds);
885
886
887 if (f_v) {
888 cout << "gl_classes::identify2 "
889 "before compute_generalized_kernels_for_each_block" << endl;
890 }
891
893 Mtx, Irreds, nb_irreds,
894 Table_of_polynomials->Degree, Mult, Data,
895 verbose_level);
896
897 if (f_v) {
898 cout << "gl_classes::identify2 "
899 "after compute_generalized_kernels_for_each_block" << endl;
900 }
901
902 Int_vec_zero(Select_partition, nb_irreds);
903 for (i = 0; i < nb_irreds; i++) {
904 Select_partition[Irreds[i]] = Data[i].part_idx;
905 }
906
907 if (f_v) {
908 cout << "gl_classes::identify2 before "
909 "choose_basis_for_rational_normal_form" << endl;
910 }
911
912
914 nb_irreds, Basis, verbose_level);
915
916
917 if (f_v) {
918 cout << "gl_classes::identify2 after "
919 "choose_basis_for_rational_normal_form" << endl;
920 }
921
922
923 if (f_vv) {
924 cout << "gl_classes::identify2 "
925 "transformation matrix = " << endl;
927 cout << endl;
928 }
929
930
931 FREE_OBJECTS(Data);
932 FREE_int(Irreds);
933
934 if (f_v) {
935 cout << "gl_classes::identify2 "
936 "k = " << k << " q = " << q << " done" << endl;
937 }
938}
939
941 int *Mtx, int *Irreds, int nb_irreds,
942 int *Degree, int *Mult, matrix_block_data *Data,
943 int verbose_level)
944{
945 int f_v = (verbose_level >= 1);
946 int f_vv = (verbose_level >= 2);
947 int h, u, d, tt, *poly_coeffs, b0;
950 int *M2;
951
952 if (f_v) {
953 cout << "gl_classes::compute_generalized_kernels_for_each_block" << endl;
954 }
955
956 M2 = NEW_int(k * k);
957
958 U.create_object_by_rank(P, 0, __FILE__, __LINE__, verbose_level);
959 b0 = 0;
960 for (h = 0; h < nb_irreds; h++) {
961 if (f_vv) {
962 cout << "gl_classes::compute_generalized_kernels_for_each_block "
963 "polynomial " << h << " / " << nb_irreds << endl;
964 }
965 u = Irreds[h];
966 d = Degree[u];
967
969
970 poly_coeffs = Table_of_polynomials->Tables[d] + tt * (d + 1);
971
972 U.delete_object(P);
974 P, d, poly_coeffs);
975
976 if (f_vv) {
977 cout << "gl_classes::compute_generalized_kernels_for_each_block "
978 "polynomial = ";
979 U.print_object(P, cout);
980 cout << endl;
981 }
982
984 P, Mtx, M2, k,
985 verbose_level);
986
987 if (f_vv) {
988 cout << "gl_classes::compute_generalized_kernels_for_each_block "
989 "matrix substituted into polynomial = " << endl;
991 cout << endl;
992 }
993
994
995
997 Data + h, M2, d, b0,
998 Mult[u], poly_coeffs,
999 verbose_level);
1000
1001 b0 += d * Mult[u];
1002
1003
1004 if (f_v) {
1005 cout << "gl_classes::compute_generalized_kernels_for_each_block "
1006 "after compute_generalized_kernels" << endl;
1007 }
1008
1009 } // next h
1010
1011 U.delete_object(P);
1012 FREE_int(M2);
1013
1014 if (f_v) {
1015 cout << "gl_classes::compute_generalized_kernels_for_each_block done" << endl;
1016 }
1017}
1018
1019
1021 matrix_block_data *Data,
1022 int *M2, int d, int b0, int m, int *poly_coeffs,
1023 int verbose_level)
1024{
1025 int f_v = (verbose_level >= 1);
1026 int f_vv = (verbose_level >= 2);
1027 int cnt, c, rank;
1028 int *M3, *M4;
1029 int *base_cols;
1031
1032 if (f_v) {
1033 cout << "gl_classes::compute_generalized_kernels" << endl;
1034 }
1035 M3 = NEW_int(k * k);
1036 M4 = NEW_int(k * k);
1037 base_cols = NEW_int(k);
1038
1039 Data->allocate(k + 1);
1040
1041 Data->m = m;
1042 Data->d = d;
1043 Data->poly_coeffs = poly_coeffs;
1044 Data->b0 = b0;
1045 Data->b1 = b0 + d * m;
1046
1047 Int_vec_copy(M2, M3, k * k);
1048 Int_vec_zero(Data->dual_part, k);
1049
1050 for (cnt = 1; cnt <= k; cnt++) {
1051
1052 if (f_vv) {
1053 cout << "gl_classes::compute_generalized_kernels "
1054 "cnt = " << cnt << " computing kernel of:" << endl;
1056 cout << endl;
1057 }
1058 Int_vec_copy(M3, M4, k * k);
1059
1060 rank = F->Linear_algebra->Gauss_simple(M4, k, k, base_cols, 0 /*verbose_level*/);
1061
1063 base_cols, rank, &Data->K[cnt], 0 /* verbose_level */);
1064
1065 if (f_vv) {
1066 cout << "gl_classes::compute_generalized_kernels "
1067 "kernel = " << endl;
1069 Data->K[cnt].m, Data->K[cnt].n);
1070 cout << endl;
1071 }
1072
1073 c = Data->K[cnt].n / d;
1074 if (cnt > 1) {
1075 c -= Data->K[cnt - 1].n / d;
1076 }
1077 Data->dual_part[c - 1]++;
1078
1079 if (Data->K[cnt].n == m * d) {
1080 break;
1081 }
1082
1083 F->Linear_algebra->mult_matrix_matrix(M3, M2, M4, k, k, k, 0 /* verbose_level */);
1084 Int_vec_copy(M4, M3, k * k);
1085
1086 }
1087
1088 Data->height = cnt;
1089
1090 if (f_v) {
1091 cout << "height=" << Data->height << endl;
1092 cout << "gl_classes::compute_generalized_kernels dual_part = ";
1093 Combi.partition_print(cout, Data->dual_part, m);
1094 cout << endl;
1095 }
1096
1097 Combi.partition_dual(Data->dual_part,
1098 Data->part, m,
1099 verbose_level);
1100
1101 if (f_v) {
1102 cout << "gl_classes::compute_generalized_kernels part = ";
1103 Combi.partition_print(cout,
1104 Data->part, m);
1105 cout << endl;
1106 }
1107
1108 Data->part_idx = identify_partition(Data->part,
1109 m, verbose_level - 2);
1110
1111 if (f_v) {
1112 cout << "gl_classes::compute_generalized_kernels "
1113 "part_idx = " << Data->part_idx << endl;
1114 }
1115
1116 FREE_int(M3);
1117 FREE_int(M4);
1118 FREE_int(base_cols);
1119 if (f_v) {
1120 cout << "gl_classes::compute_generalized_kernels done" << endl;
1121 }
1122
1123}
1124
1125int gl_classes::identify_partition(int *part, int m, int verbose_level)
1126{
1127 int f_v = (verbose_level >= 1);
1128 int i;
1130
1131 if (f_v) {
1132 cout << "gl_classes::identify_partition" << endl;
1133 }
1134 for (i = 0; i < Nb_part[m]; i++) {
1135 //cout << "i=" << i << endl;
1136 if (Sorting.int_vec_compare(Partitions[m] + i * m, part, m) == 0) {
1137 break;
1138 }
1139 }
1140 if (i == Nb_part[m]) {
1141 cout << "gl_classes::identify_partition "
1142 "did not find partition" << endl;
1143 cout << "looking for:" << endl;
1144 Int_vec_print(cout, part, m);
1145 cout << endl;
1146 cout << "in:" << endl;
1148 exit(1);
1149 }
1150 if (f_v) {
1151 cout << "gl_classes::identify_partition done" << endl;
1152 }
1153 return i;
1154}
1155
1157 int *Mtx, matrix_block_data *Data, int nb_irreds,
1158 int *Basis,
1159 int verbose_level)
1160{
1161 int f_v = (verbose_level >= 1);
1162 int f_vv = (verbose_level >= 2);
1163 int b, h;
1164
1165 if (f_v) {
1166 cout << "gl_classes::choose_basis_for_rational_normal_form" << endl;
1167 }
1168 if (f_vv) {
1169 cout << "gl_classes::choose_basis_for_rational_normal_form "
1170 "Mtx=" << endl;
1172 cout << endl;
1173 }
1174 b = 0;
1175 Int_vec_zero(Basis, k * k);
1176
1177 for (h = 0; h < nb_irreds; h++) {
1178 if (f_vv) {
1179 cout << "gl_classes::choose_basis_for_rational_normal_form "
1180 "before choose_basis_for_rational_normal_form_block "
1181 << h << " / " << nb_irreds << " b = " << b << endl;
1182 }
1183
1185 Mtx,
1186 Data + h, Basis, b,
1187 verbose_level - 2);
1188
1189
1190 if (f_vv) {
1191 cout << "gl_classes::identify2 after "
1192 "choose_basis_for_rational_normal_form_block "
1193 << h << " / " << nb_irreds << endl;
1194 }
1195
1196
1197 }
1198 if (b != k) {
1199 cout << "gl_classes::choose_basis_for_rational_normal_form "
1200 "b != k" << endl;
1201 exit(1);
1202 }
1203
1204 if (f_v) {
1205 cout << "gl_classes::choose_basis_for_rational_normal_form "
1206 "done" << endl;
1207 }
1208}
1209
1211 int *Mtx, matrix_block_data *Data,
1212 int *Basis, int &b,
1213 int verbose_level)
1214// chooses a basis for the block associated
1215// with one particular irreducible polynomial
1216// b is the number of columns in Basis before and after
1217{
1218 int f_v = (verbose_level >= 1);
1219 int c, e, f, af, B0, b0, g, ii, coeff, i, j;
1220 //int *v, *w;
1221
1222
1223 if (f_v) {
1224 cout << "gl_classes::choose_basis_for_rational_"
1225 "normal_form_block" << endl;
1226 }
1227
1228 B0 = b;
1229
1230 //v = NEW_int(k);
1231 //w = NEW_int(k);
1232
1233 for (f = Data->height; f >= 1; f--) {
1234 af = Data->part[f - 1];
1235 if (f_v) {
1236 cout << "f=" << f << " af=" << af << endl;
1237 }
1238 for (e = 0; e < af; e++) {
1239 if (f_v) {
1240 cout << "f=" << f << " af=" << af << " e=" << e << endl;
1241 }
1242
1243 data_structures::int_matrix *Forbidden_subspace;
1244
1245 Forbidden_subspace = NEW_OBJECT(data_structures::int_matrix);
1246
1247 Forbidden_subspace->allocate(k, b - B0);
1248
1249 for (j = 0; j < b - B0; j++) {
1250 for (i = 0; i < k; i++) {
1251 Forbidden_subspace->s_ij(i, j) = Basis[i * k + B0 + j];
1252 }
1253 }
1254
1255
1256 if (f > 1) {
1258 &Data->K[f], &Data->K[f - 1], Forbidden_subspace,
1259 v, verbose_level - 1);
1260 }
1261 else {
1262 data_structures::int_matrix *Dummy_subspace;
1263
1264 Dummy_subspace = NEW_OBJECT(data_structures::int_matrix);
1265
1266 Dummy_subspace->allocate(k, 0);
1267
1269 &Data->K[f], Dummy_subspace, Forbidden_subspace, v,
1270 verbose_level - 1);
1271
1272
1273 FREE_OBJECT(Dummy_subspace);
1274 }
1275 FREE_OBJECT(Forbidden_subspace);
1276
1277 if (f_v) {
1278 cout << "chosing vector v=";
1279 Int_vec_print(cout, v, k);
1280 cout << endl;
1281 }
1282 for (c = 0; c < f; c++) {
1283 b0 = b;
1284 if (f_v) {
1285 cout << "c=" << c << " / " << f << " b0=" << b0 << endl;
1286 }
1287 for (g = 0; g < Data->d; g++) {
1288 if (f_v) {
1289 cout << "c=" << c << " / " << f << " b0=" << b0
1290 << "g=" << g << " / " << Data->d << endl;
1291 }
1292 for (i = 0; i < k; i++) {
1293 Basis[i * k + b] = v[i];
1294 }
1295 if (f_v) {
1296 cout << "Basis=" << endl;
1298 }
1299 b++;
1301 if (f_v) {
1302 cout << "forced vector w=";
1303 Int_vec_print(cout, w, k);
1304 cout << endl;
1305 }
1306 Int_vec_copy(w, v, k);
1307
1308 if (g == Data->d - 1) {
1309 for (ii = 0; ii < Data->d; ii++) {
1310 coeff = Data->poly_coeffs[ii];
1311 //coeff = F->negate(Data->poly_coeffs[ii]);
1312 // mistake corrected Dec 29, 2016
1314 Basis + b0 + ii, k, coeff, k);
1315 }
1316 }
1317
1318 } // next g
1319 } // next c
1320 if (f_v) {
1321 cout << "gl_classes::choose_basis_for_rational_normal_"
1322 "form_block Basis = " << endl;
1324 cout << endl;
1325 }
1326 } // next e
1327 } // next f
1328
1329 //FREE_int(v);
1330 //FREE_int(w);
1331
1332 if (f_v) {
1333 cout << "gl_classes::choose_basis_for_rational_normal_"
1334 "form_block done" << endl;
1335 }
1336}
1337
1338
1340 int *Mtx, gl_class_rep *R,
1341 int *Basis, int **&Gens, int &nb_gens, int &nb_alloc,
1342 int verbose_level)
1343{
1344 int f_v = (verbose_level >= 1);
1345 int f_vv = (verbose_level >= 2);
1346 int *M2;
1347 int *M3;
1348 int *Basis_inv;
1349 int *Mult;
1350 int *Select_partition;
1351 int i;
1352
1353
1354 if (f_v) {
1355 cout << "gl_classes::generators_for_centralizer "
1356 "k = " << k << " q = " << q << endl;
1357 cout << "verbose_level=" << verbose_level << endl;
1358 }
1359 if (f_vv) {
1360 cout << "gl_classes::generators_for_centralizer " << endl;
1362 }
1363
1364 M2 = NEW_int(k * k);
1365 M3 = NEW_int(k * k);
1366 Basis_inv = NEW_int(k * k);
1368 Select_partition = NEW_int(Table_of_polynomials->nb_irred);
1369
1370 {
1373
1374
1375
1376 U.create_object_by_rank(char_poly, 0, __FILE__, __LINE__, verbose_level);
1377
1378 U.characteristic_polynomial(Mtx, k, char_poly, verbose_level - 2);
1379
1380 if (f_vv) {
1381 cout << "gl_classes::generators_for_centralizer "
1382 "The characteristic polynomial is ";
1383 U.print_object(char_poly, cout);
1384 cout << endl;
1385 }
1386
1388 Mtx, M2, k, verbose_level);
1389 if (f_vv) {
1390 cout << "gl_classes::generators_for_centralizer "
1391 "After substitution, the matrix is " << endl;
1393 }
1394
1395
1396
1397 if (f_v) {
1398 cout << "gl_classes::generators_for_centralizer before factorize_polynomial" << endl;
1399 }
1400
1401 Table_of_polynomials->factorize_polynomial(char_poly, Mult, verbose_level);
1402
1403 if (f_v) {
1404 cout << "gl_classes::generators_for_centralizer after factorize_polynomial" << endl;
1405 }
1406
1407 if (f_v) {
1408 cout << "gl_classes::generators_for_centralizer factorization: ";
1410 cout << endl;
1411 }
1412
1413
1414 nb_gens = 0;
1415
1416 if (f_v) {
1417 cout << "gl_classes::generators_for_centralizer "
1418 "before centralizer_generators" << endl;
1419 }
1421 Mtx, char_poly, Mult, Select_partition,
1422 Basis, Gens, nb_gens, nb_alloc,
1423 verbose_level);
1424 if (f_v) {
1425 cout << "gl_classes::generators_for_centralizer "
1426 "after centralizer_generators" << endl;
1427 }
1428
1429
1430 if (f_v) {
1431 cout << "gl_classes::generators_for_centralizer "
1432 "we found " << nb_gens << " transformation matrices" << endl;
1433 }
1434 if (f_vv) {
1435 cout << "gl_classes::generators_for_centralizer "
1436 "we found " << nb_gens << " transformation matrices, "
1437 "they are" << endl;
1438 int i;
1439 for (i = 0; i < nb_gens; i++) {
1440 cout << "transformation matrix " << i << " / "
1441 << nb_gens << " is" << endl;
1443 }
1444 }
1445
1446 for (i = 0; i < nb_gens; i++) {
1447 F->Linear_algebra->matrix_inverse(Gens[i], Basis_inv, k,
1448 0 /* verbose_level */);
1449 F->Linear_algebra->mult_matrix_matrix(Basis, Basis_inv, M2, k, k, k,
1450 0 /* verbose_level */);
1451 Int_vec_copy(M2, Gens[i], k * k);
1452 }
1453
1454 if (f_vv) {
1455 cout << "gl_classes::generators_for_centralizer "
1456 "we found " << nb_gens << " generators" << endl;
1457 int i;
1458 for (i = 0; i < nb_gens; i++) {
1459 cout << "generator " << i << " / " << nb_gens << " is" << endl;
1461 }
1462 }
1463
1464
1466 Mult, Select_partition, verbose_level);
1467
1468
1469
1470 F->Linear_algebra->matrix_inverse(Basis, Basis_inv, k, 0 /* verbose_level */);
1471
1472 F->Linear_algebra->mult_matrix_matrix(Basis_inv, Mtx, M2, k, k, k,
1473 0 /* verbose_level */);
1474 F->Linear_algebra->mult_matrix_matrix(M2, Basis, M3, k, k, k,
1475 0 /* verbose_level */);
1476
1477 if (f_vv) {
1478 cout << "gl_classes::generators_for_centralizer "
1479 "B^-1 * A * B = " << endl;
1481 cout << endl;
1482 }
1483
1484
1485 U.delete_object(char_poly);
1486
1487 }
1488
1489 FREE_int(M2);
1490 FREE_int(M3);
1491 FREE_int(Basis_inv);
1492 FREE_int(Mult);
1493 FREE_int(Select_partition);
1494
1495 if (f_v) {
1496 cout << "gl_classes::generators_for_centralizer "
1497 "k = " << k << " q = " << q << " done" << endl;
1498 }
1499}
1500
1501
1502
1504 ring_theory::unipoly_object &poly, int *Mult, int *Select_partition,
1505 int *Basis, int **&Gens, int &nb_gens, int &nb_alloc,
1506 int verbose_level)
1507{
1508 int f_v = (verbose_level >= 1);
1509 //int f_vv = (verbose_level >= 2);
1510 int i, h, nb_irreds;
1511 int *Irreds;
1512
1513 if (f_v) {
1514 cout << "gl_classes::centralizer_generators "
1515 "k = " << k << " q = " << q << endl;
1516 }
1517
1520
1521 Irreds = NEW_int(nb_irreds);
1522
1523
1524 i = 0;
1525 for (h = Table_of_polynomials->nb_irred - 1; h >= 0; h--) {
1526
1527 if (Mult[h] == 0) {
1528 continue;
1529 }
1530 Irreds[i++] = h;
1531
1532 } // next h
1533
1534
1535 if (f_v) {
1536 cout << "gl_classes::centralizer_generators "
1537 "k = " << k << " q = " << q << " Irreds: ";
1538 Int_vec_print(cout, Irreds, nb_irreds);
1539 cout << endl;
1540 }
1541
1542
1543
1544
1545 matrix_block_data *Data;
1546
1547 Data = NEW_OBJECTS(matrix_block_data, nb_irreds);
1548
1549
1550 if (f_v) {
1551 cout << "gl_classes::centralizer_generators "
1552 "before compute_data_on_blocks" << endl;
1553 }
1554
1556 Mtx, Irreds, nb_irreds,
1557 Table_of_polynomials->Degree, Mult, Data,
1558 verbose_level);
1559
1560
1561 Int_vec_zero(Select_partition, nb_irreds);
1562 for (i = 0; i < nb_irreds; i++) {
1563 Select_partition[Irreds[i]] = Data[i].part_idx;
1564 }
1565
1566 if (f_v) {
1567 cout << "gl_classes::centralizer_generators "
1568 "before choose_basis_for_rational_normal_form" << endl;
1569 }
1570
1571
1572
1573
1575 Mtx, Data,
1576 nb_irreds, Basis,
1577 verbose_level);
1578
1579
1580 if (f_v) {
1581 cout << "gl_classes::centralizer_generators "
1582 "after choose_basis_for_rational_normal_form" << endl;
1583 }
1584
1585
1586
1587 nb_gens = 0;
1588
1589
1590 for (h = 0; h < nb_irreds; h++) {
1591 if (f_v) {
1592 cout << "gl_classes::centralizer_generators "
1593 "before centralizer_generators_block " << h
1594 << " / " << nb_irreds << endl;
1595 }
1596
1597 centralizer_generators_block(Mtx, Data, nb_irreds, h,
1598 Gens, nb_gens, nb_alloc,
1599 verbose_level);
1600
1601 } // next h
1602
1603
1604 FREE_OBJECTS(Data);
1605
1606 FREE_int(Irreds);
1607
1608 if (f_v) {
1609 cout << "gl_classes::centralizer_generators "
1610 "k = " << k << " q = " << q << " done, "
1611 "we found " << nb_gens << " generators" << endl;
1612 }
1613}
1614
1615
1617 matrix_block_data *Data, int nb_irreds, int h,
1618 int **&Gens, int &nb_gens, int &nb_alloc,
1619 int verbose_level)
1620{
1621 int f_v = (verbose_level >= 1);
1622 int f_vv = (verbose_level >= 2);
1623 int level1, level2, coset, i, af;
1624 int *Basis;
1625
1626 if (f_v) {
1627 cout << "gl_classes::centralizer_generators_block "
1628 "h = " << h << endl;
1629 }
1630
1631 Basis = NEW_int(k * k);
1632
1633
1634
1635 for (level1 = Data[h].height; level1 >= 1; level1--) {
1636 if (f_vv) {
1637 cout << "gl_classes::centralizer_generators_block "
1638 "h = " << h << " level1 = " << level1 << endl;
1639 }
1640
1641 af = Data[h].part[level1 - 1];
1642 for (level2 = 0; level2 < af; level2++) {
1643
1644 if (f_vv) {
1645 cout << "gl_classes::centralizer_generators_block "
1646 "h = " << h << " level1 = " << level1
1647 << " level2=" << level2 << " / " << af << endl;
1648 }
1649
1650 coset = 0;
1651 while (TRUE) {
1652
1653 Int_vec_zero(Basis, k * k);
1654
1655
1656
1657 int b = 0;
1658 for (i = 0; i < h; i++) {
1660 Mtx, Data + i,
1661 Basis, b,
1662 verbose_level - 2);
1663 }
1664
1665 if (f_vv) {
1666 cout << "gl_classes::centralizer_generators_block "
1667 "h = " << h << " level1 = " << level1
1668 << " level2 = " << level2
1669 << " coset = " << coset << endl;
1670 }
1671 if (b != Data[h].b0) {
1672 cout << "gl_classes::centralizer_generators_block "
1673 "b != Data[h].b0" << endl;
1674 exit(1);
1675 }
1677 level1, level2, coset,
1678 Mtx, Data + h, b, Basis,
1679 verbose_level - 2)) {
1680 break;
1681 }
1682
1683 if (b != Data[h].b1) {
1684 cout << "gl_classes::centralizer_generators_block "
1685 "b != Data[h].b1" << endl;
1686 exit(1);
1687 }
1688 for (i = h + 1; i < nb_irreds; i++) {
1690 Mtx, Data + i,
1691 Basis, b,
1692 verbose_level - 2);
1693 }
1694 if (b != k) {
1695 cout << "gl_classes::centralizer_generators_block "
1696 "b != k" << endl;
1697 exit(1);
1698 }
1699
1700 if (f_vv) {
1701 cout << "gl_classes::centralizer_generators_block "
1702 "h = " << h << " level1 = " << level1
1703 << " level2=" << level2 << " / " << af
1704 << " chosen matrix:" << endl;
1706 }
1707
1708
1709 if (nb_gens == nb_alloc) {
1710 int **Gens1;
1711 int nb_alloc_new = nb_alloc + 10;
1712
1713 Gens1 = NEW_pint(nb_alloc_new);
1714 for (i = 0; i < nb_alloc; i++) {
1715 Gens1[i] = Gens[i];
1716 }
1717 FREE_pint(Gens);
1718 Gens = Gens1;
1719 nb_alloc = nb_alloc_new;
1720 }
1721 Gens[nb_gens] = NEW_int(k * k);
1722 Int_vec_copy(Basis, Gens[nb_gens], k * k);
1723 nb_gens++;
1724
1725
1726 }
1727 }
1728 }
1729
1730
1731 FREE_int(Basis);
1732
1733 if (f_v) {
1734 cout << "gl_classes::centralizer_generators_block done" << endl;
1735 }
1736}
1737
1738
1739
1741 int level1, int level2, int &coset,
1742 int *Mtx, matrix_block_data *Data, int &b, int *Basis,
1743 int verbose_level)
1744{
1745 int f_v = (verbose_level >= 1);
1746 int f_vv = (verbose_level >= 2);
1747 int c, e, f, af, B0, b0, g, ii, coeff, i, j;
1748 int *v, *w;
1749 int ret = TRUE;
1750
1751
1752 if (f_v) {
1753 cout << "gl_classes::choose_basis_for_rational_normal_form_coset "
1754 "level1 = " << level1
1755 << " level2 = " << level2
1756 << " coset = " << coset << endl;
1757 }
1758
1759 B0 = b;
1760
1761 v = NEW_int(k);
1762 w = NEW_int(k);
1763
1764 for (f = Data->height; f >= 1; f--) {
1765 af = Data->part[f - 1];
1766 if (f_v) {
1767 cout << "f=" << f << " af=" << af << endl;
1768 }
1769 for (e = 0; e < af; e++) {
1770 if (f_vv) {
1771 cout << "f=" << f << " af=" << af << " e=" << e << endl;
1772 }
1773
1774 data_structures::int_matrix *Forbidden_subspace;
1775
1776 Forbidden_subspace = NEW_OBJECT(data_structures::int_matrix);
1777
1778 Forbidden_subspace->allocate(k, b - B0);
1779
1780 for (j = 0; j < b - B0; j++) {
1781 for (i = 0; i < k; i++) {
1782 Forbidden_subspace->s_ij(i, j) =
1783 Basis[i * k + B0 + j];
1784 }
1785 }
1786
1787
1788 if (f > 1) {
1789 if (f == level1 && e == level2) {
1791 coset, &Data->K[f], &Data->K[f - 1],
1792 Forbidden_subspace, v, verbose_level - 2)) {
1793 ret = FALSE;
1794 }
1795 }
1796 else {
1798 &Data->K[f], &Data->K[f - 1], Forbidden_subspace,
1799 v, verbose_level - 2);
1800 }
1801 }
1802 else {
1803 data_structures::int_matrix *Dummy_subspace;
1804
1805 Dummy_subspace = NEW_OBJECT(data_structures::int_matrix);
1806
1807 Dummy_subspace->allocate(k, 0);
1808
1809 if (f == level1 && e == level2) {
1810 //cout << "f = " << f << " == level, calling "
1811 // "choose_vector_in_here_but_not_in_here_or_here_column_spaces_coset" << endl;
1813 coset, &Data->K[f], Dummy_subspace,
1814 Forbidden_subspace, v,
1815 verbose_level - 2)) {
1816 ret = FALSE;
1817 }
1818 }
1819 else {
1821 &Data->K[f], Dummy_subspace, Forbidden_subspace, v,
1822 verbose_level - 2);
1823 }
1824
1825
1826 FREE_OBJECT(Dummy_subspace);
1827 }
1828 FREE_OBJECT(Forbidden_subspace);
1829
1830
1831 if (ret == FALSE) {
1832 if (f_v) {
1833 cout << "gl_classes::choose_basis_for_rational_normal_"
1834 "form_coset level1 = " << level1 << " level2 = "
1835 << level2 << " coset = " << coset
1836 << " could not choose vector, finished" << endl;
1837 }
1838 goto the_end;
1839 }
1840 if (f_vv) {
1841 cout << "chosing vector v=";
1842 Int_vec_print(cout, v, k);
1843 cout << endl;
1844 }
1845 for (c = 0; c < f; c++) {
1846 b0 = b;
1847 if (f_vv) {
1848 cout << "c=" << c << " b0=" << b0 << endl;
1849 }
1850 for (g = 0; g < Data->d; g++) {
1851 if (f_vv) {
1852 cout << "g=" << g << endl;
1853 }
1854 for (i = 0; i < k; i++) {
1855 Basis[i * k + b] = v[i];
1856 }
1857 b++;
1859 if (f_vv) {
1860 cout << "forced vector w=";
1861 Int_vec_print(cout, w, k);
1862 cout << endl;
1863 }
1864 Int_vec_copy(w, v, k);
1865
1866 if (g == Data->d - 1) {
1867 for (ii = 0; ii < Data->d; ii++) {
1868 coeff = F->negate(Data->poly_coeffs[ii]);
1870 Basis + b0 + ii, k, coeff, k);
1871 }
1872 }
1873
1874 } // next g
1875 } // next c
1876 if (f_vv) {
1877 cout << "gl_classes::choose_basis_for_rational_normal_"
1878 "form_coset Basis = " << endl;
1880 cout << endl;
1881 }
1882 } // next e
1883 } // next f
1884
1885the_end:
1886 FREE_int(v);
1887 FREE_int(w);
1888
1889 if (f_v) {
1890 cout << "gl_classes::choose_basis_for_rational_normal_"
1891 "form_coset done" << endl;
1892 }
1893 return ret;
1894}
1895
1896
1898 int nb_reps, gl_class_rep *R, int verbose_level)
1899{
1900 int f_v = (verbose_level >= 1);
1901 int m, i;
1903
1904 if (f_v) {
1905 cout << "gl_classes::find_class_rep" << endl;
1906 }
1907 m = R->type_coding->m;
1908 for (i = 0; i < nb_reps; i++) {
1909 if (Reps[i].type_coding->m != m) {
1910 continue;
1911 }
1912 if (Sorting.int_vec_compare(Reps[i].type_coding->M,
1913 R->type_coding->M, m * 3) == 0) {
1914 break;
1915 }
1916 }
1917 if (i == nb_reps) {
1918 //cout << "gl_classes::find_class_rep dould not "
1919 //"find representative" << endl;
1920 //exit(1);
1921 return -1;
1922 }
1923 if (f_v) {
1924 cout << "gl_classes::find_class_rep done" << endl;
1925 }
1926 return i;
1927}
1928
1929void gl_classes::report(ostream &ost, int verbose_level)
1930{
1931 int f_v = (verbose_level >= 1);
1932
1933 int nb_classes;
1934 gl_class_rep *R;
1935
1936 if (f_v) {
1937 cout << "gl_classes::report" << endl;
1938 }
1939 make_classes(R, nb_classes,
1940 FALSE /* f_no_eigenvalue_one */,
1941 verbose_level - 1);
1942
1943 int i;
1944
1945 ost << "\\section*{Conjugacy Classes of ${\\rm GL}(" << k << "," << q << ")$}" << endl;
1946
1947
1948 int *M;
1949 int f_elements_exponential = FALSE;
1950 string symbol_for_print;
1951
1952
1953 symbol_for_print.assign("\\alpha");
1954
1955 M = NEW_int(k * k);
1956
1957 ost << "The number of conjugacy classes of ${\\rm GL}(" << k << "," << q << ")$ is " << nb_classes << ":\\\\" << endl;
1958 ost << "$$" << endl;
1959 for (i = 0; i < nb_classes; i++) {
1960
1961
1962 make_matrix_from_class_rep(M, R + i, 0 /* verbose_level */);
1963
1964
1965 ost << "\\left[" << endl;
1966 F->latex_matrix(ost,
1967 f_elements_exponential, symbol_for_print, M, k, k);
1968 ost << "\\right]" << endl;
1969 if (i < nb_classes - 1) {
1970 ost << ", " << endl;
1971 }
1972 if ((i + 1) % 5 == 0) {
1973 ost << "$$" << endl;
1974 ost << "$$" << endl;
1975 }
1976
1977 }
1978 ost << "$$" << endl;
1979 ost << "\\bigskip" << endl;
1980
1981 FREE_int(M);
1982
1983
1984
1985 for (i = 0; i < nb_classes; i++) {
1986 ost << "Class " << i << " / "
1987 << nb_classes << "\\\\" << endl;
1989 }
1990 FREE_OBJECTS(R);
1991 if (f_v) {
1992 cout << "gl_classes::report done" << endl;
1993 }
1994}
1995
1997 ostream &ost, gl_class_rep *R)
1998{
1999 int *Mtx;
2000 ring_theory::longinteger_object go, co, cl, r, f, g;
2002 int *Select_polynomial, *Select_Partition;
2003 int i, a, m, p, b;
2004 int f_elements_exponential = FALSE;
2005 string symbol_for_print;
2007
2008 Mtx = NEW_int(k * k);
2009
2010 symbol_for_print.assign("\\alpha");
2011
2012
2013 Select_polynomial = NEW_int(Table_of_polynomials->nb_irred);
2014 Select_Partition = NEW_int(Table_of_polynomials->nb_irred);
2015 Int_vec_zero(Select_polynomial, Table_of_polynomials->nb_irred);
2016 Int_vec_zero(Select_Partition, Table_of_polynomials->nb_irred);
2017
2018 for (i = 0; i < R->type_coding->m; i++) {
2019 a = R->type_coding->s_ij(i, 0);
2020 m = R->type_coding->s_ij(i, 1);
2021 p = R->type_coding->s_ij(i, 2);
2022 Select_polynomial[a] = m;
2023 Select_Partition[a] = p;
2024 }
2025
2026
2027 go.create(1, __FILE__, __LINE__);
2028 a = NT.i_power_j(q, k);
2029 for (i = 0; i < k; i++) {
2030 b = a - NT.i_power_j(q, i);
2031 f.create(b, __FILE__, __LINE__);
2032 D.mult(go, f, g);
2033 g.assign_to(go);
2034 }
2035
2036
2037
2038 make_matrix_from_class_rep(Mtx, R, 0 /* verbose_level */);
2039
2040 centralizer_order_Kung(Select_polynomial,
2041 Select_Partition, co, 0 /*verbose_level - 2*/);
2042
2043 D.integral_division(go, co, cl, r, 0 /* verbose_level */);
2044
2045
2046 ost << "$";
2047 for (i = 0; i < R->type_coding->m; i++) {
2048 a = R->type_coding->s_ij(i, 0);
2049 m = R->type_coding->s_ij(i, 1);
2050 p = R->type_coding->s_ij(i, 2);
2051 ost << a << "," << m << "," << p;
2052 if (i < R->type_coding->m - 1) {
2053 ost << ";";
2054 }
2055 }
2056 ost << "$" << endl;
2057 ost << "$$" << endl;
2058 ost << "\\left[" << endl;
2059 F->latex_matrix(ost,
2060 f_elements_exponential, symbol_for_print, Mtx, k, k);
2061 ost << "\\right]";
2062 //ost << "_{";
2063 //ost << co << "}" << endl;
2064 ost << "$$" << endl;
2065
2066 ost << "centralizer order $" << co << "$\\\\";
2067 ost << "class size $" << cl << "$\\\\" << endl;
2068 //ost << endl;
2069
2070 FREE_int(Select_polynomial);
2071 FREE_int(Select_Partition);
2072 FREE_int(Mtx);
2073}
2074
2075
2076
2077}}}
2078
2079
2080
conjugacy class in GL(n,q) described using rational normal form
Definition: algebra.h:260
data_structures::int_matrix * type_coding
Definition: algebra.h:262
void init(int nb_irred, int *Select_polynomial, int *Select_partition, int verbose_level)
ring_theory::longinteger_object * class_length
Definition: algebra.h:264
ring_theory::longinteger_object * centralizer_order
Definition: algebra.h:263
void generators_for_centralizer(int *Mtx, gl_class_rep *R, int *Basis, int **&Gens, int &nb_gens, int &nb_alloc, int verbose_level)
void centralizer_generators(int *Mtx, ring_theory::unipoly_object &poly, int *Mult, int *Select_partition, int *Basis, int **&Gens, int &nb_gens, int &nb_alloc, int verbose_level)
void make_matrix_in_rational_normal_form(int *Mtx, int *Select, int *Select_Partition, int verbose_level)
Definition: gl_classes.cpp:244
void print_matrix_and_centralizer_order_latex(std::ostream &ost, gl_class_rep *R)
void centralizer_order_Kung_basic(int nb_irreds, int *poly_degree, int *poly_mult, int *partition_idx, ring_theory::longinteger_object &co, int verbose_level)
Definition: gl_classes.cpp:346
void compute_generalized_kernels(matrix_block_data *Data, int *M2, int d, int b0, int m, int *poly_coeffs, int verbose_level)
void choose_basis_for_rational_normal_form(int *Mtx, matrix_block_data *Data, int nb_irreds, int *Basis, int verbose_level)
void centralizer_generators_block(int *Mtx, matrix_block_data *Data, int nb_irreds, int h, int **&Gens, int &nb_gens, int &nb_alloc, int verbose_level)
void compute_generalized_kernels_for_each_block(int *Mtx, int *Irreds, int nb_irreds, int *Degree, int *Mult, matrix_block_data *Data, int verbose_level)
Definition: gl_classes.cpp:940
int first(int *Select, int *Select_partition, int verbose_level)
Definition: gl_classes.cpp:157
void init(int k, field_theory::finite_field *F, int verbose_level)
Definition: gl_classes.cpp:67
int choose_basis_for_rational_normal_form_coset(int level1, int level2, int &coset, int *Mtx, matrix_block_data *Data, int &b, int *Basis, int verbose_level)
void centralizer_order_Kung(int *Select_polynomial, int *Select_partition, ring_theory::longinteger_object &co, int verbose_level)
Definition: gl_classes.cpp:414
void make_classes(gl_class_rep *&R, int &nb_classes, int f_no_eigenvalue_one, int verbose_level)
Definition: gl_classes.cpp:471
int next(int *Select, int *Select_partition, int verbose_level)
Definition: gl_classes.cpp:181
void choose_basis_for_rational_normal_form_block(int *Mtx, matrix_block_data *Data, int *Basis, int &b, int verbose_level)
void report(std::ostream &ost, int verbose_level)
ring_theory::table_of_irreducible_polynomials * Table_of_polynomials
Definition: algebra.h:460
void make_matrix_from_class_rep(int *Mtx, gl_class_rep *R, int verbose_level)
Definition: gl_classes.cpp:205
int select_partition_first(int *Select, int *Select_partition, int verbose_level)
Definition: gl_classes.cpp:123
void identify2(int *Mtx, ring_theory::unipoly_object &poly, int *Mult, int *Select_partition, int *Basis, int verbose_level)
Definition: gl_classes.cpp:832
int find_class_rep(gl_class_rep *Reps, int nb_reps, gl_class_rep *R, int verbose_level)
void identify_matrix(int *Mtx, gl_class_rep *R, int *Basis, int verbose_level)
Definition: gl_classes.cpp:704
int select_partition_next(int *Select, int *Select_partition, int verbose_level)
Definition: gl_classes.cpp:135
int identify_partition(int *part, int m, int verbose_level)
rational normal form of a matrix in GL(n,q) for gl_class_rep
Definition: algebra.h:583
void partition_dual(int *part, int *dual_part, int n, int verbose_level)
void make_all_partitions_of_n(int n, int *&Table, int &nb, int verbose_level)
a collection of functions related to sorted vectors
void latex_matrix(std::ostream &f, int f_elements_exponential, std::string &symbol_for_print, int *M, int m, int n)
void vector_add_apply_with_stride(int *v, int *w, int stride, int c, int n)
int choose_vector_in_here_but_not_in_here_or_here_column_spaces_coset(int &coset, data_structures::int_matrix *V, data_structures::int_matrix *W1, data_structures::int_matrix *W2, int *v, int verbose_level)
void mult_matrix_matrix(int *A, int *B, int *C, int m, int n, int o, int verbose_level)
void choose_vector_in_here_but_not_in_here_or_here_column_spaces(data_structures::int_matrix *V, data_structures::int_matrix *W1, data_structures::int_matrix *W2, int *v, int verbose_level)
void mult_vector_from_the_right(int *A, int *v, int *Av, int m, int n)
int Gauss_simple(int *A, int m, int n, int *base_cols, int verbose_level)
void matrix_inverse(int *A, int *Ainv, int n, int verbose_level)
void matrix_get_kernel_as_int_matrix(int *M, int m, int n, int *base_cols, int nb_base_cols, data_structures::int_matrix *kernel, int verbose_level)
domain to compute with objects of type longinteger
Definition: ring_theory.h:240
void add(longinteger_object &a, longinteger_object &b, longinteger_object &c)
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)
a class to represent arbitrary precision integers
Definition: ring_theory.h:366
void create(long int i, const char *file, int line)
a table of all irreducible polynomials over GF(q) of degree less than a certain value
Definition: ring_theory.h:659
void factorize_polynomial(unipoly_object &char_poly, int *Mult, int verbose_level)
domain of polynomials in one variable over a finite field
Definition: ring_theory.h:691
void create_object_of_degree_with_coefficients(unipoly_object &p, int d, int *coeff)
void substitute_matrix_in_polynomial(unipoly_object &p, int *Mtx_in, int *Mtx_out, int k, int verbose_level)
void create_object_by_rank(unipoly_object &p, long int rk, const char *file, int line, int verbose_level)
void characteristic_polynomial(int *Mtx, int k, unipoly_object &char_poly, int verbose_level)
void print_object(unipoly_object p, std::ostream &ost)
#define FREE_OBJECTS(p)
Definition: foundations.h:652
#define FREE_int(p)
Definition: foundations.h:640
#define Int_vec_zero(A, B)
Definition: foundations.h:713
#define NEW_pint(n)
Definition: foundations.h:627
#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 Int_vec_copy(A, B, C)
Definition: foundations.h:693
#define FREE_pint(p)
Definition: foundations.h:641
#define Int_vec_print(A, B, C)
Definition: foundations.h:685
orbiter_kernel_system::orbiter_session * Orbiter
global Orbiter session
the orbiter library for the classification of combinatorial objects