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

563665 views
1
#include "typedef.h"
2
#include "contrib.h"
3
#include "matrix.h"
4
#include "getput.h"
5
#include "idem.h"
6
#include "sort.h"
7
#include "orbit.h"
8
#include "bravais.h"
9
10
static int *trace_list_B;
11
static int *order_list_B;
12
13
static int *traces_of_inv_A;
14
static int **traces_of_prod_A;
15
16
static int *image_of_Gen_A;
17
18
static void *xmalloc (int size, const char *string)
19
{
20
void *pointer;
21
22
if( (pointer = malloc(size)) == NULL)
23
{
24
perror (string);
25
exit (2);
26
}
27
28
return pointer;
29
}
30
31
static int krit_kon_mat (matrix_TYP **A, matrix_TYP **B, int anz,
32
matrix_TYP ***M, int *dim)
33
{
34
matrix_TYP **AA, **BA, **AB,**Prod, *mat;
35
int ab, aa, ba, pp,i,j;
36
37
AB = solve_endo (A, B, anz, &ab);
38
BA = solve_endo (B, A, anz, &ba);
39
*dim = ab;
40
*M = AB;
41
if (ab == ba)
42
{
43
AA = solve_endo (A, A, anz, &aa);
44
if (ab == aa)
45
{
46
Prod = (matrix_TYP **) xmalloc (aa * aa * sizeof (matrix_TYP *), "krit_kon_mat"); /* Prod = (matrix_TYP **) calloc (aa*aa, sizeof (matrix_TYP *)); */
47
for (i=0; i<aa; i++)
48
for (j=0; j<aa; j++)
49
Prod[i*aa + j] = mat_mul (AB[i], BA[j]);
50
51
mat = mat_to_line (Prod, aa*aa);
52
53
for (i=0; i<aa*aa; i++)
54
free_mat (Prod[i]);
55
free (Prod);
56
57
pp = tgauss (mat);
58
free_mat (mat);
59
60
if (pp == aa)
61
{
62
if (ab != 0)
63
{
64
for (i=0; i<ba; i++)
65
free_mat (BA[i]);
66
free (BA);
67
}
68
if (aa != 0)
69
{
70
for (i=0; i<aa; i++)
71
free_mat (AA[i]);
72
free (AA);
73
}
74
return 1;
75
}
76
else
77
{
78
if (ab != 0)
79
{
80
for (i=0; i<ba; i++)
81
free_mat (BA[i]);
82
free (BA);
83
}
84
if (aa != 0)
85
{
86
for(i=0; i<aa; i++)
87
free_mat (AA[i]);
88
free (AA);
89
}
90
return 0;
91
}
92
}
93
else
94
{
95
if (ab != 0)
96
{
97
for (i=0; i<ba; i++)
98
free_mat (BA[i]);
99
free (BA);
100
}
101
if (aa != 0)
102
{
103
for (i=0; i<aa; i++)
104
free_mat (AA[i]);
105
free (AA);
106
}
107
return 0;
108
}
109
}
110
else
111
{
112
if (ab != 0)
113
{
114
for (i=0; i<ba; i++)
115
free_mat (BA[i]);
116
free (BA);
117
}
118
if (aa != 0)
119
{
120
for (i=0; i<aa; i++)
121
free_mat (AA[i]);
122
free (AA);
123
}
124
return 0;
125
}
126
127
}
128
129
130
static matrix_TYP *suche_max_rank (matrix_TYP *mat_best, matrix_TYP **solve,
131
int dim, int step, int *found,
132
int rank_mat_best, int *rank)
133
{
134
matrix_TYP **alternative, *m, *n, *B, *gau, *mat;
135
int i, l, rank_m, rank_n, rank_B, rank_mat, z = 0;
136
137
B = solve[step];
138
gau = ggauss(B);
139
rank_B = gau->rows;
140
alternative = (matrix_TYP **) calloc (rank_B,sizeof(matrix_TYP *));
141
free_mat (gau);
142
143
for(l=1; l<rank_B+1 && rank_mat_best != B->rows; l++)
144
{
145
mat = imat_add (mat_best,B,1,l);
146
gau = ggauss (mat);
147
rank_mat = gau->rows;
148
free_mat (gau);
149
if (rank_mat > rank_mat_best)
150
{
151
rank_mat_best=rank_mat;
152
for (i=0; i<z; i++)
153
free_mat(alternative[i]);
154
z = 0;
155
if(mat_best != solve[0])
156
free_mat(mat_best);
157
mat_best=mat;
158
}
159
else
160
{
161
if(rank_mat == rank_mat_best)
162
{
163
alternative[z] = mat;
164
z++;
165
}
166
else
167
free_mat(mat);
168
}
169
}
170
*rank = rank_mat_best;
171
if (rank_mat_best == B->rows)
172
{
173
*found = 1;
174
for(i=0; i<z; i++)
175
free_mat (alternative[i]);
176
free (alternative);
177
178
if (mat_best != solve[0])
179
return mat_best;
180
else
181
return copy_mat(mat_best);
182
}
183
if(step == dim-1)
184
{
185
*found = 0;
186
for (i=0; i<z; i++)
187
free_mat (alternative[i]);
188
free (alternative);
189
return mat_best;
190
}
191
m = suche_max_rank (mat_best, solve, dim, step+1, found,
192
rank_mat_best, &rank_m);
193
while (z > 0 && *found == 0)
194
{
195
n = suche_max_rank (alternative[z-1], solve, dim, step+1, found,
196
rank_mat_best, &rank_n);
197
z--;
198
if(rank_n > rank_m)
199
{
200
free_mat (m);
201
m = n;
202
rank_m = rank_n;
203
}
204
else
205
free_mat (n);
206
}
207
*rank = rank_m;
208
209
for (i=0; i<z; i++)
210
free_mat (alternative[i]);
211
free (alternative);
212
213
return m;
214
}
215
216
217
static matrix_TYP *suche_kon_mat (matrix_TYP **solve, int dim)
218
{
219
int rank_mat_best, found = 0;
220
matrix_TYP *A, *gau, *mat_best;
221
222
A = solve[0];
223
gau = ggauss (A);
224
/* rank_mat_best=gau->rows; */
225
if(dim > 1)
226
mat_best = suche_max_rank (A, solve, dim, 1, &found, gau->rows,
227
&rank_mat_best);
228
else
229
{
230
rank_mat_best = gau->rows;
231
mat_best = copy_mat (A);
232
}
233
free_mat (gau);
234
if(rank_mat_best != A->rows)
235
printf("Keine invertierbare Loesung gefunden.\n");
236
return(mat_best);
237
}
238
239
/* Hier wird die Ordnung von m ausgerechnet, und zurueckgegeben. */
240
241
static int order (matrix_TYP *m)
242
{
243
int i = 1;
244
matrix_TYP *n, *E;
245
246
n = copy_mat (m);
247
E = einheitsmatrix(m->rows);
248
249
while(cmp_mat(n, E) != 0)
250
{
251
n = mat_muleq(n, m);
252
253
i++;
254
}
255
256
free_mat(E);
257
258
free_mat(n);
259
260
return i;
261
}
262
263
static int **calc_traces_of_prod (bravais_TYP *G)
264
{
265
int **mat, i, j;
266
267
matrix_TYP *waste;
268
269
mat = (int **) xmalloc(G->gen_no*sizeof(int *), "calc_traces_of_prod");
270
271
for (i=0; i<G->gen_no; i++)
272
mat[i] = (int *) xmalloc(G->gen_no*sizeof(int),"calc_traces_of_prod");
273
274
/* Keine Lust Symmetrie der Matrix zu benutzen! */
275
for (i=0; i<G->gen_no; i++)
276
for (j=0; j<G->gen_no; j++)
277
{
278
waste = mat_mul(G->gen[i],G->gen[j]);
279
280
mat[i][j] = trace(waste);
281
282
free_mat(waste);
283
}
284
285
286
return mat;
287
}
288
289
static int *calc_traces_of_inv (bravais_TYP *G)
290
{
291
int *mat, i;
292
293
matrix_TYP *waste;
294
295
mat = (int *) xmalloc(G->gen_no*sizeof(int), "calc_traces_of_inv");
296
297
298
for (i=0; i<G->gen_no; i++)
299
{
300
waste = mat_inv(G->gen[i]);
301
302
mat[i] = trace(waste);
303
304
free_mat(waste);
305
}
306
307
308
return mat;
309
}
310
311
/* Get Conjugation Classes of "G" under Group "H". Store the con_class
312
of each element in "list[]" and an "representant_of_con_class" in
313
the array. Return_value is the last array. */
314
315
static int *con_classes (matrix_TYP **G, int order_of_G,
316
bravais_TYP *H, int *number_of_con_classes)
317
{
318
matrix_TYP **orbit;
319
int i, j, pos_in_list, length, *representant_of_con_class, *list;
320
int orbit_options[6] = {4, 0, 0, 0, 0, 0};
321
/* acting.from = Left,
322
acting.by = Conjugation;*/
323
324
*number_of_con_classes = 0;
325
326
list = (int *)xmalloc(order_of_G * sizeof(int), "con_classes");
327
328
representant_of_con_class = (int *)xmalloc(order_of_G * sizeof(int),
329
"con_classes");
330
/* Worst-Case-Allocation: Every element its own con_class. */
331
332
for (i=0; i<order_of_G; i++)
333
list[i] = -1;
334
335
for (i=0; i<order_of_G; i++)
336
if(list[i] == -1)
337
{
338
orbit = orbit_alg(G[i], H, NULL, orbit_options,
339
&length);
340
341
representant_of_con_class[*number_of_con_classes] = i;
342
343
for (j=0; j<length; j++)
344
{
345
pos_in_list = mat_search (orbit[j], G, order_of_G, mat_comp);
346
list[pos_in_list] = *number_of_con_classes;
347
348
free_mat (orbit[j]);
349
}
350
351
free (orbit);
352
353
(*number_of_con_classes) ++;
354
355
}
356
357
representant_of_con_class = (int *) realloc(representant_of_con_class, *number_of_con_classes * sizeof(int));
358
/* Just for the fun of saving a bit of memory. */
359
360
free(list);
361
362
return representant_of_con_class;
363
}
364
365
366
367
/* compute the trace of every element in "group" and store it in "trace_list". */
368
369
static int *compute_trace (matrix_TYP **group, int group_order)
370
{
371
int i;
372
373
int *trace_list = (int *) xmalloc (group_order * sizeof(int), "compute_trace");
374
375
for (i=0; i<group_order; i++)
376
trace_list[i] = trace (group[i]);
377
378
return trace_list;
379
380
}
381
382
383
384
/* compute the order of every element in "group" and store it in "order_list". */
385
386
static int *compute_order (matrix_TYP **group, int group_order)
387
{
388
int i;
389
390
int *order_list = (int *) xmalloc (group_order * sizeof(int), "compute_order");
391
392
for (i=0; i<group_order; i++)
393
order_list[i] = order (group[i]);
394
395
return order_list;
396
397
}
398
399
400
static int end_test (matrix_TYP **matrix, matrix_TYP **A, matrix_TYP **B,
401
int number_of_el_in_A)
402
{
403
matrix_TYP **AA;/*, *mat;*/
404
int found, dim, i;
405
406
found = krit_kon_mat(A, B, number_of_el_in_A, &AA, &dim);
407
408
if (found == TRUE)
409
{
410
/*mat = suche_kon_mat(AA,dim);
411
*matrix = mat;*/
412
*matrix = suche_kon_mat(AA, dim);
413
414
for(i=0; i<dim; i++)
415
free_mat (AA[i]);
416
free (AA);
417
}
418
419
return found;
420
}
421
422
/* returns centralizer of the group generated by elements "H" in
423
"list_of_H". "list_of_H" is "number_of_H"-elements long. */
424
425
static bravais_TYP *get_centralizer(matrix_TYP **H, bravais_TYP *G,
426
int list_of_H[], int number_of_H)
427
{
428
bravais_TYP *C1, *C2;
429
430
matrix_TYP **waste;
431
432
int orbit_options[6] = {4, 0, 3, 0, 0, 0};
433
/*acting.and_calc_stab = TRUE;*/
434
/* act.from = Left,
435
act.by = Conjugation;*/
436
int i, j, laenge;
437
438
C1 = copy_bravais (G);
439
440
C2 = init_bravais (G->dim);
441
442
/* Dies laeuft in etwa darauf hinaus die Stabilisatoren aller "H"s zu
443
schneiden. */
444
for (i=0; i<number_of_H; i++)
445
{
446
waste = orbit_alg(H[list_of_H[i]], C1, C2, orbit_options, &laenge);
447
448
for(j=0; j<laenge; j++)
449
free_mat(waste[j]);
450
free(waste);
451
452
free_bravais(C1);
453
454
C1 = C2;
455
456
C2 = init_bravais (G->dim);
457
458
}
459
460
free_bravais (C2);
461
462
return C1;
463
}
464
465
466
static int traces_are_ok(matrix_TYP *new_element, bravais_TYP *Group_A, matrix_TYP **Group_B, int next_gen)
467
{
468
matrix_TYP *waste;
469
470
int i;
471
472
waste = mat_inv(new_element);
473
474
if (trace(waste) != traces_of_inv_A[next_gen])
475
{
476
free_mat (waste);
477
478
return FALSE;
479
}
480
481
free_mat (waste);
482
483
waste = mat_mul(new_element, new_element);
484
485
if (trace(waste) != traces_of_prod_A[next_gen][next_gen])
486
{
487
free_mat (waste);
488
return FALSE;
489
}
490
491
free_mat (waste);
492
493
for (i=0; i<next_gen; i++)
494
{
495
waste = mat_mul(new_element, Group_B[image_of_Gen_A[i]]);
496
497
if (trace(waste) != traces_of_prod_A[next_gen][i])
498
{
499
free_mat (waste);
500
return FALSE;
501
}
502
503
free_mat (waste);
504
}
505
506
507
return TRUE;
508
509
}
510
511
512
/* function tests if mapping of the generators "Gen_A" in "Group_B" exists
513
which projects "Gen_A[0],..,Gen_A[next_gen -1]" on
514
"Group_B[image_of_Gen_A[0]],...,Group_B[image_of_Gen_A]". writes a
515
possible result back into the rest of the global array "image_of_Gen_A[]".
516
Returns "1" if it succeeds and "0" if it does not. */
517
static int construct_Image_Gen_A (int next_gen, bravais_TYP *Gen_A,
518
int group_order, bravais_TYP *Gen_B,
519
matrix_TYP **Group_B)
520
{
521
int *rep_con_class, number_of_con_classes,
522
trace_next_gen, order_next_gen;
523
524
matrix_TYP *matrix, **Bild;
525
526
int i, j;
527
528
bravais_TYP *centralizer;
529
530
trace_next_gen = trace(Gen_A->gen[next_gen]);
531
order_next_gen = order(Gen_A->gen[next_gen]);
532
533
/* Stabilizer of trivial group is whole group. Maybe faster. */
534
if (next_gen> 0)
535
centralizer = get_centralizer(Group_B, Gen_B, image_of_Gen_A, next_gen);
536
else
537
centralizer = copy_bravais(Gen_B);
538
539
rep_con_class = con_classes (Group_B, group_order, centralizer,
540
&number_of_con_classes);
541
542
543
544
Bild = (matrix_TYP **)xmalloc( (next_gen+1) * sizeof(matrix_TYP *),"construct_Image_Gen_A");
545
546
547
for (i=0; i<next_gen; i++)
548
Bild[i] = Group_B[image_of_Gen_A[i]];
549
550
551
for (i=0; i<number_of_con_classes; i++)
552
if(trace_list_B[rep_con_class[i]] == trace_next_gen &&
553
order_list_B[rep_con_class[i]] == order_next_gen &&
554
traces_are_ok(Group_B[rep_con_class[i]], Gen_A, Group_B, next_gen) == TRUE)
555
{
556
Bild[next_gen] = Group_B[rep_con_class[i]];
557
558
if(end_test (&matrix, Bild, Gen_A->gen, next_gen + 1) == TRUE)
559
{
560
free_mat(matrix);
561
562
image_of_Gen_A[next_gen] = rep_con_class[i];
563
564
if(next_gen + 1 == Gen_A->gen_no)
565
{
566
free (Bild);
567
free (rep_con_class);
568
569
free_bravais (centralizer);
570
571
return TRUE;
572
}
573
else
574
if (construct_Image_Gen_A (next_gen + 1, Gen_A, group_order, Gen_B, Group_B) == TRUE)
575
{
576
free (Bild);
577
free (rep_con_class);
578
579
free_bravais (centralizer);
580
581
return TRUE;
582
}
583
584
}
585
586
}
587
588
free (Bild);
589
free (rep_con_class);
590
591
free_bravais (centralizer);
592
593
return FALSE;
594
}
595
596
597
matrix_TYP *suche_kand (bravais_TYP *Gen_A, bravais_TYP *Gen_B)
598
{
599
matrix_TYP **Group_A, **Group_B;
600
int group_order,laenge, i;
601
602
matrix_TYP *matrix = NULL, **Bild;
603
604
int orbit_options[6] = {0, 0, 0, 0, 0, 0};
605
606
/* acting.from = Left,
607
acting.by = Normal_Operation,
608
acting.on = Matrix_M,
609
acting.until_orbit_length = 0,
610
acting.and_calc_stab = FALSE,
611
acting.until_stab_length = 0;
612
acting.with_inverse = FALSE;
613
*/
614
615
616
/* Check, if the groups have same dimension. */
617
if (Gen_A->dim != Gen_B->dim)
618
{
619
fprintf (stdout, "Groups have different dimension.\n");
620
621
return NULL;
622
}
623
624
/* Compute all elements of the two groups */
625
Group_A = orbit_alg (Gen_A->gen[0], Gen_A, NULL, orbit_options, &group_order);
626
627
Group_B = orbit_alg (Gen_B->gen[0], Gen_B, NULL, orbit_options, &laenge);
628
629
/* We were only interested in the order of Group A,
630
now the Generators are enough. */
631
for (i=0; i<group_order; i++)
632
free_mat (Group_A[i]);
633
free(Group_A);
634
635
/* Check, if the groups have same order. */
636
if (group_order != laenge)
637
{
638
fprintf (stdout, "Groups are of different order.\n");
639
640
for (i=0; i<laenge; i++)
641
free_mat (Group_B[i]);
642
643
free (Group_B);
644
645
return NULL;
646
}
647
648
/* This is necessary because of a "search_mat", at least this is
649
what I believe. */
650
mat_quicksort (Group_B, 0, group_order - 1, mat_comp);
651
652
653
654
/* orbit_options[0] = 4;*/
655
/* acting.from = Left,
656
acting.by = Conjugation;*/
657
658
659
660
trace_list_B = compute_trace (Group_B, group_order);
661
662
order_list_B = compute_order (Group_B, group_order);
663
664
665
traces_of_prod_A = calc_traces_of_prod (Gen_A);
666
traces_of_inv_A = calc_traces_of_inv (Gen_A);
667
668
669
image_of_Gen_A = (int *) xmalloc (Gen_A->gen_no * sizeof(int), "suche_kand");
670
671
672
if (construct_Image_Gen_A( 0, Gen_A,group_order, Gen_B, Group_B) == TRUE)
673
{
674
Bild = (matrix_TYP **)xmalloc(Gen_A->gen_no * sizeof(matrix_TYP *),"construct_Image_Gen_A");
675
676
for (i=0; i<Gen_A->gen_no; i++)
677
Bild[i] = Group_B[image_of_Gen_A[i]];
678
679
680
if(end_test (&matrix, Bild, Gen_A->gen, Gen_A->gen_no) != TRUE)
681
matrix = NULL;
682
683
free(Bild);
684
}
685
686
687
free (image_of_Gen_A);
688
689
for (i=0; i<group_order; i++)
690
free_mat (Group_B[i]);
691
free (Group_B);
692
693
free(trace_list_B);
694
695
free(order_list_B);
696
697
698
for (i=0; i<Gen_A->gen_no; i++)
699
free (traces_of_prod_A[i]);
700
free (traces_of_prod_A);
701
702
free (traces_of_inv_A);
703
704
705
return matrix;
706
}
707
708
709
710
711
712