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: 26.09.00 by Oliver Heidbuechel */
2
3
#include <typedef.h>
4
#include <matrix.h>
5
#include <bravais.h>
6
#include <base.h>
7
#include <graph.h>
8
#include <sort.h>
9
#include <zass.h>
10
#include <longtools.h>
11
12
13
/* --------------------------------------------------------------------------- */
14
/* Add two cocycles in standard representation C_d1 x ... x C_dn and */
15
/* transform the result into standard representation */
16
/* --------------------------------------------------------------------------- */
17
matrix_TYP *add_mod_D(matrix_TYP *A,
18
matrix_TYP *B,
19
matrix_TYP *D,
20
int first,
21
int diff)
22
{
23
int i;
24
25
matrix_TYP *sol;
26
27
28
sol = init_mat(diff, 1, "");
29
for (i = 0; i < diff; i++){
30
sol->array.SZ[i][0] = (A->array.SZ[i][0] + B->array.SZ[i][0]) %
31
D->array.SZ[i + first][i + first];
32
if (sol->array.SZ[i][0] < 0)
33
sol->array.SZ[i][0] += D->array.SZ[i + first][i + first];
34
}
35
36
return(sol);
37
}
38
39
40
41
/* --------------------------------------------------------------------------- */
42
/* return min(a,b) */
43
/* --------------------------------------------------------------------------- */
44
static int min(int a,
45
int b)
46
{
47
if (a < b)
48
return(a);
49
else
50
return(b);
51
}
52
53
54
55
/* --------------------------------------------------------------------------- */
56
/* which affine classes are in the image */
57
/* --------------------------------------------------------------------------- */
58
/* names: names for the affine classes */
59
/* aff_no: total number of affine classes */
60
/* image_gen: generating system of the image */
61
/* D: the second return value of cohomology */
62
/* anz: save the number of affine classes in the image here */
63
/* --------------------------------------------------------------------------- */
64
int *aff_classes_in_image(MP_INT *names,
65
int aff_no,
66
int coho_size,
67
matrix_TYP **orbit,
68
matrix_TYP **image_gen,
69
int gen_no,
70
matrix_TYP *D,
71
int *anz)
72
{
73
int i, j, k, pos, /* m, */
74
first, last, diff,
75
insg, flag = 0,
76
*list, *aff_list;
77
78
matrix_TYP *tmp;
79
80
MP_INT val;
81
82
83
mpz_init(&val);
84
aff_list = (int *)calloc(aff_no, sizeof(int));
85
list = (int *)calloc(coho_size, sizeof(int));
86
list[0] = -1;
87
anz[0] = 1;
88
aff_list[0] = 1;
89
for (first = 0; first < D->cols && D->array.SZ[first][first] == 1; first++);
90
for (last = first; last < D->cols && D->array.SZ[last][last] != 0; last++);
91
diff = last - first;
92
if (orbit[0] == NULL)
93
orbit[0] = init_mat(diff, 1, "");
94
/* m = coho_size; */
95
96
/* orbit algorithm */
97
for (i = 0; i < coho_size && anz[0] < aff_no; i++){
98
if (list[i] == -1){
99
for (j = 0; j < gen_no; j++){
100
tmp = add_mod_D(orbit[i], image_gen[j], D, first, diff);
101
valuation(tmp, D, &val);
102
pos = mpz_get_ui(&val);
103
if (list[pos] == 0){
104
/* new element in the orbit */
105
list[pos] = -1;
106
if (orbit[pos] == NULL){
107
orbit[pos] = tmp;
108
tmp = NULL;
109
}
110
for (k = 0; k < aff_no; k++){
111
if (mpz_cmp(&val, &names[k]) == 0){
112
/* found representative of the k-th affine class */
113
aff_list[k] = 1;
114
anz[0]++;
115
break;
116
}
117
}
118
}
119
if (tmp != NULL)
120
free_mat(tmp);
121
/*
122
if (list[pos] == -1){
123
m = min(pos, m);
124
}
125
*/
126
}
127
list[i] = 1;
128
/*
129
if (m == i){
130
m = coho_size;
131
}
132
else{
133
i = m - 1;
134
}
135
*/
136
i = -1;
137
}
138
}
139
140
/* clean */
141
mpz_clear(&val);
142
free(list);
143
144
return(aff_list);
145
}
146
147
148
149
150
151
/* --------------------------------------------------------------------------- */
152
/* calculate all elements in the group generated by M */
153
/* in the cohomology group given by the second return value of cohomology */
154
/* the elements of M have to be in in this cohomology group */
155
/* return list, which number/element of the cohomology group is in our group */
156
/* --------------------------------------------------------------------------- */
157
/* M: generating system */
158
/* D: the second return value of cohomology */
159
/* anz: save the order of the group here */
160
/* elements: save the elements of the group (at the correct place in the */
161
/* cohomology group) here */
162
/* coho_size: size of the cohomology group */
163
/* --------------------------------------------------------------------------- */
164
int *aufspannen(int coho_size,
165
matrix_TYP **elements,
166
matrix_TYP **M,
167
int gen_no,
168
matrix_TYP *D,
169
int *anz)
170
{
171
int i, j, pos, /* m, */
172
first, last, diff,
173
*list;
174
175
matrix_TYP *tmp;
176
177
MP_INT val;
178
179
180
mpz_init(&val);
181
list = (int *)calloc(coho_size, sizeof(int));
182
list[0] = -1;
183
anz[0] = 1;
184
for (first = 0; first < D->cols && D->array.SZ[first][first] == 1; first++);
185
for (last = first; last < D->cols && D->array.SZ[last][last] != 0; last++);
186
diff = last - first;
187
if (elements[0] == NULL)
188
elements[0] = init_mat(diff, 1, "");
189
/* m = coho_size; */
190
191
/* orbit algorithm */
192
for (i = 0; i < coho_size && anz[0] < coho_size; i++){
193
if (list[i] == -1){
194
for (j = 0; j < gen_no; j++){
195
tmp = add_mod_D(elements[i], M[j], D, first, diff);
196
valuation(tmp, D, &val);
197
pos = mpz_get_ui(&val);
198
if (list[pos] == 0){
199
/* new element in the orbit */
200
anz[0]++;
201
list[pos] = -1;
202
if (elements[pos] == NULL){
203
elements[pos] = tmp;
204
tmp = NULL;
205
}
206
}
207
if (tmp != NULL)
208
free_mat(tmp);
209
/*
210
if (list[pos] == -1){
211
m = min(pos, m);
212
}
213
*/
214
}
215
list[i] = 1;
216
/*
217
if (m == i){
218
m = coho_size;
219
}
220
else{
221
i = m - 1;
222
}
223
*/
224
i = -1;
225
}
226
}
227
228
for (i = 0; i < coho_size; i++){
229
if (list[i] == -1)
230
list[i] = 1;
231
}
232
233
/* clean */
234
mpz_clear(&val);
235
236
return(list);
237
}
238
239
240
241
/* ----------------------------------------------------------------------------- */
242
static void mod(int *a,
243
int b)
244
{
245
a[0] %= b;
246
if (a[0] < 0)
247
a[0] += b;
248
}
249
250
251
252
/* ----------------------------------------------------------------------------- */
253
static int search_next(int *list,
254
int *ker_list,
255
int coho_size)
256
{
257
int i;
258
259
if (ker_list != NULL){
260
for (i = 1; i < coho_size; i++){
261
if (ker_list[i] == 1 && list[i] == 0)
262
return(i);
263
}
264
}
265
else{
266
for (i = 1; i < coho_size; i++){
267
if (list[i] == 0)
268
return(i);
269
}
270
}
271
272
return(-1);
273
}
274
275
276
/* ----------------------------------------------------------------------------- */
277
/* calculate the representation of S on H^1(...)/Ker(phi) */
278
/* ----------------------------------------------------------------------------- */
279
matrix_TYP **new_representation(matrix_TYP **S,
280
int S_no,
281
H1_mod_ker_TYP H1_mod_ker,
282
matrix_TYP *A)
283
{
284
int i, j, k, d, s,
285
erz_no, A_first;
286
287
matrix_TYP **rep,
288
*tmp, *temp;
289
290
291
erz_no = H1_mod_ker.erz_no;
292
rep = (matrix_TYP **)calloc(S_no, sizeof(matrix_TYP *));
293
for (A_first = 0; A_first < A->cols && A->array.SZ[A_first][A_first] == 1; A_first++);
294
295
for (i = 0; i < S_no; i++){
296
rep[i] = init_mat(erz_no, erz_no, "");
297
for (j = 0; j < erz_no; j++){
298
299
/* bilde Basiselement ab mit Erzeuger von S1 */
300
tmp = mat_mul(S[i], H1_mod_ker.M[j]);
301
for (k = 0; k < tmp->rows; k++){
302
tmp->array.SZ[k][0] %= A->array.SZ[k + A_first][k + A_first];
303
if (tmp->array.SZ[k][0] < 0)
304
tmp->array.SZ[k][0] += A->array.SZ[k + A_first][k + A_first];
305
}
306
307
/* Berechne Standardform als Element von H^1/Ker */
308
temp = mat_mul(H1_mod_ker.i, tmp);
309
free_mat(tmp);
310
for (k = 0; k < temp->rows; k++){
311
temp->array.SZ[k][0] %= H1_mod_ker.D->array.SZ[k][k];
312
if (temp->array.SZ[k][0] < 0)
313
temp->array.SZ[k][0] += H1_mod_ker.D->array.SZ[k][k];
314
}
315
316
/* trage in Matrix ein */
317
for (k = 0; k < erz_no; k++){
318
rep[i]->array.SZ[k][j] = temp->array.SZ[k + H1_mod_ker.D_first][0];
319
}
320
free_mat(temp);
321
}
322
}
323
return(rep);
324
}
325
326
327
328
/* ----------------------------------------------------------------------------- */
329
/* from the H^1/Ker representation to the H^1 representation */
330
/* ----------------------------------------------------------------------------- */
331
static matrix_TYP *back_to_H1(matrix_TYP *elem,
332
H1_mod_ker_TYP Hk)
333
{
334
int i;
335
336
matrix_TYP *mat;
337
338
rational eins, zahl;
339
340
eins.z = eins.n = zahl.n = 1;
341
342
343
mat = copy_mat(Hk.M[0]);
344
for (i = 0; i < mat->rows; i++){
345
mat->array.SZ[i][0] *= elem->array.SZ[0][0];
346
}
347
348
for (i = 1; i < Hk.erz_no; i++){
349
if (elem->array.SZ[i][0] != 0){
350
zahl.z = elem->array.SZ[i][0];
351
mat = mat_addeq(mat, Hk.M[i], eins, zahl);
352
}
353
}
354
355
return(mat);
356
}
357
358
359
360
/* ----------------------------------------------------------------------------- */
361
/* orbit algorithm: act with S on H^1(...)/Ker(phi) */
362
/* in orbit 0 is only the 0 element */
363
/* save WORDS for the stabilizers of ksi + Ker(phi) for a representative in */
364
/* each orbit */
365
/* start = NULL: berechne alle Orbits */
366
/* start != NULL: berechne nur den Orbit von start */
367
/* ----------------------------------------------------------------------------- */
368
matrix_TYP ***H1_mod_ker_orbit_alg(H1_mod_ker_TYP H1_mod_ker,
369
matrix_TYP **S,
370
int S_no,
371
int *anz,
372
int **length,
373
int ****WORDS,
374
int **WORDS_no,
375
matrix_TYP *start)
376
{
377
matrix_TYP *D,
378
*tmp,
379
**elem,
380
***rep;
381
382
int i, j, k, /* m, */ i__,
383
pos, number, addmem,
384
*list, *smallest, **words,
385
coho_size, erz_no, counter = 0;
386
387
MP_INT val, cohom_size, MP_i;
388
389
390
mpz_init(&val);
391
erz_no = H1_mod_ker.erz_no;
392
D = init_mat(erz_no, erz_no, "");
393
for (i = 0; i < erz_no; i++){
394
D->array.SZ[i][i] = H1_mod_ker.D->array.SZ[i + H1_mod_ker.D_first][i + H1_mod_ker.D_first];
395
}
396
cohom_size = cohomology_size(D);
397
coho_size = mpz_get_ui(&cohom_size);
398
elem = (matrix_TYP **)calloc(coho_size, sizeof(matrix_TYP *));
399
list = (int *)calloc(coho_size, sizeof(int));
400
length[0] = (int *)calloc(coho_size + 1, sizeof(int));
401
smallest = (int *)calloc(coho_size + 1, sizeof(int));
402
WORDS[0] = (int ***)calloc(coho_size + 1, sizeof(int **));
403
WORDS_no[0] = (int *)calloc(coho_size + 1, sizeof(int));
404
405
if (start == NULL){
406
if (coho_size > 1)
407
i = 1;
408
else
409
i = -1;
410
anz[0] = 1;
411
counter = length[0][0] = 1;
412
smallest[0] = 0;
413
}
414
else{
415
anz[0] = 1;
416
for (k = 0; k < erz_no; k++)
417
mod(start->array.SZ[k], D->array.SZ[k][k]);
418
valuation(start, D, &val);
419
i = mpz_get_ui(&val);
420
}
421
422
423
while (i != -1){
424
WORDS[0][anz[0]] = (int **)calloc(1024, sizeof(int *));
425
words = (int **)calloc(coho_size, sizeof(int *));
426
list[i] = -anz[0];
427
smallest[anz[0]] = i;
428
length[0][anz[0]] = 1;
429
mpz_init_set_si(&MP_i, i);
430
elem[i] = reverse_valuation(&MP_i, D);
431
mpz_clear(&MP_i);
432
/* m = coho_size; */
433
for (; i < coho_size && counter < coho_size; i++){
434
if (list[i] == -anz[0]){
435
for (j = 0; j < S_no; j++){
436
tmp = mat_mul(S[j], elem[i]);
437
for (k = 0; k < erz_no; k++)
438
mod(tmp->array.SZ[k], D->array.SZ[k][k]);
439
valuation(tmp, D, &val);
440
pos = mpz_get_ui(&val);
441
442
/* paranoia test */
443
if (list[pos] != 0 && abs(list[pos]) != anz[0]){
444
fprintf(stderr, "ERROR in H1_mod_ker_orbit_alg!\n");
445
exit(8);
446
}
447
448
if (list[pos] == 0){
449
/* new element in the orbit */
450
/*words[pos] = (int *)calloc(MIN_SPEICHER, sizeof(int));*/
451
if (i != smallest[anz[0]]){
452
words[pos] = (int *)calloc(words[i][0] + 2, sizeof(int)); /*N*/
453
/*memcpy(words[pos], words[i], (words[i][0] + 1) * sizeof(int));*/
454
for (i__ = 0; i__ < words[i][0] + 1; i__++){
455
words[pos][i__] = words[i][i__];
456
}
457
words[pos][words[i][0] + 1] = -(j+1);
458
words[pos][0]++;
459
}
460
else{
461
words[pos] = (int *)calloc(2, sizeof(int)); /*N*/
462
words[pos][0] = 1;
463
words[pos][1] = -(j+1);
464
}
465
list[pos] = -anz[0];
466
counter++;
467
length[0][anz[0]]++;
468
elem[pos] = tmp;
469
tmp = NULL;
470
}
471
else{
472
/* we got this element already */
473
if (WORDS_no[0][anz[0]] % 1024 == 0){ /*N*/
474
WORDS[0][anz[0]] = (int **)realloc(WORDS[0][anz[0]],
475
(1024 + WORDS_no[0][anz[0]]) * sizeof(int *));
476
}
477
478
/*WORDS[0][anz[0]][WORDS_no[0][anz[0]]] = (int *)calloc(MIN_SPEICHER, sizeof(int));*/
479
if (pos != smallest[anz[0]]){ /*N*/
480
addmem = words[pos][0];
481
}
482
else{
483
addmem = 0;
484
}
485
if (i != smallest[anz[0]]){
486
WORDS[0][anz[0]][WORDS_no[0][anz[0]]] = (int *)calloc(words[i][0] + 2 + addmem, sizeof(int));/*N*/
487
/*memcpy(WORDS[0][anz[0]][WORDS_no[0][anz[0]]], words[i], (words[i][0] + 1) * sizeof(int)); */
488
for (i__ = 0; i__ < words[i][0] + 1; i__++){
489
WORDS[0][anz[0]][WORDS_no[0][anz[0]]][i__] = words[i][i__];
490
}
491
WORDS[0][anz[0]][WORDS_no[0][anz[0]]][words[i][0] + 1] = -(j+1);
492
WORDS[0][anz[0]][WORDS_no[0][anz[0]]][0]++;
493
}
494
else{
495
WORDS[0][anz[0]][WORDS_no[0][anz[0]]] = (int *)calloc(2 + addmem, sizeof(int));/*N*/
496
WORDS[0][anz[0]][WORDS_no[0][anz[0]]][0] = 1;
497
WORDS[0][anz[0]][WORDS_no[0][anz[0]]][1] = -(j+1);
498
}
499
if (pos != smallest[anz[0]]){
500
number = WORDS[0][anz[0]][WORDS_no[0][anz[0]]][0] + words[pos][0];
501
for (k = 0; k < words[pos][0]; k++){
502
WORDS[0][anz[0]][WORDS_no[0][anz[0]]][number - k] = -words[pos][k + 1];
503
}
504
WORDS[0][anz[0]][WORDS_no[0][anz[0]]][0] = number;
505
}
506
WORDS_no[0][anz[0]]++;
507
508
509
free_mat(tmp);
510
}
511
/*
512
if (list[pos] == -anz[0]){
513
m = min(pos, m);
514
}
515
*/
516
}
517
list[i] = anz[0];
518
/*
519
if (m == i){
520
m = coho_size;
521
}
522
else{
523
i = m - 1;
524
}
525
*/
526
i = -1;
527
}
528
}
529
if (start == NULL){
530
i = search_next(list, NULL, coho_size);
531
}
532
else{
533
i = -1;
534
}
535
anz[0]++;
536
for (j = 0; j < coho_size; j++)
537
if (words[j] != NULL)
538
free(words[j]);
539
free(words);
540
}
541
542
543
/* representatives */
544
rep = (matrix_TYP ***)calloc(anz[0], sizeof(matrix_TYP **));
545
for (i = 1; i < anz[0]; i++){
546
rep[i] = (matrix_TYP **)calloc(length[0][i], sizeof(matrix_TYP *));
547
counter = 0;
548
for (j = 0; j < coho_size; j++){
549
if ((list[j] == i || list[j] == -i) && counter < length[0][i]){
550
rep[i][counter] = back_to_H1(elem[j], H1_mod_ker);
551
counter++;
552
}
553
}
554
}
555
556
/* clean */
557
mpz_clear(&cohom_size);
558
mpz_clear(&val);
559
free_mat(D);
560
free(list);
561
free(smallest);
562
for (i = 1; i < coho_size; i++)
563
if (elem[i] != NULL)
564
free_mat(elem[i]);
565
free(elem);
566
567
568
return(rep);
569
}
570
571
572
/* ----------------------------------------------------------------------------- */
573
/* orbitalgorithm on a subgroup of H^1 */
574
/* ker_elements: list of elements in the subgroup */
575
/* H^1 is given by D, the second return value of cohomology */
576
/* coho_size: size of H^1 */
577
/* N: operating group */
578
/* no: number of elements in N */
579
/* ker_list: list, which element of the cohomology group is in the subgroup */
580
/* ker_order: order of the subgroup */
581
/* anz: save the number of orbits here */
582
/* length: save the length of an orbit here */
583
/* ----------------------------------------------------------------------------- */
584
/* in orbit 0 is only the 0-element */
585
/* ----------------------------------------------------------------------------- */
586
matrix_TYP **orbit_ker(matrix_TYP **ker_elements,
587
int ker_order,
588
matrix_TYP *D,
589
matrix_TYP **N,
590
int no,
591
int coho_size,
592
int *ker_list,
593
int *anz,
594
int **length)
595
{
596
int i, j, k, /* m, */ pos,
597
first, last, diff, counter,
598
ttt = 0,
599
*list, *smallest;
600
601
matrix_TYP **orbit_rep,
602
*tmp;
603
604
MP_INT val;
605
606
607
for (first = 0; first < D->cols && D->array.SZ[first][first] == 1; first++);
608
for (last = first; last < D->cols && D->array.SZ[last][last] != 0; last++);
609
diff = last - first;
610
length[0] = (int *)calloc(coho_size, sizeof(int));
611
anz[0] = counter = length[0][0] = 1;
612
for (i = 1; i < coho_size; i++){
613
if (ker_list[i] == 1)
614
break;
615
}
616
617
/* only 0-element in the subgroup */
618
if (i == coho_size){
619
orbit_rep = (matrix_TYP **)calloc(1, sizeof(matrix_TYP *));
620
orbit_rep[0] = init_mat(diff, 1, "");
621
return(orbit_rep);
622
}
623
624
mpz_init(&val);
625
list = (int *)calloc(coho_size, sizeof(int));
626
smallest = (int *)calloc(coho_size, sizeof(int));
627
628
/* orbit algorithm */
629
while (i != -1){
630
list[i] = -anz[0];
631
smallest[anz[0]] = i;
632
length[0][anz[0]] = 1;
633
/* m = coho_size; */
634
for (; i < coho_size && counter < ker_order; i++){
635
if (list[i] == -anz[0]){
636
for (j = 0; j < no; j++){
637
tmp = mat_mul(N[j], ker_elements[i]);
638
for (k = first; k < last; k++)
639
mod(tmp->array.SZ[k-first], D->array.SZ[k][k]);
640
valuation(tmp, D, &val);
641
pos = mpz_get_ui(&val);
642
643
/* paranoia test */
644
if (ker_list[pos] != 1 || (list[pos] != 0 && abs(list[pos]) != anz[0])){
645
fprintf(stderr, "ERROR in orbit_ker!\n");
646
exit(7);
647
}
648
649
if (list[pos] == 0){
650
/* new element in the orbit */
651
list[pos] = -anz[0];
652
counter++;
653
length[0][anz[0]]++;
654
}
655
free_mat(tmp);
656
/*
657
if (list[pos] == -anz[0]){
658
m = min(pos, m);
659
}
660
*/
661
}
662
list[i] = anz[0];
663
/*
664
if (m == i){
665
m = coho_size;
666
}
667
else{
668
i = m - 1;
669
}
670
*/
671
i = -1;
672
}
673
}
674
i = search_next(list, ker_list, coho_size);
675
anz[0]++;
676
}
677
678
/* save representatives */
679
orbit_rep = (matrix_TYP **)calloc(anz[0], sizeof(matrix_TYP *));
680
for (i = 0; i < anz[0]; i++){
681
orbit_rep[i] = copy_mat(ker_elements[smallest[i]]);
682
if (GRAPH_DEBUG)
683
ttt += length[0][i];
684
}
685
686
if (GRAPH_DEBUG){
687
if (ttt != ker_order){
688
fprintf(stderr, "NEIN!!!!!!!!!!!!\n");
689
exit(5);
690
}
691
}
692
693
/* clean */
694
mpz_clear(&val);
695
free(smallest);
696
free(list);
697
698
return(orbit_rep);
699
}
700
701
702
703
704
/* ----------------------------------------------------------------------------- */
705
/* orbitalgorithm on a ksi + ker, where ker is a subgroup of H^1 */
706
/* ker_elements: list of elements in the subgroup */
707
/* H^1 is given by D, the second return value of cohomology */
708
/* coho_size: size of H^1 */
709
/* N: operating group (IS CHANGED !!!) */
710
/* no: number of elements in N */
711
/* ker_list: list, which element of the cohomology group is in the subgroup */
712
/* ker_order: order of the subgroup */
713
/* anz: save the number of orbits here */
714
/* length: save the length of an orbit here */
715
/* ----------------------------------------------------------------------------- */
716
/* in orbit 0 is only the 0-element */
717
/* ----------------------------------------------------------------------------- */
718
matrix_TYP **orbit_ksi_plus_ker(matrix_TYP *ksi,
719
matrix_TYP **ker_elements,
720
int ker_order,
721
matrix_TYP *D,
722
matrix_TYP **N,
723
int no,
724
int coho_size,
725
int *ker_list,
726
int *anz,
727
int **length)
728
{
729
int i, j, k, /* m, */ rows, first, last, diff, pos,
730
ttt = 0,
731
*list, *smallest, counter;
732
733
matrix_TYP *tmp, **orbit_rep;
734
735
rational eins, minuseins;
736
737
MP_INT val;
738
739
740
741
rows = ker_elements[0]->rows - 1;
742
743
if (ker_order > 1){
744
eins.z = eins.n = minuseins.n = 1;
745
minuseins.z = -1;
746
for (first = 0; first < D->cols && D->array.SZ[first][first] == 1; first++);
747
for (last = first; last < D->cols && D->array.SZ[last][last] != 0; last++);
748
diff = last - first;
749
750
for (i = 0; i < no; i++){
751
tmp = mat_mul(N[i], ksi);
752
mat_addeq(tmp, ksi, eins, minuseins);
753
for (j = 0; j < rows; j++){
754
tmp->array.SZ[j][0] %= D->array.SZ[j + first][j + first];
755
if (tmp->array.SZ[j][0] < 0){
756
tmp->array.SZ[j][0] += D->array.SZ[j + first][j + first];
757
}
758
}
759
real_mat(N[i], rows + 1, rows);
760
real_mat(N[i], rows + 1, rows + 1);
761
N[i]->array.SZ[rows][rows] = 1;
762
for (j = 0; j < rows; j++){
763
N[i]->array.SZ[j][rows] = tmp->array.SZ[j][0];
764
}
765
free_mat(tmp);
766
}
767
768
mpz_init(&val);
769
list = (int *)calloc(coho_size, sizeof(int));
770
smallest = (int *)calloc(coho_size, sizeof(int));
771
length[0] = (int *)calloc(coho_size, sizeof(int));
772
counter = anz[0] = 1;
773
i = 0;
774
775
/* orbit algorithm */
776
while (i != -1){
777
list[i] = -anz[0];
778
smallest[anz[0] - 1] = i;
779
length[0][anz[0] - 1] = 1;
780
/* m = coho_size; */
781
for (; i < coho_size && counter < ker_order; i++){
782
if (list[i] == -anz[0]){
783
for (j = 0; j < no; j++){
784
tmp = mat_mul(N[j], ker_elements[i]);
785
for (k = first; k < last; k++)
786
mod(tmp->array.SZ[k-first], D->array.SZ[k][k]);
787
valuation(tmp, D, &val);
788
pos = mpz_get_ui(&val);
789
790
/* paranoia test */
791
if (ker_list[pos] != 1 || (list[pos] != 0 && abs(list[pos]) != anz[0])){
792
fprintf(stderr, "ERROR in orbit_ksi_plus_ker!\n");
793
exit(7);
794
}
795
796
if (list[pos] == 0){
797
/* new element in the orbit */
798
list[pos] = -anz[0];
799
counter++;
800
length[0][anz[0] - 1]++;
801
}
802
free_mat(tmp);
803
/*
804
if (list[pos] == -anz[0]){
805
m = min(pos, m);
806
}
807
*/
808
}
809
list[i] = anz[0];
810
/*
811
if (m == i){
812
m = coho_size;
813
}
814
else{
815
i = m - 1;
816
}
817
*/
818
i = -1;
819
}
820
}
821
i = search_next(list, ker_list, coho_size);
822
anz[0]++;
823
}
824
825
/* save representatives */
826
anz[0]--;
827
orbit_rep = (matrix_TYP **)calloc(anz[0], sizeof(matrix_TYP *));
828
for (i = 0; i < anz[0]; i++){
829
orbit_rep[i] = copy_mat(ker_elements[smallest[i]]);
830
real_mat(orbit_rep[i], rows, 1);
831
if (GRAPH_DEBUG){
832
ttt += length[0][i];
833
}
834
}
835
836
if (GRAPH_DEBUG){
837
if (ttt != ker_order){
838
fprintf(stderr, "NEIN!!!!!!!!!!!!\n");
839
exit(5);
840
}
841
}
842
843
/* clean */
844
mpz_clear(&val);
845
free(smallest);
846
free(list);
847
}
848
else{
849
/* trivial part */
850
length[0] = (int *)calloc(1, sizeof(int));
851
length[0][0] = anz[0] = 1;
852
orbit_rep = (matrix_TYP **)calloc(1, sizeof(matrix_TYP *));
853
orbit_rep[0] = init_mat(rows, 1, "");
854
}
855
856
return(orbit_rep);
857
}
858
859
860
861
/* -------------------------------------------------------------------- */
862
static int search_pos(matrix_TYP *mat, matrix_TYP **menge, int anz)
863
{
864
int i;
865
866
for (i = 0; i < anz; i++){
867
if (cmp_mat(mat, menge[i]) == 0)
868
return(i);
869
}
870
return(-1);
871
}
872
873
874
875
/* -------------------------------------------------------------------- */
876
/* orbit_on_lattices */
877
/* Let R be a (affine) space group and P its pointgroup. */
878
/* Calculation of the orbits of the P-invariant max. sublattices or min.*/
879
/* superlattices (saved in gitter) under the operation of the linear */
880
/* part of the affine normalizer of R. */
881
/* return number of orbits */
882
/* -------------------------------------------------------------------- */
883
/* gitter: lattices in normal form */
884
/* gitter_no: number of lattices (>= 1 !!!) */
885
/* N: affine_normalizer of R (linear part) */
886
/* N_no: number of generators of the normalizer */
887
/* list: list, which lattice is in which orbit */
888
/* length: list with the lengthes of the orbits */
889
/* smallest: for each orbit, lowest number of the elements in it */
890
/* conj: if conj, save conjugating matrices here */
891
/* -------------------------------------------------------------------- */
892
int orbit_on_lattices(matrix_TYP **gitter,
893
int gitter_no,
894
matrix_TYP **N,
895
int N_no,
896
int *list,
897
int *length,
898
int *smallest,
899
matrix_TYP **conj)
900
{
901
int i, j, m, pos, counter, anz, dim;
902
903
matrix_TYP *tmp;
904
905
906
dim = gitter[0]->rows;
907
anz = i = counter = 0;
908
909
/* orbit algorithm */
910
while (i != -1){
911
anz++;
912
counter++;
913
list[i] = -anz;
914
if (conj)
915
conj[i] = init_mat(dim, dim, "1");
916
length[anz] = 1;
917
smallest[anz] = i;
918
for (; i < gitter_no && counter < gitter_no; i++){
919
if (list[i] == -anz){
920
m = gitter_no;
921
for (j = 0; j < N_no; j++){
922
tmp = mat_mul(N[j], gitter[i]);
923
long_col_hnf(tmp);
924
pos = search_pos(tmp, gitter, gitter_no);
925
926
/* paranoia test */
927
if (pos == -1 || (list[pos] != 0 && abs(list[pos]) != anz)){
928
fprintf(stderr, "ERROR in operiere_gitter!\n");
929
exit(7);
930
}
931
932
if (list[pos] == 0){
933
/* new element in the orbit */
934
list[pos] = -anz;
935
counter++;
936
length[anz]++;
937
if (conj){
938
conj[pos] = mat_mul(N[j], conj[i]);
939
}
940
}
941
free_mat(tmp);
942
if (list[pos] == -anz){
943
m = min(pos, m);
944
}
945
}
946
list[i] = anz;
947
i = m - 1;
948
}
949
}
950
i = search_next(list, NULL, gitter_no);
951
}
952
953
for (i = 0; i < gitter_no; i++){
954
if (list[i] < 0) list[i] *= (-1);
955
}
956
957
return(anz);
958
}
959
960
961
962
/* -------------------------------------------------------------------- */
963
static matrix_TYP *add_mod_lattice(matrix_TYP *A,
964
matrix_TYP *B,
965
matrix_TYP *D,
966
matrix_TYP *Ti,
967
matrix_TYP *T,
968
int dim,
969
int erz_no)
970
{
971
int i, j;
972
973
rational eins;
974
975
matrix_TYP *C, *tmp, *tmp2;
976
977
978
eins.z = eins.n = 1;
979
980
C = mat_add(A, B, eins, eins);
981
tmp = mat_mul(Ti, C);
982
for (i = 0; i < erz_no; i++){
983
for (j = 0; j < dim; j++){
984
tmp->array.SZ[i * dim + j][0] %= D->array.SZ[j][j];
985
if (tmp->array.SZ[i * dim + j][0] < 0)
986
tmp->array.SZ[i * dim + j][0] += D->array.SZ[j][j];
987
}
988
}
989
990
tmp2 = mat_mul(T, tmp);
991
free_mat(tmp);
992
free_mat(C);
993
return(tmp2);
994
}
995
996
997
998
/* -------------------------------------------------------------------- */
999
/* calculate information about Ker phi | B^1 */
1000
/* -------------------------------------------------------------------- */
1001
matrix_TYP **kernel_factor_fct(matrix_TYP **translationen,
1002
int translanz,
1003
int erz_no,
1004
matrix_TYP *lattice,
1005
int *anz)
1006
{
1007
int i, j, dim, pos, size = 1024;
1008
1009
matrix_TYP *tmp, **elem, *D, *R, *Li, *Li_d, *L_d, *L;
1010
1011
1012
anz[0] = 1;
1013
dim = lattice->rows;
1014
elem = (matrix_TYP **)calloc(size, sizeof(matrix_TYP *));
1015
elem[0] = init_mat(erz_no * dim, 1, "");
1016
L = init_mat(dim, dim, "1");
1017
R = init_mat(dim, dim, "1");
1018
D = long_elt_mat(L, lattice, R);
1019
Li = mat_inv(L);
1020
L_d = matrix_on_diagonal(L, erz_no);
1021
Li_d = matrix_on_diagonal(Li, erz_no);
1022
1023
for (i = 0; i < anz[0]; i++){
1024
for (j = 0; j < translanz; j++){
1025
tmp = add_mod_lattice(elem[i], translationen[j], D, L_d, Li_d, dim, erz_no);
1026
pos = search_pos(tmp, elem, anz[0]);
1027
if (pos == -1){
1028
if (anz[0] >= size){
1029
size += 1024;
1030
elem = realloc(elem, size * sizeof(matrix_TYP *));
1031
}
1032
elem[anz[0]] = tmp;
1033
tmp = NULL;
1034
anz[0]++;
1035
}
1036
else{
1037
free_mat(tmp);
1038
}
1039
}
1040
}
1041
1042
/* clean */
1043
free_mat(D);
1044
free_mat(R);
1045
free_mat(L);
1046
free_mat(Li);
1047
free_mat(L_d);
1048
free_mat(Li_d);
1049
1050
return(elem);
1051
}
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065