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
/****************************************************************************
2
@
3
@ ----------------------------------------------------------------------------
4
@
5
@ FILE: normalop.c
6
@
7
@ ----------------------------------------------------------------------------
8
@
9
******************************************************************************/
10
11
#include <typedef.h>
12
#include <getput.h>
13
#include <matrix.h>
14
#include <base.h>
15
#include <gmp.h>
16
#include <zass.h>
17
#include <longtools.h>
18
#include <orbit.h>
19
#include <sort.h>
20
#include <bravais.h>
21
#include <contrib.h>
22
#include <graph.h>
23
24
#define TWOTO21 2097152
25
26
extern int INFO_LEVEL;
27
28
static void mod(int *a,int b)
29
{
30
a[0] = a[0] % b;
31
if (a[0]<0) a[0] += b;
32
}
33
34
static void valuation_here(matrix_TYP *x,matrix_TYP *D,MP_INT *val)
35
{
36
int first,
37
last,
38
i;
39
40
MP_INT prod,
41
tmp;
42
43
mpz_init_set_si(&prod,1);
44
mpz_set_si(val,0);
45
mpz_init(&tmp);
46
47
/* set first and last */
48
for (first = 0;first<D->cols && D->array.SZ[first][first] == 1;first++);
49
for (last = 0;last<D->cols && D->array.SZ[last][last] != 0;last++);
50
51
for (i=first;i<last;i++){
52
mod(x->array.SZ[i-first],D->array.SZ[i][i]);
53
mpz_mul_ui(&tmp,&prod,(unsigned long ) x->array.SZ[i-first][0]);
54
mpz_add(val,val,&tmp);
55
mpz_mul_ui(&prod,&prod,(unsigned long) D->array.SZ[i][i]);
56
}
57
58
mpz_clear(&prod);
59
mpz_clear(&tmp);
60
61
return;
62
} /* valuation(.....) */
63
64
static int hash(struct tree *p,MP_INT *valuations,MP_INT *new_val,int pos)
65
{
66
67
int cmp;
68
69
if ((p==NULL) || (p->no <0)){
70
fprintf(stderr,"fehler in hash\n");
71
}
72
73
cmp = mpz_cmp(new_val,valuations+p->no);
74
75
if (cmp < 0){
76
if (p->left == NULL){
77
if (pos != -1){
78
p->left = (struct tree *) calloc(1,sizeof(struct tree));
79
p->left->no = pos;
80
}
81
return -1;
82
}
83
else{
84
return hash(p->left,valuations,new_val,pos);
85
}
86
}
87
else if (cmp > 0){
88
if (p->right == NULL){
89
if (pos != -1){
90
p->right = (struct tree *) calloc(1,sizeof(struct tree));
91
p->right->no = pos;
92
}
93
return -1;
94
}
95
else{
96
return hash(p->right,valuations,new_val,pos);
97
}
98
}
99
else{
100
return p->no;
101
}
102
103
} /* static int hash(...) */
104
105
static int smallest(struct tree *p)
106
{
107
if (p==NULL){
108
printf("error in smallest\n");
109
exit(3);
110
}
111
112
if (p->left == NULL){
113
return p->no;
114
}
115
else{
116
return smallest(p->left);
117
}
118
119
} /* static int smallest(...) */
120
121
/**************************************************************************
122
@
123
@ -------------------------------------------------------------------------
124
@
125
@ matrix_TYP *orbit_rep(matrix_TYP *x,
126
@ matrix_TYP **N,
127
@ int nanz,
128
@ matrix_TYP *D,
129
@ int option,
130
@ char *B,
131
@ MP_INT *l,
132
@ int *anz,
133
@ int **word,
134
@ int word_flag,
135
@ int ***WORDS,
136
@ int *NUMBER_OF_WORDS)
137
@
138
@
139
@ option: an integer controling the behaviours of the function.
140
@ option = 0: return the length of the orbit via anz[0] and
141
@ the smallest representative via return.
142
@ option = 1: return straight if we found a smaller
143
@ representative, and return this one.
144
@ anz[0] has no defined meaning in this case.
145
@ char *B:
146
@
147
@ l: the valuation of the representative returned is via
148
@ this pointer.
149
@
150
@ int **word: needed only for word_flag==TRUE:
151
@ returns a list of integers word with the following property:
152
@ N[word[0][1]] * N[word[0][2]] * ... *N[word[0][word[0][0]]
153
@ is a word representing the smallest representative in the
154
@ orbit.
155
@ int word_flag: drives the behaviour of the function:
156
@ for word_flag == TRUE it calculates such a word described
157
@ above, otherwise it will not change word[0] (hopefully).
158
@ int ***WORDS:
159
@ int *NUMBER_OF_WORDS:
160
@
161
@ Neither the matrices given nor any global variable is changed.
162
@
163
@ -------------------------------------------------------------------------
164
@
165
***************************************************************************/
166
static matrix_TYP *static_orbit_rep(matrix_TYP *x,
167
matrix_TYP **N,
168
int nanz,
169
matrix_TYP *D,
170
int option,
171
char *B,
172
MP_INT *l,
173
int *anz,
174
int **word,
175
int word_flag,
176
int ***WORDS,
177
int *NUMBER_OF_WORDS)
178
{
179
int first,
180
last,
181
i,
182
j,
183
k,
184
h,
185
**orb_words,
186
speicher; /* the number of allocated memory for valuations
187
and orbit, and orb_words */
188
MP_INT *valuations,
189
new_val; /* the valuation of the newly calculated vector */
190
191
matrix_TYP *erg,
192
**orbit,
193
*tmp;
194
195
struct tree *p;
196
197
/* set first and last */
198
for (first = 0;first<D->cols && D->array.SZ[first][first] == 1;first++);
199
for (last = 0;last<D->cols && D->array.SZ[last][last] != 0;last++);
200
201
/* get memory */
202
p = (struct tree *) calloc(1,sizeof(struct tree));
203
speicher = MIN_SPEICHER;
204
valuations = (MP_INT *) malloc(speicher * sizeof(MP_INT));
205
for (i=0;i<speicher;i++) mpz_init(&valuations[i]);
206
mpz_init(&new_val);
207
orbit = (matrix_TYP **) malloc(speicher * sizeof(matrix_TYP*));
208
orbit[0] = copy_mat(x);
209
if (word_flag){
210
orb_words = (int **) malloc(speicher * sizeof(int ));
211
orb_words[0] = (int *) malloc(sizeof(int));
212
orb_words[0][0] = 0;
213
}
214
valuation_here(x,D,&valuations[0]);
215
216
/* anz[0] is the length of the orbit so far */
217
anz[0] = 1;
218
erg = NULL;
219
220
for (i=0;i<anz[0] && erg == NULL;i++){
221
for (j=0;j<nanz && erg == NULL;j++){
222
tmp = mat_mul(N[j],orbit[i]);
223
224
/* normalize tmp modulo the diagonal entries of D */
225
for (k=first;k<last;k++)
226
mod(tmp->array.SZ[k-first],D->array.SZ[k][k]);
227
228
valuation_here(tmp,D,&new_val);
229
230
h = hash(p,valuations,&new_val,anz[0]);
231
232
if (h != (-1)){
233
/* the element is not new */
234
free_mat(tmp);
235
236
/* inserted this case to handle the stabilizer of a cozycle
237
as well: tilman 15.03. */
238
if (WORDS){
239
240
/* we got a new generator of the stabilizer of the cozycle */
241
WORDS[0][NUMBER_OF_WORDS[0]] = (int *) calloc(
242
orb_words[h][0]+orb_words[i][0]+2, sizeof(int));
243
WORDS[0][NUMBER_OF_WORDS[0]][0] =
244
orb_words[h][0]+orb_words[i][0]+1;
245
for (k=1;k<=orb_words[h][0];k++){
246
WORDS[0][NUMBER_OF_WORDS[0]][k] =
247
-orb_words[h][orb_words[h][0] - k + 1] - 1;
248
}
249
WORDS[0][NUMBER_OF_WORDS[0]][orb_words[h][0]+1] = j+1;
250
for (k=1;k<=orb_words[i][0];k++){
251
WORDS[0][NUMBER_OF_WORDS[0]][orb_words[h][0]+1+k] =
252
orb_words[i][k] + 1;
253
}
254
255
NUMBER_OF_WORDS[0]++;
256
if (NUMBER_OF_WORDS[0] % MIN_SPEICHER)
257
WORDS[0] = (int **) realloc( WORDS[0] ,
258
(NUMBER_OF_WORDS[0]+MIN_SPEICHER) * sizeof(int));
259
}
260
}
261
else{
262
/* the element is new */
263
264
/* get more memory is nessesary */
265
if (anz[0] >= speicher){
266
speicher += MIN_SPEICHER;
267
valuations = (MP_INT *) realloc(valuations,
268
speicher * sizeof(MP_INT));
269
for (k=anz[0];k<speicher;k++) mpz_init(&valuations[k]);
270
orbit = (matrix_TYP **) realloc(orbit,
271
speicher * sizeof(matrix_TYP *));
272
if (word_flag){
273
orb_words = realloc(orb_words,speicher * sizeof(int));
274
}
275
}
276
277
mpz_set(valuations+anz[0],&new_val);
278
orbit[anz[0]] = tmp;
279
anz[0]++;
280
281
if (word_flag){
282
orb_words[anz[0]-1] = (int *) malloc( (orb_words[i][0] + 2)
283
* sizeof(int));
284
memcpy(orb_words[anz[0]-1]+2,orb_words[i]+1,(orb_words[i][0])
285
* sizeof(int));
286
orb_words[anz[0]-1][0] = orb_words[i][0] + 1;
287
orb_words[anz[0]-1][1] = j;
288
}
289
290
/* here is the place to check whether the option allows us
291
to exit straigth if tmp is small enough */
292
if ((option == 1) && (mpz_cmp(&new_val,&valuations[0])<0)){
293
erg = tmp;
294
mpz_set(l,&new_val);
295
anz[0]--;
296
}
297
298
/* mark this element got in the element list B */
299
if (B!= NULL) B[mpz_get_ui(&new_val)] = TRUE;
300
}
301
}
302
}
303
304
/* now get the smallest representative if nessesary */
305
if (option == 0 || (option == 1 && erg == NULL)){
306
k = smallest(p);
307
erg = copy_mat(orbit[k]);
308
mpz_set(l,&valuations[k]);
309
if (word_flag){
310
word[0] = orb_words[k];
311
/* just malloced to be able to free it */
312
orb_words[k] = (int *) malloc(1*sizeof(int));
313
}
314
}
315
316
/* cleaning up */
317
for (i=0;i<anz[0];i++) free_mat(orbit[i]);
318
free(orbit);
319
for (i=0;i<speicher;i++) mpz_clear(valuations+i);
320
free(valuations);
321
free_tree(p);
322
mpz_clear(&new_val);
323
if (word_flag){
324
for (i=0;i<anz[0];i++) free(orb_words[i]);
325
free(orb_words);
326
}
327
328
return erg;
329
}
330
331
332
333
334
static int gives_rise_to_torsionfree_space_group(
335
bravais_TYP *G,
336
matrix_TYP *D,
337
matrix_TYP *cocycle,
338
matrix_TYP *x)
339
{
340
341
bravais_TYP *R; /* holds the space group */
342
343
int i,
344
j,
345
k,
346
*res;
347
348
matrix_TYP *C;
349
350
351
R = init_bravais(G->dim+1);
352
C = convert_to_cozycle(x,cocycle,D);
353
354
R->gen = (matrix_TYP **) malloc(G->gen_no * sizeof(matrix_TYP *));
355
R->gen_no = G->gen_no;
356
for (i=0;i<G->gen_no;i++){
357
R->gen[i] = copy_mat(G->gen[i]);
358
real_mat(R->gen[i],G->dim+1,G->dim+1);
359
R->gen[i]->array.SZ[G->dim][G->dim] = 1;
360
iscal_mul(R->gen[i],C->kgv);
361
R->gen[i]->kgv = C->kgv;
362
}
363
364
/* stick the cocycle in the last column of the matrices generating R */
365
k = 0;
366
for (i=0;i<R->gen_no;i++){
367
for (j=0;j<G->dim;j++){
368
R->gen[i]->array.SZ[j][G->dim] = C->array.SZ[k][0];
369
k++;
370
}
371
Check_mat(R->gen[i]);
372
}
373
374
res = torsionfree(R,&i,&j);
375
i = res[0] ; free(res);
376
377
free_bravais(R);
378
free_mat(C);
379
380
return i;
381
}
382
383
384
385
386
/**************************************************************************
387
@
388
@ -------------------------------------------------------------------------
389
@
390
@ matrix_TYP **extensions(matrix_TYP *cozycle,
391
@ matrix_TYP *D,
392
@ matrix_TYP *R,
393
@ bravais_TYP *G,
394
@ int **lengths,
395
@ MP_INT **names,
396
@ int *number_of_orbits,
397
@ int option)
398
@
399
@ Returns the cozycles which generate the isomorphims classes of
400
@ extensions of G by the natural ZG-module. The split extension is
401
@ represented by an all zero matrix.
402
@
403
@ The arguments are:
404
@ matrix_TYP *cozykle: 1st matrix returned by cohomolgy for G.
405
@ matrix_TYP *D: 2nd matrix returned by cohomolgy for G.
406
@ matrix_TYP *R: 3rd matrix returned by cohomolgy for G.
407
@ bravais_TYP *G: the group in question.
408
@ int **lengths: length[0] returns a pointer to the lengths
409
@ of the orbits respectively
410
@ MP_INT **names: names[0] returns a pointer to the names of
411
@ the cozycles as they would appear in a call
412
@ of identify(.....).
413
@ int *number_of_orbits: the number of orbits the normalizer induces
414
@ on the cohomology group.
415
@ MP_INT coho_size: order of the cohomology group
416
@ int option: controls the behaviour of the function:
417
@ option & 1: construct only torsion free extensions
418
@ int *list_of_names: if list_of_names != NULL save of each cocycle the number of the
419
@ smallest represenatative in it's orbit there
420
@ -------------------------------------------------------------------------
421
@
422
***********************************************************************/
423
matrix_TYP **extensions_o(matrix_TYP *cozycle,
424
matrix_TYP *D,
425
matrix_TYP *R,
426
bravais_TYP *G,
427
int **lengths,
428
MP_INT **names,
429
int *number_of_orbits,
430
int ****WORDS,
431
int **NUMBER_OF_WORDS,
432
matrix_TYP ***N,
433
MP_INT coho_size,
434
int option,
435
int *list_of_names)
436
{
437
int i, j, k, anz, *wort, act_val_int, coho_size_int,
438
Nanz = G->normal_no + G->cen_no,
439
orbit_length, **WWW;
440
441
char *tested;
442
443
MP_INT act_val,
444
new_val,
445
got_size;
446
447
matrix_TYP *x,
448
*y,
449
**erg; /* stores the representatives of the orbits=isomorphism
450
classes of extensions as rational matrices */
451
452
if (INFO_LEVEL & 7){
453
fprintf(stderr,"entered extensions\n");
454
}
455
456
number_of_orbits[0] = 0; /* should be changed to a calculation via burnside's
457
lemma */
458
459
mpz_init_set_si(&act_val,0);
460
mpz_init_set_si(&got_size,0);
461
mpz_init(&new_val);
462
463
erg = (matrix_TYP **) malloc(sizeof(matrix_TYP *));
464
lengths[0] = (int *) malloc(sizeof(int));
465
names[0] = (MP_INT *) malloc(sizeof(MP_INT));
466
N[0] = (matrix_TYP **)calloc(Nanz, sizeof(matrix_TYP *));
467
468
if (list_of_names != NULL){
469
coho_size_int = mpz_get_ui(&coho_size);
470
}
471
472
if (mpz_get_ui(&coho_size) < TWOTO21){
473
tested = (char *)calloc(mpz_get_ui(&coho_size), sizeof(char));
474
}
475
else{
476
tested = NULL;
477
if (list_of_names != NULL){
478
fprintf(stderr, "The cohomology group is too big!\n");
479
fprintf(stderr, "If you are really interested in the graph of group - subgroup relations\n");
480
fprintf(stderr, "please start the program again with the option -l!\n");
481
exit(3);
482
}
483
}
484
485
for (i=0;i<Nanz;i++){
486
if (i<G->cen_no){
487
N[0][i] = normalop(cozycle,D,R,G,G->cen[i],i == (Nanz-1));
488
}
489
else{
490
N[0][i] = normalop(cozycle,D,R,G,G->normal[i-G->cen_no],i == (Nanz-1));
491
}
492
if (INFO_LEVEL & 16){
493
put_mat(N[0][i],NULL,"N[i]",2);
494
}
495
}
496
497
if (is_option('v')){
498
fprintf(stderr,"The 1-cohomology group has ");
499
mpz_out_str(stderr,10,&coho_size);
500
}
501
502
while((mpz_cmp(&got_size, &coho_size)<0) && (mpz_cmp(&act_val, &coho_size)<0)){
503
504
if (INFO_LEVEL == 17 ||
505
is_option('v')){
506
fprintf(stderr,"Got %d extensions so far\n",*number_of_orbits);
507
}
508
509
if (tested == NULL || !tested[mpz_get_ui(&act_val)]){
510
511
if (tested != NULL) tested[mpz_get_ui(&act_val)] = TRUE;
512
513
WWW = (int **)calloc(MIN_SPEICHER, sizeof(int *));
514
anz = 0;
515
x = reverse_valuation(&act_val,D);
516
y = static_orbit_rep(x,N[0],Nanz,D,1,tested,&new_val,&orbit_length,
517
&wort, 1, &WWW, &anz);
518
free(wort);
519
520
if ((INFO_LEVEL & 4) || list_of_names != NULL)
521
act_val_int = mpz_get_ui(&act_val);
522
523
if (INFO_LEVEL & 4){
524
printf("act_val %d\n", act_val_int);
525
put_mat(x,NULL,"x",2);
526
put_mat(y,NULL,"y",2);
527
}
528
529
if (list_of_names != NULL){
530
for (k = 1; k < coho_size_int; k++){
531
if (list_of_names[k] == 0 && tested[k] == TRUE)
532
list_of_names[k] = act_val_int;
533
}
534
}
535
536
if (mpz_cmp(&new_val,&act_val) == 0 &&
537
(!(option & 1) ||
538
gives_rise_to_torsionfree_space_group( G, D, cozycle, x))){
539
if (number_of_orbits[0] % MIN_SPEICHER == 0){
540
erg = (matrix_TYP **) realloc(erg,
541
(number_of_orbits[0] + MIN_SPEICHER)*sizeof(matrix_TYP*));
542
lengths[0] = (int *) realloc(lengths[0],
543
(number_of_orbits[0] + MIN_SPEICHER)*sizeof(int));
544
names[0] = (MP_INT *) realloc(names[0],
545
(number_of_orbits[0] + MIN_SPEICHER)*sizeof(MP_INT));
546
WORDS[0] = (int ***)realloc(WORDS[0],
547
(number_of_orbits[0] + MIN_SPEICHER)*sizeof(int **));
548
NUMBER_OF_WORDS[0] = (int *)realloc(NUMBER_OF_WORDS[0],
549
(number_of_orbits[0] + MIN_SPEICHER)*sizeof(int));
550
551
}
552
erg[number_of_orbits[0]] = convert_to_cozycle(x,cozycle,D);
553
lengths[0][number_of_orbits[0]] = orbit_length;
554
mpz_init_set(names[0]+number_of_orbits[0],&act_val);
555
mpz_add_ui(&got_size,&got_size,(unsigned long) orbit_length);
556
WORDS[0][number_of_orbits[0]] = (int **)calloc(anz, sizeof(int *));
557
for (j = 0; j < anz; j++){
558
WORDS[0][number_of_orbits[0]][j] = WWW[j];
559
}
560
NUMBER_OF_WORDS[0][number_of_orbits[0]] = anz;
561
free(WWW);
562
number_of_orbits[0]++;
563
}
564
else{
565
for (j = 0; j < anz; j++)
566
free(WWW[j]);
567
free(WWW);
568
}
569
570
/* clean up and increase act_val */
571
free_mat(y);
572
free_mat(x);
573
}
574
mpz_add_ui(&act_val,&act_val,1);
575
}
576
577
if (tested != NULL ) free(tested);
578
mpz_clear(&act_val);
579
mpz_clear(&new_val);
580
mpz_clear(&got_size);
581
582
return erg;
583
} /* extensions (.... ) */
584
585
586
587
588
/***************************************************************************/
589
void my_translation(matrix_TYP *TR,
590
matrix_TYP *preimage,
591
matrix_TYP *coz,
592
bravais_TYP *G)
593
{
594
595
int i,
596
j,
597
k,
598
**WORDS;
599
600
matrix_TYP *tmp,
601
*tmp2,
602
**MAP;
603
604
rational eins, minuseins;
605
606
607
eins.z = eins.n = minuseins.n = 1; minuseins.z = -1;
608
WORDS = (int **)calloc(G->gen_no, sizeof(int *));
609
610
tmp2 = long_mat_inv(TR);
611
MAP = (matrix_TYP **) malloc(G->gen_no * sizeof(matrix_TYP *));
612
for (j=0;j<G->gen_no;j++){
613
MAP[j] = copy_mat(G->gen[j]);
614
real_mat(MAP[j],MAP[j]->rows+1,MAP[j]->cols);
615
real_mat(MAP[j],MAP[j]->rows,MAP[j]->cols+1);
616
MAP[j]->array.SZ[G->dim][G->dim] = 1;
617
for (k=0;k<G->dim;k++){
618
MAP[j]->array.SZ[k][G->dim]=preimage->array.SZ[j*G->dim+k][0];
619
}
620
tmp = mat_kon(TR,MAP[j],tmp2);
621
free_mat(MAP[j]);
622
MAP[j] = tmp;
623
}
624
tmp = reget_gen(MAP,G->gen_no,G,WORDS,TRUE);
625
tmp->kgv = preimage->kgv;
626
627
for (i=0;i<G->gen_no;i++){
628
free_mat(MAP[i]);
629
free(WORDS[i]);
630
}
631
free(MAP);
632
free(WORDS);
633
634
tmp = mat_addeq(tmp, coz, eins, minuseins);
635
636
coboundary(G,tmp,TR);
637
free_mat(tmp2);
638
free_mat(tmp);
639
640
return;
641
642
}
643
644
645
646