Orbiter 2022
Combinatorial Objects
group_generators_domain.cpp
Go to the documentation of this file.
1// group_generators_domain.cpp
2//
3// Anton Betten
4//
5// moved here from projective.cpp: September 4, 2016
6
7
8
9
10#include "foundations.h"
11
12
13using namespace std;
14
15
16namespace orbiter {
17namespace layer1_foundations {
18namespace algebra {
19
20
21
23{
24
25}
26
28{
29
30}
31
32
34 int &nb_perms, int *&perms, int verbose_level)
35{
36 int f_v = (verbose_level >= 1);
37 int f_vv = (verbose_level >= 2);
38 int i;
40
41 if (f_v) {
42 cout << "group_generators_domain::generators_symmetric_group" << endl;
43 }
44 if (deg <= 1) {
45 nb_perms = 0;
46 perms = NULL;
47 return;
48 }
49 nb_perms = deg - 1;
50 perms = NEW_int(nb_perms * deg);
51 for (i = 0; i < nb_perms; i++) {
52 Combi.perm_identity(perms + i * deg, deg);
53 perms[i * deg + i] = i + 1;
54 perms[i * deg + i + 1] = i;
55 }
56 if (f_v) {
57 cout << "group_generators_domain::generators_symmetric_group generators are:" << endl;
58 }
59 if (f_vv) {
60 for (i = 0; i < nb_perms; i++) {
61 Combi.perm_print(cout, perms + i * deg, deg);
62 cout << endl;
63 }
64 }
65 if (f_v) {
66 cout << "group_generators_domain::generators_symmetric_group done" << endl;
67 }
68}
69
71 int &nb_perms, int *&perms, int verbose_level)
72{
73 int f_v = (verbose_level >= 1);
74 int f_vv = (verbose_level >= 2);
75 int i = 0, j;
77
78 if (f_v) {
79 cout << "group_generators_domain::generators_cyclic_group" << endl;
80 }
81 if (deg <= 1) {
82 nb_perms = 0;
83 perms = NULL;
84 return;
85 }
86 nb_perms = 1;
87 perms = NEW_int(nb_perms * deg);
88 for (j = 0; j < deg; j++) {
89 perms[i * deg + j] = j + 1;
90 }
91 perms[i * deg + i + deg - 1] = 0;
92 if (f_v) {
93 cout << "group_generators_domain::generators_cyclic_group generators are:" << endl;
94 }
95 if (f_vv) {
96 for (i = 0; i < nb_perms; i++) {
97 Combi.perm_print(cout, perms + i * deg, deg);
98 cout << endl;
99 }
100 }
101 if (f_v) {
102 cout << "group_generators_domain::generators_cyclic_group done" << endl;
103 }
104}
105
107 int &nb_perms, int *&perms, int verbose_level)
108{
109 int f_v = (verbose_level >= 1);
110 int f_vv = (verbose_level >= 2);
111 int i = 0, j, d2;
113
114 if (f_v) {
115 cout << "group_generators_domain::generators_dihedral_group" << endl;
116 }
117 if (deg <= 1) {
118 nb_perms = 0;
119 perms = NULL;
120 return;
121 }
122 d2 = deg >> 1;
123 nb_perms = 2;
124 perms = NEW_int(nb_perms * deg);
125 for (j = 0; j < deg; j++) {
126 perms[i * deg + j] = j + 1;
127 }
128 perms[i * deg + i + deg - 1] = 0;
129 i++;
130 for (j = 0; j <= d2; j++) {
131 perms[i * deg + j] = deg - 1 - j;
132 perms[i * deg + deg - 1 - j] = j;
133 }
134 if (f_v) {
135 cout << "group_generators_domain::generators_dihedral_group "
136 "generators for dihedral group of degree "
137 << deg << " created" << endl;
138 }
139 if (f_vv) {
140 for (i = 0; i < nb_perms; i++) {
141 Combi.perm_print(cout, perms + i * deg, deg);
142 cout << endl;
143 }
144 }
145 if (f_v) {
146 cout << "group_generators_domain::generators_dihedral_group one" << endl;
147 }
148}
149
151 int &nb_perms, int *&perms, int verbose_level)
152{
153 int f_v = (verbose_level >= 1);
154 int f_vv = (verbose_level >= 2);
155 int i = 0, j, d2;
157
158 if (f_v) {
159 cout << "group_generators_domain::generators_dihedral_involution" << endl;
160 }
161 if (deg <= 1) {
162 nb_perms = 0;
163 perms = NULL;
164 return;
165 }
166 d2 = deg >> 1;
167 nb_perms = 1;
168 perms = NEW_int(nb_perms * deg);
169 i = 0;
170 for (j = 0; j <= d2; j++) {
171 perms[i * deg + j] = deg - 1 - j;
172 perms[i * deg + deg - 1 - j] = j;
173 }
174 if (f_v) {
175 cout << "group_generators_domain::generators_dihedral_involution "
176 "generators for dihedral involution of degree "
177 << deg << " created" << endl;
178 }
179 if (f_vv) {
180 for (i = 0; i < nb_perms; i++) {
181 Combi.perm_print(cout, perms + i * deg, deg);
182 cout << endl;
183 }
184 }
185 if (f_v) {
186 cout << "group_generators_domain::generators_dihedral_involution done" << endl;
187 }
188}
189
191 int &nb_perms, int *&perms, int verbose_level)
192{
193 int f_v = (verbose_level >= 1);
194 int f_vv = (verbose_level >= 2);
195 int i = 0, j;
197
198 if (f_v) {
199 cout << "group_generators_domain::generators_identity_group" << endl;
200 }
201 if (deg <= 1) {
202 nb_perms = 0;
203 perms = NULL;
204 return;
205 }
206 nb_perms = 1;
207 perms = NEW_int(nb_perms * deg);
208 for (j = 0; j < deg; j++) {
209 perms[j] = j;
210 }
211 if (f_v) {
212 cout << "group_generators_domain::generators_identity_group "
213 "generators for identity group of degree "
214 << deg << " created" << endl;
215 }
216 if (f_vv) {
217 for (i = 0; i < nb_perms; i++) {
218 Combi.perm_print(cout, perms + i * deg, deg);
219 cout << endl;
220 }
221 }
222 if (f_v) {
223 cout << "group_generators_domain::generators_identity_group done" << endl;
224 }
225}
226
228 int nb_pairs,
229 int &nb_perms, int *&perms, int &degree,
230 int verbose_level)
231{
232 int f_v = (verbose_level >= 1);
233 int f_vv = (verbose_level >= 2);
234 int i;
236
237 if (f_v) {
238 cout << "group_generators_domain::generators_Hall_reflection" << endl;
239 }
240 degree = nb_pairs * 2;
241 nb_perms = 1;
242 perms = NEW_int(nb_perms * degree);
243 Combi.perm_identity(perms, degree);
244 for (i = 0; i < nb_pairs; i++) {
245 perms[2 * i] = 2 * i + 1;
246 perms[2 * i + 1] = 2 * i;
247 }
248 if (f_v) {
249 cout << "group_generators_domain::generators_Hall_reflection "
250 "generators for the Hall reflection group "
251 "of degree "
252 << degree << " created" << endl;
253 }
254 if (f_vv) {
255 for (i = 0; i < 1; i++) {
256 Combi.perm_print(cout, perms + i * degree, degree);
257 cout << endl;
258 }
259 }
260 if (f_v) {
261 cout << "group_generators_domain::generators_Hall_reflection done" << endl;
262 }
263}
264
266 int nb_pairs,
267 int &nb_perms, int *&perms, int &degree,
268 int verbose_level)
269{
270 int f_v = (verbose_level >= 1);
271 int f_vv = (verbose_level >= 2);
272 int i, h;
274
275 if (f_v) {
276 cout << "group_generators_domain::generators_Hall_reflection_normalizer_group" << endl;
277 }
278 degree = nb_pairs * 2;
279 nb_perms = nb_pairs + (nb_pairs - 1);
280 perms = NEW_int(nb_perms * degree);
281 h = 0;
282 for (i = 0; i < nb_pairs; i++, h++) {
283 Combi.perm_identity(perms + h * degree, degree);
284 perms[h * degree + 2 * i] = 2 * i + 1;
285 perms[h * degree + 2 * i + 1] = 2 * i;
286 }
287 for (i = 0; i < nb_pairs - 1; i++, h++) {
288 Combi.perm_identity(perms + h * degree, degree);
289 perms[h * degree + 2 * i] = 2 * (i + 1);
290 perms[h * degree + 2 * i + 1] = 2 * (i + 1) + 1;
291 perms[h * degree + 2 * (i + 1)] = 2 * i;
292 perms[h * degree + 2 * (i + 1) + 1] = 2 * i + 1;
293 }
294 if (h != nb_perms) {
295 cout << "group_generators_domain::generators_Hall_reflection_normalizer_group "
296 "h != nb_perms" << endl;
297 exit(1);
298 }
299 if (f_v) {
300 cout << "group_generators_domain::generators_Hall_reflection_normalizer_group "
301 "generators for normalizer of the Hall reflection group "
302 "of degree "
303 << degree << " created" << endl;
304 }
305 if (f_vv) {
306 for (i = 0; i < nb_perms; i++) {
307 Combi.perm_print(cout, perms + i * degree, degree);
308 cout << endl;
309 }
310 }
311 if (f_v) {
312 cout << "group_generators_domain::generators_Hall_reflection_normalizer_group done" << endl;
313 }
314}
315
317 int nb_pairs,
318 int *&factors, int &nb_factors)
319{
320 int i, j, nb_perms;
321 int f_v = FALSE;
322
323 if (f_v) {
324 cout << "group_generators_domain::order_Hall_reflection_normalizer_factorized" << endl;
325 }
326 nb_perms = nb_pairs + nb_pairs - 1;
327 nb_factors = nb_perms;
328 factors = NEW_int(nb_perms);
329 j = 0;
330 for (i = 0; i < nb_pairs; i++, j++) {
331 factors[j] = 2;
332 }
333 for (i = 0; i < nb_pairs - 1; i++, j++) {
334 factors[j] = nb_pairs - i;
335 }
336 if (j != nb_factors) {
337 cout << "group_generators_domain:order_Hall_reflection_normalizer_factorized "
338 "j != nb_perms" << endl;
339 exit(1);
340 }
341}
342
344 int n, int *&factors, int &nb_factors)
345{
346 int i, j;
347
348 nb_factors = n + n - 1;
349 factors = NEW_int(nb_factors);
350 j = 0;
351 for (i = 0; i < n - 1; i++, j++) {
352 factors[j] = n - i;
353 }
354 for (i = 0; i < n; i++, j++) {
355 factors[j] = 2;
356 }
357 if (j != nb_factors) {
358 cout << "group_generators_domain::order_Bn_group_factorized "
359 "j != nb_factors" << endl;
360 exit(1);
361 }
362}
363
365 int n, int &deg, int &nb_perms, int *&perms,
366 int verbose_level)
367{
368 int f_v = (verbose_level >= 1);
369 int f_vv = (verbose_level >= 2);
370 int i, j;
372
373 if (f_v) {
374 cout << "group_generators_domain::generators_Bn_group" << endl;
375 }
376 deg = 2 * n;
377 nb_perms = n - 1 + n;
378 perms = NEW_int(nb_perms * deg);
379 j = 0;
380 for (i = 0; i < n - 1; i++, j++) {
381 Combi.perm_identity(perms + j * deg, deg);
382 perms[j * deg + 2 * i] = 2 * (i + 1);
383 perms[j * deg + 2 * i + 1] = 2 * (i + 1) + 1;
384 perms[j * deg + 2 * (i + 1)] = 2 * i;
385 perms[j * deg + 2 * (i + 1) + 1] = 2 * i + 1;
386 }
387 for (i = 0; i < n; i++, j++) {
388 Combi.perm_identity(perms + j * deg, deg);
389 perms[j * deg + 2 * i] = 2 * i + 1;
390 perms[j * deg + 2 * i + 1] = 2 * i;
391 }
392 if (f_v) {
393 cout << "generators for Bn group of order n = " << n
394 << " and degree " << deg << " created" << endl;
395 }
396 if (j != nb_perms) {
397 cout << "generators_Bn_group j != nb_perms" << endl;
398 exit(1);
399 }
400 if (f_vv) {
401 for (i = 0; i < nb_perms; i++) {
402 Combi.perm_print(cout, perms + i * deg, deg);
403 cout << endl;
404 }
405 }
406 if (f_v) {
407 cout << "group_generators_domain::generators_Bn_group done" << endl;
408 }
409}
410
412 int deg1, int nb_perms1, int *perms1,
413 int deg2, int nb_perms2, int *perms2,
414 int &deg3, int &nb_perms3, int *&perms3,
415 int verbose_level)
416{
417 int f_v = (verbose_level >= 1);
418 int f_vv = (verbose_level >= 2);
419 int i, k = 0;
420 int *id1, *id2;
422
423 if (f_v) {
424 cout << "group_generators_domain::generators_direct_product" << endl;
425 }
426 deg3 = deg1 * deg2;
427 nb_perms3 = nb_perms1 + nb_perms2;
428 perms3 = NEW_int(nb_perms3 * deg3);
429 id1 = NEW_int(deg1);
430 id2 = NEW_int(deg2);
431 Combi.perm_identity(id1, deg1);
432 Combi.perm_identity(id2, deg2);
433
434 for (i = 0; i < nb_perms1; i++) {
435 Combi.perm_direct_product(deg1, deg2,
436 perms1 + i * deg1, id2, perms3 + k * deg3);
437 k++;
438 }
439 for (i = 0; i < nb_perms2; i++) {
440 Combi.perm_direct_product(deg1, deg2, id1,
441 perms2 + i * deg2, perms3 + k * deg3);
442 k++;
443 }
444 FREE_int(id1);
445 FREE_int(id2);
446 if (f_vv) {
447 for (i = 0; i < nb_perms3; i++) {
448 Combi.perm_print(cout, perms3 + i * deg3, deg3);
449 cout << endl;
450 }
451 }
452 if (f_v) {
453 cout << "group_generators_domain::generators_direct_product done" << endl;
454 }
455}
456
458 int deg1, int nb_perms1, int *perms1,
459 int deg2, int nb_perms2, int *perms2,
460 int &deg3, int &nb_perms3, int *&perms3,
461 int verbose_level)
462{
463 int f_v = (verbose_level >= 1);
464 int f_vv = (verbose_level >= 2);
465 int i, k = 0;
467
468 if (f_v) {
469 cout << "group_generators_domain::generators_concatenate" << endl;
470 }
471 if (deg1 != deg2) {
472 cout << "group_generators_domain::generators_concatenate"
473 " deg1 != deg2" << endl;
474 exit(1);
475 }
476 deg3 = deg1;
477 nb_perms3 = nb_perms1 + nb_perms2;
478 perms3 = NEW_int(nb_perms3 * deg3);
479
480 k = 0;
481 for (i = 0; i < nb_perms1; i++) {
482 Combi.perm_move(perms1 + i * deg1, perms3 + k * deg3, deg3);
483 k++;
484 }
485 for (i = 0; i < nb_perms2; i++) {
486 Combi.perm_move(perms2 + i * deg1, perms3 + k * deg3, deg3);
487 k++;
488 }
489 if (f_v) {
490 cout << "generators concatenated" << endl;
491 }
492 if (f_vv) {
493 for (i = 0; i < nb_perms3; i++) {
494 Combi.perm_print(cout, perms3 + i * deg3, deg3);
495 cout << endl;
496 }
497 }
498 if (f_v) {
499 cout << "group_generators_domain::generators_concatenate done" << endl;
500 }
501}
502
503
505 int n, int q,
506 int f_semilinear, int verbose_level)
507{
508 int f_v = (verbose_level >= 1);
509 int base_len;
510
511 if (f_v) {
512 cout << "group_generators_domain::matrix_group_base_len_projective_group" << endl;
513 }
514 base_len = n;
515 if (q > 2) {
516 base_len++;
517 }
518 if (f_semilinear) {
519 base_len++;
520 }
521 if (f_v) {
522 cout << "group_generators_domain::matrix_group_base_len_projective_group: "
523 "n=" << n << " q=" << q
524 << " f_semilinear=" << f_semilinear
525 << " base_len = " << base_len << endl;
526 }
527 if (f_v) {
528 cout << "group_generators_domain::matrix_group_base_len_projective_group done" << endl;
529 }
530 return base_len;
531}
532
534 int n, int q,
535 int f_semilinear, int verbose_level)
536{
537 int f_v = (verbose_level >= 1);
538 int base_len;
539
540 base_len = 1; // the point 0 takes care of killing the translations
541 base_len += n;
542 if (f_semilinear) {
543 base_len++;
544 }
545 if (f_v) {
546 cout << "group_generators_domain::matrix_group_base_len_affine_group: "
547 "n=" << n << " q=" << q
548 << " f_semilinear=" << f_semilinear
549 << " base_len = " << base_len << endl;
550 }
551 return base_len;
552}
553
555 int n, int q,
556 int f_semilinear, int verbose_level)
557{
558 int f_v = (verbose_level >= 1);
559 int base_len;
560
561 base_len = 0; // no need to kill translations
562 base_len += n;
563 if (f_semilinear) {
564 base_len++;
565 }
566 if (f_v) {
567 cout << "group_generators_domain::matrix_group_base_len_general_linear_group: "
568 "n=" << n << " q=" << q
569 << " f_semilinear=" << f_semilinear
570 << " base_len = " << base_len << endl;
571 }
572 return base_len;
573}
574
576 int epsilon, int k, int q,
577 ring_theory::longinteger_object &go, int verbose_level)
578// k is projective dimension
579{
580 int f_v = (verbose_level >= 1);
581 int w, m;
583
584 if (f_v) {
585 cout << "group_generators_domain::order_POmega_epsilon" << endl;
586 }
587 w = Gg.Witt_index(epsilon, k);
588 if (epsilon == -1) {
589 m = w + 1;
590 }
591 else {
592 m = w;
593 }
594 order_Pomega(epsilon, m, q, go, verbose_level);
595 if (f_v) {
596 cout << "group_generators_domain::order_POmega_epsilon "
597 "done epsilon=" << epsilon
598 << " k=" << k << " q=" << q << " order=" << go << endl;
599 }
600
601#if 0
602 int f_v = (verbose_level >= 1);
603 int n;
604
605 n = Witt_index(epsilon, k);
606 if (f_v) {
607 cout << "Witt index is " << n << endl;
608 }
609 if (epsilon == 0) {
610 order_Pomega(0, n, q, go, verbose_level);
611 }
612 else if (epsilon == 1) {
613 order_Pomega_plusminus(1, n, q, go, verbose_level);
614 }
615 else if (epsilon == -1) {
616 order_Pomega_plusminus(-1, n, q, go, verbose_level);
617 }
618#endif
619}
620
621
623 int f_semilinear,
624 int epsilon, int k, int q,
625 ring_theory::longinteger_object &go, int verbose_level)
626// k is projective dimension
627{
628 int f_v = (verbose_level >= 1);
629 int m;
632
633 if (f_v) {
634 cout << "group_generators_domain::order_PO_epsilon" << endl;
635 }
636 m = Gg.Witt_index(epsilon, k);
637 if (f_v) {
638 cout << "Witt index = " << m << endl;
639 }
640 order_PO(epsilon, m, q, go, verbose_level);
641 if (f_semilinear) {
642 int p, e;
644
645 NT.factor_prime_power(q, p, e);
646 D.mult_integer_in_place(go, e);
647 }
648 if (f_v) {
649 cout << "order_Pgroup_generators_domain::order_PO_epsilon done "
650 "f_semilinear=" << f_semilinear
651 << " epsilon=" << epsilon << " k=" << k
652 << " q=" << q << " order=" << go << endl;
653 }
654}
655
657 int epsilon, int m, int q,
658 ring_theory::longinteger_object &o, int verbose_level)
659{
660 int f_v = (verbose_level >= 1);
661
662 if (f_v) {
663 cout << "group_generators_domain::order_PO epsilon = " << epsilon
664 << " m=" << m << " q=" << q << endl;
665 }
666
667 if (epsilon == 0) {
668 order_PO_parabolic(m, q, o, verbose_level);
669 }
670 else if (epsilon == 1) {
671 order_PO_plus(m, q, o, verbose_level);
672 }
673 else if (epsilon == -1) {
674 order_PO_minus(m, q, o, verbose_level);
675 }
676 else {
677 cout << "group_generators_domain::order_PO fatal: epsilon = " << epsilon << endl;
678 exit(1);
679 }
680}
681
683 int epsilon, int m, int q,
684 ring_theory::longinteger_object &o, int verbose_level)
685{
686 if (epsilon == 0) {
687 order_Pomega_parabolic(m, q, o, verbose_level);
688 }
689 else if (epsilon == 1) {
690 order_Pomega_plus(m, q, o, verbose_level);
691 }
692 else if (epsilon == -1) {
693 order_Pomega_minus(m, q, o, verbose_level);
694 }
695 else {
696 cout << "group_generators_domain::order_Pomega "
697 "fatal: epsilon = " << epsilon << endl;
698 exit(1);
699 }
700}
701
703 int m, int q,
704 ring_theory::longinteger_object &o, int verbose_level)
705// m = Witt index, the dimension is n = 2m
706{
707 int f_v = (verbose_level >= 1);
709 ring_theory::longinteger_object O, Q, R, S, T, Two, minusone;
710 int i;
712
713
714 Two.create(2, __FILE__, __LINE__);
715 minusone.create(-1, __FILE__, __LINE__);
716 Q.create(q, __FILE__, __LINE__);
717 D.power_int(Q, m * (m - 1));
718 if (f_v) {
719 cout << "group_generators_domain::order_PO_plus " << q << "^(" << m << "*"
720 << m - 1 << ") = " << Q << endl;
721 }
722 // now Q = q^{m(m-1)}
723
724 O.create(1, __FILE__, __LINE__);
725 for (i = 1; i <= m - 1; i++) {
726 R.create(q, __FILE__, __LINE__);
727 D.power_int(R, 2 * i);
728 D.add(R, minusone, S);
729 if (f_v) {
730 cout << "group_generators_domain::order_PO_plus " << q << "^"
731 << 2 * i << " - 1 = " << S << endl;
732 }
733 D.mult(O, S, T);
734 T.assign_to(O);
735 }
736 // now O = \prod_{i=1}^{m-1} (q^{2i}-1)
737
738 R.create(q, __FILE__, __LINE__);
739 D.power_int(R, m);
740 D.add(R, minusone, S);
741 if (f_v) {
742 cout << "group_generators_domain::order_PO_plus " << q << "^" << m << " - 1 = " << S << endl;
743 }
744 // now S = q^m-1
745
746 D.mult(O, S, T);
747 T.assign_to(O);
748
749 D.mult(O, Q, T);
750 if (TRUE /*EVEN(q)*/) {
751 D.mult(T, Two, o);
752 }
753 else {
754 T.assign_to(o);
755 }
756
757
758 if (f_v) {
759 cout << "group_generators_domain::order_PO_plus the order of PO" << "("
760 << Gg.dimension_given_Witt_index(1, m) << ","
761 << q << ") is " << o << endl;
762 }
763}
764
766 int m, int q,
767 ring_theory::longinteger_object &o, int verbose_level)
768// m = Witt index, the dimension is n = 2m+2
769{
770 int f_v = (verbose_level >= 1);
772 ring_theory::longinteger_object O, Q, R, S, T, Two, plusone, minusone;
773 int i;
775
776
777 Two.create(2, __FILE__, __LINE__);
778 plusone.create(1, __FILE__, __LINE__);
779 minusone.create(-1, __FILE__, __LINE__);
780 Q.create(q, __FILE__, __LINE__);
781 D.power_int(Q, m * (m + 1));
782 if (f_v) {
783 cout << "group_generators_domain::order_PO_minus " << q << "^(" << m << "*"
784 << m + 1 << ") = " << Q << endl;
785 }
786 // now Q = q^{m(m+1)}
787
788 O.create(1, __FILE__, __LINE__);
789 for (i = 1; i <= m; i++) {
790 R.create(q, __FILE__, __LINE__);
791 D.power_int(R, 2 * i);
792 D.add(R, minusone, S);
793 if (f_v) {
794 cout << "group_generators_domain::order_PO_minus " << q << "^" << 2 * i
795 << " - 1 = " << S << endl;
796 }
797 D.mult(O, S, T);
798 T.assign_to(O);
799 }
800 // now O = \prod_{i=1}^{m} (q^{2i}-1)
801
802 R.create(q, __FILE__, __LINE__);
803 D.power_int(R, m + 1);
804 D.add(R, plusone, S);
805 if (f_v) {
806 cout << "group_generators_domain::order_PO_minus " << q << "^" << m + 1
807 << " + 1 = " << S << endl;
808 }
809 // now S = q^{m+1}-1
810
811 D.mult(O, S, T);
812 T.assign_to(O);
813
814 D.mult(O, Q, T);
815 if (EVEN(q)) {
816 D.mult(T, Two, o);
817 }
818 else {
819 T.assign_to(o);
820 }
821
822
823 if (f_v) {
824 cout << "group_generators_domain::order_PO_minus the order of PO^-" << "("
825 << Gg.dimension_given_Witt_index(-1, m) << ","
826 << q << ") is " << o << endl;
827 }
828}
829
831 int m, int q,
832 ring_theory::longinteger_object &o, int verbose_level)
833// m = Witt index, the dimension is n = 2m+1
834{
835 int f_v = (verbose_level >= 1);
837 ring_theory::longinteger_object O, Q, R, S, T, minusone;
838 int i;
840
841
842 minusone.create(-1, __FILE__, __LINE__);
843 Q.create(q, __FILE__, __LINE__);
844 D.power_int(Q, m * m);
845 if (f_v) {
846 cout << "group_generators_domain::order_PO_parabolic " << q << "^(" << m
847 << "^2" << ") = " << Q << endl;
848 }
849 // now Q = q^{m^2}
850
851 O.create(1, __FILE__, __LINE__);
852 for (i = 1; i <= m; i++) {
853 R.create(q, __FILE__, __LINE__);
854 D.power_int(R, 2 * i);
855 D.add(R, minusone, S);
856 if (f_v) {
857 cout << "group_generators_domain::order_PO_parabolic " << q << "^"
858 << 2 * i << " - 1 = " << S << endl;
859 }
860 D.mult(O, S, T);
861 T.assign_to(O);
862 }
863 // now O = \prod_{i=1}^{m} (q^{2i}-1)
864
865
866 D.mult(O, Q, o);
867
868
869 if (f_v) {
870 cout << "group_generators_domain::order_PO_parabolic the order of PO" << "("
871 << Gg.dimension_given_Witt_index(0, m) << ","
872 << q << ") is " << o << endl;
873 }
874}
875
876
878 int m, int q,
879 ring_theory::longinteger_object &o, int verbose_level)
880// m = Witt index, the dimension is n = 2m
881{
882 int f_v = (verbose_level >= 1);
884 ring_theory::longinteger_object O, Q, R, S, S1, T, minusone;
885 int i, r;
887
888
889 if (f_v) {
890 cout << "group_generators_domain::order_Pomega_plus" << endl;
891 }
892 minusone.create(-1, __FILE__, __LINE__);
893 Q.create(q, __FILE__, __LINE__);
894 D.power_int(Q, m * (m - 1));
895 if (f_v) {
896 cout << q << "^(" << m << "*" << m - 1 << ") = " << Q << endl;
897 }
898 O.create(1, __FILE__, __LINE__);
899 for (i = 1; i <= m - 1; i++) {
900 R.create(q, __FILE__, __LINE__);
901 D.power_int(R, 2 * i);
902 D.add(R, minusone, S);
903 if (f_v) {
904 cout << q << "^" << 2 * i << " - 1 = " << S << endl;
905 }
906 D.mult(O, S, T);
907 T.assign_to(O);
908 }
909
910 R.create(q, __FILE__, __LINE__);
911 D.power_int(R, m);
912 D.add(R, minusone, S);
913 if (f_v) {
914 cout << q << "^" << m << " - 1 = " << S << endl;
915 }
916 D.integral_division_by_int(S, 2, S1, r);
917 if (r == 0) {
918 S1.assign_to(S);
919 }
920 D.integral_division_by_int(S, 2, S1, r);
921 if (r == 0) {
922 S1.assign_to(S);
923 }
924
925 D.mult(O, S, T);
926 T.assign_to(O);
927
928 D.mult(O, Q, T);
929 T.assign_to(o);
930
931
932 if (f_v) {
933 cout << "group_generators_domain::order_Pomega_plus "
934 "the order of P\\Omega^1" << "("
935 << Gg.dimension_given_Witt_index(1, m) << ","
936 << q << ") is " << o << endl;
937 }
938}
939
941 int m, int q,
942 ring_theory::longinteger_object &o, int verbose_level)
943// m = half the dimension,
944// the dimension is n = 2m, the Witt index is m - 1
945{
946 int f_v = (verbose_level >= 1);
948 ring_theory::longinteger_object O, Q, R, S, S1, T, minusone, plusone;
949 int i, r;
951
952 if (f_v) {
953 cout << "group_generators_domain::order_Pomega_minus m=" << m << " q=" << q << endl;
954 }
955 minusone.create(-1, __FILE__, __LINE__);
956 plusone.create(1, __FILE__, __LINE__);
957 Q.create(q, __FILE__, __LINE__);
958 D.power_int(Q, m * (m - 1));
959 if (f_v) {
960 cout << q << "^(" << m << "*" << m - 1 << ") = " << Q << endl;
961 }
962 O.create(1, __FILE__, __LINE__);
963 for (i = 1; i <= m - 1; i++) {
964 R.create(q, __FILE__, __LINE__);
965 D.power_int(R, 2 * i);
966 D.add(R, minusone, S);
967 if (f_v) {
968 cout << q << "^" << 2 * i << " - 1 = " << S << endl;
969 }
970 D.mult(O, S, T);
971 T.assign_to(O);
972 }
973
974 R.create(q, __FILE__, __LINE__);
975 D.power_int(R, m);
976 D.add(R, plusone, S);
977 if (f_v) {
978 cout << q << "^" << m << " + 1 = " << S << endl;
979 }
980 D.integral_division_by_int(S, 2, S1, r);
981 if (r == 0) {
982 if (f_v) {
983 cout << "divide by 2" << endl;
984 }
985 S1.assign_to(S);
986 }
987 D.integral_division_by_int(S, 2, S1, r);
988 if (r == 0) {
989 if (f_v) {
990 cout << "divide by 2" << endl;
991 }
992 S1.assign_to(S);
993 }
994
995 D.mult(O, S, T);
996 T.assign_to(O);
997
998 D.mult(O, Q, T);
999 T.assign_to(o);
1000
1001
1002 if (f_v) {
1003 cout << "group_generators_domain::order_Pomega_minus "
1004 "the order of P\\Omega^-1" << "("
1005 << Gg.dimension_given_Witt_index(-1, m - 1) << ","
1006 << q << ") is " << o << endl;
1007 }
1008}
1009
1011 int m, int q,
1012 ring_theory::longinteger_object &o, int verbose_level)
1013// m = Witt index, the dimension is n = 2m + 1
1014{
1015 int f_v = (verbose_level >= 1);
1017 ring_theory::longinteger_object O, Q, R, S, T, minusone;
1018 int i, r;
1020
1021
1022 minusone.create(-1, __FILE__, __LINE__);
1023 Q.create(q, __FILE__, __LINE__);
1024 D.power_int(Q, m * m);
1025 if (f_v) {
1026 cout << q << "^(" << m << "^2) = " << Q << endl;
1027 }
1028 O.create(1, __FILE__, __LINE__);
1029 for (i = 1; i <= m; i++) {
1030 R.create(q, __FILE__, __LINE__);
1031 D.power_int(R, 2 * i);
1032 D.add(R, minusone, S);
1033 if (f_v) {
1034 cout << q << "^" << 2 * i << " - 1 = " << S << endl;
1035 }
1036 D.mult(O, S, T);
1037 T.assign_to(O);
1038 }
1039 D.mult(O, Q, T);
1040 if (EVEN(q)) {
1041 T.assign_to(o);
1042 }
1043 else {
1044 D.integral_division_by_int(T, 2, o, r);
1045 }
1046 if (f_v) {
1047 cout << "group_generators_domain::order_Pomega_parabolic the order of P\\Omega" << "("
1048 << Gg.dimension_given_Witt_index(0, m) << ","
1049 << q << ") is " << o << endl;
1050 }
1051}
1052
1054 int epsilon, int m, int q, int verbose_level)
1055{
1056 if (epsilon == 0) {
1057 if (EVEN(q)) {
1058 return 1;
1059 }
1060 else {
1061 return 2;
1062 }
1063 }
1064 if (epsilon == 1) {
1065 if (EVEN(q)) {
1066 return 2;
1067 }
1068 else {
1069 if (DOUBLYEVEN(q - 1)) {
1070 return 4;
1071 }
1072 else {
1073 if (EVEN(m)) {
1074 return 4;
1075 }
1076 else {
1077 return 2;
1078 }
1079 }
1080 }
1081 }
1082 if (epsilon == -1) {
1083 if (EVEN(q)) {
1084 return 2;
1085 }
1086 else {
1087 if (DOUBLYEVEN(q - 1)) {
1088 return 2;
1089 }
1090 else {
1091 if (EVEN(m + 1)) {
1092 return 2;
1093 }
1094 else {
1095 return 4;
1096 }
1097 }
1098 }
1099 }
1100#if 0
1101 if (epsilon == -1) {
1102 cout << "index_POmega_in_PO epsilon = -1 not "
1103 "yet implemented, returning 1" << endl;
1104 return 1;
1105 exit(1);
1106 }
1107#endif
1108 cout << "index_POmega_in_PO epsilon not recognized, "
1109 "epsilon=" << epsilon << endl;
1110 exit(1);
1111}
1112
1114 long int *orbit, long int *orbit_inv, int verbose_level)
1115{
1116 int f_v = (verbose_level >= 1);
1117 int f_vv = FALSE; //(verbose_level >= 1);
1118 int *v = NEW_int(n + 1);
1120 long int l, ll;
1121 long int a, b, c;
1122 long int i, j;
1123
1124 if (f_v) {
1125 cout << "group_generators_domain::diagonal_orbit_perm" << endl;
1126 }
1127 l = Gg.nb_PG_elements(n - 1, F->q);
1128 ll = Gg.nb_AG_elements(n - 1, F->q - 1);
1129
1130 //cout << "l = " << l << endl;
1131 for (i = 0; i < l; i++) {
1132 orbit[i] = i;
1133 orbit_inv[i] = i;
1134 }
1135 for (i = 0; i < ll; i++) {
1136 v[0] = 1;
1137 Gg.AG_element_unrank(F->q - 1, v + 1, 1, n - 1, i);
1138 for (j = 1; j < n; j++) {
1139 v[j]++;
1140 }
1141 if (f_vv) {
1142 cout << i << " : ";
1143 for (j = 0; j < n; j++) {
1144 cout << v[j] << " ";
1145 }
1146 }
1147 F->PG_element_rank_modified_lint(v, 1, n, a);
1148 if (f_vv) {
1149 cout << " : " << a << endl;
1150 }
1151 b = orbit_inv[a];
1152 c = orbit[i];
1153 orbit[i] = a;
1154 orbit[b] = c;
1155 orbit_inv[a] = i;
1156 orbit_inv[c] = b;
1157 }
1158 FREE_int(v);
1159 if (f_v) {
1160 cout << "group_generators_domain::diagonal_orbit_perm done" << endl;
1161 }
1162}
1163
1165 long int *orbit, long int *orbit_inv,
1166 int verbose_level)
1167{
1168 int f_v = (verbose_level >= 1);
1169 int f_vv = FALSE;// (verbose_level >= 1);
1170 int *v = NEW_int(n);
1172 long int l;
1173 long int ll;
1174 long int a, b, c;
1175 long int i, j;
1176
1177 if (f_v) {
1178 cout << "group_generators_domain::frobenius_orbit_perm n=" << n
1179 << " (vector space dimension)" << endl;
1180 }
1181 l = Gg.nb_PG_elements(n - 1, F->q);
1182 ll = F->e;
1183 if (f_v) {
1184 cout << "group_generators_domain::frobenius_orbit_perm l=" << l << endl;
1185 }
1186 if (F->e == 1) {
1187 cout << "group_generators_domain::frobenius_orbit_perm GFq.e == 1" << endl;
1188 exit(1);
1189 }
1190 //cout << "l = " << l << endl;
1191 for (i = 0; i < l; i++) {
1192 orbit[i] = i;
1193 orbit_inv[i] = i;
1194 }
1195 if (f_v) {
1196 cout << "before PG_element_unrank_modified("
1197 << n + F->p << ")" << endl;
1198 }
1199 F->PG_element_unrank_modified(v, 1, n, n + F->p);
1200 if (f_v) {
1201 cout << "after PG_element_unrank_modified("
1202 << n + F->p << ")" << endl;
1203 }
1204 for (i = 0; i < ll; i++) {
1205 if (f_vv) {
1206 cout << i << " : ";
1207 for (j = 0; j < n; j++) {
1208 cout << v[j] << " ";
1209 }
1210 }
1211 F->PG_element_rank_modified_lint(v, 1, n, a);
1212 if (f_vv) {
1213 cout << " : " << a << endl;
1214 }
1215 b = orbit_inv[a];
1216 c = orbit[i];
1217 orbit[i] = a;
1218 orbit[b] = c;
1219 orbit_inv[a] = i;
1220 orbit_inv[c] = b;
1221 F->PG_element_apply_frobenius(n, v, 1);
1222 }
1223 FREE_int(v);
1224 if (f_v) {
1225 cout << "group_generators_domain::frobenius_orbit_perm done" << endl;
1226 }
1227}
1228
1230 int f_semilinear,
1231 int base_len, int degree,
1232 long int *base, int *transversal_length,
1233 long int **orbit, long int **orbit_inv,
1234 int verbose_level)
1235{
1236 int f_v = (verbose_level >= 1);
1237 int f_vv = FALSE; //(verbose_level >= 2);
1238 int i;
1240
1241
1242 if (f_v) {
1243 cout << "group_generators_domain::projective_matrix_group_base_and_orbits "
1244 "base_len=" << base_len << endl;
1245 }
1246 for (i = 0; i < base_len; i++) {
1247 base[i] = i;
1248 }
1249 for (i = 0; i < base_len; i++) {
1250 transversal_length[i] = i;
1251 }
1252 if (f_v) {
1253 cout << "group_generators_domain::projective_matrix_group_base_and_orbits "
1254 "transversal_length: ";
1255 Int_vec_print(cout, transversal_length, base_len);
1256 cout << endl;
1257 }
1258 if (f_semilinear) {
1259 base[base_len - 1] = n + F->p;
1260 // here was an error: the -1 was missing
1261 // A.B. 11/11/05
1262 // no that -1 needs to go
1263 // A.B. 3/9/2006
1264 }
1265 //transversal_length[0] = nb_PG_elements(n - 1, q);
1266 for (i = 0; i < n; i++) {
1267 transversal_length[i] =
1268 Gg.nb_PG_elements_not_in_subspace(n - 1, i - 1, F->q);
1269 if (f_vv) {
1270 cout << "group_generators_domain::projective_matrix_group_base_and_orbits "
1271 "transversal " << i << " of length "
1272 << transversal_length[i] << endl;
1273 }
1274 if (f_vv) {
1275 cout << "group_generators_domain::projective_matrix_group_base_and_orbits "
1276 "before PG_element_modified_not_in_subspace_perm" << endl;
1277 }
1279 orbit[i], orbit_inv[i], 0);
1280
1281 if (f_vv) {
1282 cout << "group_generators_domain::projective_matrix_group_base_and_orbits "
1283 "after PG_element_modified_not_in_subspace_perm" << endl;
1284 }
1285
1286 if (FALSE) {
1287 Lint_vec_print(cout, orbit[i], degree);
1288 cout << endl;
1289 Lint_vec_print(cout, orbit_inv[i], degree);
1290 cout << endl;
1291 }
1292 }
1293 if (F->q > 2) {
1294 transversal_length[i] = Gg.nb_AG_elements(n - 1, F->q - 1);
1295 if (f_vv) {
1296 cout << "group_generators_domain::projective_matrix_group_base_and_orbits: "
1297 "diagonal transversal " << i << " of length "
1298 << transversal_length[i] << endl;
1299 }
1300 if (f_vv) {
1301 cout << "finite_field::projective_matrix_group_base_and_orbits "
1302 "before diagonal_orbit_perm" << endl;
1303 }
1304 diagonal_orbit_perm(n, F, orbit[i], orbit_inv[i], 0);
1305
1306 if (f_vv) {
1307 cout << "projective_matrix_group_base_and_orbits "
1308 "after diagonal_orbit_perm" << endl;
1309 }
1310
1311 if (FALSE) {
1312 Lint_vec_print(cout, orbit[i], degree);
1313 cout << endl;
1314 Lint_vec_print(cout, orbit_inv[i], degree);
1315 cout << endl;
1316 }
1317 i++;
1318 }
1319 if (f_semilinear) {
1320 transversal_length[i] = F->e;
1321 if (f_vv) {
1322 cout << "group_generators_domain::projective_matrix_group_base_and_orbits: "
1323 "frobenius transversal " << i << " of length "
1324 << transversal_length[i] << endl;
1325 }
1326 if (f_vv) {
1327 cout << "finite_field::projective_matrix_group_base_and_orbits "
1328 "before frobenius_orbit_perm" << endl;
1329 }
1331 orbit[i], orbit_inv[i], verbose_level - 2);
1332
1333 if (f_vv) {
1334 cout << "group_generators_domain::projective_matrix_group_base_and_orbits "
1335 "after frobenius_orbit_perm" << endl;
1336 }
1337
1338 if (FALSE) {
1339 Lint_vec_print(cout, orbit[i], degree);
1340 cout << endl;
1341 Lint_vec_print(cout, orbit_inv[i], degree);
1342 cout << endl;
1343 }
1344 i++;
1345 }
1346 if (i != base_len) {
1347 cout << "group_generators_domain::projective_matrix_group_base_and_orbits "
1348 "i != base_len" << endl;
1349 cout << "i=" << i << endl;
1350 cout << "base_len=" << base_len << endl;
1351 exit(1);
1352 }
1353 if (f_vv) {
1354 cout << "group_generators_domain::projective_matrix_group_base_and_orbits base: ";
1355 Lint_vec_print(cout, base, base_len);
1356 cout << endl;
1357 cout << "projective_matrix_group_base_and_orbits "
1358 "transversal_length: ";
1359 Int_vec_print(cout, transversal_length, base_len);
1360 cout << endl;
1361 }
1362 if (f_v) {
1363 cout << "group_generators_domain::projective_matrix_group_base_and_orbits done" << endl;
1364 }
1365}
1366
1368 int f_semilinear,
1369 int base_len, int degree,
1370 long int *base, int *transversal_length,
1371 int verbose_level)
1372{
1373 int f_v = (verbose_level >= 1);
1374 int f_vv = (verbose_level >= 2);
1375 int i;
1377
1378
1379 if (f_v) {
1380 cout << "group_generators_domain::projective_matrix_group_base_and_transversal_length" << endl;
1381 }
1382 for (i = 0; i < base_len; i++) {
1383 base[i] = i;
1384 }
1385 if (f_semilinear) {
1386 base[base_len - 1] = n + F->p;
1387 // here was an error: the -1 was missing
1388 // A.B. 11/11/05
1389 // no that -1 needs to go
1390 // A.B. 3/9/2006
1391 }
1392 //transversal_length[0] = nb_PG_elements(n - 1, q);
1393 for (i = 0; i < n; i++) {
1394 transversal_length[i] =
1395 Gg.nb_PG_elements_not_in_subspace(n - 1, i - 1, F->q);
1396 if (f_vv) {
1397 cout << "group_generators_domain::projective_matrix_group_base_and_transversal_length "
1398 "transversal " << i << " of length "
1399 << transversal_length[i] << endl;
1400 }
1401 }
1402 if (F->q > 2) {
1403 transversal_length[i] = Gg.nb_AG_elements(n - 1, F->q - 1);
1404 if (f_vv) {
1405 cout << "group_generators_domain::projective_matrix_group_base_and_transversal_length: "
1406 "diagonal transversal " << i << " of length "
1407 << transversal_length[i] << endl;
1408 }
1409 i++;
1410 }
1411 if (f_semilinear) {
1412 transversal_length[i] = F->e;
1413 if (f_vv) {
1414 cout << "group_generators_domain::projective_matrix_group_base_and_transversal_length: "
1415 "frobenius transversal " << i << " of length "
1416 << transversal_length[i] << endl;
1417 }
1418 i++;
1419 }
1420 if (f_v) {
1421 cout << "group_generators_domain::projective_matrix_group_base_and_transversal_length base: ";
1422 Lint_vec_print(cout, base, base_len);
1423 cout << endl;
1424 cout << "finite_field::projective_matrix_group_base_and_transversal_length "
1425 "transversal_length: ";
1426 Int_vec_print(cout, transversal_length, base_len);
1427 cout << endl;
1428 }
1429 if (f_v) {
1430 cout << "group_generators_domain::projective_matrix_group_base_and_transversal_length done" << endl;
1431 }
1432}
1433
1435 int f_semilinear,
1436 int base_len, int degree,
1437 long int *base, int *transversal_length,
1438 int verbose_level)
1439{
1440 int f_v = (verbose_level >= 1);
1441 int f_vv = (verbose_level >= 2);
1442 int i, c;
1444
1445
1446 if (f_v) {
1447 cout << "group_generators_domain::affine_matrix_group_base_and_transversal_length" << endl;
1448 }
1449 c = 0;
1450 base[c] = 0;
1451 transversal_length[c] = NT.i_power_j(F->q, n);
1452 c++;
1453 for (i = 0; i < n; i++) {
1454 base[c] = NT.i_power_j_lint(F->q, i);
1455 transversal_length[c] = NT.i_power_j_lint(F->q, n) - NT.i_power_j_lint(F->q, i);
1456 c++;
1457 }
1458 if (f_semilinear) {
1459 base[c] = F->q + F->p;
1460 transversal_length[c] = F->e;
1461 c++;
1462 }
1463 if (c != base_len) {
1464 cout << "group_generators_domain::affine_matrix_group_base_and_transversal_length "
1465 "c != base_len" << endl;
1466 exit(1);
1467 }
1468 if (f_vv) {
1469 cout << "group_generators_domain::affine_matrix_group_base_and_transversal_length base: ";
1470 Lint_vec_print(cout, base, base_len);
1471 cout << endl;
1472 cout << "finite_field::affine_matrix_group_base_and_transversal_length "
1473 "transversal_length: ";
1474 Int_vec_print(cout, transversal_length, base_len);
1475 cout << endl;
1476 }
1477 if (f_v) {
1478 cout << "group_generators_domain::affine_matrix_group_base_and_transversal_length done" << endl;
1479 }
1480}
1481
1482
1484 int f_semilinear,
1485 int base_len, int degree,
1486 long int *base, int *transversal_length,
1487 int verbose_level)
1488{
1489 int f_v = (verbose_level >= 1);
1490 int f_vv = (verbose_level >= 2);
1491 int i, c;
1493
1494
1495 if (f_v) {
1496 cout << "group_generators_domain::general_linear_matrix_group_base_and_transversal_length" << endl;
1497 }
1498 c = 0;
1499 for (i = 0; i < n; i++) {
1500 base[c] = NT.i_power_j_lint(F->q, i);
1501 transversal_length[c] = NT.i_power_j_lint(F->q, n) - NT.i_power_j_lint(F->q, i);
1502 c++;
1503 }
1504 if (f_semilinear) {
1505 base[c] = F->q + F->p;
1506 transversal_length[c] = F->e;
1507 c++;
1508 }
1509 if (c != base_len) {
1510 cout << "group_generators_domain::general_linear_matrix_group_base_and_"
1511 "transversal_length c != base_len" << endl;
1512 cout << "c=" << c << endl;
1513 cout << "base_len=" << base_len << endl;
1514 exit(1);
1515 }
1516 if (f_vv) {
1517 cout << "group_generators_domain::general_linear_matrix_group_base_and_"
1518 "transversal_length base: ";
1519 Lint_vec_print(cout, base, base_len);
1520 cout << endl;
1521 cout << "group_generators_domain::general_linear_matrix_group_base_and_"
1522 "transversal_length transversal_length: ";
1523 Int_vec_print(cout, transversal_length, base_len);
1524 cout << endl;
1525 }
1526 if (f_v) {
1527 cout << "group_generators_domain::general_linear_matrix_group_base_and_transversal_length done" << endl;
1528 }
1529}
1530
1531
1534 int f_semilinear,
1535 int *&data, int &size, int &nb_gens,
1536 int verbose_level)
1537{
1538 int f_v = (verbose_level >= 1);
1539 int f_vv = (verbose_level >= 2);
1540 int h, u, cur;
1541 int *M;
1543
1544 if (f_v) {
1545 cout << "group_generators_domain::strong_generators_for_projective_linear_group" << endl;
1546 }
1547 size = n * n;
1548 if (f_semilinear) {
1549 size++;
1550 }
1551 nb_gens = 0;
1552 if (f_semilinear) {
1553 nb_gens++;
1554 }
1555 if (F->q > 2) {
1556 nb_gens += n - 1;
1557 }
1558 nb_gens += (n - 1) * F->e;
1559 nb_gens += n - 1;
1560 data = NEW_int(size * nb_gens);
1561 M = NEW_int(size);
1562
1563 cur = 0;
1564
1565 // the automorphic collineation:
1566 if (f_semilinear) {
1568 M[n * n] = 1;
1569 Int_vec_copy(M, data + cur * size, size);
1570 cur++;
1571 }
1572
1573
1574 // the primitive elements on the diagonal:
1575 if (F->q > 2) {
1576 for (h = 0; h < n - 1; h++) {
1577 if (f_vv) {
1578 cout << "generators for primitive elements "
1579 "on the diagonal:" << endl;
1580 }
1582 M[h * n + h] = F->primitive_root();
1583 if (f_semilinear) {
1584 M[n * n] = 0;
1585 }
1586 Int_vec_copy(M, data + cur * size, size);
1587 cur++;
1588 }
1589 }
1590
1591 // the entries in the last row:
1592 for (h = 0; h < n - 1; h++) {
1593 if (f_vv) {
1594 cout << "generators for entries in the last row "
1595 "(e=" << F->e << "):" << endl;
1596 }
1597 for (u = 0; u < F->e; u++) {
1599 M[(n - 1) * n + h] = NT.i_power_j(F->p, u);
1600 if (f_semilinear) {
1601 M[n * n] = 0;
1602 }
1603 Int_vec_copy(M, data + cur * size, size);
1604 cur++;
1605 }
1606 }
1607
1608 // the swaps along the diagonal:
1609 for (h = n - 2; h >= 0; h--) {
1610 if (f_vv) {
1611 cout << "generators for swaps along the diagonal:" << endl;
1612 }
1614 M[h * n + h] = 0;
1615 M[h * n + h + 1] = 1;
1616 M[(h + 1) * n + h] = 1;
1617 M[(h + 1) * n + h + 1] = 0;
1618 if (f_semilinear) {
1619 M[n * n] = 0;
1620 }
1621 Int_vec_copy(M, data + cur * size, size);
1622 cur++;
1623 }
1624
1625 if (cur != nb_gens) {
1626 cout << "group_generators_domain::strong_generators_for_projective_linear_group "
1627 "cur != nb_gens" << endl;
1628 exit(1);
1629 }
1630
1631 FREE_int(M);
1632 if (f_v) {
1633 cout << "group_generators_domain::strong_generators_for_projective_linear_group "
1634 "done" << endl;
1635 }
1636}
1637
1638
1641 int f_semilinear,
1642 int *&data, int &size, int &nb_gens,
1643 int verbose_level)
1644{
1645 int f_v = (verbose_level >= 1);
1646 int f_vv = (verbose_level >= 2);
1647 int h, u, cur;
1649
1650 if (f_v) {
1651 cout << "group_generators_domain::strong_generators_for_affine_linear_group" << endl;
1652 }
1653 size = n * n + n;
1654 if (f_semilinear) {
1655 size++;
1656 }
1657 nb_gens = 0;
1658 if (f_semilinear) {
1659 nb_gens++; // the field automorphism
1660 }
1661 nb_gens += (n - 1) * F->e; // the bottom layer
1662
1663 if (F->q > 2) {
1664 nb_gens++;
1665 }
1666
1667 nb_gens += n - 1; // the transpositions
1668
1669 nb_gens += n * F->e; // the translations
1670
1671 data = NEW_int(size * nb_gens);
1672
1673 cur = 0;
1674 if (f_semilinear) {
1675 Int_vec_zero(data + cur * size, size);
1676 F->Linear_algebra->identity_matrix(data + cur * size, n);
1677 data[cur * size + n * n + n] = 1;
1678 cur++;
1679 }
1680
1681 // the entries in the last row:
1682 for (h = 0; h < n - 1; h++) {
1683 if (f_vv) {
1684 cout << "generators for entries in the last row "
1685 "(e=" << F->e << "):" << endl;
1686 }
1687 for (u = 0; u < F->e; u++) {
1688 Int_vec_zero(data + cur * size, size);
1689 F->Linear_algebra->identity_matrix(data + cur * size, n);
1690
1691 data[cur * size + (n - 1) * n + h] = NT.i_power_j(F->p, u);
1692 if (f_semilinear) {
1693 data[cur * size + n * n + n] = 0;
1694 }
1695 cur++;
1696 } // next u
1697 } // next h
1698
1699 if (F->q > 2) {
1700 // the primitive element on the last diagonal:
1701 h = n - 1;
1702 if (f_vv) {
1703 cout << "generators for primitive element "
1704 "on the last diagonal:" << endl;
1705 }
1706 Int_vec_zero(data + cur * size, size);
1707 F->Linear_algebra->identity_matrix(data + cur * size, n);
1708
1709 data[cur * size + h * n + h] = F->primitive_root();
1710 if (f_semilinear) {
1711 data[cur * size + n * n + n] = 0;
1712 }
1713 cur++;
1714 } // if
1715
1716
1717 // the swaps along the diagonal:
1718 for (h = n - 2; h >= 0; h--) {
1719 if (f_vv) {
1720 cout << "generators for swaps along the diagonal:" << endl;
1721 }
1722 Int_vec_zero(data + cur * size, size);
1723 F->Linear_algebra->identity_matrix(data + cur * size, n);
1724 data[cur * size + h * n + h] = 0;
1725 data[cur * size + h * n + h + 1] = 1;
1726 data[cur * size + (h + 1) * n + h] = 1;
1727 data[cur * size + (h + 1) * n + h + 1] = 0;
1728 if (f_semilinear) {
1729 data[cur * size + n * n + n] = 0;
1730 }
1731 cur++;
1732 } // next h
1733
1734 // the translations:
1735 for (h = 0; h < n; h++) {
1736 for (u = 0; u < F->e; u++) {
1737 Int_vec_zero(data + cur * size, size);
1738 F->Linear_algebra->identity_matrix(data + cur * size, n);
1739
1740 data[cur * size + n * n + h] = NT.i_power_j(F->p, u);
1741 if (f_semilinear) {
1742 data[cur * size + n * n + n] = 0;
1743 }
1744 cur++;
1745 } // next u
1746 } // next h
1747
1748 if (cur != nb_gens) {
1749 cout << "group_generators_domain::strong_generators_for_affine_linear_group "
1750 "cur != nb_gens" << endl;
1751 exit(1);
1752 }
1753 if (f_v) {
1754 cout << "group_generators_domain::strong_generators_for_affine_linear_group done" << endl;
1755 }
1756}
1757
1760 int f_semilinear,
1761 int *&data, int &size, int &nb_gens,
1762 int verbose_level)
1763{
1764 int f_v = (verbose_level >= 1);
1765 int f_vv = (verbose_level >= 2);
1766 int h, u, cur;
1768
1769 if (f_v) {
1770 cout << "group_generators_domain::strong_generators_for_general_linear_group" << endl;
1771 }
1772 size = n * n;
1773 if (f_semilinear) {
1774 size++;
1775 }
1776 nb_gens = 0;
1777 if (f_semilinear) {
1778 nb_gens++; // the field automorphism
1779 }
1780 nb_gens += (n - 1) * F->e; // the bottom layer
1781
1782 if (F->q > 2) {
1783 nb_gens++;
1784 }
1785
1786 nb_gens += n - 1; // the transpositions
1787
1788
1789 data = NEW_int(size * nb_gens);
1790
1791 cur = 0;
1792 if (f_semilinear) {
1793 Int_vec_zero(data + cur * size, size);
1794 F->Linear_algebra->identity_matrix(data + cur * size, n);
1795 data[cur * size + n * n] = 1;
1796 cur++;
1797 }
1798
1799 // the entries in the last row:
1800 for (h = 0; h < n - 1; h++) {
1801 if (f_vv) {
1802 cout << "generators for entries in the last row "
1803 "(e=" << F->e << "):" << endl;
1804 }
1805 for (u = 0; u < F->e; u++) {
1806 Int_vec_zero(data + cur * size, size);
1807 F->Linear_algebra->identity_matrix(data + cur * size, n);
1808
1809 data[cur * size + (n - 1) * n + h] = NT.i_power_j(F->p, u);
1810 if (f_semilinear) {
1811 data[cur * size + n * n] = 0;
1812 }
1813 cur++;
1814 } // next u
1815 } // next h
1816
1817 if (F->q > 2) {
1818 // the primitive element on the last diagonal:
1819 h = n - 1;
1820 if (f_vv) {
1821 cout << "generators for primitive element "
1822 "on the last diagonal:" << endl;
1823 }
1824 Int_vec_zero(data + cur * size, size);
1825 F->Linear_algebra->identity_matrix(data + cur * size, n);
1826
1827 data[cur * size + h * n + h] = F->primitive_root();
1828 if (f_semilinear) {
1829 data[cur * size + n * n] = 0;
1830 }
1831 cur++;
1832 } // if
1833
1834
1835 // the swaps along the diagonal:
1836 for (h = n - 2; h >= 0; h--) {
1837 if (f_vv) {
1838 cout << "generators for swaps along the diagonal:" << endl;
1839 }
1840 Int_vec_zero(data + cur * size, size);
1841 F->Linear_algebra->identity_matrix(data + cur * size, n);
1842 data[cur * size + h * n + h] = 0;
1843 data[cur * size + h * n + h + 1] = 1;
1844 data[cur * size + (h + 1) * n + h] = 1;
1845 data[cur * size + (h + 1) * n + h + 1] = 0;
1846 if (f_semilinear) {
1847 data[cur * size + n * n] = 0;
1848 }
1849 cur++;
1850 } // next h
1851
1852
1853 if (cur != nb_gens) {
1854 cout << "group_generators_domain::strong_generators_for_general_linear_group "
1855 "cur != nb_gens" << endl;
1856 exit(1);
1857 }
1858 if (f_v) {
1859 cout << "group_generators_domain::strong_generators_for_general_linear_group done" << endl;
1860 }
1861}
1862
1865 int f_semilinear, int k,
1866 int *&data, int &size, int &nb_gens,
1867 int verbose_level)
1868{
1869 int f_v = (verbose_level >= 1);
1870 int f_vv = (verbose_level >= 2);
1871 int h, g, u, cur;
1872 int *M;
1874
1875 if (f_v) {
1876 cout << "group_generators_domain::generators_for_parabolic_subgroup" << endl;
1877 }
1878 size = n * n;
1879
1880 if (f_semilinear) {
1881 size++;
1882 }
1883
1884 nb_gens = 0;
1885
1886 // count the Frobenius generator
1887 if (f_semilinear) {
1888 nb_gens++;
1889 }
1890
1891 // count the generators with primitive elements on the diagonal:
1892 if (F->q > 2) {
1893 nb_gens += n - 1;
1894 }
1895
1896
1897 // count the generators with entries in row k:
1898 for (h = 0; h < k - 1; h++) {
1899 for (u = 0; u < F->e; u++) {
1900 nb_gens++;
1901 }
1902 }
1903 // count the generators with entries in row n:
1904 for (h = k; h < n - 1; h++) {
1905 for (u = 0; u < F->e; u++) {
1906 nb_gens++;
1907 }
1908 }
1909
1910 // count the generators with entries in the lower left block:
1911 nb_gens += k * (n - k) * F->e;
1912
1913 // count the swaps:
1914 for (h = n - 2; h >= k; h--) {
1915 nb_gens++;
1916 }
1917 for (h = k - 2; h >= 0; h--) {
1918 nb_gens++;
1919 }
1920#if 0
1921 if (k > 1 && k < n - 1) {
1922 nb_gens += n - 2; // swaps
1923 }
1924 else {
1925 nb_gens += n - 1; // swaps
1926 }
1927#endif
1928
1929
1930 data = NEW_int(size * nb_gens);
1931 M = NEW_int(size);
1932
1933 cur = 0;
1934
1935 // the automorphic collineation:
1936 if (f_semilinear) {
1938 M[n * n] = 1;
1939 Int_vec_copy(M, data + cur * size, size);
1940 cur++;
1941 }
1942
1943
1944 // the primitive elements on the diagonal:
1945 if (f_vv) {
1946 cout << "generators for primitive elements "
1947 "on the diagonal, cur=" << cur << endl;
1948 }
1949 if (F->q > 2) {
1950 for (h = 0; h < n - 1; h++) {
1952 M[h * n + h] = F->primitive_root();
1953 if (f_semilinear) {
1954 M[n * n] = 0;
1955 }
1956 Int_vec_copy(M, data + cur * size, size);
1957 cur++;
1958 }
1959 }
1960
1961 // the entries in the row k:
1962 if (f_vv) {
1963 cout << "generators for the entries in the last row "
1964 "of a diagonal block, cur=" << cur << endl;
1965 }
1966 for (h = 0; h < k - 1; h++) {
1967 for (u = 0; u < F->e; u++) {
1969 M[(k - 1) * n + h] = NT.i_power_j(F->p, u);
1970 if (f_semilinear) {
1971 M[n * n] = 0;
1972 }
1973 Int_vec_copy(M, data + cur * size, size);
1974 cur++;
1975 }
1976 }
1977
1978 // the entries in the row n:
1979 for (h = k; h < n - 1; h++) {
1980 for (u = 0; u < F->e; u++) {
1982 M[(n - 1) * n + h] = NT.i_power_j(F->p, u);
1983 if (f_semilinear) {
1984 M[n * n] = 0;
1985 }
1986 Int_vec_copy(M, data + cur * size, size);
1987 cur++;
1988 }
1989 }
1990
1991 // entries in the lower left block:
1992 if (f_vv) {
1993 cout << "generators for the entries in the lower left block, "
1994 "cur=" << cur << endl;
1995 }
1996 for (g = k; g < n; g++) {
1997 for (h = 0; h < k; h++) {
1998 for (u = 0; u < F->e; u++) {
2000 M[g * n + h] = NT.i_power_j(F->p, u);
2001 if (f_semilinear) {
2002 M[n * n] = 0;
2003 }
2004 Int_vec_copy(M, data + cur * size, size);
2005 cur++;
2006 }
2007 }
2008 }
2009
2010 // the swaps along the diagonal:
2011 if (f_vv) {
2012 cout << "generators for swaps along the diagonal, "
2013 "cur=" << cur << endl;
2014 }
2015 for (h = n - 2; h >= k; h--) {
2017 M[h * n + h] = 0;
2018 M[h * n + h + 1] = 1;
2019 M[(h + 1) * n + h] = 1;
2020 M[(h + 1) * n + h + 1] = 0;
2021 if (f_semilinear) {
2022 M[n * n] = 0;
2023 }
2024 Int_vec_copy(M, data + cur * size, size);
2025 cur++;
2026 }
2027 for (h = k - 2; h >= 0; h--) {
2029 M[h * n + h] = 0;
2030 M[h * n + h + 1] = 1;
2031 M[(h + 1) * n + h] = 1;
2032 M[(h + 1) * n + h + 1] = 0;
2033 if (f_semilinear) {
2034 M[n * n] = 0;
2035 }
2036 Int_vec_copy(M, data + cur * size, size);
2037 cur++;
2038 }
2039
2040 if (cur != nb_gens) {
2041 cout << "group_generators_domain::generators_for_parabolic_subgroup "
2042 "cur != nb_gens" << endl;
2043 cout << "cur = " << cur << endl;
2044 cout << "nb_gens = " << nb_gens << endl;
2045 exit(1);
2046 }
2047
2048 FREE_int(M);
2049 if (f_v) {
2050 cout << "group_generators_domain::generators_for_parabolic_subgroup done" << endl;
2051 }
2052}
2053
2055 int f_semilinear, field_theory::finite_field *F,
2056 int *&data, int &size, int &nb_gens,
2057 int verbose_level)
2058{
2059 int f_v = (verbose_level >= 1);
2060 int f_vv = (verbose_level >= 2);
2061 int u, cur, i, j;
2062 int *M;
2063 int n = 4;
2065
2066 if (f_v) {
2067 cout << "group_generators_domain::generators_for_stabilizer_of_three_collinear_"
2068 "points_in_PGL4" << endl;
2069 }
2070 size = n * n;
2071 if (f_semilinear) {
2072 size++;
2073 }
2074
2075 nb_gens = 0;
2076
2077 // automorphic
2078 if (f_semilinear) {
2079 nb_gens++;
2080 }
2081 nb_gens += 3; // Sym_3 in top left block plus scalars
2082 nb_gens++; // scalars bottom right
2083
2084
2085
2086 nb_gens += 4 * F->e; // lower left block
2087
2088 nb_gens++; // swaps lower right
2089 nb_gens += F->e; // PGL2 in lower right, bottom row
2090
2091 data = NEW_int(size * nb_gens);
2092 M = NEW_int(size);
2093
2094 cur = 0;
2095
2096 // the automorphic collineation:
2097 if (f_semilinear) {
2099 M[n * n] = 1;
2100 Int_vec_copy(M, data + cur * size, size);
2101 cur++;
2102 }
2103
2104 // Sym_3 in top left block:
2105 if (f_vv) {
2106 cout << "generators for Sym_3 in top left block, "
2107 "cur=" << cur << endl;
2108 }
2110 M[0 * 4 + 0] = 0;
2111 M[0 * 4 + 1] = 1;
2112 M[1 * 4 + 0] = 1;
2113 M[1 * 4 + 1] = 0;
2114 if (f_semilinear) {
2115 M[n * n] = 0;
2116 }
2117 Int_vec_copy(M, data + cur * size, size);
2118 cur++;
2120 M[0 * 4 + 0] = 0;
2121 M[0 * 4 + 1] = 1;
2122 M[1 * 4 + 0] = F->negate(1);
2123 M[1 * 4 + 1] = F->negate(1);
2124 if (f_semilinear) {
2125 M[n * n] = 0;
2126 }
2127 Int_vec_copy(M, data + cur * size, size);
2128 cur++;
2130 M[0 * 4 + 0] = F->primitive_root();
2131 M[0 * 4 + 1] = 0;
2132 M[1 * 4 + 0] = 0;
2133 M[1 * 4 + 1] = F->primitive_root();
2134 if (f_semilinear) {
2135 M[n * n] = 0;
2136 }
2137 Int_vec_copy(M, data + cur * size, size);
2138 cur++;
2139
2140 // scalars in bottom right:
2142 M[3 * 4 + 3] = F->primitive_root();
2143 if (f_semilinear) {
2144 M[n * n] = 0;
2145 }
2146 Int_vec_copy(M, data + cur * size, size);
2147 cur++;
2148
2149 // lower left block:
2150 for (i = 2; i < 4; i++) {
2151 for (j = 0; j < 2; j++) {
2152 for (u = 0; u < F->e; u++) {
2154 M[i * n + j] = NT.i_power_j(F->p, u);
2155 if (f_semilinear) {
2156 M[n * n] = 0;
2157 }
2158 Int_vec_copy(M, data + cur * size, size);
2159 cur++;
2160 }
2161 }
2162 }
2163
2164 // swaps lower right:
2166 M[2 * 4 + 2] = 0;
2167 M[2 * 4 + 3] = 1;
2168 M[3 * 4 + 2] = 1;
2169 M[3 * 4 + 3] = 0;
2170 if (f_semilinear) {
2171 M[n * n] = 0;
2172 }
2173 Int_vec_copy(M, data + cur * size, size);
2174 cur++;
2175
2176 // PGL2 in lower right, bottom row
2177 for (u = 0; u < F->e; u++) {
2179 M[3 * n + 2] = NT.i_power_j(F->p, u);
2180 if (f_semilinear) {
2181 M[n * n] = 0;
2182 }
2183 Int_vec_copy(M, data + cur * size, size);
2184 cur++;
2185 }
2186
2187
2188
2189
2190 if (cur != nb_gens) {
2191 cout << "group_generators_domain::generators_for_stabilizer_of_three_"
2192 "collinear_points_in_PGL4 cur != nb_gens" << endl;
2193 cout << "cur = " << cur << endl;
2194 cout << "nb_gens = " << nb_gens << endl;
2195 exit(1);
2196 }
2197
2198 FREE_int(M);
2199 if (f_v) {
2200 cout << "group_generators_domain::generators_for_stabilizer_of_three_"
2201 "collinear_points_in_PGL4 done" << endl;
2202 }
2203}
2204
2205
2207 int f_semilinear, field_theory::finite_field *F,
2208 int *&data, int &size, int &nb_gens,
2209 int verbose_level)
2210{
2211 int f_v = (verbose_level >= 1);
2212 int f_vv = (verbose_level >= 2);
2213 int u, cur, j;
2214 int *M;
2215 int n = 4;
2217
2218 if (f_v) {
2219 cout << "group_generators_domain::generators_for_stabilizer_of_triangle_in_PGL4" << endl;
2220 }
2221 size = n * n;
2222 if (f_semilinear) {
2223 size++;
2224 }
2225
2226 nb_gens = 0;
2227
2228 // automorphic
2229 if (f_semilinear) {
2230 nb_gens++;
2231 }
2232 nb_gens += 2; // Sym_3 in top left block
2233 nb_gens += 3; // scalars in top left block
2234 nb_gens++; // scalars bottom right
2235
2236 nb_gens += 3 * F->e; // lower left block
2237
2238 data = NEW_int(size * nb_gens);
2239 M = NEW_int(size);
2240
2241 cur = 0;
2242
2243 // the automorphic collineation:
2244 if (f_semilinear) {
2246 M[n * n] = 1;
2247 Int_vec_copy(M, data + cur * size, size);
2248 cur++;
2249 }
2250
2251 // Sym_3 in top left block:
2252 if (f_vv) {
2253 cout << "generators for Sym_3 in top left block, "
2254 "cur=" << cur << endl;
2255 }
2257 M[0 * 4 + 0] = 0;
2258 M[0 * 4 + 1] = 1;
2259 M[1 * 4 + 0] = 1;
2260 M[1 * 4 + 1] = 0;
2261 if (f_semilinear) {
2262 M[n * n] = 0;
2263 }
2264 Int_vec_copy(M, data + cur * size, size);
2265 cur++;
2267 M[0 * 4 + 0] = 0;
2268 M[1 * 4 + 1] = 0;
2269 M[2 * 4 + 2] = 0;
2270 M[0 * 4 + 2] = 1;
2271 M[1 * 4 + 0] = 1;
2272 M[2 * 4 + 1] = 1;
2273 if (f_semilinear) {
2274 M[n * n] = 0;
2275 }
2276 Int_vec_copy(M, data + cur * size, size);
2277 cur++;
2278
2279 // scalars in top left block:
2281 M[0 * 4 + 0] = F->primitive_root();
2282 if (f_semilinear) {
2283 M[n * n] = 0;
2284 }
2285 Int_vec_copy(M, data + cur * size, size);
2286 cur++;
2288 M[1 * 4 + 1] = F->primitive_root();
2289 if (f_semilinear) {
2290 M[n * n] = 0;
2291 }
2292 Int_vec_copy(M, data + cur * size, size);
2293 cur++;
2295 M[2 * 4 + 2] = F->primitive_root();
2296 if (f_semilinear) {
2297 M[n * n] = 0;
2298 }
2299 Int_vec_copy(M, data + cur * size, size);
2300 cur++;
2301
2302 // scalars bottom right
2304 M[3 * 4 + 3] = F->primitive_root();
2305 if (f_semilinear) {
2306 M[n * n] = 0;
2307 }
2308 Int_vec_copy(M, data + cur * size, size);
2309 cur++;
2310
2311 // lower left block
2312 for (j = 0; j < 3; j++) {
2313 for (u = 0; u < F->e; u++) {
2315 M[3 * n + j] = NT.i_power_j(F->p, u);
2316 if (f_semilinear) {
2317 M[n * n] = 0;
2318 }
2319 Int_vec_copy(M, data + cur * size, size);
2320 cur++;
2321 }
2322 }
2323
2324
2325 if (cur != nb_gens) {
2326 cout << "group_generators_domain::generators_for_stabilizer_of_triangle_in_PGL4 "
2327 "cur != nb_gens" << endl;
2328 cout << "cur = " << cur << endl;
2329 cout << "nb_gens = " << nb_gens << endl;
2330 exit(1);
2331 }
2332
2333 FREE_int(M);
2334 if (f_v) {
2335 cout << "group_generators_domain::generators_for_stabilizer_of_triangle_in_PGL4 done" << endl;
2336 }
2337}
2338
2340 int n, field_theory::finite_field *F, int f_semilinear, int i, int j,
2341 int verbose_level)
2342{
2343 int f_v = (verbose_level >= 1);
2344 int f_vv = (verbose_level >= 2);
2345
2346 int transversal_length;
2347 int ii, jj, i0, a;
2349
2350 if (f_v) {
2351 cout << "group_generators_domain::builtin_transversal_rep_GLnq "
2352 "GL(" << n << "," << F->q << ") i = " << i
2353 << " j = " << j << endl;
2354 }
2355
2356 // make the n x n identity matrix:
2357 for (ii = 0; ii < n * n; ii++) {
2358 A[ii] = 0;
2359 }
2360 for (ii = 0; ii < i; ii++) {
2361 A[ii * n + ii] = 1;
2362 }
2363 if (f_semilinear) {
2364 A[n * n] = 0;
2365 }
2366
2367 if ((i == n + 1 && F->q > 2) || (i == n && F->q == 2)) {
2368 if (!f_semilinear) {
2369 cout << "group_generators_domain::builtin_transversal_rep_GLnq "
2370 "must be semilinear to access transversal " << n << endl;
2371 exit(1);
2372 }
2373 A[n * n] = j;
2374 }
2375 else if (i == n && F->q > 2) {
2376 transversal_length = Gg.nb_AG_elements(n - 1, F->q - 1);
2377 if (j >= transversal_length) {
2378 cout << "group_generators_domain::builtin_transversal_rep_GLnq "
2379 "j = " << j << " >= transversal_length = "
2380 << transversal_length << endl;
2381 exit(1);
2382 }
2383 int *v = NEW_int(n);
2384 Gg.AG_element_unrank(F->q - 1, v, 1, n - 1, j);
2385 A[0] = 1;
2386 for (jj = 0; jj < n - 1; jj++) {
2387 A[(jj + 1) * n + (jj + 1)] = v[jj] + 1;
2388 }
2389 FREE_int(v);
2390 }
2391 else {
2392 if (i == 0) {
2393 F->PG_element_unrank_modified(A + i, n, n, j);
2394 }
2395 else {
2397 A + i, n, n, i - 1, j);
2398 }
2399 i0 = -1;
2400 for (ii = 0; ii < n; ii++) {
2401 a = A[ii * n + i];
2402 if (ii >= i && i0 == -1 && a != 0) {
2403 i0 = ii;
2404 }
2405 }
2406 if (f_vv) {
2407 cout << "i0 = " << i0 << endl;
2408 }
2409 for (jj = i; jj < i0; jj++) {
2410 A[jj * n + jj + 1] = 1;
2411 }
2412 for (jj = i0 + 1; jj < n; jj++) {
2413 A[jj * n + jj] = 1;
2414 }
2415 //int_matrix_transpose(n, A);
2417 }
2418
2419 if (f_vv) {
2420 cout << "group_generators_domain::transversal_rep_GLnq[" << i << "][" << j << "] = \n";
2421 Int_vec_print_integer_matrix(cout, A, n, n);
2422 }
2423}
2424
2426 int coordinate_idx, int field_base_idx, int *perm, int verbose_level)
2427// perm points to q^n int's
2428// field_base_idx is the base element whose translation
2429// we compute, 0 \le field_base_idx < e
2430// coordinate_idx is the coordinate in which we shift,
2431// 0 \le coordinate_idx < n
2432{
2433 int f_v = (verbose_level >= 1);
2434 long int i, j, l, a;
2435 int *v;
2438
2439 if (f_v) {
2440 cout << "group_generators_domain::affine_translation "
2441 "coordinate_idx=" << coordinate_idx
2442 << " field_base_idx=" << field_base_idx << endl;
2443 }
2444 v = NEW_int(n);
2445 l = Gg.nb_AG_elements(n, F->q);
2446 a = NT.i_power_j(F->p, field_base_idx);
2447 for (i = 0; i < l; i++) {
2448 Gg.AG_element_unrank(F->q, v, 1, l, i);
2449 v[coordinate_idx] = F->add(v[coordinate_idx], a);
2450 j = Gg.AG_element_rank(F->q, v, 1, l);
2451 perm[i] = j;
2452 }
2453 FREE_int(v);
2454}
2455
2457 int multiplication_order, int *perm, int verbose_level)
2458// perm points to q^n int's
2459// compute the diagonal multiplication by alpha, i.e.
2460// the multiplication by alpha of each component
2461{
2462 int f_v = (verbose_level >= 1);
2463 long int i, j, l, k;
2464 int alpha_power, a;
2465 int *v;
2467
2468 if (f_v) {
2469 cout << "group_generators_domain::affine_multiplication" << endl;
2470 }
2471 v = NEW_int(n);
2472 alpha_power = (F->q - 1) / multiplication_order;
2473 if (alpha_power * multiplication_order != F->q - 1) {
2474 cout << "group_generators_domain::affine_multiplication: "
2475 "multiplication_order does not divide F->q - 1" << endl;
2476 exit(1);
2477 }
2478 a = F->power(F->alpha, alpha_power);
2479 l = Gg.nb_AG_elements(n, F->q);
2480 for (i = 0; i < l; i++) {
2481 Gg.AG_element_unrank(F->q, v, 1, l, i);
2482 for (k = 0; k < n; k++) {
2483 v[k] = F->mult(v[k], a);
2484 }
2485 j = Gg.AG_element_rank(F->q, v, 1, l);
2486 perm[i] = j;
2487 }
2488 FREE_int(v);
2489}
2490
2492 int k, int *perm, int verbose_level)
2493// perm points to q^n int's
2494// compute the diagonal action of the Frobenius automorphism
2495// to the power k, i.e.,
2496// raises each component to the p^k-th power
2497{
2498 int f_v = (verbose_level >= 1);
2499 long int i, j, l, u;
2500 int *v;
2502
2503 if (f_v) {
2504 cout << "group_generators_domain::affine_frobenius" << endl;
2505 }
2506 v = NEW_int(n);
2507 l = Gg.nb_AG_elements(n, F->q);
2508 for (i = 0; i < l; i++) {
2509 Gg.AG_element_unrank(F->q, v, 1, l, i);
2510 for (u = 0; u < n; u++) {
2511 v[u] = F->frobenius_power(v[u], k);
2512 }
2513 j = Gg.AG_element_rank(F->q, v, 1, l);
2514 perm[i] = j;
2515 }
2516 FREE_int(v);
2517}
2518
2519
2521{
2522 int nb_gens;
2523
2524 nb_gens = F->e * n;
2525 return nb_gens;
2526}
2527
2529{
2530 int i, j, k = 0;
2531 int degree;
2533
2534 degree = Gg.nb_AG_elements(n, F->q);
2535
2536 for (i = 0; i < n; i++) {
2537 for (j = 0; j < F->e; j++, k++) {
2538 affine_translation(n, F, i, j, gens + k * degree, 0 /* verbose_level */);
2539 }
2540 }
2541}
2542
2544 int f_translations,
2545 int f_semilinear, int frobenius_power,
2546 int f_multiplication, int multiplication_order,
2547 int &nb_gens, int &degree, int *&gens,
2548 int &base_len, long int *&the_base, int verbose_level)
2549{
2550 int f_v = (verbose_level >= 1);
2551 int k, h;
2553
2554 if (f_v) {
2555 cout << "group_generators_domain::affine_generators" << endl;
2556 }
2557 degree = Gg.nb_AG_elements(n, F->q);
2558 nb_gens = 0;
2559 base_len = 0;
2560 if (f_translations) {
2561 nb_gens += all_affine_translations_nb_gens(n, F);
2562 base_len++;
2563 }
2564 if (f_multiplication) {
2565 nb_gens++;
2566 base_len++;
2567 }
2568 if (f_semilinear) {
2569 nb_gens++;
2570 base_len++;
2571 }
2572
2573 gens = NEW_int(nb_gens * degree);
2574 the_base = NEW_lint(base_len);
2575 k = 0;
2576 h = 0;
2577 if (f_translations) {
2578 all_affine_translations(n, F, gens);
2580 the_base[h++] = 0;
2581 }
2582 if (f_multiplication) {
2583 affine_multiplication(n, F, multiplication_order,
2584 gens + k * degree, 0 /* verbose_level */);
2585 k++;
2586 the_base[h++] = 1;
2587 }
2588 if (f_semilinear) {
2589 affine_frobenius(n, F, frobenius_power, gens + k * degree, 0 /* verbose_level */);
2590 k++;
2591 the_base[h++] = F->p;
2592 }
2593 if (f_v) {
2594 cout << "group_generators_domain::affine_generators done" << endl;
2595 }
2596}
2597
2599 int n, int m,
2600 long int *orbit, long int *orbit_inv,
2601 int verbose_level)
2602{
2603 int f_v = (verbose_level >= 1);
2604 int *v = NEW_int(n + 1);
2606 long int l = Gg.nb_PG_elements(n, F->q);
2607 long int ll = Gg.nb_PG_elements_not_in_subspace(n, m, F->q);
2608 long int i, j1 = 0, j2 = ll, f_in, j;
2609
2610 if (f_v) {
2611 cout << "group_generators_domain::PG_element_modified_not_in_subspace_perm" << endl;
2612 }
2613 for (i = 0; i < l; i++) {
2614 F->PG_element_unrank_modified_lint(v, 1, n + 1, i);
2615 f_in = Gg.PG_element_modified_is_in_subspace(n, m, v);
2616 if (f_v) {
2617 cout << i << " : ";
2618 for (j = 0; j < n + 1; j++) {
2619 cout << v[j] << " ";
2620 }
2621 }
2622 if (f_in) {
2623 if (f_v) {
2624 cout << " is in the subspace" << endl;
2625 }
2626 orbit[j2] = i;
2627 orbit_inv[i] = j2;
2628 j2++;
2629 }
2630 else {
2631 if (f_v) {
2632 cout << " is not in the subspace" << endl;
2633 }
2634 orbit[j1] = i;
2635 orbit_inv[i] = j1;
2636 j1++;
2637 }
2638 }
2639 if (j1 != ll) {
2640 cout << "j1 != ll" << endl;
2641 exit(1);
2642 }
2643 if (j2 != l) {
2644 cout << "j2 != l" << endl;
2645 exit(1);
2646 }
2647 FREE_int(v);
2648 if (f_v) {
2649 cout << "group_generators_domain::PG_element_modified_not_in_subspace_perm done" << endl;
2650 }
2651}
2652
2653
2654
2655
2656}}}
2657
2658
void all_affine_translations(int n, field_theory::finite_field *F, int *gens)
void general_linear_matrix_group_base_and_transversal_length(int n, field_theory::finite_field *F, int f_semilinear, int base_len, int degree, long int *base, int *transversal_length, int verbose_level)
int matrix_group_base_len_projective_group(int n, int q, int f_semilinear, int verbose_level)
void generators_for_stabilizer_of_triangle_in_PGL4(int f_semilinear, field_theory::finite_field *F, int *&data, int &size, int &nb_gens, int verbose_level)
void generators_concatenate(int deg1, int nb_perms1, int *perms1, int deg2, int nb_perms2, int *perms2, int &deg3, int &nb_perms3, int *&perms3, int verbose_level)
void order_Pomega_plus(int m, int q, ring_theory::longinteger_object &o, int verbose_level)
void generators_dihedral_involution(int deg, int &nb_perms, int *&perms, int verbose_level)
void order_Pomega_parabolic(int m, int q, ring_theory::longinteger_object &o, int verbose_level)
void generators_symmetric_group(int deg, int &nb_perms, int *&perms, int verbose_level)
int all_affine_translations_nb_gens(int n, field_theory::finite_field *F)
int matrix_group_base_len_general_linear_group(int n, int q, int f_semilinear, int verbose_level)
void builtin_transversal_rep_GLnq(int *A, int n, field_theory::finite_field *F, int f_semilinear, int i, int j, int verbose_level)
void generators_dihedral_group(int deg, int &nb_perms, int *&perms, int verbose_level)
void generators_Hall_reflection(int nb_pairs, int &nb_perms, int *&perms, int &degree, int verbose_level)
void order_PO_plus(int m, int q, ring_theory::longinteger_object &o, int verbose_level)
void generators_Bn_group(int n, int &deg, int &nb_perms, int *&perms, int verbose_level)
void order_Hall_reflection_normalizer_factorized(int nb_pairs, int *&factors, int &nb_factors)
void order_Pomega(int epsilon, int k, int q, ring_theory::longinteger_object &go, int verbose_level)
void frobenius_orbit_perm(int n, field_theory::finite_field *F, long int *orbit, long int *orbit_inv, int verbose_level)
void order_Bn_group_factorized(int n, int *&factors, int &nb_factors)
void affine_translation(int n, field_theory::finite_field *F, int coordinate_idx, int field_base_idx, int *perm, int verbose_level)
void generators_direct_product(int deg1, int nb_perms1, int *perms1, int deg2, int nb_perms2, int *perms2, int &deg3, int &nb_perms3, int *&perms3, int verbose_levels)
int matrix_group_base_len_affine_group(int n, int q, int f_semilinear, int verbose_level)
void generators_identity_group(int deg, int &nb_perms, int *&perms, int verbose_level)
void strong_generators_for_affine_linear_group(int n, field_theory::finite_field *F, int f_semilinear, int *&data, int &size, int &nb_gens, int verbose_level)
void projective_matrix_group_base_and_orbits(int n, field_theory::finite_field *F, int f_semilinear, int base_len, int degree, long int *base, int *transversal_length, long int **orbit, long int **orbit_inv, int verbose_level)
void generators_cyclic_group(int deg, int &nb_perms, int *&perms, int verbose_level)
void order_PO_epsilon(int f_semilinear, int epsilon, int k, int q, ring_theory::longinteger_object &go, int verbose_level)
void generators_for_parabolic_subgroup(int n, field_theory::finite_field *F, int f_semilinear, int k, int *&data, int &size, int &nb_gens, int verbose_level)
void affine_multiplication(int n, field_theory::finite_field *F, int multiplication_order, int *perm, int verbose_level)
void order_PO_minus(int m, int q, ring_theory::longinteger_object &o, int verbose_level)
void projective_matrix_group_base_and_transversal_length(int n, field_theory::finite_field *F, int f_semilinear, int base_len, int degree, long int *base, int *transversal_length, int verbose_level)
void diagonal_orbit_perm(int n, field_theory::finite_field *F, long int *orbit, long int *orbit_inv, int verbose_level)
void affine_frobenius(int n, field_theory::finite_field *F, int k, int *perm, int verbose_level)
void affine_matrix_group_base_and_transversal_length(int n, field_theory::finite_field *F, int f_semilinear, int base_len, int degree, long int *base, int *transversal_length, int verbose_level)
void generators_for_stabilizer_of_three_collinear_points_in_PGL4(int f_semilinear, field_theory::finite_field *F, int *&data, int &size, int &nb_gens, int verbose_level)
void affine_generators(int n, field_theory::finite_field *F, int f_translations, int f_semilinear, int frobenius_power, int f_multiplication, int multiplication_order, int &nb_gens, int &degree, int *&gens, int &base_len, long int *&the_base, int verbose_level)
void order_POmega_epsilon(int epsilon, int m, int q, ring_theory::longinteger_object &o, int verbose_level)
int index_POmega_in_PO(int epsilon, int m, int q, int verbose_level)
void order_Pomega_minus(int m, int q, ring_theory::longinteger_object &o, int verbose_level)
void generators_Hall_reflection_normalizer_group(int nb_pairs, int &nb_perms, int *&perms, int &degree, int verbose_level)
void strong_generators_for_projective_linear_group(int n, field_theory::finite_field *F, int f_semilinear, int *&data, int &size, int &nb_gens, int verbose_level)
void order_PO(int epsilon, int m, int q, ring_theory::longinteger_object &o, int verbose_level)
void PG_element_modified_not_in_subspace_perm(field_theory::finite_field *F, int n, int m, long int *orbit, long int *orbit_inv, int verbose_level)
void order_PO_parabolic(int m, int q, ring_theory::longinteger_object &o, int verbose_level)
void strong_generators_for_general_linear_group(int n, field_theory::finite_field *F, int f_semilinear, int *&data, int &size, int &nb_gens, int verbose_level)
void perm_direct_product(long int n1, long int n2, int *perm1, int *perm2, int *perm3)
void PG_element_unrank_modified(int *v, int stride, int len, int a)
void PG_element_unrank_modified_lint(int *v, int stride, int len, long int a)
void PG_element_unrank_modified_not_in_subspace(int *v, int stride, int len, int m, long int a)
void PG_element_rank_modified_lint(int *v, int stride, int len, long int &a)
various functions related to geometries
Definition: geometry.h:721
void AG_element_unrank(int q, int *v, int stride, int len, long int a)
long int nb_PG_elements_not_in_subspace(int n, int m, int q)
long int AG_element_rank(int q, int *v, int stride, int len)
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 integral_division_by_int(longinteger_object &a, int b, longinteger_object &q, int &r)
void mult(longinteger_object &a, longinteger_object &b, longinteger_object &c)
a class to represent arbitrary precision integers
Definition: ring_theory.h:366
void create(long int i, const char *file, int line)
#define Int_vec_print_integer_matrix(A, B, C, D)
Definition: foundations.h:690
#define FREE_int(p)
Definition: foundations.h:640
#define Int_vec_zero(A, B)
Definition: foundations.h:713
#define Lint_vec_print(A, B, C)
Definition: foundations.h:686
#define NEW_int(n)
Definition: foundations.h:625
#define TRUE
Definition: foundations.h:231
#define FALSE
Definition: foundations.h:234
#define EVEN(x)
Definition: foundations.h:221
#define Int_vec_copy(A, B, C)
Definition: foundations.h:693
#define DOUBLYEVEN(x)
Definition: foundations.h:223
#define NEW_lint(n)
Definition: foundations.h:628
#define Int_vec_print(A, B, C)
Definition: foundations.h:685
the orbiter library for the classification of combinatorial objects