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

563640 views
1
/* last change: 07.02.2001 by Oliver Heidbuechel */
2
3
4
#include <ZZ.h>
5
#include <typedef.h>
6
#include <presentation.h>
7
#include <matrix.h>
8
#include <bravais.h>
9
#include <base.h>
10
#include <datei.h>
11
#include <graph.h>
12
#include <gmp.h>
13
#include <zass.h>
14
#include <tools.h>
15
#include <longtools.h>
16
#include <voronoi.h>
17
#include <symm.h>
18
#include <autgrp.h>
19
#include <reduction.h>
20
21
#define MYSIZE 1024
22
23
/* boolean GRAPH = FALSE; */
24
25
26
/* --------------------------------------------------------------------- */
27
/* Konjugiere bravais_TYP */
28
/* (genauer berechne T B T^{-1}) */
29
/* Quellcode konj_bravais.c und normalizer.c entnommen */
30
/* Es wird nur ->gen, ->gen_no, ->normal, ->normal_no, ->order und */
31
/* ->divisors, ->form, ->form_no angelegt. */
32
/* --------------------------------------------------------------------- */
33
/* B: zu konjugierende Gruppe */
34
/* T: Matrix mit der konjugiert wird */
35
/* Ti: Inverse zu T */
36
/* --------------------------------------------------------------------- */
37
static bravais_TYP *my_konj_bravais(bravais_TYP *B,
38
matrix_TYP *T,
39
matrix_TYP *Ti)
40
{
41
int i, dim, Vanz;
42
bravais_TYP *G, *BG, *BGtr;
43
matrix_TYP *Titr, *waste, *tmp, *tmp2, *A;
44
voronoi_TYP **V;
45
46
G = init_bravais(B->dim);
47
48
/* Order */
49
if (B->order != 0){
50
G->order = B->order;
51
memcpy(G->divisors,B->divisors,100*sizeof(int));
52
}
53
54
/* Generators */
55
if(B->gen_no != 0)
56
{
57
G->gen_no = B->gen_no;
58
if( (G->gen = (matrix_TYP **)malloc(B->gen_no *sizeof(matrix_TYP *))) == NULL)
59
{
60
printf("malloc of 'G->gen' in 'konj_bravais' failed\n");
61
exit(2);
62
}
63
for(i=0;i<B->gen_no;i++)
64
{
65
waste = mat_mul(T, B->gen[i]);
66
G->gen[i] = mat_mul(waste, Ti);
67
free_mat(waste);
68
}
69
}
70
71
/* Normalizer, weiter wird der Formenraum von G angelegt */
72
BG = bravais_group(G, FALSE);
73
74
/* let's see whether we already got the formspace */
75
if (BG->form == NULL){
76
BG->form = formspace(BG->gen, BG->gen_no, 1, &BG->form_no);
77
}
78
BGtr = tr_bravais(BG, 1, FALSE);
79
80
/* firstly calculate an positive definite BG-invariant form */
81
tmp2 = init_mat(BG->dim,BG->dim,"1");
82
tmp = rform(BG->gen,BG->gen_no,tmp2,101);
83
free_mat(tmp2);
84
85
/* now calculate the trace bifo */
86
tmp2 = trace_bifo(BG->form,BGtr->form,BG->form_no);
87
A = first_perfect(tmp, BG, BGtr->form, tmp2, &Vanz);
88
free_mat(tmp2);
89
free_mat(tmp);
90
91
V = normalizer(A, BG, BGtr, 1949, &Vanz);
92
93
/* now we got BG and it's normalizer, so see what we can do with G */
94
G->normal = normalizer_in_N(G, BG, &G->normal_no, FALSE);
95
96
/* clean */
97
for(i = 0; i < Vanz; i++){
98
clear_voronoi(V[i]);
99
free(V[i]);
100
}
101
free(V);
102
free_mat(A);
103
free_bravais(BG);
104
free_bravais(BGtr);
105
106
return(G);
107
}
108
109
110
111
112
113
/* --------------------------------------------------------------------- */
114
/* Calculate H^1(G, Q^n/Z^n) */
115
/* G < GL_n(Z) finite, relator: presentation in relator format */
116
/* relatoranz: number of rows in the presentation */
117
/* see .../Zassen/zass.c */
118
/* --------------------------------------------------------------------- */
119
matrix_TYP **calculate_H1(bravais_TYP *G,
120
word *relator,
121
int relatoranz)
122
{
123
matrix_TYP **X,
124
**matinv;
125
126
long dim;
127
128
int i;
129
130
131
/* prepare */
132
matinv = (matrix_TYP **)calloc(G->gen_no, sizeof(matrix_TYP *));
133
134
/* calculate H^1 */
135
X = cohomology(&dim, G->gen, matinv, relator, G->gen_no, relatoranz);
136
137
/* clean */
138
for (i = 0; i < G->gen_no; i++){
139
if (matinv[i] != NULL)
140
free_mat(matinv[i]);
141
}
142
free(matinv);
143
144
return(X);
145
}
146
147
148
149
/* --------------------------------------------------------------------- */
150
/* free the structure coz_TYP */
151
/* --------------------------------------------------------------------- */
152
void free_coz_TYP(coz_TYP coz_info)
153
{
154
int i;
155
156
mpz_clear(&coz_info.name);
157
mpz_clear(&coz_info.number);
158
free_mat(coz_info.std_coz);
159
free_mat(coz_info.diff);
160
for (i = 0; coz_info.WORDS != NULL && i < coz_info.WORDS_no; i++)
161
free(coz_info.WORDS[i]);
162
if (coz_info.WORDS != NULL)
163
free(coz_info.WORDS);
164
if (coz_info.Stab){
165
for (i = 0; i < coz_info.Stab_no; i++)
166
free_mat(coz_info.Stab[i]);
167
free(coz_info.Stab);
168
}
169
if (coz_info.darst != NULL)
170
free_mat(coz_info.darst);
171
for (i = 0; coz_info.aff_transl != NULL && i < coz_info.aff_transl_no; i++)
172
free_mat(coz_info.aff_transl[i]);
173
if (coz_info.aff_transl)
174
free(coz_info.aff_transl);
175
if (coz_info.N_darst){
176
for (i = 0; i < coz_info.N_darst_no; i++)
177
free_mat(coz_info.N_darst[i]);
178
free(coz_info.N_darst);
179
}
180
for (i = 0; i < coz_info.N_darst_no; i++){
181
if (coz_info.N_inv[i] != NULL) free_mat(coz_info.N_inv[i]);
182
}
183
free(coz_info.N_inv);
184
free_mat(coz_info.coz);
185
for (i = 0; i < 3; i++)
186
free_mat(coz_info.X[i]);
187
free(coz_info.X);
188
free_mat(coz_info.GLS);
189
}
190
191
192
193
/* --------------------------------------------------------------------- */
194
/* Calculate information about a cocycle, i. e. fill the structure */
195
/* coz_TYP for a coz given in coz, G is the corresponding point-group */
196
/* X contains the return value of cohomology for G */
197
/* G->normal has to generate together with G->gen N_Gl_n(Z) (G). */
198
/* G->zentr isn't considered!!! */
199
/* --------------------------------------------------------------------- */
200
/* coz_info.Stab = Stabilisator des Cozykels / G !!! */
201
/* --------------------------------------------------------------------- */
202
coz_TYP identify_coz(bravais_TYP *G,
203
matrix_TYP *coz,
204
matrix_TYP **X)
205
{
206
matrix_TYP **TR, **N_inv;
207
208
coz_TYP coz_info;
209
210
rational eins, minuseins;
211
212
MP_INT null;
213
214
int i, zen_no;
215
216
217
zen_no = G->zentr_no;
218
G->zentr_no = 0;
219
coz_info.GLS = mat_inv(X[2]);
220
221
if (X[0]->cols >= 1){
222
/* prepare */
223
eins.z = eins.n = minuseins.n = 1;
224
minuseins.z = -1;
225
mpz_init_set_si(&coz_info.name, 0);
226
mpz_init_set_si(&coz_info.number, 0);
227
mpz_init_set_si(&null, 0);
228
coz_info.WORDS = (int **)calloc(MIN_SPEICHER, sizeof(int *));
229
coz_info.WORDS_no = 0;
230
N_inv = (matrix_TYP **)calloc(G->normal_no, sizeof(matrix_TYP *));
231
232
/* get information about the cocycle */
233
TR = identify(X[0], X[1], X[2], G, &coz, &coz_info.name, 1, 1,
234
&coz_info.WORDS, &coz_info.WORDS_no);
235
236
coz_info.darst = standard_rep(coz, coz_info.GLS, X[1]);
237
valuation(coz_info.darst, X[1], &coz_info.number);
238
coz_info.std_coz = convert_to_cozycle(coz_info.darst, X[0], X[1]);
239
coz_info.diff = mat_add(coz, coz_info.std_coz, eins, minuseins);
240
241
coz_info.Stab = stab_coz(coz_info.WORDS, coz_info.WORDS_no, G->normal,
242
N_inv, G->normal_no, mpz_cmp(&coz_info.name, &null),
243
&coz_info.Stab_no);
244
245
/* represenation of G->normal on H^1(G,Q^n/Z^n) */
246
coz_info.N_darst_no = G->normal_no;
247
coz_info.N_darst = (matrix_TYP **)calloc(G->normal_no, sizeof(matrix_TYP *));
248
249
/* eigentlich UEBERFLUESSIG:wird schon in identify berechnet */
250
for (i = 0; i < G->normal_no; i++){
251
coz_info.N_darst[i] = normalop(X[0], X[1], X[2], G, G->normal[i], 1);
252
}
253
254
/* clean */
255
free_mat(TR[0]);
256
free(TR);
257
mpz_clear(&null);
258
for (i = 0; i < G->normal_no; i++){
259
if (N_inv[i] != NULL) free_mat(N_inv[i]);
260
}
261
free(N_inv);
262
}
263
else{
264
/* trivial H^1 */
265
coz_info.std_coz = init_mat(coz->rows, 1, "");
266
mpz_init_set_si(&coz_info.name, 0);
267
mpz_init_set_si(&coz_info.number, 0);
268
coz_info.diff = copy_mat(coz);
269
coz_info.WORDS = NULL;
270
coz_info.Stab = (matrix_TYP **)calloc(G->normal_no, sizeof(matrix_TYP *));
271
for (i = 0; i < G->normal_no; i++){
272
coz_info.Stab[i] = copy_mat(G->normal[i]);
273
}
274
coz_info.Stab_no = G->normal_no;
275
coz_info.darst = init_mat(0, 0, "");
276
coz_info.N_darst = NULL;
277
coz_info.N_darst_no = 0;
278
}
279
G->zentr_no = zen_no;
280
coz_info.aff_transl = NULL;
281
coz_info.aff_transl_no = 0;
282
coz_info.coz = copy_mat(coz);
283
coz_info.X = (matrix_TYP **)calloc(3, sizeof(matrix_TYP *));
284
coz_info.N_inv = (matrix_TYP **)calloc(G->normal_no, sizeof(matrix_TYP *));
285
for (i = 0; i < 3; i++)
286
coz_info.X[i] = copy_mat(X[i]);
287
288
return(coz_info);
289
}
290
291
292
293
/* --------------------------------------------------------------------- */
294
/* informations about G-invariant sublattices */
295
/* --------------------------------------------------------------------- */
296
typedef struct
297
{
298
matrix_TYP **lattices; /* sublattices (matrices in long_col_hnf - Form) */
299
boolean *trivialflag; /* trivialflag == TRUE iff lattice[i] == p_i * Z^n */
300
int no; /* number of sublattices */
301
int *orbitlist; /* lattices[i] belongs to orbit orbitlist[i] in 1,2, ... */
302
int *orbitlength; /* orbitlength[i]: length of the orbits i = 1, 2, ... */
303
int *smallest; /* smallest[i]: number of the lattice with the lowest
304
number in orbit[i], i = 1, 2, ... */
305
int orbit_no; /* number of orbits */
306
matrix_TYP **conj; /* conj[i] * lattices[smallest[orbitlist[i]]] = lattices[i] */
307
} sublattice_TYP;
308
309
310
311
/* --------------------------------------------------------------------- */
312
/* free the structure sublattice_TYP */
313
/* --------------------------------------------------------------------- */
314
static void free_sublattice_TYP(sublattice_TYP SL)
315
{
316
int i;
317
318
319
for (i = 0; i < SL.no; i++){
320
free_mat(SL.lattices[i]);
321
free_mat(SL.conj[i]);
322
}
323
free(SL.lattices);
324
free(SL.conj);
325
free(SL.orbitlist);
326
free(SL.orbitlength);
327
free(SL.smallest);
328
free(SL.trivialflag);
329
}
330
331
332
333
/* --------------------------------------------------------------------- */
334
/* returns NULL iff cocycle "coz" isn't in the image or is 0 */
335
/* otherwise returns sol with phi(sol) = coz_darst */
336
/* (C_a x C_b x ... - representation) */
337
/* --------------------------------------------------------------------- */
338
static matrix_TYP *cocycle_in_image(matrix_TYP *coz,
339
matrix_TYP *coz_darst,
340
matrix_TYP *phi,
341
matrix_TYP **image_gen,
342
int image_gen_no,
343
matrix_TYP *GLS,
344
matrix_TYP *D,
345
int flag,
346
int erz_no,
347
boolean *is_in_image)
348
{
349
matrix_TYP *sol = NULL,
350
**images, **koords,
351
*tmp;
352
353
int i, j, k, pos, first, last, diff,
354
anz, size = MYSIZE,
355
*number;
356
357
MP_INT val;
358
359
360
361
/* two trivial cases */
362
if (flag == 2 || flag == 3 || equal_zero(coz_darst)){
363
is_in_image[0] = TRUE;
364
return(sol);
365
}
366
367
/* further cases */
368
if (flag == 1){
369
is_in_image[0]= FALSE;
370
}
371
else if (flag == 0){
372
if (erz_no == 0){
373
is_in_image[0] = FALSE;
374
}
375
else{
376
/* prepare */
377
anz = 1;
378
for (first = 0; first < D->cols && D->array.SZ[first][first] == 1; first++);
379
for (last = first; last < D->cols && D->array.SZ[last][last] != 0; last++);
380
diff = last - first;
381
images = (matrix_TYP **)calloc(size, sizeof(matrix_TYP *));
382
images[0] = init_mat(diff, 1, "");
383
number = (int *)calloc(size, sizeof(int));
384
koords = (matrix_TYP **)calloc(size, sizeof(matrix_TYP *));
385
koords[0] = init_mat(image_gen_no, 1, "");
386
mpz_init(&val);
387
is_in_image[0] = FALSE;
388
389
/* orbit algorithm (surely, there are better methods)*/
390
for (i = 0; !is_in_image[0] && i < anz; i++){
391
for (j = 0; !is_in_image[0] && j < image_gen_no; j++){
392
if (!equal_zero(image_gen[j])){
393
tmp = add_mod_D(images[i], image_gen[j], D, first, diff);
394
valuation(tmp, D, &val);
395
pos = mpz_get_ui(&val);
396
for (k = 0; k < anz; k++){
397
if (number[k] == pos)
398
break;
399
}
400
if (k == anz){
401
/* new element in the orbit */
402
if (anz >= size){
403
size += MYSIZE;
404
images = realloc(images, size * sizeof(matrix_TYP *));
405
number = realloc(number, size * sizeof(int));
406
koords = realloc(koords, size * sizeof(matrix_TYP *));
407
}
408
images[anz] = tmp;
409
koords[anz] = copy_mat(koords[i]);
410
koords[anz]->array.SZ[j][0]++;
411
number[anz] = pos;
412
if (cmp_mat(images[anz], coz_darst) == 0){
413
sol = copy_mat(koords[anz]);
414
is_in_image[0] = TRUE;
415
}
416
anz++;
417
}
418
else
419
free_mat(tmp);
420
}
421
}
422
}
423
424
/* clean */
425
for (i = 0; i < anz; i++){
426
free_mat(koords[i]);
427
free_mat(images[i]);
428
}
429
free(koords);
430
free(images);
431
free(number);
432
mpz_clear(&val);
433
}
434
}
435
else{
436
fprintf(stderr, "This flag isn't allowed. ERROR in cocycle_in_image!\n");
437
exit(4);
438
}
439
440
return(sol);
441
}
442
443
444
445
/* --------------------------------------------------------------------- */
446
/* H1: return value of cohomology */
447
/* koord: koordinates of a cocyle in H^1(...) = C_a x C_b x ... */
448
/* returns cocycle */
449
/* --------------------------------------------------------------------- */
450
matrix_TYP *darst_to_C1(matrix_TYP **H1,
451
matrix_TYP *koord)
452
{
453
matrix_TYP *C1, *tmp;
454
455
int first, last, diff, i, j;
456
457
rational eins, zahl;
458
459
460
/* prepare */
461
for (first = 0; first < H1[1]->cols && H1[1]->array.SZ[first][first] == 1; first++);
462
for (last = first; last < H1[1]->cols && H1[1]->array.SZ[last][last] != 0; last++);
463
diff = last - first;
464
eins.z = eins.n = 1;
465
466
/* paranoia */
467
if (diff != koord->rows){
468
fprintf(stderr, "ERROR in darst_to_C1!!!\n");
469
exit(9);
470
}
471
472
C1 = init_mat(H1[0]->rows, 1, "");
473
for (i = 0; i < diff; i++){
474
if (koord->array.SZ[i][0] != 0){
475
tmp = init_mat(H1[0]->rows, 1, "");
476
for (j = 0; j < H1[0]->rows; j++){
477
tmp->array.SZ[j][0] = H1[0]->array.SZ[j][i];
478
}
479
zahl.z = koord->array.SZ[i][0];
480
zahl.n = H1[1]->array.SZ[i + first][i + first];
481
Normal(&zahl);
482
C1 = mat_addeq(C1, tmp, eins, zahl);
483
free_mat(tmp);
484
}
485
}
486
487
return(C1);
488
}
489
490
491
492
/* --------------------------------------------------------------------- */
493
/* adds an element of B^1(G, Q^n/L) to preimage such that afterwarts */
494
/* phi (preimage) = coz (in C^1) */
495
/* case: normalizer element is ID */
496
/* [part of this code is part of the code in coboundary] */
497
/* --------------------------------------------------------------------- */
498
static void korrektes_urbild_ID(matrix_TYP *preimage,
499
matrix_TYP *coz,
500
bravais_TYP *G)
501
{
502
matrix_TYP *diff, *A, *B, *tmp, **erg;
503
504
rational eins, minuseins;
505
506
int i, n, k, l;
507
508
509
eins.z = eins.n = minuseins.n = 1; minuseins.z = -1;
510
diff = mat_add(coz, preimage, eins, minuseins);
511
512
n = G->dim;
513
514
B = init_mat(n * G->gen_no, n, "k");
515
516
/* belegen der matrix B = (g_1 - I, ...)^tr */
517
for (i = 0; i < G->gen_no; i++){
518
for (k = 0; k < n; k++){
519
for (l = 0; l < n; l++){
520
if (k == l){
521
B->array.SZ[k+i*n][l] = G->gen[i]->array.SZ[k][l] - 1;
522
}
523
else{
524
B->array.SZ[k+i*n][l] = G->gen[i]->array.SZ[k][l];
525
}
526
}
527
}
528
}
529
530
A = copy_mat(B);
531
real_mat(A, A->rows, A->cols + 1);
532
533
/* rechte Seite */
534
for (i = 0; i < G->gen_no; i++)
535
for (k = 0; k < n; k++)
536
A->array.SZ[i * n + k][n] = diff->array.SZ[i * n + k][0];
537
538
k = long_row_gauss(A);
539
real_mat(A, k, A->cols);
540
541
/* kick out the rows which have 0's in the first n entries */
542
for (i = A->rows - 1; i > 0; i--){
543
for (k = 0; k < n && A->array.SZ[i][k] == 0; k++);
544
if (k == n){
545
if (A->array.SZ[i][n] % diff->kgv){
546
fprintf(stderr,"error in korrektes_urbild_ID\n");
547
exit(3);
548
}
549
else{
550
real_mat(A,A->rows-1,A->cols);
551
}
552
}
553
}
554
555
real_mat(diff, A->rows, 1);
556
557
for (i = 0; i < A->rows; i++)
558
diff->array.SZ[i][0] = A->array.SZ[i][n];
559
560
real_mat(A,A->rows, n);
561
562
Check_mat(A);
563
Check_mat(diff);
564
565
/* put_mat(A,0,0,0);
566
put_mat(diff,0,0,0); */
567
568
erg = long_solve_mat(A, diff);
569
570
if (erg == NULL || erg[0] == NULL){
571
fprintf(stderr,"error in korrektes_urbild_ID\n");
572
exit(3);
573
}
574
575
tmp = mat_mul(B, erg[0]);
576
577
preimage = mat_addeq(preimage, tmp, eins, eins);
578
579
/* clean */
580
if (erg[0] != NULL) free_mat(erg[0]);
581
if (erg[1] != NULL) free_mat(erg[1]);
582
free(erg);
583
free_mat(A);
584
free_mat(B);
585
free_mat(diff);
586
free_mat(tmp);
587
}
588
589
590
/* --------------------------------------------------------------------- */
591
/* adds an element of B^1(G, Q^n/L) to preimage such that afterwarts */
592
/* phi (preimage) = coz (in C^1) */
593
/* case: normalizer element is possibly NOT ID */
594
/* [part of this code is part of the code in coboundary] */
595
/* --------------------------------------------------------------------- */
596
static void korrektes_urbild(matrix_TYP **preimage,
597
coz_TYP *coz_info,
598
bravais_TYP *G,
599
matrix_TYP *L,
600
boolean flag)
601
{
602
matrix_TYP *rep, *paranoia, **N_darst_inv, **N, **NNN, **orbit, *n, *tmp, **conj;
603
604
bravais_TYP *R, *RR;
605
606
int **words, word_no, i, j, k,
607
anz, size = MYSIZE, first, last, diff, pos,
608
*number;
609
610
boolean found;
611
612
MP_INT val;
613
614
615
616
rep = standard_rep(preimage[0], coz_info->GLS, coz_info->X[1]);
617
618
if (cmp_mat(rep, coz_info->darst) == 0){
619
korrektes_urbild_ID(preimage[0], coz_info->coz, G);
620
free_mat(rep);
621
}
622
else{
623
624
/* calculate the stabilizer of the lattice */
625
if (flag){
626
N = coz_info->N_darst;
627
NNN = G->normal;
628
word_no = G->normal_no;
629
}
630
else{
631
words = stab_lattice(L, G->normal, G->normal_no, &word_no, NULL, 0, NULL);
632
633
N_darst_inv = (matrix_TYP **)calloc(G->normal_no, sizeof(matrix_TYP *));
634
N = (matrix_TYP **)calloc(word_no, sizeof(matrix_TYP *));
635
NNN = (matrix_TYP **)calloc(word_no, sizeof(matrix_TYP *));
636
for (i = 0; i < word_no; i++){
637
NNN[i] = mapped_word(words[i], G->normal, coz_info->N_inv);
638
paranoia = mat_mul(NNN[i], L);
639
long_col_hnf(paranoia);
640
if (cmp_mat(paranoia, L) != 0){
641
fprintf(stderr, "ERROR in korrektes_urbild!\n");
642
exit(9);
643
}
644
free_mat(paranoia);
645
N[i] = graph_mapped_word(words[i], coz_info->N_darst, N_darst_inv, coz_info->X[1]);
646
free(words[i]);
647
}
648
free(words);
649
for (i = 0; i < G->normal_no; i++){
650
if (N_darst_inv[i] != NULL) free_mat(N_darst_inv[i]);
651
}
652
free(N_darst_inv);
653
}
654
655
/* find n in N with n rep = coz_info->darst */
656
for (first = 0; first < coz_info->X[1]->cols && coz_info->X[1]->array.SZ[first][first] == 1; first++);
657
for (last = first; last < coz_info->X[1]->cols && coz_info->X[1]->array.SZ[last][last] != 0; last++);
658
diff = last - first;
659
found = FALSE;
660
anz = 1;
661
orbit = (matrix_TYP **)calloc(size, sizeof(matrix_TYP *));
662
number = (int *)calloc(size, sizeof(int));
663
conj = (matrix_TYP **)calloc(size, sizeof(matrix_TYP *));
664
conj[0] = init_mat(G->dim, G->dim, "1");
665
orbit[0] = copy_mat(rep);
666
tmp = NULL;
667
mpz_init(&val);
668
valuation(orbit[0], coz_info->X[1], &val);
669
number[0] = mpz_get_ui(&val);
670
n = NULL;
671
672
/* out of orbit_rep */
673
for (i = 0; !found && i < anz; i++){
674
for (j = 0; !found && j < word_no; j++){
675
tmp = mat_mul(N[j], orbit[i]);
676
for (k = 0; k < diff; k++){
677
tmp->array.SZ[k][0] %= coz_info->X[1]->array.SZ[k + first][k + first];
678
if (tmp->array.SZ[k][0] < 0)
679
tmp->array.SZ[k][0] += coz_info->X[1]->array.SZ[k + first][k + first];
680
}
681
valuation(tmp, coz_info->X[1], &val);
682
pos = mpz_get_ui(&val);
683
for (k = 0; k < anz; k++){
684
if (number[k] == pos)
685
break;
686
}
687
if (k == anz){
688
/* new element in the orbit */
689
if (anz >= size){
690
size += MYSIZE;
691
orbit = realloc(orbit, size * sizeof(matrix_TYP *));
692
number = realloc(number, size * sizeof(int));
693
conj = realloc(conj, size * sizeof(matrix_TYP *));
694
}
695
orbit[anz] = tmp;
696
conj[anz] = mat_mul(NNN[j], conj[i]);
697
number[anz] = pos;
698
if (cmp_mat(orbit[anz], coz_info->darst) == 0){
699
n = copy_mat(conj[anz]);
700
found = TRUE;
701
}
702
anz++;
703
}
704
else
705
free_mat(tmp);
706
}
707
}
708
709
/* paranoia test */
710
if (n == NULL){
711
fprintf(stderr, "ERROR 1 in korrektes_urbild\n");
712
exit(3);
713
}
714
715
/* calculate the correct preimage */
716
real_mat(n, n->rows + 1, n->cols);
717
real_mat(n, n->rows, n->cols + 1);
718
n->array.SZ[G->dim][G->dim] = 1;
719
my_translation(n, preimage[0], coz_info->coz, G);
720
R = extract_r(G, preimage[0]);
721
free_mat(preimage[0]);
722
RR = konj_bravais(R, n);
723
preimage[0] = sg(RR, G);
724
725
/* clean */
726
free_mat(n);
727
free_bravais(R);
728
free_bravais(RR);
729
for (i = 0; i < anz; i++){
730
free_mat(conj[i]);
731
free_mat(orbit[i]);
732
}
733
free(orbit);
734
free(conj);
735
free(number);
736
mpz_clear(&val);
737
if (flag){
738
N = NULL;
739
NNN = NULL;
740
}
741
else{
742
for (i = 0; i < word_no; i++){
743
free_mat(N[i]);
744
free_mat(NNN[i]);
745
}
746
free(NNN);
747
free(N);
748
}
749
free_mat(rep);
750
}
751
}
752
753
754
755
/* --------------------------------------------------------------------- */
756
/* With one preimage and the kernels we can calculate all preimages in */
757
/* C^1(G, Q^n/L) */
758
/* --------------------------------------------------------------------- */
759
static matrix_TYP **calculate_all_preimages(matrix_TYP *preimage,
760
matrix_TYP **kernel_gen,
761
matrix_TYP **k_g_darst,
762
int kernel_gen_no,
763
matrix_TYP *D,
764
matrix_TYP **b1_kernel,
765
int b1_kernel_no,
766
int *anz)
767
{
768
matrix_TYP **preimages, *tmp, **elements;
769
770
int size = MYSIZE,
771
i, j, k, pos, alt,
772
*number,
773
first, last, diff;
774
775
MP_INT val;
776
777
rational eins;
778
779
780
eins.z = eins.n = 1;
781
782
/* all preimages up to addition with element of Ker phi | B^1(B, Q^n/L) */
783
if (kernel_gen_no > 0){
784
/* prepare */
785
anz[0] = 1;
786
preimages = (matrix_TYP **)calloc(size, sizeof(matrix_TYP *));
787
preimages[0] = copy_mat(preimage);
788
number = (int *)calloc(size, sizeof(int));
789
elements = (matrix_TYP **)calloc(size, sizeof(matrix_TYP *));
790
elements[0] = init_mat(k_g_darst[0]->rows, 1, "");
791
mpz_init(&val);
792
for (first = 0; first < D->cols && D->array.SZ[first][first] == 1; first++);
793
for (last = first; last < D->cols && D->array.SZ[last][last] != 0; last++);
794
diff = last - first;
795
796
/* orbit algorithm */
797
for (i = 0; i < anz[0]; i++){
798
for (j = 0; j < kernel_gen_no; j++){
799
tmp = add_mod_D(elements[i], k_g_darst[j], D, first, diff);
800
valuation(tmp, D, &val);
801
pos = mpz_get_ui(&val);
802
for (k = 0; k < anz[0]; k++){
803
if (number[k] == pos)
804
break;
805
}
806
if (k == anz[0]){
807
/* new element in the orbit */
808
anz[0]++;
809
if (anz[0] >= size){
810
size += MYSIZE;
811
preimages = realloc(preimages, size * sizeof(matrix_TYP *));
812
number = realloc(number, size * sizeof(int));
813
elements = realloc(elements, size * sizeof(matrix_TYP *));
814
}
815
elements[anz[0] - 1] = tmp;
816
preimages[anz[0] - 1] = mat_add(preimages[i], kernel_gen[j], eins, eins);
817
number[anz[0] - 1] = pos;
818
}
819
else
820
free_mat(tmp);
821
}
822
}
823
824
/* clean */
825
mpz_clear(&val);
826
free(number);
827
for (i = 0; i < anz[0]; i++)
828
free_mat(elements[i]);
829
free(elements);
830
831
alt = anz[0];
832
anz[0] = anz[0] * b1_kernel_no;
833
if (size < anz[0])
834
preimages = realloc(preimages, anz[0] * sizeof(matrix_TYP *));
835
}
836
else{
837
/* trivial case */
838
alt = 1;
839
anz[0] = b1_kernel_no;
840
preimages = (matrix_TYP **)calloc(anz[0], sizeof(matrix_TYP *));
841
preimages[0] = copy_mat(preimage);
842
}
843
844
/* add elements of Ker phi | B^1(B, Q^n/L) */
845
for (i = 1; i < b1_kernel_no; i++){
846
for (j = 0; j < alt; j++){
847
preimages[i * alt + j] = mat_add(preimages[j], b1_kernel[i], eins, eins);
848
}
849
}
850
851
return(preimages);
852
}
853
854
855
856
/* --------------------------------------------------------------------- */
857
/* calculate the maximal klassengleich subgroups for R(G,coz) with */
858
/* translation lattice L */
859
/* --------------------------------------------------------------------- */
860
/* G: Pointgroup, G->normal and G->gen have to generate N_{Gl_n(Z)}(G) */
861
/* GL: G mit Gitter L konjugiert */
862
/* aflag: calculate subgroups up to conjugation of the affine normalizer */
863
/* of R */
864
/* anz: Speichere die Anzahl der Raumgruppen hier */
865
/* length: wenn aflag, dann speichere die Laengen der Bahnen hier */
866
/* --------------------------------------------------------------------- */
867
static bravais_TYP **subgroups_for_L(coz_TYP *coz_info,
868
matrix_TYP *L,
869
bravais_TYP *G,
870
bravais_TYP *GL,
871
matrix_TYP **H_G_Z,
872
matrix_TYP **H_GL_Z,
873
int *anz,
874
int **length,
875
boolean aflag)
876
{
877
boolean is_in_image;
878
879
int i, b1_kernel_no;
880
881
matrix_TYP *diag, *GLS, *tmp, *tmp2, **reps,
882
*phi, *kernel_mat, **kernel_gen, **image,
883
*koord, *preimage, **all_preimages,
884
**k, *nullcoz, **b1_kernel;
885
886
H1_mod_ker_TYP H1_mod_ker;
887
888
int image_gen_no;
889
890
bravais_TYP **SG;
891
892
893
/* prepare */
894
anz[0] = 0;
895
GLS = mat_inv(H_G_Z[2]);
896
diag = matrix_on_diagonal(L, G->gen_no);
897
898
/* calculate Phi */
899
calculate_phi(diag, H_GL_Z[0], H_G_Z, H_GL_Z, GLS, &phi,
900
&kernel_mat, &image, &image_gen_no, &H1_mod_ker);
901
902
903
/* is cocycle in the image (phi koord = coz->darst) */
904
koord = cocycle_in_image(coz_info->coz, coz_info->darst, phi, image, image_gen_no, GLS,
905
H_G_Z[1], H1_mod_ker.flag, H1_mod_ker.erz_no, &is_in_image);
906
907
908
if (is_in_image){
909
910
/* calculate information about Ker phi | B^1 */
911
if (coz_info->aff_transl == NULL){ /* we calculate it only once */
912
coz_info->aff_transl = transl_aff_normal(G->gen, G->gen_no, &coz_info->aff_transl_no);
913
}
914
b1_kernel = kernel_factor_fct(coz_info->aff_transl, coz_info->aff_transl_no, G->gen_no, L,
915
&b1_kernel_no);
916
917
if (!aflag){
918
/* Berechne alle Untergruppen */
919
/* ========================== */
920
921
/* calculate preimage of cocycle (in C^1)*/
922
if (koord == NULL){
923
preimage = init_mat(coz_info->coz->rows, 1, "");
924
}
925
else{
926
tmp = darst_to_C1(H_GL_Z, koord);
927
preimage = mat_mul(diag, tmp);
928
free_mat(tmp);
929
}
930
korrektes_urbild(&preimage, coz_info, G, L, FALSE);
931
932
/* calculate generators for Ker(phi on H^1(G,Q^n/L)) such that
933
phi(gen) = 0 in C^1 */
934
nullcoz = init_mat(coz_info->coz->rows, 1, "");
935
kernel_gen = (matrix_TYP **)calloc(kernel_mat->cols, sizeof(matrix_TYP *));
936
k = col_to_list(kernel_mat);
937
for (i = 0; i < kernel_mat->cols; i++){
938
tmp = darst_to_C1(H_GL_Z, k[i]);
939
kernel_gen[i] = mat_mul(diag, tmp);
940
free_mat(tmp);
941
korrektes_urbild_ID(kernel_gen[i], nullcoz, G);
942
}
943
free_mat(nullcoz);
944
945
/*
946
if (coz_info->aff_transl == NULL){
947
coz_info->aff_transl = transl_aff_normal(G->gen, G->gen_no, &coz_info->aff_transl_no);
948
}
949
b1_kernel = kernel_factor_fct(coz_info->aff_transl, coz_info->aff_transl_no, G->gen_no, L,
950
&b1_kernel_no);
951
*/
952
953
/* calculate all preimages */
954
all_preimages = calculate_all_preimages(preimage, kernel_gen, k, kernel_mat->cols,
955
H_GL_Z[1], b1_kernel, b1_kernel_no, anz);
956
/* calculate the groups */
957
SG = (bravais_TYP **)calloc(anz[0], sizeof(bravais_TYP *));
958
for (i = 0; i < anz[0]; i++){
959
SG[i] = extract_r(G, all_preimages[i]);
960
free_mat(all_preimages[i]);
961
}
962
963
/* clean */
964
free(all_preimages);
965
free_mat(preimage);
966
/*
967
for (i = 0; i < b1_kernel_no; i++){
968
free_mat(b1_kernel[i]);
969
}
970
if (b1_kernel)
971
free(b1_kernel);
972
*/
973
for (i = 0; i < kernel_mat->cols; i++){
974
free_mat(kernel_gen[i]);
975
free_mat(k[i]);
976
}
977
free(k);
978
free(kernel_gen);
979
}
980
else{
981
/* Berechne nur Vertreter unter dem affinen Normalisator */
982
/* ===================================================== */
983
reps = calculate_representatives(G, GL, H_G_Z, H_GL_Z, L, phi,
984
H1_mod_ker, koord, kernel_mat, anz, length);
985
SG = (bravais_TYP **)calloc(anz[0], sizeof(bravais_TYP *));
986
for (i = 0; i < anz[0]; i++){
987
tmp = darst_to_C1(H_GL_Z, reps[i]);
988
free_mat(reps[i]);
989
tmp2 = mat_mul(diag, tmp);
990
free_mat(tmp);
991
korrektes_urbild(&tmp2, coz_info, G, L, FALSE);
992
SG[i] = extract_r(G, tmp2);
993
free_mat(tmp2);
994
length[0][i] *= b1_kernel_no;
995
}
996
free(reps);
997
}
998
for (i = 0; i < b1_kernel_no; i++){
999
free_mat(b1_kernel[i]);
1000
}
1001
if (b1_kernel)
1002
free(b1_kernel);
1003
}
1004
else{
1005
SG = NULL;
1006
}
1007
1008
/* clean */
1009
if (koord != NULL)
1010
free_mat(koord);
1011
free_mat(GLS);
1012
free_mat(diag);
1013
free_mat(kernel_mat);
1014
free_mat(phi);
1015
free_H1_mod_ker_TYP(H1_mod_ker);
1016
for (i = 0; i < image_gen_no; i++){
1017
free_mat(image[i]);
1018
}
1019
free(image);
1020
1021
return(SG);
1022
}
1023
1024
1025
1026
1027
1028
1029
1030
/* --------------------------------------------------------------------- */
1031
/* Returns the maximal klassengleich subgroups of R with p_i-power-index */
1032
/* where p_i is a prime given in G->divisors */
1033
/* R has to be in standard affine form without translations */
1034
/* an G has to be the point group of R */
1035
/* with correct normalizer */
1036
/* Returns the number of these subgroups via anz. */
1037
1038
/* G->normal and G->gen have to generate the normalizer of G!!!!! */
1039
1040
/* aflag: FALSE => calculate all max. k-subgroups */
1041
/* TRUE => calculate max. k-subgroups up to conjugation of */
1042
/* the affine normalizer of R */
1043
/* orbitlength: speichere die Laengen der Bahnen (nur wenn aflag) */
1044
/* --------------------------------------------------------------------- */
1045
bravais_TYP **max_k_sub(bravais_TYP *G,
1046
bravais_TYP *R,
1047
matrix_TYP *pres,
1048
int *anz,
1049
boolean aflag,
1050
boolean debugflag,
1051
int **orbitlength)
1052
{
1053
sublattice_TYP SL;
1054
1055
bravais_TYP **S, *GL, **SG_L;
1056
1057
matrix_TYP **H_G_Z, **H_GL_Z,
1058
*coz, *tmp, *diag, *preimage,
1059
*L, *Linv, *conj,
1060
**b1_kernel;
1061
1062
word *relator;
1063
1064
int i, j, k, sg_L_no, b1_kernel_no,
1065
size = MYSIZE, counter, *length = NULL;
1066
1067
coz_TYP coz_info;
1068
1069
rational eins;
1070
1071
1072
1073
/* prepare */
1074
cen_to_norm(G);
1075
relator = (word *) calloc(pres->rows, sizeof(word));
1076
for (i = 0; i < pres->rows; i++){
1077
matrix_2_word(pres, relator + i, i);
1078
}
1079
coz = extract_c(R);
1080
eins.z = eins.n = 1;
1081
anz[0] = 0;
1082
S = (bravais_TYP **)calloc(0, sizeof(bravais_TYP *));
1083
if (aflag)
1084
orbitlength[0] = (int *)calloc(0, sizeof(int));
1085
1086
/* calculate the sublattices */
1087
SL.lattices = max_sublattices(G, &SL.no, &SL.trivialflag, debugflag);
1088
1089
/* calculate H^1(G, Q^n/Z^n) */
1090
H_G_Z = calculate_H1(G, relator, pres->rows);
1091
1092
/* identify the cocyle */
1093
coz_info = identify_coz(G, coz, H_G_Z);
1094
1095
/* calculate the orbits on the lattices under the stabilizer of the cocycle */
1096
SL.orbitlist = (int *)calloc(SL.no, sizeof(int));
1097
SL.orbitlength = (int *)calloc(SL.no + 1, sizeof(int));
1098
SL.smallest = (int *)calloc(SL.no + 1, sizeof(int));
1099
SL.conj = (matrix_TYP **)calloc(SL.no, sizeof(matrix_TYP *));
1100
SL.orbit_no = orbit_on_lattices(SL.lattices, SL.no, coz_info.Stab, coz_info.Stab_no,
1101
SL.orbitlist, SL.orbitlength, SL.smallest, SL.conj);
1102
1103
for (i = 1; i <= SL.orbit_no; i++){
1104
/* calculate the maximal klassengleich subgroups for a representative of each orbit */
1105
L = SL.lattices[SL.smallest[i]];
1106
1107
if ( TRUE ){
1108
/*
1109
if (!SL.trivialflag[SL.smallest[i]]){
1110
*/
1111
/* lattice != p_i * Z^n */
1112
Linv = mat_inv(L);
1113
GL = my_konj_bravais(G, Linv, L);
1114
1115
/* calculate H^1(GL, Q^n/Z^n) */
1116
H_GL_Z = calculate_H1(GL, relator, pres->rows);
1117
1118
/* subgroups */
1119
SG_L = subgroups_for_L(&coz_info, L, G, GL, H_G_Z, H_GL_Z, &sg_L_no, &length, aflag);
1120
1121
if (sg_L_no > 0){
1122
if (aflag){
1123
S = (bravais_TYP **)realloc(S, (anz[0] + sg_L_no)
1124
* sizeof(bravais_TYP *));
1125
orbitlength[0] = (int *)realloc(orbitlength[0], (anz[0] + sg_L_no)
1126
* sizeof(int));
1127
}
1128
else{
1129
S = (bravais_TYP **)realloc(S, (anz[0] + sg_L_no * SL.orbitlength[i])
1130
* sizeof(bravais_TYP *));
1131
}
1132
for (j = 0; j < sg_L_no; j++){
1133
plus_translationen(SG_L[j], L);
1134
S[anz[0] + j] = SG_L[j];
1135
if (aflag){
1136
orbitlength[0][anz[0] + j] = length[j] * SL.orbitlength[i];
1137
}
1138
}
1139
1140
/* corresponding subgroups for the other lattices in this orbit */
1141
if (!aflag){
1142
counter = 1;
1143
for (j = SL.smallest[i] + 1; j < SL.no; j++){
1144
if (SL.orbitlist[j] == i){
1145
conj = to_aff_normal_element(SL.conj[j], coz, 0, G, R);
1146
for (k = 0; k < sg_L_no; k++){
1147
S[anz[0] + counter * sg_L_no + k] =
1148
konj_bravais(S[anz[0] + k], conj);
1149
}
1150
free_mat(conj);
1151
counter++;
1152
}
1153
}
1154
if (counter != SL.orbitlength[i]){ /* paranoiatest */
1155
fprintf(stderr, "ERROR in max_k_sub!\n");
1156
exit(8);
1157
}
1158
anz[0] += (sg_L_no * SL.orbitlength[i]);
1159
}
1160
else{
1161
anz[0] += sg_L_no;
1162
}
1163
}
1164
1165
/* clean */
1166
for (j = 0; j < 3; j++)
1167
free_mat(H_GL_Z[j]);
1168
free(H_GL_Z);
1169
free_bravais(GL);
1170
free_mat(Linv);
1171
if (SG_L != NULL)
1172
free(SG_L);
1173
if (length)
1174
free(length);
1175
length = NULL;
1176
}
1177
else{
1178
/* lattice == p_i * Z^n (there is only one lattice in this orbit) */
1179
/* calculate Ker(phi restricted to B^1(G,Q^n/L)) (here: phi = Id)*/
1180
1181
/* this isn't correct!!! there has to be an additional condition
1182
example: min.56.1.1.1 min.56.1.1 2 3 */
1183
1184
/* Das ist nicht korrekt, weil | phi^{-1} (0 + B^1) |
1185
nicht zwangslaeufig 1 ist. Dann wuerde es funktionieren! */
1186
1187
if (coz_info.aff_transl == NULL){ /* we calculate it only once */
1188
coz_info.aff_transl = transl_aff_normal(G->gen, G->gen_no,
1189
&coz_info.aff_transl_no);
1190
}
1191
b1_kernel = kernel_factor_fct(coz_info.aff_transl, coz_info.aff_transl_no,
1192
G->gen_no, L, &b1_kernel_no);
1193
if (size < (anz[0] + b1_kernel_no)){
1194
S = (bravais_TYP **)realloc(S, (anz[0] + b1_kernel_no) * sizeof(bravais_TYP *));
1195
size = anz[0] + b1_kernel_no;
1196
}
1197
1198
if (coz_info.darst->cols == 0 || equal_zero(coz_info.darst)){
1199
preimage = init_mat(coz->rows, 1, "");
1200
}
1201
else{
1202
tmp = darst_to_C1(H_G_Z, coz_info.darst);
1203
diag = matrix_on_diagonal(L, G->gen_no);
1204
preimage = mat_mul(diag, tmp);
1205
free_mat(tmp);
1206
free_mat(diag);
1207
}
1208
korrektes_urbild(&preimage, &coz_info, G, L, TRUE);
1209
1210
for (j = 0; j < b1_kernel_no; j++){
1211
b1_kernel[j] = mat_addeq(b1_kernel[j], preimage, eins, eins);
1212
S[j + anz[0]] = extract_r(G, b1_kernel[j]);
1213
free_mat(b1_kernel[j]);
1214
plus_translationen(S[j + anz[0]], L);
1215
}
1216
free(b1_kernel);
1217
free_mat(preimage);
1218
anz[0] += b1_kernel_no;
1219
}
1220
L = NULL;
1221
}
1222
1223
/* paranoia test */
1224
if (debugflag){
1225
for (j = 0; j < anz[0]; j++){
1226
if (S[j] != NULL && !is_k_subgroup(S[j], R, G, G->gen[0]->rows, pres)){
1227
fprintf(stderr, "ERROR: das ist gar keine Untergruppe!\n");
1228
put_bravais(S[j],0,0);
1229
put_bravais(R,0,0);
1230
exit(8);
1231
}
1232
}
1233
}
1234
1235
/* clean */
1236
free_sublattice_TYP(SL);
1237
for (i = 0; i < pres->rows; i++)
1238
wordfree(relator + i);
1239
free(relator);
1240
for (i = 0; i < 3; i++)
1241
free_mat(H_G_Z[i]);
1242
free(H_G_Z);
1243
free_coz_TYP(coz_info);
1244
free_mat(coz);
1245
1246
return(S);
1247
}
1248
1249
1250
1251
1252
1253