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

563642 views
1
#include<typedef.h>
2
#include<getput.h>
3
#include<matrix.h>
4
#include<longtools.h>
5
#include<tools.h>
6
#include"zass.h"
7
8
9
10
11
12
matrix_TYP *scalar(long n,long a)
13
/* liefert eine skalarmatrix mit dem eintrag a */
14
{
15
long i;
16
matrix_TYP *erg;
17
18
erg = init_mat(n,n,"k");
19
20
for (i=0;i<n;i++){erg->array.SZ[i][i]=a;}
21
22
return erg;
23
} /* scalar */
24
25
matrix_TYP *matrizen_in_word(matrix_TYP **mat,matrix_TYP **matinv,word g)
26
/* geht davon aus, das alle (benoetigten) matrizen in **mat
27
quadratisch von gleicher groesse sind. anderfalls wird nicht abgebrochen */
28
{
29
matrix_TYP *erg,*tmp_matrix;
30
long i,n;
31
32
n = mat[0]->cols;
33
erg = scalar(n,g.faktor);
34
35
for (i=0;i<=g.last;i++){
36
if (g.pointer[i]>0){
37
tmp_matrix = mat_mul(erg,mat[g.pointer[i]-1]);
38
free_mat(erg);
39
erg = tmp_matrix;
40
}
41
else if (g.pointer[i]<0){
42
/* 1ster fall, die inverse ist noch nicht berechnet */
43
if (matinv[-g.pointer[i]-1]==NULL){
44
matinv[-g.pointer[i]-1]= mat_inv(mat[-g.pointer[i]-1]);
45
}
46
tmp_matrix = mat_mul(erg,matinv[-g.pointer[i]-1]);
47
free_mat(erg);
48
erg = tmp_matrix;
49
}
50
}
51
52
if (INFO_LEVEL & 4){
53
put_mat(erg,NULL,NULL,2);
54
}
55
56
return erg;
57
} /* matrizen_in_word */
58
59
60
61
static void norm_word(word *g)
62
/* soll die auftretenden worte vereinfachen */
63
{
64
int i,j;
65
66
/* wenn der faktor des relators = 0, dann auch der relator */
67
if (g[0].faktor==0){
68
g[0].last = -1;
69
for (i=0;i<g[0].speicher;i++){
70
g[0].pointer[i]=0;
71
}
72
}
73
74
/* suchen nach einsen (representiert durch nullen) im relator */
75
i = 0;
76
while(i<=g[0].last){
77
if (g[0].pointer[i]==0){
78
for (j=i+1;j<=g[0].last;j++){
79
g[0].pointer[j-1]=g[0].pointer[j];
80
}
81
g[0].last--;
82
}
83
else{
84
i++;
85
}
86
}
87
88
/* suchen nach ausdruecken wie x_j * x_j^(-1) */
89
i=0;
90
while(i<g[0].last){
91
if (g[0].pointer[i]==(-g[0].pointer[i+1])){
92
g[0].pointer[i]=0;
93
g[0].pointer[i+1]=0;
94
/* und jetzt die enstandenen nullen eliminieren
95
(geht nicht durch vertauschen der while-schleifen, weil
96
so x_1 * x_2 * x_2^(-1) * x_1^(-1) nicht erkannt wuerde) */
97
norm_word(g);
98
/* nur der sicherheit halber */
99
i= -1;
100
}
101
i++;
102
}
103
104
return;
105
}
106
107
extern int wordfree(word *a)
108
{
109
110
free(a[0].pointer);
111
112
return TRUE;
113
}
114
115
static int ini_word(word *a,int laenge)
116
{
117
a[0].pointer = (long *) malloc(laenge * sizeof(long));
118
a[0].speicher = laenge;
119
a[0].last = 0;
120
121
return TRUE;
122
}
123
124
125
static int test_relator(matrix_TYP **mat,matrix_TYP **matinv,word *relator,long anz)
126
/* testet, ob die relationen in *relator erfuellt sind:
127
wenn ja: return true; sonst false */
128
{
129
long i,n;
130
int flag;
131
matrix_TYP *id,*tmp;
132
133
flag = TRUE;
134
i = 0;
135
n = mat[0]->cols;
136
id = scalar(n,1);
137
138
while(i<anz && flag==TRUE){
139
tmp = matrizen_in_word(mat,matinv,relator[i]);
140
141
if (INFO_LEVEL & 4){
142
put_mat(tmp,NULL,"tmp in test_relator",2);
143
put_mat(id,NULL,"id in test_relator",2);
144
}
145
146
if (cmp_mat(tmp,id)!=0){
147
flag = FALSE;
148
}
149
i++;
150
free_mat(tmp);
151
}
152
153
free_mat(id);
154
return flag;
155
} /* test_relator */
156
157
void matrix_2_word(matrix_TYP *matrix,word *relator,long zeile)
158
{
159
long i,hilf;
160
161
if (relator[0].speicher !=0 ){
162
free(relator[0].pointer);
163
relator[0].speicher = 0;
164
}
165
166
ini_word(relator,matrix->cols);
167
168
relator[0].last = matrix->cols -1;
169
relator[0].faktor = 1;
170
171
hilf = 0;
172
for (i=0;i<=relator[0].last;i++){
173
relator[0].pointer[i] = matrix->array.SZ[zeile][i+hilf];
174
if (relator[0].pointer[i] == 0){i--;hilf++;relator[0].last--;}
175
}
176
177
norm_word(relator);
178
179
return;
180
} /* matrix_2_word */
181
182
static matrix_TYP *fox_deriv_mat(matrix_TYP **mat, matrix_TYP **matinv,word a,long j)
183
/* soll rekursiv die j-te fox-derivation vom word a berechnen und sie
184
in erg abspeichern */
185
{
186
word g,h;
187
long i,teil;
188
matrix_TYP *erg,
189
*nu_g,
190
*nu_h,
191
*g_mat,
192
*tmp;
193
194
if (INFO_LEVEL & 4){
195
printf("fox_deriv_mat\n");
196
}
197
198
norm_word(&a);
199
200
if ( a.last==0 || a.last == (-1) ){
201
if (a.pointer[0]==j){
202
erg = scalar(mat[0]->cols,1);
203
}
204
else if (a.pointer[0]==(-j)){
205
tmp = scalar(mat[0]->cols,-1);
206
if (matinv[j-1]==NULL){
207
matinv[j-1]=mat_inv(mat[j-1]);
208
}
209
erg = mat_mul(tmp,matinv[j-1]);
210
free_mat(tmp);
211
}
212
else{
213
erg = scalar(mat[0]->cols,0);
214
}
215
}
216
else{
217
218
/* die ersten teil erzeuger von a werden in g
219
gespeichert, der rest in h */
220
teil = 1;
221
ini_word(&g,teil);
222
ini_word(&h,a.last);
223
224
for (i=0;i<=a.last;i++){
225
if (i<teil){
226
g.pointer[i] = a.pointer[i];
227
}
228
else{
229
h.pointer[i-teil] = a.pointer[i];
230
}
231
}
232
233
g.last= teil-1;
234
h.last= a.last-teil;
235
g.faktor=1;
236
h.faktor=1;
237
nu_g = fox_deriv_mat(mat,matinv,g,j);
238
nu_h = fox_deriv_mat(mat,matinv,h,j);
239
240
g_mat = matrizen_in_word(mat,matinv,g);
241
242
tmp = mat_mul(g_mat,nu_h);
243
244
erg = mat_add(nu_g,tmp,One,One);
245
246
wordfree(&g);
247
wordfree(&h);
248
249
free_mat(g_mat);
250
free_mat(nu_g);
251
free_mat(nu_h);
252
free_mat(tmp);
253
254
}
255
256
if (INFO_LEVEL &4){
257
printf("return aus fox_deriv_mat\n");
258
}
259
260
return erg;
261
}
262
263
264
matrix_TYP *calc_B(matrix_TYP **mat,long anz_erzeuger)
265
{
266
long i,k,l,n;
267
matrix_TYP *B;
268
269
n = mat[0]->cols;
270
271
/* reservieren des speichers fuer die matrix B, die die
272
erzeuger - id uebereinander enthaelt */
273
B = init_mat(n*anz_erzeuger,n,"k");
274
275
/* belegen der matrix B */
276
for (i=0;i<anz_erzeuger;i++){
277
for (k=0;k<n;k++){
278
for (l=0;l<n;l++){
279
if (k == l){
280
B->array.SZ[k+i*n][l]=mat[i]->array.SZ[k][l]-1;
281
}
282
else{
283
B->array.SZ[k+i*n][l]=mat[i]->array.SZ[k][l];
284
}
285
}
286
}
287
}
288
289
if (INFO_LEVEL & 4){
290
put_mat(B,NULL,"%B",2);
291
}
292
293
return B;
294
} /* calc_B */
295
296
static matrix_TYP *calc_A(matrix_TYP **mat,matrix_TYP **matinv,word *relator,
297
int erzeuger,int relatoren)
298
{
299
matrix_TYP *eingesetzt,
300
*A;
301
long i,j,k,l,n;
302
303
/* reservieren von speicher fuer die grosse matrix A */
304
n = mat[0]->cols;
305
A = init_mat(n*relatoren,n*erzeuger,"k");
306
307
/* berechnen der j-ten foxableitung des i-ten relators */
308
for (i=0;i<relatoren;i++){
309
for (j=1;j<=erzeuger;j++){
310
311
eingesetzt = fox_deriv_mat(mat,matinv,relator[i],j);
312
313
if (INFO_LEVEL & 4){
314
put_mat(eingesetzt,NULL,NULL,2);
315
}
316
317
Check_mat(eingesetzt);
318
319
/* umspeichern der eintraege aus der fox-ableitung in das
320
gleichungssystem A */
321
for (k=0;k<n;k++){
322
for (l=0;l<n;l++){
323
A->array.SZ[n*i+k][n*(j-1)+l] = eingesetzt->array.SZ[k][l];
324
}
325
}
326
327
/* die matrix eingesetzt wird wieder benutzt */
328
free_mat(eingesetzt);
329
}
330
}
331
332
if (is_option('s')){
333
put_mat(A,FILENAMES[2],"system of congruences to determine H^1(G,**)",2);
334
}
335
336
if (INFO_LEVEL & 4){
337
put_mat(A,NULL,NULL,2);
338
}
339
340
return A;
341
} /* calc_A */
342
343
344
345
matrix_TYP** cohomology(long *dim,
346
matrix_TYP **mat,
347
matrix_TYP **matinv,
348
word *relator,
349
int erzeuger,
350
int relatoren)
351
{ matrix_TYP *A,
352
*B,
353
*B_tr,
354
*cozykel,
355
*elementar,
356
**tmp;
357
358
int corang_a,rang_b,erg,i;
359
360
if (INFO_LEVEL &4){
361
printf("in cohomology\n");
362
}
363
364
/* ueberprueft die gegeben relatoren */
365
if (test_relator(mat,matinv,relator,relatoren)==FALSE){
366
fprintf(stderr,"Error in Cohomlogy:\n");
367
fprintf(stderr,"One of the given relators it not satisfied\n");
368
fprintf(stderr,"by this generating set.\n");
369
fflush(stderr);
370
exit(3);
371
}
372
373
/* berechnet die matrix des fuer die cozykel zu
374
loesenden gleichungssystems */
375
A = calc_A(mat,matinv,relator,erzeuger,relatoren);
376
377
if (INFO_LEVEL & 4){
378
put_mat(A,NULL,"A",2);
379
}
380
381
/* enthaelt nur die erzeuger - id hintereinander,
382
spannt also den raum der coraender auf */
383
B = calc_B(mat, erzeuger);
384
B_tr = tr_pose(B);
385
386
387
/* shrink the linear system of equations by a gauss algorithm,
388
note that this also removes the dependence of the result
389
from the given presentation */
390
long_row_hnf(A);
391
392
/* loesen der gleichungssysteme */
393
tmp = cong_solve(A);
394
395
cozykel = tmp[0];
396
elementar = tmp[1];
397
398
if (INFO_LEVEL &4){
399
put_mat(cozykel,NULL,"cozykel",2);
400
put_mat(elementar,NULL,"elementar",2);
401
}
402
403
rang_b = tgauss(B_tr);
404
405
/* berechnen des coranges von A */
406
corang_a = 0;
407
for (i=0;i<elementar->cols;i++){
408
if (elementar->array.SZ[i][i]==0){
409
corang_a++;
410
}
411
}
412
413
dim[0] = erg = corang_a - rang_b;
414
415
if (INFO_LEVEL & 4){
416
printf("corang_a %d\n",corang_a);
417
printf("rang_b %d\n",rang_b);
418
printf("erg %d\n",erg);
419
}
420
421
if (erg == 0){
422
/* die Q-dimesionen der Coraender und Cozykel sind gleich, d.h.
423
es kommt nur torsion dazu */
424
for (i=elementar->cols-1;0<=i;i--){
425
if (elementar->array.SZ[i][i]==0){
426
kill_col(elementar,i);
427
kill_row(elementar,i);
428
kill_col(cozykel,i);
429
}
430
}
431
}
432
else{
433
/* es interesiert */
434
for (i=elementar->cols-1;0<=i;i--){
435
if (elementar->array.SZ[i][i]!=0){
436
kill_col(elementar,i);
437
kill_row(elementar,i);
438
kill_col(cozykel,i);
439
}
440
}
441
}
442
443
if (INFO_LEVEL & 4){
444
put_mat(A,NULL,NULL,2);
445
put_mat(B,NULL,NULL,2);
446
put_mat(elementar,NULL,NULL,2);
447
put_mat(cozykel,NULL,NULL,2);
448
}
449
450
free_mat(A);
451
free_mat(B);
452
free_mat(B_tr);
453
free_mat(elementar);
454
455
/* free_mat(cozykel); */
456
/* free_mat(tmp2); */
457
tmp[0] = cozykel;
458
tmp[1] = tmp[3];
459
460
tmp = (matrix_TYP **) realloc(tmp,3 *sizeof(matrix_TYP *));
461
/* tmp[1] = elementar; */
462
463
return tmp;
464
} /* cohomology */
465
466
467