Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download

GAP 4.8.9 installation with standard packages -- copy to your CoCalc project to get it

563580 views
1
/* last change: 01.03.01 by Oliver Heidbuechel */
2
3
4
#include <typedef.h>
5
#include <matrix.h>
6
#include <bravais.h>
7
#include <base.h>
8
#include <graph.h>
9
#include <presentation.h>
10
#include <longtools.h>
11
12
13
14
extern int INFO_LEVEL;
15
16
17
/* -------------------------------------------------------------------- */
18
/* transform the i-th row of a matrix to a list of integers */
19
/* -------------------------------------------------------------------- */
20
static int *row_to_list(matrix_TYP *mat,
21
int i)
22
{
23
int *list, n;
24
25
list = (int *)calloc(mat->cols, sizeof(int));
26
for (n = 0; n < mat->cols; n++)
27
list[n] = mat->array.SZ[i][n];
28
29
return(list);
30
}
31
32
33
34
/* -------------------------------------------------------------------- */
35
/* in mats we have words for the generators of one represenative of */
36
/* each conjugacy class of maximal subgroups of G */
37
/* in the last row there has to be the number of elements in the */
38
/* conjugacy class */
39
/* fill a t_sub_TYP - structure with the generators for each */
40
/* representative of a conjugacy class */
41
/* -------------------------------------------------------------------- */
42
static t_sub_TYP *t_sub_info(matrix_TYP **mats,
43
int anz,
44
bravais_TYP *G,
45
matrix_TYP **G_geninv)
46
{
47
t_sub_TYP *sub;
48
49
int i, j, no;
50
51
matrix_TYP **base;
52
53
54
/* prepare */
55
sub = (t_sub_TYP *)calloc(1, sizeof(t_sub_TYP));
56
sub->con_no = anz;
57
sub->groups = (bravais_TYP **)calloc(anz, sizeof(bravais_TYP *));
58
sub->worte = (int ***)calloc(anz, sizeof(int **));
59
sub->elem_no = (int *)calloc(anz, sizeof(int));
60
sub->strong = (bahn ***)calloc(anz, sizeof(bahn **));
61
sub->orders = (int *)calloc(anz, sizeof(int));
62
sub->total = 0;
63
64
for (i = 0; i < anz; i++){
65
no = mats[i]->rows - 1;
66
sub->groups[i] = init_bravais(G->dim);
67
if (no == 0)
68
sub->groups[i]->gen = NULL;
69
else
70
sub->groups[i]->gen = (matrix_TYP **)calloc(no, sizeof(matrix_TYP *));
71
sub->groups[i]->gen_no = no;
72
sub->worte[i] = (int **)calloc(no, sizeof(int *));
73
for (j = 0; j < no; j++){
74
sub->worte[i][j] = row_to_list(mats[i], j);
75
sub->groups[i]->gen[j] = mapped_word(sub->worte[i][j], G->gen, G_geninv);
76
}
77
/* in the last row there is the number of elements in the conjugacy class
78
and the order of the elements */
79
sub->elem_no[i] = mats[i]->array.SZ[no][0];
80
sub->orders[i] = sub->groups[i]->order = mats[i]->array.SZ[no][1];
81
sub->total += sub->elem_no[i];
82
83
/* calculate strong generating set */
84
base = get_base(G);
85
/*
86
???????????????????????????????????????????????????????????????????????
87
*/
88
sub->strong[i] = strong_generators(base, sub->groups[i], TRUE);
89
for (j = 0; j < G->dim; j++){
90
free_mat(base[j]);
91
}
92
free(base);
93
}
94
95
return(sub);
96
}
97
98
99
100
/* -------------------------------------------------------------------- */
101
/* free a t_sub_TYP - structure */
102
/* -------------------------------------------------------------------- */
103
static void free_t_sub_TYP(t_sub_TYP *sub)
104
{
105
int i, j, dim = sub->groups[0]->dim;
106
107
108
for (i = 0; i < sub->con_no; i++){
109
for (j = 0; j < sub->groups[i]->gen_no; j++){
110
free(sub->worte[i][j]);
111
}
112
free(sub->worte[i]);
113
free_bravais(sub->groups[i]);
114
for (j = 0; j < dim; j++){
115
free_bahn(sub->strong[i][j]);
116
free(sub->strong[i][j]);
117
}
118
free(sub->strong[i]);
119
}
120
free(sub->strong);
121
free(sub->worte);
122
free(sub->groups);
123
free(sub->elem_no);
124
free(sub->orders);
125
free(sub);
126
}
127
128
129
130
/* --------------------------------------------------------------------
131
Suppose the matrices in G->gen generate a finite matrix group, and N
132
generates a matrix group with the condition that the orbit of N
133
on the conjugated of G under N is finite.
134
135
The groups in the orbit will be given by the element that conjugates them!
136
137
Declaration of variables:
138
G: matrices generating G,
139
N: see above
140
Nanz: number of elements in N
141
strong: a set of base/strong generators for G returned by strong_generators
142
143
Sideefects: None of the variables given nor global variables should be affected.
144
145
The code is out of Base/conjugate.c!
146
-------------------------------------------------------------------- */
147
static matrix_TYP **conjugated_groups(bravais_TYP *G,
148
matrix_TYP **N,
149
int Nanz,
150
bahn **strong,
151
int *anz)
152
{
153
154
matrix_TYP **orbit, /* represents the orbit of G under N by the
155
conjugating element */
156
*test_subgroup,
157
*tmp,
158
*tmp2,
159
*tmp3,
160
*tmp4;
161
162
int found=1, /* number of conjugated subgroups found so far */
163
dealt=0, /* number of those dealt with */
164
i,
165
j,
166
k,
167
flag;
168
169
if (INFO_LEVEL & 4){
170
fprintf(stderr,"entering conjugated\n");
171
}
172
173
174
orbit = (matrix_TYP **)calloc(1, sizeof(matrix_TYP *));
175
orbit[0] = init_mat(G->gen[0]->cols, G->gen[0]->cols, "1");
176
177
/* start the orbit calculation */
178
while (dealt < found){
179
180
/* output for debugging */
181
if (INFO_LEVEL & 4){
182
fprintf(stderr,"got %i conjugated subgroups so far\n",found);
183
fprintf(stderr,"dealt with %i of these\n",dealt);
184
}
185
/* loop over the generators of N */
186
for (i=0; i < Nanz;i++){
187
188
/* calculating the new element */
189
test_subgroup = mat_mul(orbit[dealt],N[i]);
190
191
/* see if this gives really a new element */
192
j=0;
193
tmp = mat_inv(test_subgroup);
194
while ((test_subgroup != NULL) && (j< found)){
195
tmp2 = mat_mul(orbit[j],tmp);
196
tmp3 = mat_inv(tmp2);
197
k=0;
198
flag = TRUE;
199
while (flag && (k<G->gen_no)){
200
tmp4 = mat_mul(tmp2,G->gen[k]);
201
tmp4 = mat_muleq(tmp4,tmp3);
202
if (!is_element(tmp4,G,strong,NULL)){
203
flag = FALSE;
204
}
205
free_mat(tmp4);
206
k++;
207
}
208
209
if (flag){
210
free_mat(test_subgroup);
211
test_subgroup = NULL;
212
}
213
free_mat(tmp2);
214
free_mat(tmp3);
215
j++;
216
}
217
218
/* get more memory */
219
if (test_subgroup != NULL){
220
orbit = (matrix_TYP **) realloc(orbit, (found + 1) * sizeof(matrix_TYP*));
221
orbit[found] = test_subgroup;
222
found++;
223
}
224
free_mat(tmp);
225
226
} /* for (i= .... */
227
dealt++;
228
}
229
230
anz[0] = found;
231
232
return(orbit);
233
}
234
235
236
237
/* -------------------------------------------------------------------- */
238
/* Let G and H be two groups with the same finite order. */
239
/* strong has to be the result of a call of strong_generators() for G */
240
/* returns TRUE iff H == G */
241
/* -------------------------------------------------------------------- */
242
static boolean equal_groups(bravais_TYP *H,
243
bravais_TYP *G,
244
bahn **strong)
245
{
246
int i;
247
248
boolean FLAG = TRUE;
249
250
251
for (i = 0; FLAG && i < H->gen_no; i++){
252
if (!is_element(H->gen[i], G, strong, NULL)) FLAG = FALSE;
253
}
254
255
return(FLAG);
256
}
257
258
259
260
/* -------------------------------------------------------------------- */
261
/* If the elements in conjugacy class i and j are in one orbit, the */
262
/* conjugacy classes have to have the same number of elements and the */
263
/* representatives have to have the same order. */
264
/* -------------------------------------------------------------------- */
265
static int *construct_help_list(t_sub_TYP *sub)
266
{
267
int *help, i, j, counter = 1;
268
269
boolean flag;
270
271
272
help = (int *)calloc(sub->con_no, sizeof(int));
273
for (i = 0; i < sub->con_no; i++){
274
if (help[i] == 0){
275
help[i] = -counter;
276
flag = FALSE;
277
for (j = i + 1; j < sub->con_no; j++){
278
if (sub->orders[j] == sub->orders[i] &&
279
sub->elem_no[j] == sub->elem_no[i]){
280
help[j] = -counter;
281
flag = TRUE;
282
}
283
}
284
if (flag == FALSE){
285
/* there is only one conjugacy class with this combination
286
of order and length */
287
help[i] = 0;
288
}
289
counter++;
290
}
291
}
292
293
return(help);
294
}
295
296
297
298
/* -------------------------------------------------------------------- */
299
/* mats: matrices with information about the maximal subgroups of G out */
300
/* of a GAP-programm */
301
/* no: no of mats */
302
/* pres: presentation for G */
303
/* aff_no: save the number of affine classes here */
304
/* aff_cons: save the no of conjugacy classes of each affine class here */
305
/* aff_cons_no: save the no of elements in each conjugacy class of each */
306
/* affine class here */
307
/* R: save representatives for the affine classes here */
308
/* flag: 0: only representatives are calculated */
309
/* 1: all subgroups are calculated */
310
311
/* G->normal and G->gen have to generate the normalizer of G!!!!! */
312
313
/* -------------------------------------------------------------------- */
314
bravais_TYP ****t_subgroups(bravais_TYP *G,
315
matrix_TYP **mats,
316
int no,
317
matrix_TYP *pres,
318
int *aff_no,
319
int **aff_cons,
320
int ***aff_cons_no,
321
bravais_TYP ***R,
322
int flag)
323
{
324
t_sub_TYP *sub;
325
326
bravais_TYP ****S, **group;
327
328
int i, j, k, l, counter, together,
329
cen_no, orbit_no, coho_size,
330
*stab_genno, ***WORDS, *NUMBER_OF_WORDS, *trashlist,
331
*help_list;
332
333
matrix_TYP **G_geninv, **coz, **X, **trash, **G_norminv, ***stab,
334
**conj, **Rinv, *inv, *cocycle;
335
336
MP_INT *names;
337
338
339
/* deal with trivial case */
340
if (no == 0){
341
/* there is no subgroup */
342
R[0] = (bravais_TYP **)calloc(1, sizeof(bravais_TYP *));
343
R[0][0] = init_bravais(G->dim + 1);
344
R[0][0]->gen = (matrix_TYP **)calloc(1, sizeof(matrix_TYP *));
345
R[0][0]->gen_no = 1;
346
R[0][0]->gen[0] = init_mat(G->dim + 1, G->dim + 1, "1");
347
aff_cons[0] = NULL;
348
aff_cons_no[0] = NULL;
349
aff_no[0] = 0;
350
return(NULL);
351
}
352
353
/* prepare */
354
cen_no = G->cen_no; G->cen_no = 0;
355
G_geninv = (matrix_TYP **)calloc(G->gen_no, sizeof(matrix_TYP *));
356
sub = t_sub_info(mats, no, G, G_geninv);
357
WORDS = (int ***)calloc(MIN_SPEICHER, sizeof(int **));
358
NUMBER_OF_WORDS = (int *)calloc(MIN_SPEICHER, sizeof(int));
359
coz = all_cocycles(pres, G, aff_no, G_geninv, &X, &names, WORDS, NUMBER_OF_WORDS,
360
&trash, &coho_size, &trashlist, 1);
361
if (trash != NULL){
362
for (i = 0; i < G->normal_no; i++)
363
if (trash[i] != NULL) free_mat(trash[i]);
364
free(trash);
365
}
366
for (i = 0; i < G->gen_no; i++)
367
if (G_geninv[i] != NULL) free_mat(G_geninv[i]);
368
free(G_geninv);
369
aff_cons[0] = (int *)calloc(aff_no[0], sizeof(int));
370
aff_cons_no[0] = (int **)calloc(aff_no[0], sizeof(int *));
371
R[0] = (bravais_TYP **)calloc(aff_no[0], sizeof(bravais_TYP *));
372
for (i = 0; i < aff_no[0]; i++){
373
aff_cons_no[0][i] = (int *)calloc(sub->con_no, sizeof(int));
374
R[0][i] = extract_r(G, coz[i]);
375
}
376
S = (bravais_TYP ****)calloc(aff_no[0], sizeof(bravais_TYP ***));
377
378
/* is it another trivial case */
379
if (no == 1 && mats[0]->rows == 1){
380
/* only the trivial group is a subgroup */
381
for (i = 0; i < aff_no[0]; i++){
382
S[i] = (bravais_TYP ***)calloc(1, sizeof(bravais_TYP **));
383
S[i][0] = (bravais_TYP **)calloc(1, sizeof(bravais_TYP *));
384
S[i][0][0] = init_bravais(G->dim + 1);
385
S[i][0][0]->gen = (matrix_TYP **)calloc(1, sizeof(matrix_TYP *));
386
S[i][0][0]->gen_no = 1;
387
S[i][0][0]->gen[0] = init_mat(G->dim + 1, G->dim + 1, "1");
388
aff_cons[0][i] = 1;
389
aff_cons_no[0][i][0] = 1;
390
}
391
}
392
else{
393
/* get the point group of the affine normalizer for each affine class representative */
394
G_norminv = (matrix_TYP **)calloc(G->normal_no, sizeof(matrix_TYP *));
395
stab = (matrix_TYP ***)calloc(aff_no[0], sizeof(matrix_TYP **));
396
stab_genno = (int *)calloc(aff_no[0], sizeof(int));
397
for (i = 0; i < aff_no[0]; i++){
398
stab[i] = stab_coz(WORDS[i], NUMBER_OF_WORDS[i], G->normal, G_norminv,
399
G->normal_no, i, &stab_genno[i]);
400
stab[i] = realloc(stab[i], (stab_genno[i] + G->gen_no) * sizeof(matrix_TYP *));
401
for (j = 0; j < G->gen_no; j++)
402
stab[i][j + stab_genno[i]] = G->gen[j];
403
}
404
405
/* which subgroups are in the same orbit */
406
for (i = 0; i < aff_no[0]; i++){
407
Rinv = (matrix_TYP **)calloc(R[0][i]->gen_no, sizeof(matrix_TYP *));
408
counter = 0;
409
help_list = construct_help_list(sub);
410
S[i] = (bravais_TYP ***)calloc(sub->con_no, sizeof(bravais_TYP **));
411
for (j = 0; j < sub->con_no; j++){
412
if (help_list[j] <= 0){
413
414
if (help_list[j] < 0){
415
/* possibly we have to join this conjugacy class with another one */
416
help_list[j] *= -1;
417
418
/* calculate orbit */
419
conj = conjugated_groups(sub->groups[j], stab[i], stab_genno[i] + G->gen_no,
420
sub->strong[j], &orbit_no);
421
group = (bravais_TYP **)calloc(orbit_no, sizeof(bravais_TYP *));
422
423
if (orbit_no % sub->elem_no[j] != 0){ /* paranoia test */
424
fprintf(stderr, "ERROR 1 in t_subgroups\n");
425
exit(6);
426
}
427
428
together = orbit_no / sub->elem_no[j];
429
/* we have to join "together" conjugacy classes - which? */
430
if (together > 1){
431
for (k = 1; together > 1 && k < orbit_no; k++){
432
inv = long_mat_inv(conj[k]);
433
group[k] = konj_bravais(sub->groups[j], inv);
434
free_mat(inv);
435
for (l = j + 1; together > 1 && l < sub->con_no; l++){
436
if (equal_groups(group[k], sub->groups[l], sub->strong[l])){
437
together--;
438
help_list[l] *= -1;
439
}
440
}
441
}
442
}
443
if (together != 1){ /* paranoia test */
444
fprintf(stderr, "ERROR 2 in t_subgroups\n");
445
exit(5);
446
}
447
}
448
else{
449
/* only the elements in this conjugacy class are in an orbit under
450
the normalizer */
451
if (sub->elem_no[j] == 1){
452
/* only one element in the conjugacy class */
453
conj = NULL;
454
orbit_no = 1;
455
group = NULL;
456
}
457
else{
458
conj = conjugated_groups(sub->groups[i], G->gen, G->gen_no,
459
sub->strong[i], &orbit_no);
460
group = (bravais_TYP **)calloc(orbit_no, sizeof(bravais_TYP *));
461
}
462
}
463
if (flag == 0)
464
S[i][counter] = (bravais_TYP **)calloc(1, sizeof(bravais_TYP *));
465
else
466
S[i][counter] = (bravais_TYP **)calloc(orbit_no, sizeof(bravais_TYP *));
467
468
/* calculate the first element in the conjugacy class */
469
S[i][counter][0] = init_bravais(R[0][i]->dim);
470
S[i][counter][0]->gen_no = sub->groups[j]->gen_no;
471
S[i][counter][0]->gen = (matrix_TYP **)calloc(sub->groups[j]->gen_no,
472
sizeof(matrix_TYP *));
473
for (k = 0; k < sub->groups[j]->gen_no; k++){
474
S[i][counter][0]->gen[k] = mapped_word(sub->worte[j][k], R[0][i]->gen, Rinv);
475
}
476
477
if (flag != 0){
478
/* calculate the other groups in this conjugacy class */
479
for (k = 1; k < orbit_no; k++){
480
if (group[k] == NULL){
481
inv = long_mat_inv(conj[k]);
482
group[k] = konj_bravais(sub->groups[j], inv);
483
free_mat(inv);
484
}
485
cocycle = sg(R[0][i], group[k]);
486
S[i][counter][k] = extract_r(group[k], cocycle);
487
free_mat(cocycle);
488
}
489
}
490
aff_cons_no[0][i][counter] = orbit_no;
491
counter++;
492
493
for (k = 0; group != NULL && k < orbit_no; k++)
494
if (group[k] != NULL) free_bravais(group[k]);
495
if (group != NULL) free(group);
496
for (k = 0; conj != NULL && k < orbit_no; k++)
497
free_mat(conj[k]);
498
if (conj != NULL) free(conj);
499
}
500
}
501
free(help_list);
502
aff_cons[0][i] = counter;
503
for (j = 0; j < R[0][i]->gen_no; j++)
504
if (Rinv[j] != NULL) free_mat(Rinv[j]);
505
free(Rinv);
506
}
507
508
/* clean */
509
for (i = 0; i < aff_no[0]; i++){
510
for (j = 0; j < stab_genno[i]; j++)
511
free_mat(stab[i][j]);
512
free(stab[i]);
513
}
514
free(stab);
515
free(stab_genno);
516
for (i = 0; i < G->normal_no; i++)
517
if (G_norminv[i] != NULL) free_mat(G_norminv[i]);
518
free(G_norminv);
519
}
520
521
/* clean */
522
free_t_sub_TYP(sub);
523
for (i = 0; i < 3; i++)
524
free_mat(X[i]);
525
free(X);
526
for (i = 0; i < aff_no[0]; i++){
527
free_mat(coz[i]);
528
if (WORDS[i] != NULL){
529
for (j = 0; j < NUMBER_OF_WORDS[i]; j++)
530
if (WORDS[i][j] != NULL)
531
free(WORDS[i][j]);
532
free(WORDS[i]);
533
}
534
mpz_clear(names + i);
535
}
536
free(coz);
537
if (WORDS != NULL) free(WORDS);
538
free(NUMBER_OF_WORDS);
539
free(names);
540
541
G->cen_no = cen_no;
542
return(S);
543
}
544
545
546
547
548
549
550
551
552
553
554